Skip to content

Commit

Permalink
Properly wrap PSIMethods that are constructors
Browse files Browse the repository at this point in the history
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: google#265
  • Loading branch information
yigit committed Jan 24, 2021
1 parent d3dcef1 commit 740e306
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.google.devtools.ksp.symbol.impl.binary.*
import com.google.devtools.ksp.symbol.impl.findPsi
import com.google.devtools.ksp.symbol.impl.java.*
import com.google.devtools.ksp.symbol.impl.kotlin.*
import com.google.devtools.ksp.symbol.impl.resolveContainingClass
import com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl
import com.google.devtools.ksp.symbol.impl.synthetic.KSPropertyGetterSyntheticImpl
import com.google.devtools.ksp.symbol.impl.synthetic.KSPropertySetterSyntheticImpl
Expand Down Expand Up @@ -320,15 +321,15 @@ class ResolverImpl(
// TODO: get rid of hardcoded check if possible.
val property = if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
moduleClassResolver
.resolveClass(JavaMethodImpl(psi).containingClass)
.resolveContainingClass(psi)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.CALLABLES
) {
(it as? PropertyDescriptor)?.getter?.findPsi() == psi || (it as? PropertyDescriptor)?.setter?.findPsi() == psi
}
} else null
property ?: moduleClassResolver
.resolveClass(JavaMethodImpl(psi).containingClass)
.resolveContainingClass(psi)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.FUNCTIONS,
filter = { it.findPsi() == psi }
Expand Down Expand Up @@ -457,9 +458,8 @@ class ResolverImpl(
check(owner is PsiMethod) {
"unexpected owner type: $owner / ${owner?.javaClass}"
}
moduleClassResolver.resolveClass(
JavaMethodImpl(owner).containingClass
)?.findEnclosedDescriptor(
moduleClassResolver.resolveContainingClass(owner)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.FUNCTIONS,
filter = { it.findPsi() == owner }
) as FunctionDescriptor
Expand Down Expand Up @@ -767,5 +767,7 @@ private inline fun ClassDescriptor.findEnclosedDescriptor(
) ?: this.staticScope.findEnclosedDescriptor(
kindFilter = kindFilter,
filter = filter
)
) ?: constructors.firstOrNull {
kindFilter.accepts(it) && filter(it)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MapSignatureProcessor : AbstractTestProcessor() {
}

override fun process(resolver: Resolver) {
listOf("Cls", "JavaIntefaceWithVoid")
listOf("Cls", "JavaIntefaceWithVoid", "JavaClass")
.map { className ->
resolver.getClassDeclarationByName(className)!!
}.forEach { subject ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class ResolveJavaTypeProcessor : AbstractTestProcessor() {
}

override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {
if (function.simpleName.asString() == "wildcardParam") {
function.parameters[0].type!!.accept(this, Unit)
function.parameters.forEach {
it.type.accept(this, Unit)
}
function.returnType?.accept(this, Unit)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ import com.intellij.psi.impl.source.PsiClassImpl
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.load.java.structure.JavaMember
import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl
import org.jetbrains.kotlin.load.java.structure.impl.JavaMethodImpl
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.descriptorUtil.getOwnerForEffectiveDispatchReceiverParameter
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.StarProjectionImpl
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver

val jvmModifierMap = mapOf(
JvmModifier.PUBLIC to Modifier.PUBLIC,
Expand Down Expand Up @@ -323,3 +327,11 @@ internal inline fun <reified T : CallableMemberDescriptor> T.findClosestOverride
}
return null
}

fun ModuleClassResolver.resolveContainingClass(psiMethod: PsiMethod): ClassDescriptor? {
return if (psiMethod.isConstructor) {
resolveClass(JavaConstructorImpl(psiMethod).containingClass)
} else {
resolveClass(JavaMethodImpl(psiMethod).containingClass)
}
}
6 changes: 5 additions & 1 deletion compiler-plugin/testData/api/resolveJavaType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

// TEST PROCESSOR: ResolveJavaTypeProcessor
// EXPECTED:
// C.<init>.X?
// kotlin.Int
// kotlin.String?
// kotlin.collections.MutableSet<out kotlin.Any?>?
Expand All @@ -32,7 +33,7 @@
// FILE: a.kt
annotation class Test
@Test
class Foo<P>: C<P>() {
class Foo<P>(p:P): C<P>(p) {

}

Expand All @@ -43,6 +44,9 @@ import java.util.List;
import java.util.Set;

public class C<T> {
public C() {}
// to reproduce the case where type reference is owned by a constructor
public <X> C(X x) {}
public int intFun() {}

public String strFun() {}
Expand Down
7 changes: 7 additions & 0 deletions compiler-plugin/testData/api/signatureMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
// ()Ljava/lang/String;
// LJavaIntefaceWithVoid;
// ()Ljava/lang/Void;
// LJavaClass;
// ()V
// END

// FILE: Cls.kt
Expand All @@ -36,3 +38,8 @@ class Cls {
interface JavaIntefaceWithVoid {
Void getVoid();
}

// FILE: JavaClass.java
class JavaClass {
JavaClass() {}
}

0 comments on commit 740e306

Please sign in to comment.