From 792b6482c050e37fc9de971d7b0fc1a45b92fa99 Mon Sep 17 00:00:00 2001 From: Timofey Solonin Date: Mon, 10 Jul 2023 09:37:18 +0200 Subject: [PATCH] Emit MultiPlatformProjects diagnostic on all declarations where expect/actual modifier is present ^KT-31281 --- .../declaration/FirExpectActualDeclarationChecker.kt | 12 +++++++++++- .../sourceCompatibility/noMultiplatformProjects.kt | 5 +++++ .../sourceCompatibility/noMultiplatformProjects.txt | 8 ++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt index 6707461db7f..9bfafd150e2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirExpectActualDeclarationChecker.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isActual @@ -26,6 +27,9 @@ import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.toSymbol +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.* @@ -34,7 +38,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration !is FirMemberDeclaration) return if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) { - if ((declaration.isExpect || declaration.isActual) && context.containingDeclarations.lastOrNull() is FirFile) { + if ((declaration.isExpect || declaration.isActual) && containsExpectOrActualModifier(declaration)) { reporter.reportOn( declaration.source, FirErrors.UNSUPPORTED_FEATURE, @@ -53,6 +57,12 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { } } + private fun containsExpectOrActualModifier(declaration: FirMemberDeclaration): Boolean { + return declaration.source.getModifierList()?.let { modifiers -> + KtTokens.EXPECT_KEYWORD in modifiers || KtTokens.ACTUAL_KEYWORD in modifiers + } ?: false + } + private fun checkExpectDeclarationModifiers( declaration: FirMemberDeclaration, context: CheckerContext, diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.kt index c7f45df8844..694dba2a20e 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.kt @@ -10,3 +10,8 @@ actual fun foo2() = 42 actual val bar2: Int actual interface Baz2 + +actual class Baz1 { + actual fun foo() { + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.txt index adc6296102d..876e1b4bbf3 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.txt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noMultiplatformProjects.txt @@ -3,6 +3,14 @@ package public actual val bar2: kotlin.Int public actual fun foo2(): kotlin.Int +public final actual class Baz1 { + public constructor Baz1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final actual fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + public actual interface Baz2 { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int