User: joe Date: 04 Nov 25 00:25 Revision: e41695012554218ed0a2e4cb04219a367127a460 Summary: Fix double-nested anonymous class resolving. Closes #2491 TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10195&personal=false Index: src/main/kotlin/platform/mcp/at/completion/AtCompletionContributor.kt =================================================================== --- src/main/kotlin/platform/mcp/at/completion/AtCompletionContributor.kt (revision f6b51c91904eef599b5e8c0d7213d51750644e8f) +++ src/main/kotlin/platform/mcp/at/completion/AtCompletionContributor.kt (revision e41695012554218ed0a2e4cb04219a367127a460) @@ -28,7 +28,7 @@ import com.demonwav.mcdev.platform.mcp.at.gen.psi.AtFieldName import com.demonwav.mcdev.platform.mcp.at.gen.psi.AtFunction import com.demonwav.mcdev.platform.mcp.at.gen.psi.AtTypes -import com.demonwav.mcdev.util.anonymousElements +import com.demonwav.mcdev.util.anonymousClasses import com.demonwav.mcdev.util.fullQualifiedName import com.demonwav.mcdev.util.getSimilarity import com.demonwav.mcdev.util.localClasses @@ -147,9 +147,7 @@ ) } - for (anonymousElement in currentClass.anonymousElements) { - val anonClass = anonymousElement as? PsiClass ?: continue - + for (anonClass in currentClass.anonymousClasses) { val name = anonClass.fullQualifiedName ?: continue result.addElement( PrioritizedLookupElement.withPriority( Index: src/main/kotlin/platform/mixin/util/AsmUtil.kt =================================================================== --- src/main/kotlin/platform/mixin/util/AsmUtil.kt (revision f6b51c91904eef599b5e8c0d7213d51750644e8f) +++ src/main/kotlin/platform/mixin/util/AsmUtil.kt (revision e41695012554218ed0a2e4cb04219a367127a460) @@ -22,7 +22,7 @@ import com.demonwav.mcdev.platform.mixin.reference.MixinSelector import com.demonwav.mcdev.util.MemberReference -import com.demonwav.mcdev.util.anonymousElements +import com.demonwav.mcdev.util.anonymousClasses import com.demonwav.mcdev.util.cached import com.demonwav.mcdev.util.childrenOfType import com.demonwav.mcdev.util.findField @@ -395,7 +395,7 @@ // find innermost PsiClass while (true) { clazz = clazz.innerClasses.firstOrNull() - ?: clazz.anonymousElements.lastOrNull { it !== clazz && it is PsiClass } as? PsiClass + ?: clazz.anonymousClasses.lastOrNull() ?: clazz.localClasses.lastOrNull() ?: break } Index: src/main/kotlin/util/class-utils.kt =================================================================== --- src/main/kotlin/util/class-utils.kt (revision f6b51c91904eef599b5e8c0d7213d51750644e8f) +++ src/main/kotlin/util/class-utils.kt (revision e41695012554218ed0a2e4cb04219a367127a460) @@ -22,10 +22,10 @@ import com.demonwav.mcdev.platform.mixin.handlers.desugar.DesugarUtil import com.intellij.codeInsight.daemon.impl.quickfix.AddMethodFix -import com.intellij.navigation.AnonymousElementProvider import com.intellij.openapi.project.Project import com.intellij.psi.CommonClassNames import com.intellij.psi.JavaPsiFacade +import com.intellij.psi.JavaRecursiveElementVisitor import com.intellij.psi.JavaRecursiveElementWalkingVisitor import com.intellij.psi.PsiAnonymousClass import com.intellij.psi.PsiClass @@ -153,7 +153,7 @@ return outerResolver(fullQualifiedName) } - var currentClass = outerResolver(fullQualifiedName.substring(0, innerPos)) ?: return null + var currentClass = outerResolver(fullQualifiedName.take(innerPos)) ?: return null var outerPos: Int while (true) { @@ -183,8 +183,8 @@ null } } else { - if (innerIndex > 0 && innerIndex <= anonymousElements.size) { - anonymousElements[innerIndex - 1] as PsiClass + if (innerIndex > 0 && innerIndex <= anonymousClasses.size) { + anonymousClasses[innerIndex - 1] } else { null } @@ -194,9 +194,9 @@ @Throws(ClassNameResolutionFailedException::class) @PublishedApi -internal fun PsiElement.getAnonymousIndex(anonymousElement: PsiElement): Int { +internal fun PsiClass.getAnonymousIndex(anonymousElement: PsiElement): Int { // Attempt to find name for anonymous class - for ((i, element) in anonymousElements.withIndex()) { + for ((i, element) in anonymousClasses.withIndex()) { if (element equivalentTo anonymousElement) { return i + 1 } @@ -205,16 +205,22 @@ throw ClassNameResolutionFailedException("Failed to determine anonymous class for $anonymousElement") } -val PsiElement.anonymousElements: Array +val PsiClass.anonymousClasses: List get() { - for (provider in AnonymousElementProvider.EP_NAME.extensionList) { - val elements = provider.getAnonymousElements(this) - if (elements.isNotEmpty()) { - return elements + val list = mutableListOf() + + acceptChildren(object : JavaRecursiveElementVisitor() { + override fun visitClass(aClass: PsiClass) { + // skip inner classes } + + override fun visitAnonymousClass(aClass: PsiAnonymousClass) { + aClass.argumentList?.accept(this) + list += aClass - } + } + }) - return emptyArray() + return list } @Throws(ClassNameResolutionFailedException::class) Index: src/test/kotlin/util/OuterClassTest.kt =================================================================== --- src/test/kotlin/util/OuterClassTest.kt (revision f6b51c91904eef599b5e8c0d7213d51750644e8f) +++ src/test/kotlin/util/OuterClassTest.kt (revision e41695012554218ed0a2e4cb04219a367127a460) @@ -68,10 +68,10 @@ ).toPsiFile().classes.single() } - this.outerAnonymousClass = outerClass.anonymousElements.single() as PsiAnonymousClass + this.outerAnonymousClass = outerClass.anonymousClasses.single() this.innerClass = outerClass.innerClasses.first() - this.innerAnonymousClass = innerClass.anonymousElements.single() as PsiAnonymousClass + this.innerAnonymousClass = innerClass.anonymousClasses.single() this.innerAnonymousInnerClass = innerAnonymousClass.innerClasses.single() this.selfReferencingGeneric = outerClass.innerClasses[1]