[FE] Prohibit expect or actual opt-in annotations
^KT-58554
This commit is contained in:
committed by
Space Team
parent
600bb3dbc7
commit
4a598afc36
+6
@@ -3457,6 +3457,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.EXPECT_ACTUAL_OPT_IN_ANNOTATION) { firDiagnostic ->
|
||||||
|
ExpectActualOptInAnnotationImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION) { firDiagnostic ->
|
add(FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION) { firDiagnostic ->
|
||||||
InitializerRequiredForDestructuringDeclarationImpl(
|
InitializerRequiredForDestructuringDeclarationImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -2415,6 +2415,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = NotAMultiplatformCompilation::class
|
override val diagnosticClass get() = NotAMultiplatformCompilation::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ExpectActualOptInAnnotation : KtFirDiagnostic<KtNamedDeclaration> {
|
||||||
|
override val diagnosticClass get() = ExpectActualOptInAnnotation::class
|
||||||
|
}
|
||||||
|
|
||||||
interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic<KtDestructuringDeclaration> {
|
interface InitializerRequiredForDestructuringDeclaration : KtFirDiagnostic<KtDestructuringDeclaration> {
|
||||||
override val diagnosticClass get() = InitializerRequiredForDestructuringDeclaration::class
|
override val diagnosticClass get() = InitializerRequiredForDestructuringDeclaration::class
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -2912,6 +2912,11 @@ internal class NotAMultiplatformCompilationImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NotAMultiplatformCompilation
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.NotAMultiplatformCompilation
|
||||||
|
|
||||||
|
internal class ExpectActualOptInAnnotationImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.ExpectActualOptInAnnotation
|
||||||
|
|
||||||
internal class InitializerRequiredForDestructuringDeclarationImpl(
|
internal class InitializerRequiredForDestructuringDeclarationImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+6
@@ -55,6 +55,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
|
|||||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectOptInAnnotation.kt")
|
||||||
|
public void testExpectOptInAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectOptInAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expectTailrec.kt")
|
@TestMetadata("expectTailrec.kt")
|
||||||
public void testExpectTailrec() throws Exception {
|
public void testExpectTailrec() throws Exception {
|
||||||
|
|||||||
+6
@@ -55,6 +55,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
|
|||||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectOptInAnnotation.kt")
|
||||||
|
public void testExpectOptInAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectOptInAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expectTailrec.kt")
|
@TestMetadata("expectTailrec.kt")
|
||||||
public void testExpectTailrec() throws Exception {
|
public void testExpectTailrec() throws Exception {
|
||||||
|
|||||||
+2
@@ -1172,6 +1172,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val ACTUAL_MISSING by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME)
|
val ACTUAL_MISSING by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME)
|
||||||
|
|
||||||
val NOT_A_MULTIPLATFORM_COMPILATION by error<PsiElement>()
|
val NOT_A_MULTIPLATFORM_COMPILATION by error<PsiElement>()
|
||||||
|
|
||||||
|
val EXPECT_ACTUAL_OPT_IN_ANNOTATION by error<KtNamedDeclaration>(PositioningStrategy.EXPECT_ACTUAL_MODIFIER)
|
||||||
}
|
}
|
||||||
|
|
||||||
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
|
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
|
||||||
|
|||||||
+1
@@ -113,6 +113,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
|||||||
REDUNDANT_NULLABLE,
|
REDUNDANT_NULLABLE,
|
||||||
INLINE_FUN_MODIFIER,
|
INLINE_FUN_MODIFIER,
|
||||||
CALL_ELEMENT_WITH_DOT,
|
CALL_ELEMENT_WITH_DOT,
|
||||||
|
EXPECT_ACTUAL_MODIFIER,
|
||||||
;
|
;
|
||||||
|
|
||||||
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"
|
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"
|
||||||
|
|||||||
@@ -626,6 +626,7 @@ object FirErrors {
|
|||||||
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error2<KtNamedDeclaration, FirBasedSymbol<*>, List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error2<KtNamedDeclaration, FirBasedSymbol<*>, List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||||
val ACTUAL_MISSING by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
val ACTUAL_MISSING by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||||
val NOT_A_MULTIPLATFORM_COMPILATION by error0<PsiElement>()
|
val NOT_A_MULTIPLATFORM_COMPILATION by error0<PsiElement>()
|
||||||
|
val EXPECT_ACTUAL_OPT_IN_ANNOTATION by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.EXPECT_ACTUAL_MODIFIER)
|
||||||
|
|
||||||
// Destructuring declaration
|
// Destructuring declaration
|
||||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<KtDestructuringDeclaration>()
|
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<KtDestructuringDeclaration>()
|
||||||
|
|||||||
+19
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.*
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.*
|
||||||
|
|
||||||
@@ -50,6 +52,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
if (declaration.isExpect) {
|
if (declaration.isExpect) {
|
||||||
checkExpectDeclarationModifiers(declaration, context, reporter)
|
checkExpectDeclarationModifiers(declaration, context, reporter)
|
||||||
|
checkOptInAnnotation(declaration, declaration.symbol, context, reporter)
|
||||||
}
|
}
|
||||||
if (declaration.isActual) {
|
if (declaration.isActual) {
|
||||||
checkActualDeclarationHasExpected(declaration, context, reporter)
|
checkActualDeclarationHasExpected(declaration, context, reporter)
|
||||||
@@ -181,6 +184,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
context,
|
context,
|
||||||
reporter,
|
reporter,
|
||||||
)
|
)
|
||||||
|
checkOptInAnnotation(declaration, expectedSingleCandidate, context, reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,4 +260,19 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
return !declaration.isAnnotationConstructor(session) &&
|
return !declaration.isAnnotationConstructor(session) &&
|
||||||
!declaration.isPrimaryConstructorOfInlineOrValueClass(session)
|
!declaration.isPrimaryConstructorOfInlineOrValueClass(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkOptInAnnotation(
|
||||||
|
declaration: FirMemberDeclaration,
|
||||||
|
expectDeclarationSymbol: FirBasedSymbol<*>,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
) {
|
||||||
|
if (declaration is FirClass &&
|
||||||
|
declaration.classKind == ClassKind.ANNOTATION_CLASS &&
|
||||||
|
!expectDeclarationSymbol.hasAnnotation(StandardClassIds.Annotations.OptionalExpectation, context.session) &&
|
||||||
|
declaration.hasAnnotation(OptInNames.REQUIRES_OPT_IN_CLASS_ID, context.session)
|
||||||
|
) {
|
||||||
|
reporter.reportOn(declaration.source, FirErrors.EXPECT_ACTUAL_OPT_IN_ANNOTATION, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -230,6 +230,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_IDENTITY_EQUALS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_IDENTITY_EQUALS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_TAILREC_FUNCTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_TAILREC_FUNCTION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_ACTUAL_OPT_IN_ANNOTATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_CLASS_AS_FUNCTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_CLASS_AS_FUNCTION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_BINARY_MOD
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_BINARY_MOD
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_IDENTITY_EQUALS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_IDENTITY_EQUALS
|
||||||
@@ -1845,6 +1846,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
)
|
)
|
||||||
map.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'")
|
map.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'")
|
||||||
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(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.")
|
||||||
|
|
||||||
// Destructuring declaration
|
// Destructuring declaration
|
||||||
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
|
||||||
|
|||||||
@@ -836,6 +836,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
|
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> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> NOT_A_MULTIPLATFORM_COMPILATION = 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_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(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(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(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");
|
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,
|
declaration, descriptor, context.trace,
|
||||||
checkActualModifier, context.expectActualTracker
|
checkActualModifier, context.expectActualTracker
|
||||||
)
|
)
|
||||||
|
checkOptInAnnotation(declaration, descriptor, descriptor, context.trace)
|
||||||
}
|
}
|
||||||
if (descriptor.isActualOrSomeContainerIsActual()) {
|
if (descriptor.isActualOrSomeContainerIsActual()) {
|
||||||
val allDependsOnModules = moduleStructureOracle.findAllDependsOnPaths(descriptor.module).flatMap { it.nodes }.toHashSet()
|
val allDependsOnModules = moduleStructureOracle.findAllDependsOnPaths(descriptor.module).flatMap { it.nodes }.toHashSet()
|
||||||
@@ -334,6 +335,7 @@ class ExpectedActualDeclarationChecker(
|
|||||||
if (expectedConstructor != null && actualConstructor != null) {
|
if (expectedConstructor != null && actualConstructor != null) {
|
||||||
checkAnnotationConstructors(expectedConstructor, actualConstructor, trace, reportOn)
|
checkAnnotationConstructors(expectedConstructor, actualConstructor, trace, reportOn)
|
||||||
}
|
}
|
||||||
|
checkOptInAnnotation(reportOn, descriptor, expected, trace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val expectSingleCandidate = compatibility.values.singleOrNull()?.singleOrNull()
|
val expectSingleCandidate = compatibility.values.singleOrNull()?.singleOrNull()
|
||||||
@@ -426,6 +428,21 @@ class ExpectedActualDeclarationChecker(
|
|||||||
return null
|
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 {
|
companion object {
|
||||||
fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
|
fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
|
||||||
this.keys.all { it is Incompatible && it.kind == IncompatibilityKind.STRONG }
|
this.keys.all { it is Incompatible && it.kind == IncompatibilityKind.STRONG }
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect annotation class ActualOnly
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION!>expect<!> annotation class Both
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMultiplatform::class)
|
||||||
|
@RequiresOptIn
|
||||||
|
@OptionalExpectation
|
||||||
|
expect annotation class MyOptIn
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION!>actual<!> annotation class ActualOnly
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION!>actual<!> annotation class Both
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
actual annotation class MyOptIn
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
expect annotation class ActualOnly
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION{JVM}!>expect<!> annotation class Both
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMultiplatform::class)
|
||||||
|
@RequiresOptIn
|
||||||
|
@OptionalExpectation
|
||||||
|
expect annotation class MyOptIn
|
||||||
|
|
||||||
|
// MODULE: m1-jvm()()(m1-common)
|
||||||
|
// FILE: jvm.kt
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION!>actual<!> annotation class ActualOnly
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
<!EXPECT_ACTUAL_OPT_IN_ANNOTATION!>actual<!> annotation class Both
|
||||||
|
|
||||||
|
@RequiresOptIn
|
||||||
|
actual annotation class MyOptIn
|
||||||
Generated
+6
@@ -22558,6 +22558,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("expectOptInAnnotation.kt")
|
||||||
|
public void testExpectOptInAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/multiplatform/expectOptInAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expectTailrec.kt")
|
@TestMetadata("expectTailrec.kt")
|
||||||
public void testExpectTailrec() throws Exception {
|
public void testExpectTailrec() throws Exception {
|
||||||
|
|||||||
@@ -189,6 +189,8 @@ object StandardClassIds {
|
|||||||
|
|
||||||
val AccessibleLateinitPropertyLiteral = "AccessibleLateinitPropertyLiteral".internalId()
|
val AccessibleLateinitPropertyLiteral = "AccessibleLateinitPropertyLiteral".internalId()
|
||||||
|
|
||||||
|
val OptionalExpectation = "OptionalExpectation".baseId()
|
||||||
|
|
||||||
object Java {
|
object Java {
|
||||||
val Deprecated = "Deprecated".javaLangId()
|
val Deprecated = "Deprecated".javaLangId()
|
||||||
val Repeatable = "Repeatable".javaAnnotationId()
|
val Repeatable = "Repeatable".javaAnnotationId()
|
||||||
|
|||||||
Reference in New Issue
Block a user