Skip to content

Commit 638d9a1

Browse files
authored
Support finding descriptors for java statics (#171)
* Handle statics in resolveJavaDeclaration This PR fixes a bug where static java declarations were not being resolved properly because we would only look at the main scope of the class declaration but we also need to check the static scope.
1 parent 104f7f5 commit 638d9a1

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt

+54-11
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
7272
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
7373
import org.jetbrains.kotlin.resolve.multiplatform.findActuals
7474
import org.jetbrains.kotlin.resolve.multiplatform.findExpects
75+
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
7576
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
76-
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
77+
import org.jetbrains.kotlin.resolve.scopes.MemberScope
7778
import org.jetbrains.kotlin.types.*
7879
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
7980
import org.jetbrains.kotlin.types.typeUtil.substitute
@@ -317,17 +318,30 @@ class ResolverImpl(
317318
is PsiMethod -> {
318319
// TODO: get rid of hardcoded check if possible.
319320
if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
320-
moduleClassResolver.resolveClass(JavaMethodImpl(psi).containingClass)
321-
?.unsubstitutedMemberScope!!.getDescriptorsFiltered().singleOrNull{
322-
(it as? PropertyDescriptor)?.getter?.findPsi() == psi || (it as? PropertyDescriptor)?.setter?.findPsi() == psi
323-
}
321+
moduleClassResolver
322+
.resolveClass(JavaMethodImpl(psi).containingClass)
323+
?.findEnclosedDescriptor(
324+
kindFilter = DescriptorKindFilter.CALLABLES
325+
) {
326+
(it as? PropertyDescriptor)?.getter?.findPsi() == psi || (it as? PropertyDescriptor)?.setter?.findPsi() == psi
327+
}
324328
} else {
325-
moduleClassResolver.resolveClass(JavaMethodImpl(psi).containingClass)
326-
?.unsubstitutedMemberScope!!.getDescriptorsFiltered().singleOrNull { it.findPsi() == psi }
329+
moduleClassResolver
330+
.resolveClass(JavaMethodImpl(psi).containingClass)
331+
?.findEnclosedDescriptor(
332+
kindFilter = DescriptorKindFilter.FUNCTIONS,
333+
filter = { it.findPsi() == psi }
334+
)
327335
}
328336
}
329-
is PsiField -> moduleClassResolver.resolveClass(JavaFieldImpl(psi).containingClass)
330-
?.unsubstitutedMemberScope!!.getDescriptorsFiltered().single { it.findPsi() == psi } as CallableMemberDescriptor
337+
is PsiField -> {
338+
moduleClassResolver
339+
.resolveClass(JavaFieldImpl(psi).containingClass)
340+
?.findEnclosedDescriptor(
341+
kindFilter = DescriptorKindFilter.VARIABLES,
342+
filter = { it.findPsi() == psi }
343+
)
344+
}
331345
else -> throw IllegalStateException("unhandled psi element kind: ${psi.javaClass}")
332346
}
333347
}
@@ -422,9 +436,16 @@ class ResolverImpl(
422436
val containingDeclaration = if (psi.owner is PsiClass) {
423437
moduleClassResolver.resolveClass(JavaClassImpl(psi.owner as PsiClass))
424438
} else {
439+
val owner = psi.owner
440+
check(owner is PsiMethod) {
441+
"unexpected owner type: $owner / ${owner?.javaClass}"
442+
}
425443
moduleClassResolver.resolveClass(
426-
JavaMethodImpl(psi.owner as PsiMethod).containingClass
427-
)?.unsubstitutedMemberScope!!.getDescriptorsFiltered().single { it.findPsi() == psi.owner } as FunctionDescriptor
444+
JavaMethodImpl(owner).containingClass
445+
)?.findEnclosedDescriptor(
446+
kindFilter = DescriptorKindFilter.FUNCTIONS,
447+
filter = { it.findPsi() == owner }
448+
) as FunctionDescriptor
428449
} as DeclarationDescriptor
429450
return getKSTypeCached(
430451
LazyJavaTypeParameterDescriptor(
@@ -697,3 +718,25 @@ private fun Name.getNonSpecialIdentifier() :String {
697718
asString().substring(1)
698719
}
699720
}
721+
722+
private inline fun MemberScope.findEnclosedDescriptor(
723+
kindFilter: DescriptorKindFilter,
724+
crossinline filter: (DeclarationDescriptor) -> Boolean
725+
) : DeclarationDescriptor? {
726+
return getContributedDescriptors(
727+
kindFilter = kindFilter
728+
).firstOrNull(filter)
729+
}
730+
731+
private inline fun ClassDescriptor.findEnclosedDescriptor(
732+
kindFilter: DescriptorKindFilter,
733+
crossinline filter: (DeclarationDescriptor) -> Boolean
734+
) : DeclarationDescriptor? {
735+
return this.unsubstitutedMemberScope.findEnclosedDescriptor(
736+
kindFilter = kindFilter,
737+
filter = filter
738+
) ?: this.staticScope.findEnclosedDescriptor(
739+
kindFilter = kindFilter,
740+
filter = filter
741+
)
742+
}

compiler-plugin/testData/api/mangledNames.kt

+11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
// fileLevelInlineReturningFun -> fileLevelInlineReturningFun
4141
// fileLevelInternalInlineReceivingFun -> fileLevelInternalInlineReceivingFun-E03SJzc
4242
// fileLevelInternalInlineReturningFun -> fileLevelInternalInlineReturningFun
43+
// JavaInput -> declarations
44+
// javaFunction -> javaFunction
45+
// staticJavaFunction -> staticJavaFunction
4346
// libPackage.Foo -> declarations
4447
// get-inlineProp -> getInlineProp-b_MPbnQ
4548
// set-inlineProp -> setInlineProp-mQ73O9w
@@ -108,3 +111,11 @@ fun fileLevelInlineReceivingFun(inline1: Inline1): Unit = TODO()
108111
fun fileLevelInlineReturningFun(): Inline1 = TODO()
109112
fun fileLevelInternalInlineReceivingFun(inline1: Inline1): Unit = TODO()
110113
fun fileLevelInternalInlineReturningFun(): Inline1 = TODO()
114+
115+
// FILE: JavaInput.java
116+
class JavaInput {
117+
String javaField;
118+
String javaFunction() {}
119+
static String staticJavaField;
120+
static void staticJavaFunction() {}
121+
}

0 commit comments

Comments
 (0)