[FE1.0] Fix false reporting of non-matching actual annotations in IDE
It was reported because in composite module analysis we have both expect and actual annotation descriptors, which may differ. This may lead to bugs in the checker of ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT diagnostic. `fqName` comparison can be safely removed, because we already check types in `areCompatibleExpectActualTypes`. Tests: - typealiasedAnnotation.kt - for annotation use (so it has different ClassId) - typealiasedAnnotationAsArgument.kt - when typealiased annotation used in another annotation as argument - sourceRetentionAnnotationsWhenTypealias.kt - tests same as compiler/testData/diagnostics/tests/multiplatform/annotationMatching/sourceRetentionAnnotationsWhenTypealias.kt No special test added for opt-in, because it's prohibited to have expect/actual opt-ins by EXPECT_ACTUAL_OPT_IN_ANNOTATION checker. ^KTIJ-26700
This commit is contained in:
committed by
Space Team
parent
dce1c1c70a
commit
77ab13400e
+28
@@ -1392,6 +1392,34 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
|
||||
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/sealedInheritorsInComplexModuleStructure.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class AnnotationMatching {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotationMatching() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sourceRetentionAnnotationsWhenTypealias.kt")
|
||||
public void testSourceRetentionAnnotationsWhenTypealias() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/sourceRetentionAnnotationsWhenTypealias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotation.kt")
|
||||
public void testTypealiasedAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotationAsArgument.kt")
|
||||
public void testTypealiasedAnnotationAsArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotationAsArgument.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
@@ -1392,6 +1392,34 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
|
||||
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/sealedInheritorsInComplexModuleStructure.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class AnnotationMatching {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotationMatching() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sourceRetentionAnnotationsWhenTypealias.kt")
|
||||
public void testSourceRetentionAnnotationsWhenTypealias() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/sourceRetentionAnnotationsWhenTypealias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotation.kt")
|
||||
public void testTypealiasedAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotationAsArgument.kt")
|
||||
public void testTypealiasedAnnotationAsArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotationAsArgument.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-4
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.multiplatform
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.mpp.*
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
@@ -368,19 +369,34 @@ class ClassicExpectActualMatchingContext(
|
||||
)
|
||||
}
|
||||
|
||||
private class AnnotationCallInfoImpl(
|
||||
private inner class AnnotationCallInfoImpl(
|
||||
val annotationDescriptor: AnnotationDescriptor,
|
||||
) : AnnotationCallInfo {
|
||||
override val annotationSymbol: AnnotationDescriptor = annotationDescriptor
|
||||
|
||||
override val classId: ClassId?
|
||||
get() = annotationDescriptor.annotationClass?.classId
|
||||
get() = getAnnotationClassDescriptor()?.classId
|
||||
|
||||
override val isRetentionSource: Boolean
|
||||
get() = annotationDescriptor.isSourceAnnotation
|
||||
get() = getAnnotationClassDescriptor()?.getAnnotationRetention() == KotlinRetention.SOURCE
|
||||
|
||||
override val isOptIn: Boolean
|
||||
get() = annotationDescriptor.annotationClass?.annotations?.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: false
|
||||
get() = getAnnotationClassDescriptor()?.annotations?.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: false
|
||||
|
||||
private fun getAnnotationClassDescriptor(): ClassDescriptor? {
|
||||
val classDescriptor = annotationDescriptor.annotationClass ?: return null
|
||||
if (!classDescriptor.isExpect) {
|
||||
return classDescriptor
|
||||
}
|
||||
val classId = classDescriptor.classId
|
||||
// For IDE composite module analysis, when actual annotation may differ
|
||||
val platformDescriptor = platformModule.findClassifierAcrossModuleDependencies(classId)
|
||||
return when (platformDescriptor) {
|
||||
is ClassDescriptor -> platformDescriptor
|
||||
is TypeAliasDescriptor -> platformDescriptor.classDescriptor ?: classDescriptor
|
||||
else -> classDescriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean
|
||||
|
||||
+1
-2
@@ -19,8 +19,7 @@ internal fun ExpectActualMatchingContext<*>.areExpressionConstValuesEqual(
|
||||
a is AnnotationDescriptor && b is AnnotationDescriptor -> {
|
||||
val aArgs = a.allValueArguments
|
||||
val bArgs = b.allValueArguments
|
||||
a.fqName == b.fqName &&
|
||||
aArgs.size == bArgs.size &&
|
||||
aArgs.size == bArgs.size &&
|
||||
areCompatibleExpectActualTypes(a.type, b.type) &&
|
||||
aArgs.keys.all { k -> areExpressionConstValuesEqual(aArgs[k], bArgs[k], collectionArgumentsCompatibilityCheckStrategy) }
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
// MODULE: common
|
||||
// TARGET_PLATFORM: Common
|
||||
expect annotation class Ann() // No @Retention SOURCE set
|
||||
|
||||
@Ann
|
||||
expect annotation class CommonVolatile
|
||||
|
||||
// MODULE: main()()(common)
|
||||
// TARGET_PLATFORM: JVM
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
actual annotation class Ann
|
||||
|
||||
actual typealias CommonVolatile = kotlin.jvm.Volatile
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: common
|
||||
// TARGET_PLATFORM: Common
|
||||
expect annotation class Test()
|
||||
|
||||
@Test
|
||||
expect fun unexpandedOnActual()
|
||||
|
||||
@Test
|
||||
expect fun expandedOnActual()
|
||||
|
||||
// MODULE: main()()(common)
|
||||
annotation class JunitTestInLib
|
||||
|
||||
actual typealias Test = JunitTestInLib
|
||||
|
||||
@Test
|
||||
actual fun unexpandedOnActual() {}
|
||||
|
||||
@JunitTestInLib
|
||||
actual fun expandedOnActual() {}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// FIR_IDENTICAL
|
||||
// DIAGNOSTICS: -TYPE_MISMATCH
|
||||
// MODULE: common
|
||||
// TARGET_PLATFORM: Common
|
||||
expect annotation class Typealiased()
|
||||
|
||||
annotation class Ann(val p: Typealiased)
|
||||
|
||||
@Ann(Typealiased())
|
||||
expect fun test()
|
||||
|
||||
// MODULE: main()()(common)
|
||||
annotation class TypealiasedImpl
|
||||
|
||||
actual typealias Typealiased = TypealiasedImpl
|
||||
|
||||
@Ann(Typealiased())
|
||||
actual fun test() {}
|
||||
|
||||
Generated
+28
@@ -24179,6 +24179,34 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/sealedInheritorsInComplexModuleStructure.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class AnnotationMatching {
|
||||
@Test
|
||||
public void testAllFilesPresentInAnnotationMatching() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sourceRetentionAnnotationsWhenTypealias.kt")
|
||||
public void testSourceRetentionAnnotationsWhenTypealias() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/sourceRetentionAnnotationsWhenTypealias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotation.kt")
|
||||
public void testTypealiasedAnnotation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typealiasedAnnotationAsArgument.kt")
|
||||
public void testTypealiasedAnnotationAsArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/multiplatformCompositeAnalysis/annotationMatching/typealiasedAnnotationAsArgument.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user