generate CHECK_CAST for smartcasted 'this'

This commit is contained in:
Svetlana Isakova
2014-01-21 13:37:36 +04:00
parent 9ed57a5767
commit 9d493b6f7b
5 changed files with 43 additions and 8 deletions
@@ -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);
}