[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.base.util.TopLevelJava9Aware
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
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.*
|
||||||
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.RETURN_TYPE
|
|
||||||
import org.jetbrains.kotlin.kapt3.util.*
|
import org.jetbrains.kotlin.kapt3.util.*
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
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.descriptorUtil.isCompanionObject
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
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.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.isError
|
import org.jetbrains.kotlin.types.isError
|
||||||
@@ -1144,12 +1144,18 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
|||||||
descriptorAnnotations: Annotations
|
descriptorAnnotations: Annotations
|
||||||
): JCModifiers {
|
): JCModifiers {
|
||||||
var seenOverride = false
|
var seenOverride = false
|
||||||
|
val seenAnnotations = mutableSetOf<AnnotationDescriptor>()
|
||||||
fun convertAndAdd(list: JavacList<JCAnnotation>, annotation: AnnotationNode): JavacList<JCAnnotation> {
|
fun convertAndAdd(list: JavacList<JCAnnotation>, annotation: AnnotationNode): JavacList<JCAnnotation> {
|
||||||
if (annotation.desc == "Ljava/lang/Override;") {
|
if (annotation.desc == "Ljava/lang/Override;") {
|
||||||
if (seenOverride) return list // KT-34569: skip duplicate @Override annotations
|
if (seenOverride) return list // KT-34569: skip duplicate @Override annotations
|
||||||
seenOverride = true
|
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
|
val annotationTree = convertAnnotation(containingClass, annotation, packageFqName, annotationDescriptor) ?: return list
|
||||||
return list.prepend(annotationTree)
|
return list.prepend(annotationTree)
|
||||||
}
|
}
|
||||||
@@ -1188,19 +1194,26 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
|
|||||||
if (stripMetadata && fqName == KOTLIN_METADATA_ANNOTATION) return null
|
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
|
val argMapping = ktAnnotation?.calleeExpression
|
||||||
?.getResolvedCall(kaptContext.bindingContext)?.valueArguments
|
?.getResolvedCall(kaptContext.bindingContext)?.valueArguments
|
||||||
?.mapKeys { it.key.name.asString() }
|
?.mapKeys { it.key.name.asString() }
|
||||||
?: emptyMap()
|
?: 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 constantValues = pairedListToMap(annotation.values)
|
||||||
|
|
||||||
val values = if (argMapping.isNotEmpty()) {
|
val values = if (argMapping.isNotEmpty()) {
|
||||||
|
|||||||
+2
-1
@@ -64,7 +64,7 @@ class ErrorTypeCorrector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class TypeKind {
|
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 {
|
fun convert(type: KtTypeElement, substitutions: SubstitutionMap): JCTree.JCExpression {
|
||||||
@@ -147,6 +147,7 @@ class ErrorTypeCorrector(
|
|||||||
RETURN_TYPE -> typeSystem.getOptimalModeForReturnType(kotlinType, false)
|
RETURN_TYPE -> typeSystem.getOptimalModeForReturnType(kotlinType, false)
|
||||||
METHOD_PARAMETER_TYPE -> typeSystem.getOptimalModeForValueParameter(kotlinType)
|
METHOD_PARAMETER_TYPE -> typeSystem.getOptimalModeForValueParameter(kotlinType)
|
||||||
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
|
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
|
||||||
|
ANNOTATION -> TypeMappingMode.DEFAULT // see genAnnotation in org/jetbrains/kotlin/codegen/AnnotationCodegen.java
|
||||||
}.updateArgumentModeFromAnnotations(kotlinType, typeSystem)
|
}.updateArgumentModeFromAnnotations(kotlinType, typeSystem)
|
||||||
|
|
||||||
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
|
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");
|
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")
|
@TestMetadata("kt34569.kt")
|
||||||
public void testKt34569() throws Exception {
|
public void testKt34569() throws Exception {
|
||||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt34569.kt");
|
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");
|
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")
|
@TestMetadata("kt34569.kt")
|
||||||
public void testKt34569() throws Exception {
|
public void testKt34569() throws Exception {
|
||||||
runTest("plugins/kapt3/kapt3-compiler/testData/converter/kt34569.kt");
|
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
|
// NON_EXISTENT_CLASS
|
||||||
// NO_VALIDATION
|
// NO_VALIDATION
|
||||||
|
|
||||||
@Suppress("UNRESOLVED_REFERENCE")
|
@Suppress("CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE")
|
||||||
object NonExistentType {
|
object NonExistentType {
|
||||||
val a: ABCDEF? = null
|
val a: ABCDEF? = null
|
||||||
val b: List<ABCDEF>? = null
|
val b: List<ABCDEF>? = null
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import java.lang.System;
|
import java.lang.System;
|
||||||
|
|
||||||
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
|
@kotlin.Suppress(names = {"CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE"})
|
||||||
@kotlin.Metadata()
|
@kotlin.Metadata()
|
||||||
public final class NonExistentType {
|
public final class NonExistentType {
|
||||||
@org.jetbrains.annotations.NotNull()
|
@org.jetbrains.annotations.NotNull()
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
// NON_EXISTENT_CLASS
|
// NON_EXISTENT_CLASS
|
||||||
// NO_VALIDATION
|
// NO_VALIDATION
|
||||||
|
|
||||||
@file:Suppress("UNRESOLVED_REFERENCE")
|
@file:Suppress("CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE")
|
||||||
|
|
||||||
typealias String2 = String
|
typealias String2 = String
|
||||||
typealias Coocoo = ABC
|
typealias Coocoo = ABC
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import java.lang.System;
|
import java.lang.System;
|
||||||
|
|
||||||
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
|
@kotlin.Suppress(names = {"CANNOT_INFER_PARAMETER_TYPE", "UNRESOLVED_REFERENCE"})
|
||||||
@kotlin.Metadata()
|
@kotlin.Metadata()
|
||||||
public final class NonExistentClassWIthoutCorrectionKt {
|
public final class NonExistentClassWIthoutCorrectionKt {
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user