[FE] Prohibit expect or actual opt-in annotations
^KT-58554
This commit is contained in:
committed by
Space Team
parent
600bb3dbc7
commit
4a598afc36
@@ -836,6 +836,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NOT_A_MULTIPLATFORM_COMPILATION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtNamedDeclaration> EXPECT_ACTUAL_OPT_IN_ANNOTATION = DiagnosticFactory0.create(ERROR, EXPECT_ACTUAL_MODIFIER);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
+1
@@ -392,6 +392,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
|
||||
MAP.put(OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE, "Declaration annotated with '@OptionalExpectation' can only be used in common module sources");
|
||||
MAP.put(NOT_A_MULTIPLATFORM_COMPILATION, "'expect' and 'actual' declarations can be used only in multiplatform projects. Learn more about Kotlin Multiplatform: https://kotl.in/multiplatform-setup");
|
||||
MAP.put(EXPECT_ACTUAL_OPT_IN_ANNOTATION, "Opt-in annotations are prohibited to be `expect` or `actual`. Instead, declare annotation once in common sources.");
|
||||
|
||||
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
|
||||
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
|
||||
|
||||
+17
@@ -64,6 +64,7 @@ class ExpectedActualDeclarationChecker(
|
||||
declaration, descriptor, context.trace,
|
||||
checkActualModifier, context.expectActualTracker
|
||||
)
|
||||
checkOptInAnnotation(declaration, descriptor, descriptor, context.trace)
|
||||
}
|
||||
if (descriptor.isActualOrSomeContainerIsActual()) {
|
||||
val allDependsOnModules = moduleStructureOracle.findAllDependsOnPaths(descriptor.module).flatMap { it.nodes }.toHashSet()
|
||||
@@ -334,6 +335,7 @@ class ExpectedActualDeclarationChecker(
|
||||
if (expectedConstructor != null && actualConstructor != null) {
|
||||
checkAnnotationConstructors(expectedConstructor, actualConstructor, trace, reportOn)
|
||||
}
|
||||
checkOptInAnnotation(reportOn, descriptor, expected, trace)
|
||||
}
|
||||
}
|
||||
val expectSingleCandidate = compatibility.values.singleOrNull()?.singleOrNull()
|
||||
@@ -426,6 +428,21 @@ class ExpectedActualDeclarationChecker(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun checkOptInAnnotation(
|
||||
reportOn: KtNamedDeclaration,
|
||||
descriptor: MemberDescriptor,
|
||||
expectDescriptor: MemberDescriptor,
|
||||
trace: BindingTrace,
|
||||
) {
|
||||
if (descriptor is ClassDescriptor &&
|
||||
descriptor.kind == ClassKind.ANNOTATION_CLASS &&
|
||||
descriptor.annotations.hasAnnotation(OptInNames.REQUIRES_OPT_IN_FQ_NAME) &&
|
||||
!expectDescriptor.annotations.hasAnnotation(OptionalAnnotationUtil.OPTIONAL_EXPECTATION_FQ_NAME)
|
||||
) {
|
||||
trace.report(Errors.EXPECT_ACTUAL_OPT_IN_ANNOTATION.on(reportOn))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
|
||||
this.keys.all { it is Incompatible && it.kind == IncompatibilityKind.STRONG }
|
||||
|
||||
Reference in New Issue
Block a user