From 851305f9813d0bacc8b47a61af535acafd11a2ca Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 10 Feb 2022 16:15:28 +0300 Subject: [PATCH] [FIR] Allow smartcasts on member properties for classes from dependsOn dependencies --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 ++ .../fir/resolve/dfa/VariableStorageImpl.kt | 11 +++- ...castOnMemberPropertyFromCommonClass.fir.kt | 17 +++++ ...martcastOnMemberPropertyFromCommonClass.kt | 17 +++++ ...artcastOnMemberPropertyFromCommonClass.txt | 65 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ 8 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index f4d50766ec3..8eba5aa99d0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -20060,6 +20060,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/multiplatform/sealedTypeAliasTopLevel.kt"); } + @Test + @TestMetadata("smartcastOnMemberPropertyFromCommonClass.kt") + public void testSmartcastOnMemberPropertyFromCommonClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index a006e033fd8..da3ba586654 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -20060,6 +20060,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/multiplatform/sealedTypeAliasTopLevel.kt"); } + @Test + @TestMetadata("smartcastOnMemberPropertyFromCommonClass.kt") + public void testSmartcastOnMemberPropertyFromCommonClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 645ebe1cb3a..efacdc1e45b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -20060,6 +20060,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/multiplatform/sealedTypeAliasTopLevel.kt"); } + @Test + @TestMetadata("smartcastOnMemberPropertyFromCommonClass.kt") + public void testSmartcastOnMemberPropertyFromCommonClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt index e46bd1b9edb..152fd7732d2 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/VariableStorageImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isFinal import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression +import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.originalOrSelf import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.resolve.fullyExpandedType @@ -190,7 +191,6 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() { property.isVar -> PropertyStability.MUTABLE_PROPERTY property.receiverTypeRef != null -> PropertyStability.PROPERTY_WITH_GETTER property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER - property.originalOrSelf().moduleData.session != session -> PropertyStability.ALIEN_PUBLIC_PROPERTY property.modality != Modality.FINAL -> { val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return null val receiverType = dispatchReceiver.typeRef.coneTypeSafe()?.fullyExpandedType(session) ?: return null @@ -201,7 +201,14 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() { else -> throw IllegalStateException("Should not be here: $receiverFir") } } - else -> PropertyStability.STABLE_VALUE + else -> { + val propertyModuleData = property.originalOrSelf().moduleData + val currentModuleData = session.moduleData + when (propertyModuleData) { + currentModuleData, in currentModuleData.dependsOnDependencies -> PropertyStability.STABLE_VALUE + else -> PropertyStability.ALIEN_PUBLIC_PROPERTY + } + } } } } diff --git a/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.fir.kt new file mode 100644 index 00000000000..28fa511b663 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.fir.kt @@ -0,0 +1,17 @@ +// MODULE: common +class Some { + val e: SomeEnum? = null +} + +enum class SomeEnum { + A, B +} + +// MODULE: main()()(common) +fun Some.test() { + if (e == null) return + val x = when (e) { + SomeEnum.A -> "a" + SomeEnum.B -> "B" + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt new file mode 100644 index 00000000000..3ac07d61b38 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt @@ -0,0 +1,17 @@ +// MODULE: common +class Some { + val e: SomeEnum? = null +} + +enum class SomeEnum { + A, B +} + +// MODULE: main()()(common) +fun Some.test() { + if (e == null) return + val x = when (e) { + SomeEnum.A -> "a" + SomeEnum.B -> "B" + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.txt b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.txt new file mode 100644 index 00000000000..0903aff6c0f --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.txt @@ -0,0 +1,65 @@ +// -- Module: -- +package + +public final class Some { + public constructor Some() + public final val e: SomeEnum? = null + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + private constructor SomeEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} + +// -- Module:
-- +package + +public fun Some.test(): kotlin.Unit + +public final class Some { + public constructor Some() + public final val e: SomeEnum? = null + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + private constructor SomeEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 51aac68ccdd..25c2d472be0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -20066,6 +20066,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/sealedTypeAliasTopLevel.kt"); } + @Test + @TestMetadata("smartcastOnMemberPropertyFromCommonClass.kt") + public void testSmartcastOnMemberPropertyFromCommonClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/smartcastOnMemberPropertyFromCommonClass.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/multiplatform/defaultArguments") @TestDataPath("$PROJECT_ROOT")