refactoring of property handling and general handling of (this,receiver)
This commit is contained in:
@@ -5,6 +5,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -53,6 +54,14 @@ public class CallableMethod implements Callable {
|
||||
this.receiverFunction = receiverClass;
|
||||
}
|
||||
|
||||
public JetType getThisType() {
|
||||
return thisClass.getDefaultType();
|
||||
}
|
||||
|
||||
public JetType getReceiverClass() {
|
||||
return receiverFunction.getReceiverParameter().getType();
|
||||
}
|
||||
|
||||
public void setNeedsThis(@Nullable ClassDescriptor receiverClass) {
|
||||
this.thisClass = receiverClass;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -123,7 +126,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
return answer;
|
||||
}
|
||||
|
||||
private void generateConstInstance(JetFunctionLiteralExpression fun) {
|
||||
private void generateConstInstance(PsiElement fun) {
|
||||
String classDescr = "L" + name + ";";
|
||||
cv.newField(fun, ACC_PRIVATE | ACC_STATIC, "$instance", classDescr, null, null);
|
||||
|
||||
@@ -149,7 +152,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetFunctionLiteral body) {
|
||||
private boolean generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
|
||||
int arity = funDescriptor.getValueParameters().size();
|
||||
|
||||
ClassDescriptorImpl function = new ClassDescriptorImpl(
|
||||
@@ -167,7 +170,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
return closureContext.outerWasUsed;
|
||||
}
|
||||
|
||||
private void generateBridge(String className, FunctionDescriptor funDescriptor, JetFunctionLiteralExpression fun, ClassBuilder cv) {
|
||||
private void generateBridge(String className, FunctionDescriptor funDescriptor, JetExpression fun, ClassBuilder cv) {
|
||||
final Method bridge = erasedInvokeSignature(funDescriptor);
|
||||
final Method delegate = invokeSignature(funDescriptor);
|
||||
|
||||
@@ -207,7 +210,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private Method generateConstructor(String funClass, JetFunctionLiteralExpression fun) {
|
||||
private Method generateConstructor(String funClass, PsiElement fun) {
|
||||
int argCount = captureThis ? 1 : 0;
|
||||
argCount += (captureReceiver != null ? 1 : 0);
|
||||
|
||||
@@ -294,7 +297,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
signatureWriter.visitTypeArgument(variance);
|
||||
|
||||
final JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
final Type rawRetType = typeMapper.boxType(typeMapper.mapType(type));
|
||||
final Type rawRetType = JetTypeMapper.boxType(typeMapper.mapType(type));
|
||||
signatureWriter.visitClassType(rawRetType.getInternalName());
|
||||
signatureWriter.visitEnd();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,9 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
@@ -101,11 +99,7 @@ public abstract class StackValue {
|
||||
return new Field(type, owner, name, isStatic);
|
||||
}
|
||||
|
||||
public static StackValue instanceField(Type type, String owner, String name) {
|
||||
return new InstanceField(type, owner, name);
|
||||
}
|
||||
|
||||
public static StackValue property(String name, String owner, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter) {
|
||||
public static Property property(String name, String owner, Type type, boolean isStatic, boolean isInterface, boolean isSuper, Method getter, Method setter) {
|
||||
return new Property(name, owner, getter, setter, isStatic, isInterface, isSuper, type);
|
||||
}
|
||||
|
||||
@@ -264,6 +258,12 @@ public abstract class StackValue {
|
||||
return new PreIncrement(index, increment);
|
||||
}
|
||||
|
||||
public static StackValue receiver(ResolvedCall<? extends CallableDescriptor> resolvedCall, StackValue receiver, ExpressionCodegen codegen, @Nullable CallableMethod callableMethod) {
|
||||
if(resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists())
|
||||
return new CallReceiver(resolvedCall, receiver, codegen, callableMethod);
|
||||
return receiver;
|
||||
}
|
||||
|
||||
private static class None extends StackValue {
|
||||
public static None INSTANCE = new None();
|
||||
private None() {
|
||||
@@ -614,7 +614,7 @@ public abstract class StackValue {
|
||||
|
||||
if(resolvedSetCall.getThisObject().exists()) {
|
||||
if(resolvedSetCall.getReceiverArgument().exists()) {
|
||||
codegen.generateFromResolvedCall(resolvedSetCall.getThisObject());
|
||||
codegen.generateFromResolvedCall(resolvedSetCall.getThisObject(), JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
v.load(realReceiverIndex - realReceiverType.getSize(), realReceiverType);
|
||||
}
|
||||
@@ -730,39 +730,11 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
static class InstanceField extends StackValue {
|
||||
final String owner;
|
||||
final String name;
|
||||
|
||||
public InstanceField(Type type, String owner, String name) {
|
||||
super(type);
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.getfield(owner, name, this.type.getDescriptor());
|
||||
coerce(type, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
v.putfield(owner, name, this.type.getDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Property extends StackValue {
|
||||
static class Property extends StackValue {
|
||||
private final String name;
|
||||
private final Method getter;
|
||||
private final Method setter;
|
||||
private final String owner;
|
||||
public final String owner;
|
||||
private final boolean isStatic;
|
||||
private final boolean isInterface;
|
||||
private boolean isSuper;
|
||||
@@ -1011,4 +983,94 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CallReceiver extends StackValue {
|
||||
private ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||
StackValue receiver;
|
||||
private ExpressionCodegen codegen;
|
||||
private CallableMethod callableMethod;
|
||||
|
||||
public CallReceiver(ResolvedCall<? extends CallableDescriptor> resolvedCall, StackValue receiver, ExpressionCodegen codegen, CallableMethod callableMethod) {
|
||||
super(calcType(resolvedCall, codegen, callableMethod));
|
||||
this.resolvedCall = resolvedCall;
|
||||
this.receiver = receiver;
|
||||
this.codegen = codegen;
|
||||
this.callableMethod = callableMethod;
|
||||
}
|
||||
|
||||
private static Type calcType(ResolvedCall<? extends CallableDescriptor> resolvedCall, ExpressionCodegen codegen, CallableMethod callableMethod) {
|
||||
ReceiverDescriptor thisObject = resolvedCall.getThisObject();
|
||||
ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument();
|
||||
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
if (thisObject.exists()) {
|
||||
if(callableMethod != null) {
|
||||
if(receiverArgument.exists()) {
|
||||
return codegen.typeMapper.mapType(callableMethod.getReceiverClass());
|
||||
}
|
||||
else {
|
||||
return codegen.typeMapper.mapType(callableMethod.getThisType());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(receiverArgument.exists()) {
|
||||
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType());
|
||||
}
|
||||
else {
|
||||
return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (receiverArgument.exists()) {
|
||||
if(callableMethod != null)
|
||||
return codegen.typeMapper.mapType(callableMethod.getReceiverClass());
|
||||
else
|
||||
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType());
|
||||
}
|
||||
else {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
ReceiverDescriptor thisObject = resolvedCall.getThisObject();
|
||||
ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument();
|
||||
if (thisObject.exists()) {
|
||||
if(receiverArgument.exists()) {
|
||||
codegen.generateFromResolvedCall(thisObject, codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType()));
|
||||
genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter());
|
||||
}
|
||||
else {
|
||||
genReceiver(v, thisObject, type, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (receiverArgument.exists()) {
|
||||
genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, ReceiverDescriptor receiverParameter) {
|
||||
if(receiver == StackValue.none()) {
|
||||
if(receiverParameter != null) {
|
||||
Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType());
|
||||
codegen.generateFromResolvedCall(receiverArgument, receiverType);
|
||||
StackValue.onStack(receiverType).put(type, v);
|
||||
}
|
||||
else {
|
||||
codegen.generateFromResolvedCall(receiverArgument, type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
receiver.put(type, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.Callable;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
@@ -14,5 +15,5 @@ import java.util.List;
|
||||
* @author yole
|
||||
*/
|
||||
public interface IntrinsicMethod extends Callable {
|
||||
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver);
|
||||
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,11 @@ public class CompileEnvironment {
|
||||
}
|
||||
|
||||
if ((rtJar == null || !rtJar.exists()) && failOnError) {
|
||||
throw new CompileEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome);
|
||||
rtJar = findActiveRtJar(failOnError);
|
||||
|
||||
if ((rtJar == null || !rtJar.exists())) {
|
||||
throw new CompileEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome);
|
||||
}
|
||||
}
|
||||
return rtJar;
|
||||
}
|
||||
@@ -144,7 +148,7 @@ public class CompileEnvironment {
|
||||
throw new CompileEnvironmentException("Could not find rt.jar in system class loader: " + StringUtil.join(loader.getURLs(), new Function<URL, String>() {
|
||||
@Override
|
||||
public String fun(URL url) {
|
||||
return url.toString();
|
||||
return url.toString() + "\n";
|
||||
}
|
||||
}, ", "));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class JetPrefixExpression extends JetUnaryExpression {
|
||||
@Nullable @IfNotParsed
|
||||
public JetExpression getBaseExpression() {
|
||||
PsiElement expression = getOperationSign().getNextSibling();
|
||||
while (expression != null && false == expression instanceof JetExpression) {
|
||||
while (expression != null && !(expression instanceof JetExpression)) {
|
||||
expression = expression.getNextSibling();
|
||||
}
|
||||
return (JetExpression) expression;
|
||||
|
||||
@@ -21,6 +21,7 @@ public class ExtensionFunctionsTest extends CodegenTestCase {
|
||||
|
||||
public void testWhenFail() throws Exception {
|
||||
loadFile();
|
||||
// System.out.println(generateToText());
|
||||
Method foo = generateFunction("foo");
|
||||
assertThrows(foo, Exception.class, null, new StringBuilder());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.jet.codegen;
|
||||
public class ObjectGenTest extends CodegenTestCase {
|
||||
public void testSimpleObject() throws Exception {
|
||||
blackBoxFile("objects/simpleObject.jet");
|
||||
// System.out.println(generateToText());
|
||||
}
|
||||
|
||||
public void testObjectLiteral() throws Exception {
|
||||
|
||||
@@ -134,6 +134,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
||||
|
||||
public void testKt257 () throws Exception {
|
||||
blackBoxFile("regressions/kt257.jet");
|
||||
// System.out.println(generateToText());
|
||||
}
|
||||
|
||||
public void testKt613 () throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user