提交 74fe24ef 编写于 作者: A Alex Tkachman

refactoring of property handling and general handling of (this,receiver)

上级 aad2d17c
......@@ -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();
}
......
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);
}
}
}
}
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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册