[KAPT] Correct error types in annotations (KT-32596)
This commit is contained in:
committed by
TeamCityServer
parent
701446ad25
commit
4f3debdec6
+24
-11
@@ -40,8 +40,7 @@ import org.jetbrains.kotlin.kapt3.base.stubs.KotlinPosition
|
||||
import org.jetbrains.kotlin.kapt3.base.util.TopLevelJava9Aware
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
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.*
|
||||
import org.jetbrains.kotlin.kapt3.util.*
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
@@ -63,6 +62,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
@@ -1144,12 +1144,18 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
||||
descriptorAnnotations: Annotations
|
||||
): JCModifiers {
|
||||
var seenOverride = false
|
||||
val seenAnnotations = mutableSetOf<AnnotationDescriptor>()
|
||||
fun convertAndAdd(list: JavacList<JCAnnotation>, annotation: AnnotationNode): JavacList<JCAnnotation> {
|
||||
if (annotation.desc == "Ljava/lang/Override;") {
|
||||
if (seenOverride) return list // KT-34569: skip duplicate @Override annotations
|
||||
seenOverride = true
|
||||
}
|
||||
val annotationDescriptor = descriptorAnnotations.singleOrNull { checkIfAnnotationValueMatches(annotation, AnnotationValue(it)) }
|
||||
// Missing annotation classes can match against multiple annotation descriptors
|
||||
val annotationDescriptor = descriptorAnnotations.firstOrNull {
|
||||
it !in seenAnnotations && checkIfAnnotationValueMatches(annotation, AnnotationValue(it))
|
||||
}?.also {
|
||||
seenAnnotations += it
|
||||
}
|
||||
val annotationTree = convertAnnotation(containingClass, annotation, packageFqName, annotationDescriptor) ?: return list
|
||||
return list.prepend(annotationTree)
|
||||
}
|
||||
@@ -1188,19 +1194,26 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
||||
if (stripMetadata && fqName == KOTLIN_METADATA_ANNOTATION) return null
|
||||
}
|
||||
|
||||
val ktAnnotation = (annotationDescriptor?.source as? PsiSourceElement)?.psi as? KtAnnotationEntry
|
||||
val ktAnnotation = annotationDescriptor?.source?.getPsi() as? KtAnnotationEntry
|
||||
val annotationFqName = getNonErrorType(
|
||||
annotationDescriptor?.type,
|
||||
ANNOTATION,
|
||||
{ ktAnnotation?.typeReference },
|
||||
{
|
||||
val useSimpleName = '.' in fqName && fqName.substringBeforeLast('.', "") == packageFqName
|
||||
|
||||
when {
|
||||
useSimpleName -> treeMaker.FqName(fqName.substring(packageFqName!!.length + 1))
|
||||
else -> treeMaker.Type(annotationType)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
val argMapping = ktAnnotation?.calleeExpression
|
||||
?.getResolvedCall(kaptContext.bindingContext)?.valueArguments
|
||||
?.mapKeys { it.key.name.asString() }
|
||||
?: emptyMap()
|
||||
|
||||
val useSimpleName = '.' in fqName && fqName.substringBeforeLast('.', "") == packageFqName
|
||||
|
||||
val annotationFqName = when {
|
||||
useSimpleName -> treeMaker.FqName(fqName.substring(packageFqName!!.length + 1))
|
||||
else -> treeMaker.Type(annotationType)
|
||||
}
|
||||
|
||||
val constantValues = pairedListToMap(annotation.values)
|
||||
|
||||
val values = if (argMapping.isNotEmpty()) {
|
||||
|
||||
+2
-1
@@ -64,7 +64,7 @@ class ErrorTypeCorrector(
|
||||
}
|
||||
|
||||
enum class TypeKind {
|
||||
RETURN_TYPE, METHOD_PARAMETER_TYPE, SUPER_TYPE
|
||||
RETURN_TYPE, METHOD_PARAMETER_TYPE, SUPER_TYPE, ANNOTATION
|
||||
}
|
||||
|
||||
fun convert(type: KtTypeElement, substitutions: SubstitutionMap): JCTree.JCExpression {
|
||||
@@ -147,6 +147,7 @@ class ErrorTypeCorrector(
|
||||
RETURN_TYPE -> typeSystem.getOptimalModeForReturnType(kotlinType, false)
|
||||
METHOD_PARAMETER_TYPE -> typeSystem.getOptimalModeForValueParameter(kotlinType)
|
||||
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
|
||||
ANNOTATION -> TypeMappingMode.DEFAULT // see genAnnotation in org/jetbrains/kotlin/codegen/AnnotationCodegen.java
|
||||
}.updateArgumentModeFromAnnotations(kotlinType, typeSystem)
|
||||
|
||||
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
||||
|
||||
+5
@@ -354,6 +354,11 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt28306.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt32596.kt")
|
||||
public void testKt32596() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt32596.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt34569.kt")
|
||||
public void testKt34569() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt34569.kt");
|
||||
|
||||
+5
@@ -355,6 +355,11 @@ public class IrClassFileToSourceStubConverterTestGenerated extends AbstractIrCla
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt28306.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt32596.kt")
|
||||
public void testKt32596() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt32596.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt34569.kt")
|
||||
public void testKt34569() throws Exception {
|
||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt34569.kt");
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// CORRECT_ERROR_TYPES
|
||||
|
||||
@file:Suppress("UNRESOLVED_REFERENCE", "ANNOTATION_ARGUMENT_MUST_BE_CONST")
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ABC
|
||||
class ErrorMissingAnnotation
|
||||
|
||||
@ABC @CDE
|
||||
class ErrorMultipleMissingAnnotations
|
||||
|
||||
@CDE @Anno(ABC::class) @ABC
|
||||
class ErrorSomeMissingAnnotations
|
||||
|
||||
annotation class Anno(val klass: KClass<*>)
|
||||
|
||||
// EXPECTED_ERROR(kotlin:12:1) cannot find symbol
|
||||
// EXPECTED_ERROR(kotlin:6:1) cannot find symbol
|
||||
// EXPECTED_ERROR(kotlin:9:1) cannot find symbol
|
||||
@@ -0,0 +1,53 @@
|
||||
import kotlin.reflect.KClass;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
public abstract @interface Anno {
|
||||
|
||||
public abstract java.lang.Class<?> klass();
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
import kotlin.reflect.KClass;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@ABC()
|
||||
public final class ErrorMissingAnnotation {
|
||||
|
||||
public ErrorMissingAnnotation() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
import kotlin.reflect.KClass;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@CDE()
|
||||
@ABC()
|
||||
public final class ErrorMultipleMissingAnnotations {
|
||||
|
||||
public ErrorMultipleMissingAnnotations() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
import kotlin.reflect.KClass;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@ABC()
|
||||
@Anno(klass = ABC.class)
|
||||
@CDE()
|
||||
public final class ErrorSomeMissingAnnotations {
|
||||
|
||||
public ErrorSomeMissingAnnotations() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// NON_EXISTENT_CLASS
|
||||
// NO_VALIDATION
|
||||
|
||||
@Suppress("UNRESOLVED_REFERENCE")
|
||||
@Suppress("CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE")
|
||||
object NonExistentType {
|
||||
val a: ABCDEF? = null
|
||||
val b: List<ABCDEF>? = null
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java.lang.System;
|
||||
|
||||
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
|
||||
@kotlin.Suppress(names = {"CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE"})
|
||||
@kotlin.Metadata()
|
||||
public final class NonExistentType {
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// NON_EXISTENT_CLASS
|
||||
// NO_VALIDATION
|
||||
|
||||
@file:Suppress("UNRESOLVED_REFERENCE")
|
||||
@file:Suppress("CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE")
|
||||
|
||||
typealias String2 = String
|
||||
typealias Coocoo = ABC
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import java.lang.System;
|
||||
|
||||
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
|
||||
@kotlin.Suppress(names = {"CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE"})
|
||||
@kotlin.Metadata()
|
||||
public final class NonExistentClassWIthoutCorrectionKt {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user