fix for broken test. (this, receiver) handling normalized
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
@@ -18,8 +20,9 @@ public class CallableMethod implements Callable {
|
|||||||
private final Method signature;
|
private final Method signature;
|
||||||
private int invokeOpcode;
|
private int invokeOpcode;
|
||||||
private final List<Type> valueParameterTypes;
|
private final List<Type> valueParameterTypes;
|
||||||
private DeclarationDescriptor thisClass = null;
|
private ClassDescriptor thisClass = null;
|
||||||
private DeclarationDescriptor receiverClass = null;
|
|
||||||
|
private FunctionDescriptor receiverFunction = null;
|
||||||
private Type generateCalleeType = null;
|
private Type generateCalleeType = null;
|
||||||
|
|
||||||
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) {
|
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) {
|
||||||
@@ -45,11 +48,11 @@ public class CallableMethod implements Callable {
|
|||||||
return valueParameterTypes;
|
return valueParameterTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNeedsReceiver(@Nullable DeclarationDescriptor receiverClass) {
|
public void setNeedsReceiver(@Nullable FunctionDescriptor receiverClass) {
|
||||||
this.receiverClass = receiverClass;
|
this.receiverFunction = receiverClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNeedsThis(@Nullable DeclarationDescriptor receiverClass) {
|
public void setNeedsThis(@Nullable ClassDescriptor receiverClass) {
|
||||||
this.thisClass = receiverClass;
|
this.thisClass = receiverClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,10 +81,14 @@ public class CallableMethod implements Callable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNeedsReceiver() {
|
public boolean isNeedsReceiver() {
|
||||||
return receiverClass != null;
|
return receiverFunction != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeclarationDescriptor getThisClass() {
|
public ClassDescriptor getThisClass() {
|
||||||
return thisClass;
|
return thisClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunctionDescriptor getReceiverFunction() {
|
||||||
|
return receiverFunction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,17 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
return new Method("invoke", JetTypeMapper.TYPE_OBJECT, args);
|
return new Method("invoke", JetTypeMapper.TYPE_OBJECT, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
|
||||||
|
Method descriptor = erasedInvokeSignature(fd);
|
||||||
|
String owner = getInternalClassName(fd);
|
||||||
|
final CallableMethod result = new CallableMethod(owner, descriptor, INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
||||||
|
if (fd.getReceiverParameter().exists()) {
|
||||||
|
result.setNeedsReceiver(fd);
|
||||||
|
}
|
||||||
|
result.requestGenerateCallee(Type.getObjectType(getInternalClassName(fd)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public Method invokeSignature(FunctionDescriptor fd) {
|
public Method invokeSignature(FunctionDescriptor fd) {
|
||||||
return state.getTypeMapper().mapSignature("invoke", fd);
|
return state.getTypeMapper().mapSignature("invoke", fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import gnu.trove.THashSet;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
@@ -13,6 +14,7 @@ import org.jetbrains.jet.lang.types.JetType;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -142,4 +144,29 @@ public class CodegenUtil {
|
|||||||
Modality.FINAL, Visibility.PUBLIC);
|
Modality.FINAL, Visibility.PUBLIC);
|
||||||
return invokeDescriptor;
|
return invokeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSubclass(ClassDescriptor subClass, ClassDescriptor superClass) {
|
||||||
|
Set<JetType> allSuperTypes = new THashSet<JetType>();
|
||||||
|
|
||||||
|
addSuperTypes(subClass.getDefaultType(), allSuperTypes);
|
||||||
|
|
||||||
|
final DeclarationDescriptor superOriginal = superClass.getOriginal();
|
||||||
|
|
||||||
|
for (JetType superType : allSuperTypes) {
|
||||||
|
final DeclarationDescriptor descriptor = superType.getConstructor().getDeclarationDescriptor();
|
||||||
|
if (descriptor != null && superOriginal.equals(descriptor.getOriginal())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addSuperTypes(JetType type, Set<JetType> set) {
|
||||||
|
set.add(type);
|
||||||
|
|
||||||
|
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
||||||
|
addSuperTypes(jetType, set);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.intellij.openapi.editor.Document;
|
|||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import gnu.trove.THashSet;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
||||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||||
@@ -15,7 +14,10 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.*;
|
import org.jetbrains.jet.lang.resolve.calls.*;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
@@ -27,8 +29,6 @@ import org.objectweb.asm.commons.Method;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -79,17 +79,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
this.intrinsics = state.getIntrinsics();
|
this.intrinsics = state.getIntrinsics();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CallableMethod asCallableMethod(FunctionDescriptor fd) {
|
|
||||||
Method descriptor = ClosureCodegen.erasedInvokeSignature(fd);
|
|
||||||
String owner = ClosureCodegen.getInternalClassName(fd);
|
|
||||||
final CallableMethod result = new CallableMethod(owner, descriptor, INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
|
||||||
if (fd.getReceiverParameter().exists()) {
|
|
||||||
result.setNeedsReceiver(fd.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
|
|
||||||
}
|
|
||||||
result.requestGenerateCallee(Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GenerationState getState() {
|
public GenerationState getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -1021,7 +1010,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (expression.getParent() instanceof JetQualifiedExpression) {
|
if (expression.getParent() instanceof JetQualifiedExpression) {
|
||||||
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
||||||
if (receiverExpression instanceof JetSuperExpression) {
|
if (receiverExpression instanceof JetSuperExpression) {
|
||||||
|
assert receiver == StackValue.none();
|
||||||
superCall = true;
|
superCall = true;
|
||||||
|
receiver = StackValue.thisOrOuter(this, context.getThisDescriptor());
|
||||||
JetSuperExpression superExpression = (JetSuperExpression) receiverExpression;
|
JetSuperExpression superExpression = (JetSuperExpression) receiverExpression;
|
||||||
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
|
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
|
||||||
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
|
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
|
||||||
@@ -1033,17 +1024,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
fd = c.getAccessor(fd);
|
fd = c.getAccessor(fd);
|
||||||
superCall = false;
|
superCall = false;
|
||||||
|
receiver = StackValue.thisOrOuter(this, enclosed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Callable callableMethod = resolveToCallable(fd, superCall);
|
Callable callable = resolveToCallable(fd, superCall);
|
||||||
return invokeCallable(fd, callableMethod, expression, receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private StackValue invokeCallable(DeclarationDescriptor fd, Callable callable, JetCallExpression expression, StackValue receiver) {
|
|
||||||
if (callable instanceof CallableMethod) {
|
if (callable instanceof CallableMethod) {
|
||||||
final CallableMethod callableMethod = (CallableMethod) callable;
|
final CallableMethod callableMethod = (CallableMethod) callable;
|
||||||
invokeMethodWithArguments(callableMethod, expression, receiver);
|
invokeMethodWithArguments(callableMethod, expression, receiver);
|
||||||
@@ -1079,11 +1066,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
CallableMethod callableMethod;
|
CallableMethod callableMethod;
|
||||||
if (fd instanceof VariableAsFunctionDescriptor) {
|
if (fd instanceof VariableAsFunctionDescriptor) {
|
||||||
assert !superCall;
|
assert !superCall;
|
||||||
callableMethod = asCallableMethod((FunctionDescriptor) fd);
|
callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
|
||||||
}
|
}
|
||||||
else if (fd instanceof ExpressionAsFunctionDescriptor) {
|
else if (fd instanceof ExpressionAsFunctionDescriptor) {
|
||||||
FunctionDescriptor invoke = CodegenUtil.createInvoke((ExpressionAsFunctionDescriptor) fd);
|
FunctionDescriptor invoke = CodegenUtil.createInvoke((ExpressionAsFunctionDescriptor) fd);
|
||||||
callableMethod = asCallableMethod(invoke);
|
callableMethod = ClosureCodegen.asCallableMethod(invoke);
|
||||||
}
|
}
|
||||||
else if (fd instanceof FunctionDescriptor) {
|
else if (fd instanceof FunctionDescriptor) {
|
||||||
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, superCall, OwnerKind.IMPLEMENTATION);
|
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, superCall, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -1108,17 +1095,30 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression, StackValue receiver) {
|
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression, StackValue receiver) {
|
||||||
final Type calleeType = callableMethod.getGenerateCalleeType();
|
final Type calleeType = callableMethod.getGenerateCalleeType();
|
||||||
if (calleeType != null && expression instanceof JetCallExpression) {
|
if (calleeType != null && expression instanceof JetCallExpression) {
|
||||||
|
assert !callableMethod.isNeedsThis();
|
||||||
gen(expression.getCalleeExpression(), calleeType);
|
gen(expression.getCalleeExpression(), calleeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||||
|
assert resolvedCall != null;
|
||||||
|
|
||||||
|
FunctionDescriptor callableDescriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||||
|
boolean hasThis = resolvedCall.getThisObject().exists();
|
||||||
|
boolean hasReceiver = resolvedCall.getReceiverArgument().exists();
|
||||||
|
|
||||||
if (callableMethod.isNeedsThis()) {
|
if (callableMethod.isNeedsThis()) {
|
||||||
if(callableMethod.isNeedsReceiver()) {
|
if(callableMethod.isNeedsReceiver()) {
|
||||||
generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);
|
generateFromResolvedCall(resolvedCall.getThisObject());
|
||||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
if(receiver == StackValue.none()) {
|
||||||
|
generateFromResolvedCall(resolvedCall.getReceiverArgument());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
receiver.put(typeMapper.mapType(callableMethod.getReceiverFunction().getReceiverParameter().getType()), v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (receiver == StackValue.none()) {
|
if (receiver == StackValue.none()) {
|
||||||
generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);
|
generateFromResolvedCall(resolvedCall.getThisObject());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
@@ -1128,7 +1128,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
if (callableMethod.isNeedsReceiver()) {
|
if (callableMethod.isNeedsReceiver()) {
|
||||||
if (receiver == StackValue.none()) {
|
if (receiver == StackValue.none()) {
|
||||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
generateFromResolvedCall(resolvedCall.getReceiverArgument());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
receiver.put(callableMethod.getSignature().getArgumentTypes()[0], v);
|
receiver.put(callableMethod.getSignature().getArgumentTypes()[0], v);
|
||||||
@@ -1143,6 +1143,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
callableMethod.invokeWithDefault(v, mask);
|
callableMethod.invokeWithDefault(v, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateFromResolvedCall(ReceiverDescriptor descriptor) {
|
||||||
|
if(descriptor instanceof ClassReceiver) {
|
||||||
|
ClassReceiver classReceiver = (ClassReceiver) descriptor;
|
||||||
|
generateThisOrOuter((ClassDescriptor) classReceiver.getDeclarationDescriptor()).put(typeMapper.mapType(descriptor.getType()), v);
|
||||||
|
}
|
||||||
|
else if(descriptor instanceof ExtensionReceiver) {
|
||||||
|
ExtensionReceiver extensionReceiver = (ExtensionReceiver) descriptor;
|
||||||
|
generateReceiver((FunctionDescriptor) extensionReceiver.getDeclarationDescriptor()).put(typeMapper.mapType(descriptor.getType()), v);
|
||||||
|
}
|
||||||
|
else if(descriptor instanceof ExpressionReceiver) {
|
||||||
|
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
|
||||||
|
genToJVMStack(expressionReceiver.getExpression());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static JetExpression getReceiverForSelector(PsiElement expression) {
|
private static JetExpression getReceiverForSelector(PsiElement expression) {
|
||||||
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
||||||
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
||||||
@@ -1151,31 +1169,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSubclass(ClassDescriptor subClass, ClassDescriptor superClass) {
|
|
||||||
Set<JetType> allSuperTypes = new THashSet<JetType>();
|
|
||||||
|
|
||||||
addSuperTypes(subClass.getDefaultType(), allSuperTypes);
|
|
||||||
|
|
||||||
final DeclarationDescriptor superOriginal = superClass.getOriginal();
|
|
||||||
|
|
||||||
for (JetType superType : allSuperTypes) {
|
|
||||||
final DeclarationDescriptor descriptor = superType.getConstructor().getDeclarationDescriptor();
|
|
||||||
if (descriptor != null && superOriginal.equals(descriptor.getOriginal())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addSuperTypes(JetType type, Set<JetType> set) {
|
|
||||||
set.add(type);
|
|
||||||
|
|
||||||
for (JetType jetType : type.getConstructor().getSupertypes()) {
|
|
||||||
addSuperTypes(jetType, set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private StackValue generateReceiver(FunctionDescriptor descriptor) {
|
private StackValue generateReceiver(FunctionDescriptor descriptor) {
|
||||||
assert context instanceof CodegenContext.FunctionContext;
|
assert context instanceof CodegenContext.FunctionContext;
|
||||||
CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context;
|
CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context;
|
||||||
@@ -1184,21 +1177,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return context.lookupInContext(descriptor, v, StackValue.local(0, JetTypeMapper.TYPE_OBJECT));
|
return context.lookupInContext(descriptor, v, StackValue.local(0, JetTypeMapper.TYPE_OBJECT));
|
||||||
// assert context instanceof CodegenContext.FunctionContext;
|
|
||||||
// CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context;
|
|
||||||
//
|
|
||||||
// StackValue result = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
|
|
||||||
// while (cur != null) {
|
|
||||||
//
|
|
||||||
// if (cur.getReceiverDescriptor() == descriptor) {
|
|
||||||
// return cur.getReceiverExpression(typeMapper);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// result = cur.getOuterExpression(result);
|
|
||||||
// cur = cur.getOuterFunction();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// throw new UnsupportedOperationException("Don't know how to generate receiver for " + descriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) {
|
public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) {
|
||||||
@@ -1209,7 +1187,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext))
|
if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext))
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
|
|
||||||
if (isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
if (CodegenUtil.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
||||||
Type type = typeMapper.mapType(calleeContainingClass.getDefaultType());
|
Type type = typeMapper.mapType(calleeContainingClass.getDefaultType());
|
||||||
result.put(JetTypeMapper.TYPE_OBJECT, v);
|
result.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
return StackValue.onStack(type);
|
return StackValue.onStack(type);
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ public class JetTypeMapper {
|
|||||||
if(isInterface && superCall) {
|
if(isInterface && superCall) {
|
||||||
descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, OwnerKind.TRAIT_IMPL);
|
descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, OwnerKind.TRAIT_IMPL);
|
||||||
}
|
}
|
||||||
thisClass = containingClass;
|
thisClass = (ClassDescriptor) functionParent;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("unknown function parent");
|
throw new UnsupportedOperationException("unknown function parent");
|
||||||
@@ -350,7 +350,7 @@ public class JetTypeMapper {
|
|||||||
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes);
|
final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes);
|
||||||
result.setNeedsThis(thisClass);
|
result.setNeedsThis(thisClass);
|
||||||
if(functionDescriptor.getReceiverParameter().exists()) {
|
if(functionDescriptor.getReceiverParameter().exists()) {
|
||||||
result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor());
|
result.setNeedsReceiver(functionDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
@@ -239,6 +240,10 @@ public abstract class StackValue {
|
|||||||
return new Composed(prefix, suffix);
|
return new Composed(prefix, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StackValue thisOrOuter(ExpressionCodegen codegen, ClassDescriptor descriptor) {
|
||||||
|
return new ThisOuter(codegen, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
private static class None extends StackValue {
|
private static class None extends StackValue {
|
||||||
public static None INSTANCE = new None();
|
public static None INSTANCE = new None();
|
||||||
private None() {
|
private None() {
|
||||||
@@ -817,4 +822,20 @@ public abstract class StackValue {
|
|||||||
suffix.store(v);
|
suffix.store(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ThisOuter extends StackValue {
|
||||||
|
private ExpressionCodegen codegen;
|
||||||
|
private ClassDescriptor descriptor;
|
||||||
|
|
||||||
|
public ThisOuter(ExpressionCodegen codegen, ClassDescriptor descriptor) {
|
||||||
|
super(JetTypeMapper.TYPE_OBJECT);
|
||||||
|
this.codegen = codegen;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(Type type, InstructionAdapter v) {
|
||||||
|
codegen.generateThisOrOuter(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user