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();
|
containingDeclaration = containingDeclaration.getOriginal();
|
||||||
|
|
||||||
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
||||||
|
boolean overridesTrait = isOverrideForTrait(propertyDescriptor);
|
||||||
propertyDescriptor = propertyDescriptor.getOriginal();
|
propertyDescriptor = propertyDescriptor.getOriginal();
|
||||||
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
|
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
|
||||||
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
|
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
|
||||||
@@ -1294,11 +1295,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
boolean isInterface;
|
boolean isInterface;
|
||||||
if (isInsideClass || isStatic || propertyDescriptor.getGetter() == null) {
|
if (isInsideClass || isStatic || propertyDescriptor.getGetter() == null) {
|
||||||
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind());
|
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind());
|
||||||
isInterface = false;
|
isInterface = overridesTrait;
|
||||||
invokeOpcode = isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL;
|
invokeOpcode = isStatic ? Opcodes.INVOKESTATIC :
|
||||||
|
overridesTrait ? Opcodes.INVOKEINTERFACE
|
||||||
|
: Opcodes.INVOKEVIRTUAL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
isInterface = CodegenUtil.isInterface(containingDeclaration);
|
isInterface = CodegenUtil.isInterface(containingDeclaration) || overridesTrait;
|
||||||
// TODO ugly
|
// TODO ugly
|
||||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
|
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
|
||||||
invokeOpcode = callableMethod.getInvokeOpcode();
|
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);
|
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
|
@Override
|
||||||
public StackValue visitCallExpression(JetCallExpression expression, StackValue receiver) {
|
public StackValue visitCallExpression(JetCallExpression expression, StackValue receiver) {
|
||||||
final JetExpression callee = expression.getCalleeExpression();
|
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);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt2390.kt");
|
blackBoxFile("regressions/kt2390.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt2391() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("regressions/kt2391.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user