Accurate representation of smart casts on complex expressions
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
fun baz(s: String?): Int {
|
||||||
|
if (s == null) return 0
|
||||||
|
return when(s) {
|
||||||
|
"abc" -> s
|
||||||
|
else -> "xyz"
|
||||||
|
}.length
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = if (baz("abc") == 3 && baz("") == 3 && baz(null) == 0) "OK" else "FAIL"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun baz(s: String?): Int {
|
||||||
|
return <!DEBUG_INFO_SMARTCAST!>if (s == null) {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val u: String? = null
|
||||||
|
if (u == null) return 0
|
||||||
|
u
|
||||||
|
}<!>.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun baz(/*0*/ s: kotlin.String?): kotlin.Int
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Smart casts on complex expressions
|
||||||
|
fun baz(s: String?): Int {
|
||||||
|
if (s == null) return 0
|
||||||
|
return <!DEBUG_INFO_SMARTCAST!>when(<!DEBUG_INFO_SMARTCAST!>s<!>) {
|
||||||
|
"abc" -> s
|
||||||
|
else -> "xyz"
|
||||||
|
}<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
var ss: String? = null
|
||||||
|
|
||||||
|
fun bar(): Int {
|
||||||
|
if (ss == null) return 0
|
||||||
|
// ss cannot be smart casted, so an error here
|
||||||
|
return when(ss) {
|
||||||
|
"abc" -> ss
|
||||||
|
else -> "xyz"
|
||||||
|
}<!UNSAFE_CALL!>.<!>length
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public var ss: kotlin.String?
|
||||||
|
public fun bar(): kotlin.Int
|
||||||
|
public fun baz(/*0*/ s: kotlin.String?): kotlin.Int
|
||||||
@@ -15225,6 +15225,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartCastOnIf.kt")
|
||||||
|
public void testSmartCastOnIf() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/smartCastOnIf.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartCastOnWhen.kt")
|
||||||
|
public void testSmartCastOnWhen() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/smartCastOnWhen.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("thisWithLabel.kt")
|
@TestMetadata("thisWithLabel.kt")
|
||||||
public void testThisWithLabel() throws Exception {
|
public void testThisWithLabel() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt");
|
||||||
|
|||||||
+6
@@ -7275,6 +7275,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("whenSmartCast.kt")
|
||||||
|
public void testWhenSmartCast() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/whenSmartCast.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/specialBuiltins")
|
@TestMetadata("compiler/testData/codegen/box/specialBuiltins")
|
||||||
|
|||||||
+8
-2
@@ -84,8 +84,14 @@ class VariablesHighlightingVisitor extends AfterAnalysisHighlightingVisitor {
|
|||||||
|
|
||||||
KotlinType smartCast = bindingContext.get(SMARTCAST, expression);
|
KotlinType smartCast = bindingContext.get(SMARTCAST, expression);
|
||||||
if (smartCast != null) {
|
if (smartCast != null) {
|
||||||
holder.createInfoAnnotation(expression, "Smart cast to " +
|
PsiElement target = expression;
|
||||||
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(smartCast))
|
if (expression instanceof KtIfExpression) {
|
||||||
|
target = ((KtIfExpression) expression).getIfKeyword();
|
||||||
|
}
|
||||||
|
else if (expression instanceof KtWhenExpression) {
|
||||||
|
target = ((KtWhenExpression) expression).getWhenKeyword();
|
||||||
|
}
|
||||||
|
holder.createInfoAnnotation(target, "Smart cast to " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(smartCast))
|
||||||
.setTextAttributes(KotlinHighlightingColors.SMART_CAST_VALUE);
|
.setTextAttributes(KotlinHighlightingColors.SMART_CAST_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun baz(s: String?): Int {
|
||||||
|
return <info descr="Smart cast to kotlin.String">if</info> (s == null) {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val u: String? = null
|
||||||
|
if (u == null) return 0
|
||||||
|
u
|
||||||
|
}.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun baz(s: String?): Int {
|
||||||
|
if (s == null) return 0
|
||||||
|
return <info descr="Smart cast to kotlin.String">when</info>(<info descr="Smart cast to kotlin.String">s</info>) {
|
||||||
|
"abc" -> s
|
||||||
|
else -> "xyz"
|
||||||
|
}.length
|
||||||
|
}
|
||||||
@@ -724,6 +724,18 @@ public class PsiCheckerTestGenerated extends AbstractPsiCheckerTest {
|
|||||||
doTestWithInfos(fileName);
|
doTestWithInfos(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SmartCastOnIf.kt")
|
||||||
|
public void testSmartCastOnIf() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCastOnIf.kt");
|
||||||
|
doTestWithInfos(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SmartCastOnWhen.kt")
|
||||||
|
public void testSmartCastOnWhen() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCastOnWhen.kt");
|
||||||
|
doTestWithInfos(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SmartCasts.kt")
|
@TestMetadata("SmartCasts.kt")
|
||||||
public void testSmartCasts() throws Exception {
|
public void testSmartCasts() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCasts.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/checker/infos/SmartCasts.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user