ugly and incomplete solution for using correct bytecode instruction when accessing properties inherited from traits (KT-2391)

This commit is contained in:
Dmitry Jemerov
2012-07-10 21:20:53 +02:00
parent e4f45fc514
commit 1fe9c291f1
3 changed files with 42 additions and 3 deletions
@@ -1228,6 +1228,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
containingDeclaration = containingDeclaration.getOriginal();
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
boolean overridesTrait = isOverrideForTrait(propertyDescriptor);
propertyDescriptor = propertyDescriptor.getOriginal();
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
@@ -1294,11 +1295,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isInterface;
if (isInsideClass || isStatic || propertyDescriptor.getGetter() == null) {
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind());
isInterface = false;
invokeOpcode = isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL;
isInterface = overridesTrait;
invokeOpcode = isStatic ? Opcodes.INVOKESTATIC :
overridesTrait ? Opcodes.INVOKEINTERFACE
: Opcodes.INVOKEVIRTUAL;
}
else {
isInterface = CodegenUtil.isInterface(containingDeclaration);
isInterface = CodegenUtil.isInterface(containingDeclaration) || overridesTrait;
// TODO ugly
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
invokeOpcode = callableMethod.getInvokeOpcode();
@@ -1309,6 +1312,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode);
}
static boolean isOverrideForTrait(CallableMemberDescriptor propertyDescriptor) {
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
final Set<? extends CallableMemberDescriptor> overriddenDescriptors = propertyDescriptor.getOverriddenDescriptors();
for (CallableMemberDescriptor descriptor : overriddenDescriptors) {
if (CodegenUtil.isInterface(descriptor.getContainingDeclaration())) {
return true;
}
}
}
return false;
}
@Override
public StackValue visitCallExpression(JetCallExpression expression, StackValue receiver) {
final JetExpression callee = expression.getCalleeExpression();
@@ -0,0 +1,19 @@
public trait LoggerAware {
public val logger: StringBuilder
}
public abstract class HttpServer(): LoggerAware {
public fun start() {
logger.append("OK")
}
}
public class MyHttpServer(): HttpServer() {
public override val logger = StringBuilder()
}
fun box(): String {
val server = MyHttpServer()
server.start()
return server.logger.toString()!!
}
@@ -461,4 +461,9 @@ public class ClassGenTest extends CodegenTestCase {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt2390.kt");
}
public void testKt2391() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt2391.kt");
}
}