correctly handle ensureReceiverOnStack() when the expression is itself a receiver; use correct type when putting/storing fields
This commit is contained in:
@@ -353,7 +353,11 @@ public class ClassCodegen {
|
||||
propertyCodegen.gen((JetProperty) declaration, kind);
|
||||
}
|
||||
else if (declaration instanceof JetFunction) {
|
||||
functionCodegen.gen((JetFunction) declaration, kind);
|
||||
try {
|
||||
functionCodegen.gen((JetFunction) declaration, kind);
|
||||
} catch (RuntimeException e) {
|
||||
throw new RuntimeException("Error generating method "+ aClass.getName() + "." + declaration.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -757,10 +757,13 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
|
||||
private void ensureReceiverOnStack(JetElement expression) {
|
||||
if (expression.getParent() instanceof JetDotQualifiedExpression) {
|
||||
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
||||
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
||||
if (!resolvesToClassOrPackage(parent.getReceiverExpression())) {
|
||||
// we have a receiver on stack
|
||||
if (myStack.isEmpty()) {
|
||||
throw new IllegalStateException("expected receiver on stack but it's not there: " + parent.getReceiverExpression().getText());
|
||||
}
|
||||
myStack.pop().put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
}
|
||||
}
|
||||
@@ -769,6 +772,15 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isReceiver(JetElement expression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof JetQualifiedExpression) {
|
||||
final JetExpression receiverExpression = ((JetQualifiedExpression) parent).getReceiverExpression();
|
||||
return expression == receiverExpression;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void pushMethodArguments(JetCall expression, Method method) {
|
||||
final Type[] argTypes = method.getArgumentTypes();
|
||||
List<JetArgument> args = expression.getValueArguments();
|
||||
|
||||
@@ -408,7 +408,7 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
if (getter == null) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, fieldOwner, name, type.getDescriptor());
|
||||
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, fieldOwner, name, this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : fieldOwner == null ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, interfaceOwner, getter.getName(), getter.getDescriptor());
|
||||
@@ -418,7 +418,7 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
if (setter == null) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, fieldOwner, name, type.getDescriptor());
|
||||
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, fieldOwner, name, this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : fieldOwner == null ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, interfaceOwner, setter.getName(), setter.getDescriptor());
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Evaluator(val expr: StringBuilder) {
|
||||
fun evaluateArg(): Int {
|
||||
return expr.length()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -15,7 +16,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPrivateVal() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PrivateVal");
|
||||
final Field[] fields = aClass.getDeclaredFields();
|
||||
assertEquals(2, fields.length); // $typeInfo, prop
|
||||
@@ -25,7 +25,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPrivateVar() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PrivateVar");
|
||||
final Object instance = aClass.newInstance();
|
||||
Method setter = findMethodByName(aClass, "setValueOfX");
|
||||
@@ -36,7 +35,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testPublicVar() throws Exception {
|
||||
loadText("class PublicVar() { public var foo = 0; }");
|
||||
System.out.println(generateToText());
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "PublicVar");
|
||||
final Object instance = aClass.newInstance();
|
||||
Method setter = findMethodByName(aClass, "setFoo");
|
||||
@@ -79,7 +77,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testFieldSetter() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
final Method method = generateFunction("append");
|
||||
method.invoke(null, "IntelliJ ");
|
||||
String value = (String) method.invoke(null, "IDEA");
|
||||
@@ -88,7 +85,6 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testFieldSetterPlusEq() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
final Method method = generateFunction("append");
|
||||
method.invoke(null, "IntelliJ ");
|
||||
String value = (String) method.invoke(null, "IDEA");
|
||||
@@ -109,8 +105,19 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testInitializersForNamespaceProperties() throws Exception {
|
||||
loadText("public val x = System.currentTimeMillis()");
|
||||
System.out.println(generateToText());
|
||||
final Method method = generateFunction("getX");
|
||||
assertIsCurrentTime((Long) method.invoke(null));
|
||||
}
|
||||
|
||||
public void testPropertyReceiverOnStack() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
final Class aClass = loadImplementationClass(generateClassesInFile(), "Evaluator");
|
||||
final Constructor constructor = aClass.getConstructor(StringBuilder.class);
|
||||
StringBuilder sb = new StringBuilder("xyzzy");
|
||||
final Object instance = constructor.newInstance(sb);
|
||||
final Method method = aClass.getMethod("evaluateArg");
|
||||
Integer result = (Integer) method.invoke(instance);
|
||||
assertEquals(5, result.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user