[FE] Skip more special annotations in KMP annotation matching
Many errors are reported in stdlib with these annotations (SinceKotlin, Deprecated, so on). But having them only on expect is a valid case. E.g. SinceKotlin added if some old platform-specific API becomes commonized. ^KT-58551
This commit is contained in:
committed by
Space Team
parent
1dcdcee452
commit
ad84c83ee9
+3
-3
@@ -287,9 +287,9 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("optionalExpectation.kt")
|
||||
public void testOptionalExpectation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/optionalExpectation.kt");
|
||||
@TestMetadata("skippedAnnotations.kt")
|
||||
public void testSkippedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/skippedAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-3
@@ -287,9 +287,9 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("optionalExpectation.kt")
|
||||
public void testOptionalExpectation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/optionalExpectation.kt");
|
||||
@TestMetadata("skippedAnnotations.kt")
|
||||
public void testSkippedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/skippedAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -357,6 +358,9 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
override val isRetentionSource: Boolean
|
||||
get() = getAnnotationClass()?.getRetention(actualSession) == AnnotationRetention.SOURCE
|
||||
|
||||
override val isOptIn: Boolean
|
||||
get() = getAnnotationClass()?.hasAnnotation(OptInNames.REQUIRES_OPT_IN_CLASS_ID, actualSession) ?: false
|
||||
|
||||
private fun getAnnotationClass(): FirRegularClassSymbol? =
|
||||
annotation.annotationTypeRef.coneType.toRegularClassSymbol(actualSession)
|
||||
}
|
||||
|
||||
+9
-4
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -467,10 +468,14 @@ internal abstract class IrExpectActualMatchingContext(
|
||||
get() = irElement.type.getClass()?.classId
|
||||
|
||||
override val isRetentionSource: Boolean
|
||||
get() {
|
||||
val annotationClass = irElement.symbol.owner.parent as? IrClass ?: return false
|
||||
return annotationClass.getAnnotationRetention() == KotlinRetention.SOURCE
|
||||
}
|
||||
get() = getAnnotationClass()?.getAnnotationRetention() == KotlinRetention.SOURCE
|
||||
|
||||
override val isOptIn: Boolean
|
||||
get() = getAnnotationClass()?.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: false
|
||||
|
||||
private fun getAnnotationClass(): IrClass? {
|
||||
return irElement.symbol.owner.parent as? IrClass
|
||||
}
|
||||
}
|
||||
|
||||
override val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean
|
||||
|
||||
+11
-1
@@ -10,6 +10,16 @@ import org.jetbrains.kotlin.mpp.TypeAliasSymbolMarker
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
|
||||
object AbstractExpectActualAnnotationMatchChecker {
|
||||
private val SKIPPED_CLASS_IDS = setOf(
|
||||
StandardClassIds.Annotations.Deprecated,
|
||||
StandardClassIds.Annotations.DeprecatedSinceKotlin,
|
||||
StandardClassIds.Annotations.OptionalExpectation,
|
||||
StandardClassIds.Annotations.RequireKotlin,
|
||||
StandardClassIds.Annotations.SinceKotlin,
|
||||
StandardClassIds.Annotations.Suppress,
|
||||
StandardClassIds.Annotations.WasExperimental,
|
||||
)
|
||||
|
||||
class Incompatibility(val expectSymbol: DeclarationSymbolMarker, val actualSymbol: DeclarationSymbolMarker)
|
||||
|
||||
fun areAnnotationsCompatible(
|
||||
@@ -36,7 +46,7 @@ object AbstractExpectActualAnnotationMatchChecker {
|
||||
val actualAnnotationsByName = actualSymbol.annotations.groupBy { it.classId }
|
||||
|
||||
for (expectAnnotation in expectSymbol.annotations) {
|
||||
if (expectAnnotation.classId == StandardClassIds.Annotations.OptionalExpectation) {
|
||||
if (expectAnnotation.classId in SKIPPED_CLASS_IDS || expectAnnotation.isOptIn) {
|
||||
continue
|
||||
}
|
||||
if (expectAnnotation.isRetentionSource && skipSourceAnnotations) {
|
||||
|
||||
+1
@@ -167,5 +167,6 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
interface AnnotationCallInfo {
|
||||
val classId: ClassId?
|
||||
val isRetentionSource: Boolean
|
||||
val isOptIn: Boolean
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -351,6 +352,9 @@ class ClassicExpectActualMatchingContext(val platformModule: ModuleDescriptor) :
|
||||
|
||||
override val isRetentionSource: Boolean
|
||||
get() = annotationDescriptor.isSourceAnnotation
|
||||
|
||||
override val isOptIn: Boolean
|
||||
get() = annotationDescriptor.annotationClass?.annotations?.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: false
|
||||
}
|
||||
|
||||
override val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean
|
||||
|
||||
Vendored
-12
@@ -1,12 +0,0 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
@OptIn(ExperimentalMultiplatform::class)
|
||||
@OptionalExpectation
|
||||
expect annotation class MyAnnotation
|
||||
|
||||
// MODULE: m1-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
@OptIn(ExperimentalMultiplatform::class)
|
||||
actual annotation class MyAnnotation
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
package kotlin
|
||||
|
||||
@OptIn(ExperimentalMultiplatform::class)
|
||||
@OptionalExpectation
|
||||
expect annotation class OptionalExpectationOnExpectOnly
|
||||
|
||||
@RequiresOptIn
|
||||
annotation class MyOptIn
|
||||
|
||||
@SinceKotlin("1.8")
|
||||
@Deprecated(message = "Some text")
|
||||
@DeprecatedSinceKotlin("1.8")
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@MyOptIn
|
||||
@WasExperimental(MyOptIn::class)
|
||||
@kotlin.internal.RequireKotlin(version = "1.8")
|
||||
expect fun skippedAnnotationsOnExpectOnly()
|
||||
|
||||
// MODULE: m1-jvm()()(m1-common)
|
||||
// FILE: jvm.kt
|
||||
package kotlin
|
||||
|
||||
@OptIn(ExperimentalMultiplatform::class)
|
||||
actual annotation class OptionalExpectationOnExpectOnly
|
||||
|
||||
actual fun skippedAnnotationsOnExpectOnly() {}
|
||||
Generated
+3
-3
@@ -22832,9 +22832,9 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("optionalExpectation.kt")
|
||||
public void testOptionalExpectation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/optionalExpectation.kt");
|
||||
@TestMetadata("skippedAnnotations.kt")
|
||||
public void testSkippedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/annotationMatching/skippedAnnotations.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -153,6 +153,7 @@ object StandardClassIds {
|
||||
val ContextFunctionTypeParams = "ContextFunctionTypeParams".baseId()
|
||||
val Deprecated = "Deprecated".baseId()
|
||||
val DeprecatedSinceKotlin = "DeprecatedSinceKotlin".baseId()
|
||||
val RequireKotlin = "RequireKotlin".internalId()
|
||||
|
||||
val HidesMembers = "HidesMembers".internalId()
|
||||
val DynamicExtension = "DynamicExtension".internalId()
|
||||
|
||||
Reference in New Issue
Block a user