diff --git a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java index 1ff1be8a719..d246b6a6b3b 100644 --- a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -18,6 +18,7 @@ public class CallableMethod { private final List 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 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; } diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 663617e782e..e64c72523cb 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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()); } diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 440e1c363e2..6ede21ad9ed 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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 valueParameterTypes = new ArrayList();