diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index ef2de012374..34cb7fc0ae3 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -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() fun convertAndAdd(list: JavacList, annotation: AnnotationNode): JavacList { 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()) { diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt index 248970557ef..70a48342061 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt @@ -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 diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java index ba5bb42e02c..9737372a601 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java @@ -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"); diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java index 7b4ddb11eb1..93b991861bd 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java @@ -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"); diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.kt b/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.kt new file mode 100644 index 00000000000..d92eca86e92 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.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 \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.txt b/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.txt new file mode 100644 index 00000000000..7f071690b2e --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/kt32596.txt @@ -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(); + } +} \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt index 9f86ee574cc..7e4acbcbd64 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt @@ -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? = null diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt index 292f74b2bc9..d5639ef1f15 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt @@ -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() diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.kt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.kt index 235ca0829cb..93078ebe3da 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.kt @@ -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 diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.txt index e59b292bb5f..586c6f34507 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClassWIthoutCorrection.txt @@ -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 { }