[K2] Prohibit smart casts for 'expect' properties

^KT-61340
This commit is contained in:
Anastasia.Nekrasova
2023-09-19 19:03:15 +03:00
committed by Space Team
parent e4ea733482
commit e3bab4a7da
9 changed files with 150 additions and 0 deletions
@@ -1723,6 +1723,28 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/smartCasts")
@TestDataPath("$PROJECT_ROOT")
public class SmartCasts {
@Test
public void testAllFilesPresentInSmartCasts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/smartCasts"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("kt61340_commonCode.kt")
public void testKt61340_commonCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_commonCode.kt");
}
@Test
@TestMetadata("kt61340_platformCode.kt")
public void testKt61340_platformCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_platformCode.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun")
@TestDataPath("$PROJECT_ROOT")
@@ -1723,6 +1723,28 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/smartCasts")
@TestDataPath("$PROJECT_ROOT")
public class SmartCasts {
@Test
public void testAllFilesPresentInSmartCasts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/smartCasts"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("kt61340_commonCode.kt")
public void testKt61340_commonCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_commonCode.kt");
}
@Test
@TestMetadata("kt61340_platformCode.kt")
public void testKt61340_platformCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_platformCode.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun")
@TestDataPath("$PROJECT_ROOT")
@@ -36,6 +36,9 @@ enum class PropertyStability(val impliedSmartcastStability: SmartcastStability?)
// Smartcast may or may not be safe, depending on whether there are concurrent writes to this local variable.
LOCAL_VAR(null),
// Smartcast is always unsafe regardless of usage.
EXPECT_PROPERTY(SmartcastStability.EXPECT_PROPERTY),
// Open or custom getter.
// Smartcast is always unsafe regardless of usage.
PROPERTY_WITH_GETTER(SmartcastStability.PROPERTY_WITH_GETTER),
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility
@@ -165,6 +166,7 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
is FirFunctionSymbol<*>, is FirClassSymbol<*> -> return PropertyStability.STABLE_VALUE
is FirBackingFieldSymbol -> return if (isVal) PropertyStability.STABLE_VALUE else PropertyStability.MUTABLE_PROPERTY
}
if (this is FirCallableSymbol && this.isExpect) return PropertyStability.EXPECT_PROPERTY
if (this !is FirVariableSymbol<*>) return null
if (this is FirFieldSymbol && !this.isFinal) return PropertyStability.MUTABLE_PROPERTY
@@ -0,0 +1,25 @@
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// MODULE: m1-common
// FILE: common.kt
expect val foo: Any
expect class Bar() {
val bus: Any
}
fun common() {
if (foo is String) <!SMARTCAST_IMPOSSIBLE!>foo<!>.length
val bar = Bar()
if (bar.bus is String) <!SMARTCAST_IMPOSSIBLE!>bar.bus<!>.length
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual val foo: Any = 2
actual class Bar actual constructor() {
actual val bus: Any
get() = "bus"
}
@@ -0,0 +1,25 @@
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// MODULE: m1-common
// FILE: common.kt
expect val foo: Any
expect class Bar() {
val bus: Any
}
fun common() {
if (foo is String) foo.length
val bar = Bar()
if (bar.bus is String) <!SMARTCAST_IMPOSSIBLE{JVM}!>bar.bus<!>.length
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual val foo: Any = 2
actual class Bar actual constructor() {
actual val bus: Any
get() = "bus"
}
@@ -0,0 +1,26 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
// MODULE: m1-common
// FILE: common.kt
expect val foo: Any
expect class Bar() {
val bus: Any
}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
actual val foo: Any = 2
actual class Bar actual constructor() {
actual val bus: Any
get() = "bus"
}
fun platform() {
if (foo is String) foo.length
val bar = Bar()
if (bar.bus is String) <!SMARTCAST_IMPOSSIBLE!>bar.bus<!>.length
}
@@ -24892,6 +24892,28 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/smartCasts")
@TestDataPath("$PROJECT_ROOT")
public class SmartCasts {
@Test
public void testAllFilesPresentInSmartCasts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/smartCasts"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
}
@Test
@TestMetadata("kt61340_commonCode.kt")
public void testKt61340_commonCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_commonCode.kt");
}
@Test
@TestMetadata("kt61340_platformCode.kt")
public void testKt61340_platformCode() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/smartCasts/kt61340_platformCode.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/multiplatform/topLevelFun")
@TestDataPath("$PROJECT_ROOT")
@@ -17,6 +17,9 @@ enum class SmartcastStability(private val str: String, val description: String =
// Smart casts are completely safe
STABLE_VALUE("stable val"),
// Smart casts are not safe
EXPECT_PROPERTY("expect property"),
// Member value with open / custom getter
// Smart casts are not safe
PROPERTY_WITH_GETTER("custom getter", "property that has open or custom getter"),