Add some data flow analysis tests on when

This commit is contained in:
Dmitry Savvinov
2018-06-08 11:29:27 +03:00
committed by Dmitry Petrov
parent ae929d0f08
commit 148d03e365
10 changed files with 213 additions and 0 deletions
@@ -0,0 +1,37 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun getBoolean() = true
fun testSafeCaptureVarInInitializer() {
var x: Int? = 42
x!!
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
val s = when (val y = run { x = 42; 32 }) {
0 -> {
<!SMARTCAST_IMPOSSIBLE!>x<!>.inc() // TODO fix smart casts for captured variables
"0"
}
else -> "!= 0"
}
<!SMARTCAST_IMPOSSIBLE!>x<!>.inc() // TODO fix smart casts for captured variables
}
fun testUnsafeCaptureVarInInitializer() {
var x: Int? = 42
x!!
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
val s = when (val y = run { x = null; 32 }) {
0 -> {
<!SMARTCAST_IMPOSSIBLE!>x<!>.inc() // NB smart cast should be impossible
"0"
}
else -> "!= 0"
}
<!SMARTCAST_IMPOSSIBLE!>x<!>.inc() // NB smart cast should be impossible
}
@@ -0,0 +1,5 @@
package
public fun getBoolean(): kotlin.Boolean
public fun testSafeCaptureVarInInitializer(): kotlin.Unit
public fun testUnsafeCaptureVarInInitializer(): kotlin.Unit
@@ -0,0 +1,43 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun testJumpOutInElvis(x: Int?) {
loop@ while (true) {
val y = when (val z = x ?: break@loop) {
0 -> "0"
else -> "not 0"
}
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
}
x<!UNSAFE_CALL!>.<!>inc()
}
fun testJumpOutInElvisLikeIf(x: Int?) {
loop@ while (true) {
val y = when (val z = if (x == null) break@loop else <!DEBUG_INFO_SMARTCAST!>x<!>) {
0 -> "0"
else -> "not 0"
}
<!DEBUG_INFO_SMARTCAST!>x<!>.inc()
}
x<!UNSAFE_CALL!>.<!>inc()
}
fun getBoolean() = true
fun testJumpOutInIf(x: Int?) {
loop@ while (true) {
val y = when (val z = if (getBoolean()) { x!!; break@loop } else x) {
0 -> "0"
else -> "not 0"
}
x<!UNSAFE_CALL!>.<!>inc()
}
x<!UNSAFE_CALL!>.<!>inc() // Actually, safe, but it's OK if it's error
}
@@ -0,0 +1,6 @@
package
public fun getBoolean(): kotlin.Boolean
public fun testJumpOutInElvis(/*0*/ x: kotlin.Int?): kotlin.Unit
public fun testJumpOutInElvisLikeIf(/*0*/ x: kotlin.Int?): kotlin.Unit
public fun testJumpOutInIf(/*0*/ x: kotlin.Int?): kotlin.Unit
@@ -0,0 +1,10 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
fun testNoSubjectVariableName(x: Int?) {
val y = when (val<!SYNTAX!><!> = 42) {
0 -> "0"
else -> "not 0"
}
}
@@ -0,0 +1,3 @@
package
public fun testNoSubjectVariableName(/*0*/ x: kotlin.Int?): kotlin.Unit
@@ -0,0 +1,23 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
enum class E { FIRST, SECOND }
fun testSmartcastToEnumInSubjectInitializer(e: E?) {
val x = <!NO_ELSE_IN_WHEN!>when<!> (val ne = e!!) { // TODO fix
E.FIRST -> "f"
E.SECOND -> "s"
}
}
sealed class Either
class Left : Either()
class Right : Either()
fun testSmartcastToSealedInSubjectInitializer(x: Any?) {
val y = <!NO_ELSE_IN_WHEN!>when<!> (val either = x as Either) { // TODO fix
is Left -> "L"
is Right -> "R"
}
}
@@ -0,0 +1,46 @@
package
public fun testSmartcastToEnumInSubjectInitializer(/*0*/ e: E?): kotlin.Unit
public fun testSmartcastToSealedInSubjectInitializer(/*0*/ x: kotlin.Any?): kotlin.Unit
public final enum class E : kotlin.Enum<E> {
enum entry FIRST
enum entry SECOND
private constructor E()
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: E): 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<E!>!
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): E
public final /*synthesized*/ fun values(): kotlin.Array<E>
}
public sealed class Either {
private constructor Either()
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 class Left : Either {
public constructor Left()
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 class Right : Either {
public constructor Right()
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
}
@@ -22470,16 +22470,31 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/when/withSubjectVariable"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("capturingInInitializer.kt")
public void testCapturingInInitializer() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/capturingInInitializer.kt");
}
@TestMetadata("invisibleOutsideOfWhen.kt")
public void testInvisibleOutsideOfWhen() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/invisibleOutsideOfWhen.kt");
}
@TestMetadata("jumpoutInInitializer.kt")
public void testJumpoutInInitializer() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/jumpoutInInitializer.kt");
}
@TestMetadata("nestedWhenWithSubject.kt")
public void testNestedWhenWithSubject() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.kt");
}
@TestMetadata("noSubjectVariableName.kt")
public void testNoSubjectVariableName() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/noSubjectVariableName.kt");
}
@TestMetadata("reassignmentToWhenSubjectVariable.kt")
public void testReassignmentToWhenSubjectVariable() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/reassignmentToWhenSubjectVariable.kt");
@@ -22500,6 +22515,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/smartCastsOnSubjectVariable.kt");
}
@TestMetadata("smartcastToEnum.kt")
public void testSmartcastToEnum() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt");
}
@TestMetadata("subjectVariableInIsPattern.kt")
public void testSubjectVariableInIsPattern() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/subjectVariableInIsPattern.kt");
@@ -22470,16 +22470,31 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/when/withSubjectVariable"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("capturingInInitializer.kt")
public void testCapturingInInitializer() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/capturingInInitializer.kt");
}
@TestMetadata("invisibleOutsideOfWhen.kt")
public void testInvisibleOutsideOfWhen() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/invisibleOutsideOfWhen.kt");
}
@TestMetadata("jumpoutInInitializer.kt")
public void testJumpoutInInitializer() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/jumpoutInInitializer.kt");
}
@TestMetadata("nestedWhenWithSubject.kt")
public void testNestedWhenWithSubject() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.kt");
}
@TestMetadata("noSubjectVariableName.kt")
public void testNoSubjectVariableName() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/noSubjectVariableName.kt");
}
@TestMetadata("reassignmentToWhenSubjectVariable.kt")
public void testReassignmentToWhenSubjectVariable() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/reassignmentToWhenSubjectVariable.kt");
@@ -22500,6 +22515,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/smartCastsOnSubjectVariable.kt");
}
@TestMetadata("smartcastToEnum.kt")
public void testSmartcastToEnum() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt");
}
@TestMetadata("subjectVariableInIsPattern.kt")
public void testSubjectVariableInIsPattern() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/withSubjectVariable/subjectVariableInIsPattern.kt");