Skip to content

Commit 11a9ae6

Browse files
yigitneetopia
authored andcommitted
Properly wrap PSIMethods that are constructors
This PR fixes a bug where we were wrapping all PsiMethods to JavaMethodImpl without checking if they are constructor. Both cases, we were wrapping them to find the containing class, so I've added an extension function to ModuleClassResolver to find containing descriptor via PsiMethod which abstracts this resolution. Also fixes a bug where ClassDescriptor.findEnclosedDescriptor was not checking constructors (also convered in the updated tests). Test: extended resolveJavaType and signatureMapper tests to trigger the crash Fixes: #265
1 parent d3dcef1 commit 11a9ae6

File tree

6 files changed

+34
-9
lines changed

6 files changed

+34
-9
lines changed

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

+8-6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.google.devtools.ksp.symbol.impl.binary.*
2727
import com.google.devtools.ksp.symbol.impl.findPsi
2828
import com.google.devtools.ksp.symbol.impl.java.*
2929
import com.google.devtools.ksp.symbol.impl.kotlin.*
30+
import com.google.devtools.ksp.symbol.impl.resolveContainingClass
3031
import com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl
3132
import com.google.devtools.ksp.symbol.impl.synthetic.KSPropertyGetterSyntheticImpl
3233
import com.google.devtools.ksp.symbol.impl.synthetic.KSPropertySetterSyntheticImpl
@@ -320,15 +321,15 @@ class ResolverImpl(
320321
// TODO: get rid of hardcoded check if possible.
321322
val property = if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
322323
moduleClassResolver
323-
.resolveClass(JavaMethodImpl(psi).containingClass)
324+
.resolveContainingClass(psi)
324325
?.findEnclosedDescriptor(
325326
kindFilter = DescriptorKindFilter.CALLABLES
326327
) {
327328
(it as? PropertyDescriptor)?.getter?.findPsi() == psi || (it as? PropertyDescriptor)?.setter?.findPsi() == psi
328329
}
329330
} else null
330331
property ?: moduleClassResolver
331-
.resolveClass(JavaMethodImpl(psi).containingClass)
332+
.resolveContainingClass(psi)
332333
?.findEnclosedDescriptor(
333334
kindFilter = DescriptorKindFilter.FUNCTIONS,
334335
filter = { it.findPsi() == psi }
@@ -457,9 +458,8 @@ class ResolverImpl(
457458
check(owner is PsiMethod) {
458459
"unexpected owner type: $owner / ${owner?.javaClass}"
459460
}
460-
moduleClassResolver.resolveClass(
461-
JavaMethodImpl(owner).containingClass
462-
)?.findEnclosedDescriptor(
461+
moduleClassResolver.resolveContainingClass(owner)
462+
?.findEnclosedDescriptor(
463463
kindFilter = DescriptorKindFilter.FUNCTIONS,
464464
filter = { it.findPsi() == owner }
465465
) as FunctionDescriptor
@@ -767,5 +767,7 @@ private inline fun ClassDescriptor.findEnclosedDescriptor(
767767
) ?: this.staticScope.findEnclosedDescriptor(
768768
kindFilter = kindFilter,
769769
filter = filter
770-
)
770+
) ?: constructors.firstOrNull {
771+
kindFilter.accepts(it) && filter(it)
772+
}
771773
}

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/MapSignatureProcessor.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class MapSignatureProcessor : AbstractTestProcessor() {
3131
}
3232

3333
override fun process(resolver: Resolver) {
34-
listOf("Cls", "JavaIntefaceWithVoid")
34+
listOf("Cls", "JavaIntefaceWithVoid", "JavaClass")
3535
.map { className ->
3636
resolver.getClassDeclarationByName(className)!!
3737
}.forEach { subject ->

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processor/ResolveJavaTypeProcessor.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class ResolveJavaTypeProcessor : AbstractTestProcessor() {
4545
}
4646

4747
override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
48-
if (function.simpleName.asString() == "wildcardParam") {
49-
function.parameters[0].type!!.accept(this, Unit)
48+
function.parameters.forEach {
49+
it.type.accept(this, Unit)
5050
}
5151
function.returnType?.accept(this, Unit)
5252
}

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/utils.kt

+12
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ import com.intellij.psi.impl.source.PsiClassImpl
3737
import org.jetbrains.kotlin.lexer.KtTokens
3838
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
3939
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
40+
import org.jetbrains.kotlin.load.java.structure.JavaMember
41+
import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl
42+
import org.jetbrains.kotlin.load.java.structure.impl.JavaMethodImpl
4043
import org.jetbrains.kotlin.psi.*
4144
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
4245
import org.jetbrains.kotlin.resolve.source.getPsi
4346
import org.jetbrains.kotlin.types.KotlinType
4447
import org.jetbrains.kotlin.types.StarProjectionImpl
4548
import org.jetbrains.kotlin.types.TypeProjectionImpl
4649
import org.jetbrains.kotlin.types.replace
50+
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
4751

4852
val jvmModifierMap = mapOf(
4953
JvmModifier.PUBLIC to Modifier.PUBLIC,
@@ -323,3 +327,11 @@ internal inline fun <reified T : CallableMemberDescriptor> T.findClosestOverride
323327
}
324328
return null
325329
}
330+
331+
fun ModuleClassResolver.resolveContainingClass(psiMethod: PsiMethod): ClassDescriptor? {
332+
return if (psiMethod.isConstructor) {
333+
resolveClass(JavaConstructorImpl(psiMethod).containingClass)
334+
} else {
335+
resolveClass(JavaMethodImpl(psiMethod).containingClass)
336+
}
337+
}

compiler-plugin/testData/api/resolveJavaType.kt

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
// TEST PROCESSOR: ResolveJavaTypeProcessor
1919
// EXPECTED:
20+
// C.<init>.X?
2021
// kotlin.Int
2122
// kotlin.String?
2223
// kotlin.collections.MutableSet<out kotlin.Any?>?
@@ -43,6 +44,9 @@ import java.util.List;
4344
import java.util.Set;
4445

4546
public class C<T> {
47+
public C() {}
48+
// to reproduce the case where type reference is owned by a constructor
49+
public <X> C(X x) {}
4650
public int intFun() {}
4751

4852
public String strFun() {}

compiler-plugin/testData/api/signatureMapper.kt

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
// ()Ljava/lang/String;
2424
// LJavaIntefaceWithVoid;
2525
// ()Ljava/lang/Void;
26+
// LJavaClass;
27+
// ()V
2628
// END
2729

2830
// FILE: Cls.kt
@@ -36,3 +38,8 @@ class Cls {
3638
interface JavaIntefaceWithVoid {
3739
Void getVoid();
3840
}
41+
42+
// FILE: JavaClass.java
43+
class JavaClass {
44+
JavaClass() {}
45+
}

0 commit comments

Comments
 (0)