From 1989328abed9e30d98c710bca8441da2d816c660 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Tue, 17 Apr 2018 18:57:07 +0300 Subject: [PATCH] [groovy] fix collecting outers for anonymous classes (IDEA-190433) --- .../lang/resolve/GrCodeReferenceResolver.kt | 15 +++++++++++---- .../plugins/groovy/lang/resolve/inners.kt | 12 +++--------- .../groovy/lang/resolve/ResolveClassTest.groovy | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GrCodeReferenceResolver.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GrCodeReferenceResolver.kt index 802c4923bbfc..b04507803f4a 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GrCodeReferenceResolver.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/GrCodeReferenceResolver.kt @@ -233,11 +233,18 @@ private fun GrCodeReferenceElement.getActualParent(): PsiElement? = containingFi * @see org.codehaus.groovy.control.ResolveVisitor.currentClass */ private fun PsiElement.getCurrentClass(): GrTypeDefinition? { - var contexts = contexts().filterIsInstance() - if (context is GrAnonymousClassDefinition) { - contexts = contexts.drop(1) + for (context in contexts()) { + if (context !is GrTypeDefinition) { + continue + } + else if (context is GrAnonymousClassDefinition && this === context.baseClassReferenceGroovy) { + continue + } + else { + return context + } } - return contexts.firstOrNull() + return null } private fun PsiFile?.skipDummies(): PsiFile? { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/inners.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/inners.kt index 59f46bb1ac96..c54bda5f2bb4 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/inners.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/inners.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. @file:Suppress("LoopToCallChain", "UseExpressionBody", "LiftReturnOrAssignment") package org.jetbrains.plugins.groovy.lang.resolve @@ -9,7 +9,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.ResolveState import com.intellij.psi.impl.PsiFileEx import com.intellij.psi.scope.PsiScopeProcessor -import com.intellij.util.SmartList +import com.intellij.psi.util.parentsOfType import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil @@ -111,13 +111,7 @@ internal fun GrTypeDefinition.processInnersInOutersNoCache(processor: PsiScopePr } private fun GrTypeDefinition.collectOuterClasses(): List { - val result = SmartList() - var current: GrTypeDefinition? = containingClass as? GrTypeDefinition - while (current != null) { - result += current - current = current.containingClass as? GrTypeDefinition - } - return result + return parentsOfType().drop(1).toList() } private fun useCaches(place: PsiElement): Boolean { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy index af7374c59f05..4b4d9f740259 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveClassTest.groovy @@ -639,5 +639,20 @@ println Outer.Inner ''', PsiClass } + void 'test resolve to inner class of outer class of anonymous class'() { + resolveByText '''\ +class Foobar { + private static class Quuz {} + void foo() { + new Runnable() { + void run() { + new Quuz() + } + } + } +} +''', PsiClass + } + private void doTest(String fileName = getTestName(false) + ".groovy") { resolve(fileName, PsiClass) } }