put "owner from call" flag into CallableMethod

This commit is contained in:
Dmitry Jemerov
2011-07-06 16:23:58 +02:00
parent 9497b41664
commit e61f69437d
3 changed files with 25 additions and 11 deletions
@@ -18,6 +18,7 @@ public class CallableMethod {
private final List<Type> valueParameterTypes;
private boolean acceptsTypeArguments = false;
private boolean needsReceiverOnStack = false;
private boolean ownerFromCall = false;
private ClassDescriptor receiverClass = null;
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) {
@@ -64,6 +65,14 @@ public class CallableMethod {
return needsReceiverOnStack;
}
public boolean isOwnerFromCall() {
return ownerFromCall;
}
public void setOwnerFromCall(boolean ownerFromCall) {
this.ownerFromCall = ownerFromCall;
}
public ClassDescriptor getReceiverClass() {
return receiverClass;
}
@@ -764,16 +764,8 @@ public class ExpressionCodegen extends JetVisitor {
PsiElement declarationPsiElement = resolveCalleeToDeclaration(funDescriptor);
CallableMethod callableMethod;
if (declarationPsiElement instanceof PsiMethod) {
final PsiMethod psiMethod = (PsiMethod) declarationPsiElement;
callableMethod = JetTypeMapper.mapToCallableMethod(psiMethod);
if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
setOwnerFromCall(callableMethod, expression);
}
}
else if (declarationPsiElement instanceof JetNamedFunction) {
final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement;
callableMethod = typeMapper.mapToCallableMethod(jetFunction);
if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) {
callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement);
}
else {
gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
@@ -827,6 +819,9 @@ public class ExpressionCodegen extends JetVisitor {
}
private void invokeMethodWithArguments(CallableMethod callableMethod, JetCallExpression expression) {
if (callableMethod.isOwnerFromCall()) {
setOwnerFromCall(callableMethod, expression);
}
if (callableMethod.needsReceiverOnStack()) {
ensureReceiverOnStack(expression, callableMethod.getReceiverClass());
}
@@ -110,6 +110,7 @@ public class JetTypeMapper {
Collections.addAll(valueParameterTypes, signature.getArgumentTypes());
int opcode;
boolean needsReceiver = false;
boolean ownerFromCall = false;
if (method.isConstructor()) {
opcode = Opcodes.INVOKESPECIAL;
}
@@ -124,11 +125,13 @@ public class JetTypeMapper {
else {
opcode = Opcodes.INVOKEVIRTUAL;
}
ownerFromCall = true;
}
final CallableMethod result = new CallableMethod(owner, signature, opcode, valueParameterTypes);
if (needsReceiver) {
result.setNeedsReceiver(null);
}
result.setOwnerFromCall(ownerFromCall);
return result;
}
@@ -383,7 +386,14 @@ public class JetTypeMapper {
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
}
public CallableMethod mapToCallableMethod(JetNamedFunction f) {
public CallableMethod mapToCallableMethod(PsiNamedElement declaration) {
if (declaration instanceof PsiMethod) {
return mapToCallableMethod((PsiMethod) declaration);
}
if (!(declaration instanceof JetNamedFunction)) {
throw new UnsupportedOperationException("unknown declaration type");
}
JetNamedFunction f = (JetNamedFunction) declaration;
final FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(f);
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>();