@@ -25,8 +25,11 @@ import com.intellij.navigation.AnonymousElementProvider
25
25
import com.intellij.openapi.project.Project
26
26
import com.intellij.psi.CommonClassNames
27
27
import com.intellij.psi.JavaPsiFacade
28
+ import com.intellij.psi.JavaRecursiveElementWalkingVisitor
29
+ import com.intellij.psi.PsiAnonymousClass
28
30
import com.intellij.psi.PsiClass
29
31
import com.intellij.psi.PsiClassType
32
+ import com.intellij.psi.PsiCompiledElement
30
33
import com.intellij.psi.PsiElement
31
34
import com.intellij.psi.PsiField
32
35
import com.intellij.psi.PsiInvalidElementAccessException
@@ -36,6 +39,7 @@ import com.intellij.psi.PsiParameterList
36
39
import com.intellij.psi.PsiPrimitiveType
37
40
import com.intellij.psi.PsiTypeParameter
38
41
import com.intellij.psi.search.GlobalSearchScope
42
+ import com.intellij.psi.util.PsiUtil
39
43
40
44
val PsiClass .packageName
41
45
get() = (containingFile as ? PsiJavaFile )?.packageName
@@ -101,8 +105,14 @@ inline fun PsiClass.buildInnerName(builder: StringBuilder, getName: (PsiClass) -
101
105
} else {
102
106
parentClass = currentClass.parent.findContainingClass() ? : throw ClassNameResolutionFailedException ()
103
107
104
- // Add index of anonymous class to list
105
- list.add(parentClass.getAnonymousIndex(currentClass).toString())
108
+ if (currentClass is PsiAnonymousClass ) {
109
+ // Add index of anonymous class to list
110
+ list.add(parentClass.getAnonymousIndex(currentClass).toString())
111
+ } else {
112
+ // Add index and name of local class to list
113
+ val currentName = currentClass.name ? : throw ClassNameResolutionFailedException ()
114
+ list.add(parentClass.getLocalIndex(currentClass).toString() + currentName)
115
+ }
106
116
}
107
117
108
118
currentClass = parentClass
@@ -157,21 +167,32 @@ fun findQualifiedClass(
157
167
}
158
168
159
169
private fun PsiClass.findInnerClass (name : String ): PsiClass ? {
160
- val anonymousIndex = name.toIntOrNull( )
161
- return if (anonymousIndex == null ) {
170
+ val innerIndexAndName = innerIndexAndName(name )
171
+ return if (innerIndexAndName == null ) {
162
172
// Named inner class
163
173
findInnerClassByName(name, false )
164
174
} else {
165
- if (anonymousIndex > 0 && anonymousIndex <= anonymousElements.size) {
166
- anonymousElements[anonymousIndex - 1 ] as PsiClass
175
+ val (innerIndex, innerName) = innerIndexAndName
176
+ if (innerName != null ) {
177
+ val localClasses = this .localClasses.filter { it.name == innerName }
178
+ if (innerIndex > 0 && innerIndex <= localClasses.size) {
179
+ localClasses[innerIndex - 1 ]
180
+ } else {
181
+ null
182
+ }
167
183
} else {
168
- null
184
+ if (innerIndex > 0 && innerIndex <= anonymousElements.size) {
185
+ anonymousElements[innerIndex - 1 ] as PsiClass
186
+ } else {
187
+ null
188
+ }
169
189
}
170
190
}
171
191
}
172
192
173
193
@Throws(ClassNameResolutionFailedException ::class )
174
- fun PsiElement.getAnonymousIndex (anonymousElement : PsiElement ): Int {
194
+ @PublishedApi
195
+ internal fun PsiElement.getAnonymousIndex (anonymousElement : PsiElement ): Int {
175
196
// Attempt to find name for anonymous class
176
197
for ((i, element) in anonymousElements.withIndex()) {
177
198
if (element equivalentTo anonymousElement) {
@@ -194,6 +215,51 @@ val PsiElement.anonymousElements: Array<PsiElement>
194
215
return emptyArray()
195
216
}
196
217
218
+ @Throws(ClassNameResolutionFailedException ::class )
219
+ @PublishedApi
220
+ internal fun PsiElement.getLocalIndex (localClass : PsiClass ): Int {
221
+ // Attempt to find index for local class
222
+ var index = 0
223
+ for (aLocalClass in localClasses) {
224
+ if (aLocalClass.name == localClass.name) {
225
+ index++
226
+ if (aLocalClass equivalentTo localClass) {
227
+ return index
228
+ }
229
+ }
230
+ }
231
+
232
+ throw ClassNameResolutionFailedException (" Failed to determine local class index for $localClass " )
233
+ }
234
+
235
+ val PsiElement .localClasses: List <PsiClass >
236
+ get() {
237
+ if (this is PsiCompiledElement ) {
238
+ return emptyList()
239
+ }
240
+
241
+ val list = mutableListOf<PsiClass >()
242
+ accept(object : JavaRecursiveElementWalkingVisitor () {
243
+ override fun visitClass (clazz : PsiClass ) {
244
+ if (clazz == = this @localClasses) {
245
+ super .visitClass(clazz)
246
+ } else {
247
+ if (PsiUtil .isLocalClass(clazz)) {
248
+ list + = clazz
249
+ }
250
+ }
251
+ }
252
+ })
253
+ return list
254
+ }
255
+
256
+ private val INNER_INDEX_AND_NAME_REGEX = " (\\ d+)(\\ w*)" .toRegex()
257
+ fun innerIndexAndName (className : String ): Pair <Int , String ?>? {
258
+ val (indexStr, name) = INNER_INDEX_AND_NAME_REGEX .matchEntire(className)?.destructured ? : return null
259
+ val index = indexStr.toIntOrNull() ? : return null
260
+ return index to name.ifEmpty { null }
261
+ }
262
+
197
263
// Inheritance
198
264
199
265
fun PsiClass.extendsOrImplements (qualifiedClassName : String ): Boolean {
0 commit comments