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,
|
modifiers,
|
||||||
treeMaker.name(simpleName),
|
treeMaker.name(simpleName),
|
||||||
genericType.typeParameters,
|
genericType.typeParameters,
|
||||||
if (hasSuperClass) genericType.superClass else null,
|
if (hasSuperClass) genericType.superClass else getSuperType(descriptor as? ClassDescriptor),
|
||||||
genericType.interfaces,
|
genericType.interfaces,
|
||||||
enumValues + fields + methods + nestedClasses).keepKdocComments(clazz)
|
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 {
|
private tailrec fun checkIfValidTypeName(containingClass: ClassNode, type: Type): Boolean {
|
||||||
if (type.sort == Type.ARRAY) {
|
if (type.sort == Type.ARRAY) {
|
||||||
return checkIfValidTypeName(containingClass, type.elementType)
|
return checkIfValidTypeName(containingClass, type.elementType)
|
||||||
@@ -1034,4 +1049,4 @@ internal tailrec fun getReferenceExpression(expression: KtExpression?): KtRefere
|
|||||||
is KtReferenceExpression -> expression
|
is KtReferenceExpression -> expression
|
||||||
is KtQualifiedExpression -> getReferenceExpression(expression.selectorExpression)
|
is KtQualifiedExpression -> getReferenceExpression(expression.selectorExpression)
|
||||||
else -> null
|
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.base.mapJListIndexed
|
||||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.METHOD_PARAMETER_TYPE
|
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.RETURN_TYPE
|
||||||
|
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.SUPER_TYPE
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -62,7 +63,7 @@ class ErrorTypeCorrector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class TypeKind {
|
enum class TypeKind {
|
||||||
RETURN_TYPE, METHOD_PARAMETER_TYPE
|
RETURN_TYPE, METHOD_PARAMETER_TYPE, SUPER_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convert(type: KtTypeElement, substitutions: SubstitutionMap): JCTree.JCExpression {
|
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
|
//TODO figure out if the containing method is an annotation method
|
||||||
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
|
||||||
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
||||||
|
SUPER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
|
||||||
}.updateArgumentModeFromAnnotations(kotlinType)
|
}.updateArgumentModeFromAnnotations(kotlinType)
|
||||||
|
|
||||||
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
||||||
|
|||||||
+14
@@ -50,6 +50,20 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
|
|||||||
assertEquals("myMethod", annotatedElements.single().simpleName.toString())
|
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
|
@Test
|
||||||
fun testComments() = test("Simple", "test.MyAnnotation") { set, roundEnv, env ->
|
fun testComments() = test("Simple", "test.MyAnnotation") { set, roundEnv, env ->
|
||||||
fun commentOf(className: String) = env.elementUtils.getDocComment(env.elementUtils.getTypeElement(className))
|
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