Fix for KT-11964: No TABLESWITCH in when on enum bytecode if enum constant is imported
#KT-11964 Fixed
This commit is contained in:
+1
@@ -161,6 +161,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, null, null, context);
|
KotlinTypeInfo typeInfo = callExpressionResolver.getSimpleNameExpressionTypeInfo(expression, null, null, context);
|
||||||
checkNull(expression, context, typeInfo.getType());
|
checkNull(expression, context, typeInfo.getType());
|
||||||
|
|
||||||
|
components.constantExpressionEvaluator.evaluateExpression(expression, context.trace, context.expectedType);
|
||||||
return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this
|
return components.dataFlowAnalyzer.checkType(typeInfo, expression, context); // TODO : Extensions to this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
import Color.RED
|
||||||
|
|
||||||
|
enum class Color { RED, GREEN, BLUE }
|
||||||
|
|
||||||
|
fun fifth(arg: Color) = when (arg) {
|
||||||
|
RED -> 1
|
||||||
|
Color.GREEN -> 2
|
||||||
|
Color.BLUE -> 3
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 1 TABLESWITCH
|
||||||
|
// 0 LOOKUPSWITCH
|
||||||
+1
-1
@@ -26,7 +26,7 @@ fun test() {
|
|||||||
|
|
||||||
when (x) {
|
when (x) {
|
||||||
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
<!INCOMPATIBLE_TYPES!>s<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
<!INCOMPATIBLE_TYPES!>""<!> -> <!UNUSED_EXPRESSION!>1<!>
|
<!INCOMPATIBLE_TYPES, DUPLICATE_LABEL_IN_WHEN!>""<!> -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
x -> <!UNUSED_EXPRESSION!>1<!>
|
x -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
1 -> <!UNUSED_EXPRESSION!>1<!>
|
1 -> <!UNUSED_EXPRESSION!>1<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1429,6 +1429,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("importedEnumEntry.kt")
|
||||||
|
public void testImportedEnumEntry() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/whenEnumOptimization/importedEnumEntry.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("manyWhensWithinClass.kt")
|
@TestMetadata("manyWhensWithinClass.kt")
|
||||||
public void testManyWhensWithinClass() throws Exception {
|
public void testManyWhensWithinClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt");
|
||||||
|
|||||||
+1
@@ -16,6 +16,7 @@ Cleaning output files:
|
|||||||
out/production/module/GetRandomEnumEntryKt.class
|
out/production/module/GetRandomEnumEntryKt.class
|
||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
out/production/module/UseEnumImplicitlyKt.class
|
out/production/module/UseEnumImplicitlyKt.class
|
||||||
|
out/production/module/UseKt$WhenMappings.class
|
||||||
out/production/module/UseKt.class
|
out/production/module/UseKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
|||||||
+1
@@ -16,6 +16,7 @@ Cleaning output files:
|
|||||||
out/production/module/GetRandomEnumEntryKt.class
|
out/production/module/GetRandomEnumEntryKt.class
|
||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
out/production/module/UseEnumImplicitlyKt.class
|
out/production/module/UseEnumImplicitlyKt.class
|
||||||
|
out/production/module/UseKt$WhenMappings.class
|
||||||
out/production/module/UseKt.class
|
out/production/module/UseKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
|||||||
+1
@@ -13,6 +13,7 @@ End of files
|
|||||||
|
|
||||||
Cleaning output files:
|
Cleaning output files:
|
||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/UseKt$WhenMappings.class
|
||||||
out/production/module/UseKt.class
|
out/production/module/UseKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
|||||||
+1
@@ -10,6 +10,7 @@ Compiling files:
|
|||||||
End of files
|
End of files
|
||||||
Cleaning output files:
|
Cleaning output files:
|
||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/UseKt$WhenMappings.class
|
||||||
out/production/module/UseKt.class
|
out/production/module/UseKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
|||||||
+1
-2
@@ -12,10 +12,9 @@ class TestAlarm {
|
|||||||
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
|
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, // ERROR
|
||||||
<warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">OtherClass.MY_INTERVAL</warning>, null); // ERROR
|
<warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">OtherClass.MY_INTERVAL</warning>, null); // ERROR
|
||||||
|
|
||||||
// Check value flow analysis, currently unsupported
|
|
||||||
val interval = 10;
|
val interval = 10;
|
||||||
val interval2 = 2L * interval;
|
val interval2 = 2L * interval;
|
||||||
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, interval2, null); // ERROR
|
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, 5000, <warning descr="Value will be forced up to 60000 as of Android 5.1; don't rely on this to be exact">interval2</warning>, null); // ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
private object OtherClass {
|
private object OtherClass {
|
||||||
|
|||||||
+5
-5
@@ -26,8 +26,8 @@ class LogTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun checkWrongTag(tag: String) {
|
fun checkWrongTag(tag: String) {
|
||||||
if (Log.isLoggable(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `null` versus `null` (Conflicting tag)">TAG1</error>, Log.DEBUG)) {
|
if (Log.isLoggable(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `MyTag1` versus `MyTag2` (Conflicting tag)">TAG1</error>, Log.DEBUG)) {
|
||||||
Log.d(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `null` versus `null`">TAG2</error>, "message") // warn: mismatched tags!
|
Log.d(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `MyTag1` versus `MyTag2`">TAG2</error>, "message") // warn: mismatched tags!
|
||||||
}
|
}
|
||||||
if (Log.isLoggable("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag` (Conflicting tag)">my_tag</error>", Log.DEBUG)) {
|
if (Log.isLoggable("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag` (Conflicting tag)">my_tag</error>", Log.DEBUG)) {
|
||||||
Log.d("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag`">other_tag</error>", "message") // warn: mismatched tags!
|
Log.d("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag`">other_tag</error>", "message") // warn: mismatched tags!
|
||||||
@@ -50,12 +50,12 @@ class LogTest {
|
|||||||
Log.d(TAG1, "message") // ok: short
|
Log.d(TAG1, "message") // ok: short
|
||||||
Log.d(TAG22, "message") // ok: short
|
Log.d(TAG22, "message") // ok: short
|
||||||
Log.d(TAG23, "message") // ok: threshold
|
Log.d(TAG23, "message") // ok: threshold
|
||||||
Log.d(TAG24, "message") // error: too long
|
Log.<error descr="The logging tag can be at most 23 characters, was 24 (123456789012345678901234)">d(TAG24, "message")</error> // error: too long
|
||||||
Log.d(LONG_TAG, "message") // error: way too long
|
Log.<error descr="The logging tag can be at most 23 characters, was 39 (MyReallyReallyReallyReallyReallyLongTag)">d(LONG_TAG, "message")</error> // error: way too long
|
||||||
|
|
||||||
// Locally defined variable tags
|
// Locally defined variable tags
|
||||||
val LOCAL_TAG = "MyReallyReallyReallyReallyReallyLongTag"
|
val LOCAL_TAG = "MyReallyReallyReallyReallyReallyLongTag"
|
||||||
Log.d(LOCAL_TAG, "message") // error: too long
|
Log.<error descr="The logging tag can be at most 23 characters, was 39 (MyReallyReallyReallyReallyReallyLongTag)">d(LOCAL_TAG, "message")</error> // error: too long
|
||||||
|
|
||||||
// Concatenated tags
|
// Concatenated tags
|
||||||
Log.<error descr="The logging tag can be at most 23 characters, was 28 (1234567890123456789012MyTag1)">d(TAG22 + TAG1, "message")</error> // error: too long
|
Log.<error descr="The logging tag can be at most 23 characters, was 28 (1234567890123456789012MyTag1)">d(TAG22 + TAG1, "message")</error> // error: too long
|
||||||
|
|||||||
Reference in New Issue
Block a user