ugly and incomplete solution for using correct bytecode instruction when accessing properties inherited from traits (KT-2391)
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user