generate CHECK_CAST for smartcasted 'this'
This commit is contained in:
@@ -293,7 +293,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitSuperExpression(@NotNull JetSuperExpression expression, StackValue data) {
|
||||
return StackValue.thisOrOuter(this, getSuperCallLabelTarget(expression), true);
|
||||
return StackValue.thisOrOuter(this, getSuperCallLabelTarget(expression), true, true);
|
||||
}
|
||||
|
||||
private ClassDescriptor getSuperCallLabelTarget(JetSuperExpression expression) {
|
||||
@@ -1720,7 +1720,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
Type scriptClassType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
|
||||
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
|
||||
ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
StackValue script = StackValue.thisOrOuter(this, scriptClass, false);
|
||||
StackValue script = StackValue.thisOrOuter(this, scriptClass, false, false);
|
||||
script.put(script.type, v);
|
||||
Type fieldType = typeMapper.mapType(valueParameterDescriptor);
|
||||
return StackValue.field(fieldType, scriptClassType, valueParameterDescriptor.getName().getIdentifier(), false);
|
||||
@@ -2152,7 +2152,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
StackValue.onStack(exprType).put(type, v);
|
||||
}
|
||||
else {
|
||||
StackValue.thisOrOuter(this, classReceiverDeclarationDescriptor, false).put(type, v);
|
||||
StackValue.thisOrOuter(this, classReceiverDeclarationDescriptor, false, false).put(type, v);
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof ScriptReceiver) {
|
||||
@@ -3418,7 +3418,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
public StackValue visitThisExpression(@NotNull JetThisExpression expression, StackValue receiver) {
|
||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false);
|
||||
return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
|
||||
}
|
||||
else {
|
||||
if (descriptor instanceof CallableDescriptor) {
|
||||
|
||||
@@ -309,10 +309,11 @@ public abstract class StackValue {
|
||||
return new Composed(prefix, suffix);
|
||||
}
|
||||
|
||||
public static StackValue thisOrOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper) {
|
||||
// Coerce this/super for traits to support traits with required classes
|
||||
// Do not coerce for other classes due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints)
|
||||
boolean coerceType = descriptor.getKind() == ClassKind.TRAIT;
|
||||
public static StackValue thisOrOuter(ExpressionCodegen codegen, ClassDescriptor descriptor, boolean isSuper, boolean isExplicit) {
|
||||
// Coerce this/super for traits to support traits with required classes.
|
||||
// Coerce explicit 'this' for the case when it is smartcasted.
|
||||
// Do not coerce for other classes due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints).
|
||||
boolean coerceType = descriptor.getKind() == ClassKind.TRAIT || (isExplicit && !isSuper);
|
||||
return new ThisOuter(codegen, descriptor, isSuper, coerceType);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A
|
||||
|
||||
class B : A() {
|
||||
fun foo(i: Int) = i
|
||||
}
|
||||
|
||||
fun A.test() = if (this is B) foo(42) else 0
|
||||
|
||||
fun box(): String {
|
||||
if (B().test() != 42) return "fail1"
|
||||
if (A().test() != 0) return "fail2"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package h
|
||||
|
||||
open class A {
|
||||
fun bar() = if (this is B) this.foo() else "fail"
|
||||
}
|
||||
|
||||
class B() : A() {
|
||||
fun foo() = "OK"
|
||||
}
|
||||
|
||||
fun box() = B().bar()
|
||||
@@ -4979,6 +4979,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/typeInfo/asInLoop.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitSmartCastedThis.kt")
|
||||
public void testImplicitSmartCastedThis() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/typeInfo/implicitSmartCastedThis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritance.kt")
|
||||
public void testInheritance() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/typeInfo/inheritance.kt");
|
||||
@@ -4999,6 +5004,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/typeInfo/primitiveTypeInfo.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastedThis.kt")
|
||||
public void testSmartCastedThis() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/typeInfo/smartCastedThis.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/typeMapping")
|
||||
|
||||
Reference in New Issue
Block a user