Skip to content

Commit

Permalink
Fix Java class constructor calculation.
Browse files Browse the repository at this point in the history
* Add support for default constructor of Java class.
* Fixed getDeclaredFunctions which will return duplicate elements for
  all constructors.
  • Loading branch information
neetopia committed Oct 2, 2020
1 parent 6c45a3b commit 6ee0964
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 4 deletions.
3 changes: 2 additions & 1 deletion api/src/main/kotlin/com/google/devtools/ksp/utils.kt
Expand Up @@ -64,7 +64,8 @@ fun KSClassDeclaration.getDeclaredProperties(): List<KSPropertyDeclaration> {
}

fun KSClassDeclaration.getConstructors(): List<KSFunctionDeclaration> {
return this.getDeclaredFunctions().filter { it.simpleName.asString() == this.simpleName.asString() }
val functions = if (this.origin == Origin.JAVA) this.getAllFunctions() else this.getDeclaredFunctions()
return functions.filter { it.simpleName.asString() == this.simpleName.asString() || it.simpleName.asString() == "<init>"}
.let { constructors ->
this.primaryConstructor?.let { constructors.plus(it) } ?: constructors
}
Expand Down
Expand Up @@ -21,6 +21,7 @@ package com.google.devtools.ksp.processor
import com.google.devtools.ksp.findAnnotationFromUseSiteTarget
import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.getConstructors
import com.google.devtools.ksp.getDeclaredFunctions
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
Expand All @@ -40,7 +41,9 @@ class ImplicitElementProcessor : AbstractTestProcessor() {
result.add(ClsClass.getConstructors().map { it.toString() }.joinToString(","))
val ITF = resolver.getClassDeclarationByName(resolver.getKSNameFromString("ITF"))!!
result.add(ITF.primaryConstructor?.simpleName?.asString() ?: "<null>")
result.add(resolver.getClassDeclarationByName(resolver.getKSNameFromString("JavaClass"))!!.primaryConstructor?.simpleName?.asString() ?: "<null>")
val JavaClass = resolver.getClassDeclarationByName("JavaClass")!!
result.add(JavaClass.primaryConstructor?.simpleName?.asString() ?: "<null>")
result.add(JavaClass.getDeclaredFunctions().map { it.simpleName.asString() }.joinToString(","))
val readOnly = ClsClass.declarations.single { it.simpleName.asString() == "readOnly" } as KSPropertyDeclaration
readOnly.getter?.let { result.add("readOnly.get(): ${it.origin} annotations from property: ${it.findAnnotationFromUseSiteTarget().map { it.shortName.asString() }.joinToString(",")}") }
readOnly.getter?.receiver?.let { result.add("readOnly.getter.owner: " + nameAndOrigin(it)) }
Expand All @@ -61,5 +64,7 @@ class ImplicitElementProcessor : AbstractTestProcessor() {
result.add(annotationType)
val ClassWithoutImplicitPrimaryConstructor = resolver.getClassDeclarationByName("ClassWithoutImplicitPrimaryConstructor")!!
result.add(ClassWithoutImplicitPrimaryConstructor.getConstructors().map { it.toString() }.joinToString(","))
val ImplictConstructorJava = resolver.getClassDeclarationByName("ImplictConstructorJava")!!
result.add(ImplictConstructorJava.getConstructors().map { it.toString() }.joinToString(","))
}
}
Expand Up @@ -78,6 +78,7 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) : KSClas
it.unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.FUNCTIONS)
.toList()
.filter { (it as FunctionDescriptor).visibility != Visibilities.INVISIBLE_FAKE }
.plus(it.constructors)
.map { (it as FunctionDescriptor).toKSFunctionDeclaration() }
} ?: emptyList()
}
Expand All @@ -92,10 +93,11 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) : KSClas
}

override val declarations: List<KSDeclaration> by lazy {
psi.fields.map { KSPropertyDeclarationJavaImpl.getCached(it) } +
(psi.fields.map { KSPropertyDeclarationJavaImpl.getCached(it) } +
psi.innerClasses.map { KSClassDeclarationJavaImpl.getCached(it) } +
psi.constructors.map { KSFunctionDeclarationJavaImpl.getCached(it) } +
psi.methods.map { KSFunctionDeclarationJavaImpl.getCached(it) }
psi.methods.map { KSFunctionDeclarationJavaImpl.getCached(it) })
.distinct()
}

override val modifiers: Set<Modifier> by lazy {
Expand Down
Expand Up @@ -32,8 +32,10 @@ import com.google.devtools.ksp.symbol.impl.java.KSFunctionDeclarationJavaImpl
import com.google.devtools.ksp.symbol.impl.java.KSPropertyDeclarationJavaImpl
import com.google.devtools.ksp.symbol.impl.java.KSTypeArgumentJavaImpl
import com.google.devtools.ksp.symbol.impl.kotlin.*
import com.intellij.psi.impl.source.PsiClassImpl
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.resolve.source.getPsi
Expand Down Expand Up @@ -254,6 +256,10 @@ internal fun KotlinType.replaceTypeArguments(newArguments: List<KSTypeArgument>)
internal fun FunctionDescriptor.toKSFunctionDeclaration(): KSFunctionDeclaration {
if (this.kind != CallableMemberDescriptor.Kind.DECLARATION) return KSFunctionDeclarationDescriptorImpl.getCached(this)
val psi = this.findPsi() ?: return KSFunctionDeclarationDescriptorImpl.getCached(this)
// Java default constructor has a kind DECLARATION of while still being synthetic.
if (psi is PsiClassImpl && this is JavaClassConstructorDescriptor) {
return KSFunctionDeclarationDescriptorImpl.getCached(this)
}
return when (psi) {
is KtFunction -> KSFunctionDeclarationImpl.getCached(psi)
is PsiMethod -> KSFunctionDeclarationJavaImpl.getCached(psi)
Expand Down
1 change: 1 addition & 0 deletions compiler-plugin/testData/api/allFunctions.kt
Expand Up @@ -19,6 +19,7 @@
// TEST PROCESSOR: AllFunctionsProcessor
// EXPECTED:
// class: Foo
// <init>(): C
// a
// aFromC
// aFromC
Expand Down
8 changes: 8 additions & 0 deletions compiler-plugin/testData/api/implicitElements.kt
Expand Up @@ -21,6 +21,7 @@
// synthetic constructor for Cls
// <null>
// <null>
// JavaClass,JavaClass,JavaClass
// readOnly.get(): SYNTHETIC annotations from property: GetAnno
// readOnly.getter.owner: readOnly: KOTLIN
// readWrite.get(): KOTLIN
Expand All @@ -31,6 +32,7 @@
// comp2.set(): SYNTHETIC
// GetAnno
// ClassWithoutImplicitPrimaryConstructor
// <init>
// END
// FILE: a.kt
annotation class GetAnno
Expand Down Expand Up @@ -59,3 +61,9 @@ public class JavaClass {
public JavaClass(int a) { this(a, "ok"); }
public JavaClass(int a, String s) { }
}

// FILE:ImplictConstructorJava.java

public class ImplictConstructorJava {

}

0 comments on commit 6ee0964

Please sign in to comment.