KT-26540: Support generated superclasses in KAPT
https://youtrack.jetbrains.net/issue/KT-26540 Included an integration test that relies on a generated superclass.
This commit is contained in:
committed by
Yan Zhulanow
parent
f147b8d2b2
commit
dfff00d55f
+17
-2
@@ -390,11 +390,26 @@ class ClassFileToSourceStubConverter(
|
||||
modifiers,
|
||||
treeMaker.name(simpleName),
|
||||
genericType.typeParameters,
|
||||
if (hasSuperClass) genericType.superClass else null,
|
||||
if (hasSuperClass) genericType.superClass else getSuperType(descriptor as? ClassDescriptor),
|
||||
genericType.interfaces,
|
||||
enumValues + fields + methods + nestedClasses).keepKdocComments(clazz)
|
||||
}
|
||||
|
||||
private inline fun getSuperType(classDescriptor: ClassDescriptor?): JCExpression? {
|
||||
if (!correctErrorTypes) {
|
||||
return null
|
||||
}
|
||||
val ktClass = (classDescriptor?.source as? PsiSourceElement)?.psi as? KtClass
|
||||
val superTypeCallEntry =
|
||||
ktClass?.getSuperTypeList()?.entries?.mapNotNull { it as? KtSuperTypeCallEntry }?.first()
|
||||
val typeFromSource = superTypeCallEntry?.typeReference?.typeElement
|
||||
val ktFile = typeFromSource?.containingKtFile
|
||||
if (ktFile != null) {
|
||||
return ErrorTypeCorrector(this, SUPER_TYPE, ktFile).convert(typeFromSource, emptyMap())
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private tailrec fun checkIfValidTypeName(containingClass: ClassNode, type: Type): Boolean {
|
||||
if (type.sort == Type.ARRAY) {
|
||||
return checkIfValidTypeName(containingClass, type.elementType)
|
||||
@@ -1034,4 +1049,4 @@ internal tailrec fun getReferenceExpression(expression: KtExpression?): KtRefere
|
||||
is KtReferenceExpression -> expression
|
||||
is KtQualifiedExpression -> getReferenceExpression(expression.selectorExpression)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.kapt3.base.mapJList
|
||||
import org.jetbrains.kotlin.kapt3.base.mapJListIndexed
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.METHOD_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.RETURN_TYPE
|
||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.SUPER_TYPE
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -62,7 +63,7 @@ class ErrorTypeCorrector(
|
||||
}
|
||||
|
||||
enum class TypeKind {
|
||||
RETURN_TYPE, METHOD_PARAMETER_TYPE
|
||||
RETURN_TYPE, METHOD_PARAMETER_TYPE, SUPER_TYPE
|
||||
}
|
||||
|
||||
fun convert(type: KtTypeElement, substitutions: SubstitutionMap): JCTree.JCExpression {
|
||||
@@ -131,6 +132,7 @@ class ErrorTypeCorrector(
|
||||
//TODO figure out if the containing method is an annotation method
|
||||
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
||||
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
||||
SUPER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
||||
}.updateArgumentModeFromAnnotations(kotlinType)
|
||||
|
||||
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
||||
|
||||
+14
@@ -50,6 +50,20 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
|
||||
assertEquals("myMethod", annotatedElements.single().simpleName.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSuperclass() = test("Superclass", "test.MyAnnotation") { set, roundEnv, env ->
|
||||
if (set.size == 1) {
|
||||
val annotatedElements = roundEnv.getElementsAnnotatedWith(set.single())
|
||||
assertEquals(1, annotatedElements.size)
|
||||
val typeElement = annotatedElements.single() as TypeElement
|
||||
assertEquals("FooBar", typeElement.superclass.toString())
|
||||
env.filer.createSourceFile("test.FooBar").openWriter().use { writer ->
|
||||
writer.write("package test;")
|
||||
writer.write("public class FooBar {}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testComments() = test("Simple", "test.MyAnnotation") { set, roundEnv, env ->
|
||||
fun commentOf(className: String) = env.elementUtils.getDocComment(env.elementUtils.getTypeElement(className))
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package error;
|
||||
|
||||
public final class NonExistentClass {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package test;
|
||||
|
||||
import java.lang.System;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@MyAnnotation()
|
||||
public final class ClassWithParent extends FooBar {
|
||||
|
||||
public ClassWithParent() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package test;
|
||||
|
||||
import java.lang.System;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
public abstract @interface MyAnnotation {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
internal annotation class MyAnnotation
|
||||
|
||||
@MyAnnotation
|
||||
internal class ClassWithParent: FooBar() {
|
||||
}
|
||||
Reference in New Issue
Block a user