diff --git a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java index 9244ee20890..83cd3d48531 100644 --- a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -10,7 +10,7 @@ import java.util.List; * @author yole */ public class CallableMethod { - private final String owner; + private String owner; private final Method signature; private final int invokeOpcode; private final List valueParameterTypes; @@ -26,6 +26,10 @@ public class CallableMethod { return owner; } + public void setOwner(String owner) { + this.owner = owner; + } + public Method getSignature() { return signature; } diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 15de921d7a2..c8c219b1fc1 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -782,7 +782,15 @@ public class ExpressionCodegen extends JetVisitor { } Method methodDescriptor; if (declarationPsiElement instanceof PsiMethod) { - methodDescriptor = generateJavaMethodCall(expression, (PsiMethod) declarationPsiElement); + final PsiMethod psiMethod = (PsiMethod) declarationPsiElement; + CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(psiMethod); + if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) { + ensureReceiverOnStack(expression, null); + setOwnerFromCall(callableMethod, expression); + } + pushMethodArguments(expression, callableMethod.getValueParameterTypes()); + callableMethod.invoke(v); + methodDescriptor = callableMethod.getSignature(); } else if (declarationPsiElement instanceof JetNamedFunction) { final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement; @@ -832,33 +840,16 @@ public class ExpressionCodegen extends JetVisitor { } } - private Method generateJavaMethodCall(JetCallExpression expression, PsiMethod psiMethod) { - final PsiClass containingClass = psiMethod.getContainingClass(); - String owner = JetTypeMapper.jvmName(containingClass); - Method methodDescriptor = JetTypeMapper.getMethodDescriptor(psiMethod); - final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC); - - if (!isStatic) { - ensureReceiverOnStack(expression, null); - if (expression.getParent() instanceof JetQualifiedExpression) { - final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); - JetType expressionType = bindingContext.getExpressionType(receiver); - DeclarationDescriptor declarationDescriptor = expressionType.getConstructor().getDeclarationDescriptor(); - PsiElement ownerDeclaration = bindingContext.getDeclarationPsiElement(declarationDescriptor); - if (ownerDeclaration instanceof PsiClass) { - owner = typeMapper.mapType(expressionType).getInternalName(); - } + private void setOwnerFromCall(CallableMethod callableMethod, JetCallExpression expression) { + if (expression.getParent() instanceof JetQualifiedExpression) { + final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); + JetType expressionType = bindingContext.getExpressionType(receiver); + DeclarationDescriptor declarationDescriptor = expressionType.getConstructor().getDeclarationDescriptor(); + PsiElement ownerDeclaration = bindingContext.getDeclarationPsiElement(declarationDescriptor); + if (ownerDeclaration instanceof PsiClass) { + callableMethod.setOwner(typeMapper.mapType(expressionType).getInternalName()); } } - pushMethodArguments(expression, methodDescriptor); - - v.visitMethodInsn(isStatic - ? Opcodes.INVOKESTATIC - : (containingClass.isInterface() ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL), - owner, - methodDescriptor.getName(), - methodDescriptor.getDescriptor()); - return methodDescriptor; } private JetExpression getReceiverForSelector(JetElement expression) { diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index e3e66039076..5cf0323a913 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -103,7 +103,8 @@ public class JetTypeMapper { } static CallableMethod mapToCallableMethod(PsiMethod method) { - String owner = jvmName(method.getContainingClass()); + final PsiClass containingClass = method.getContainingClass(); + String owner = jvmName(containingClass); Method signature = getMethodDescriptor(method); List valueParameterTypes = new ArrayList(); Collections.addAll(valueParameterTypes, signature.getArgumentTypes()); @@ -111,8 +112,14 @@ public class JetTypeMapper { if (method.isConstructor()) { opcode = Opcodes.INVOKESPECIAL; } + else if (method.hasModifierProperty(PsiModifier.STATIC)) { + opcode = Opcodes.INVOKESTATIC; + } + else if (containingClass.isInterface()) { + opcode = Opcodes.INVOKEINTERFACE; + } else { - throw new UnsupportedOperationException("TODO"); + opcode = Opcodes.INVOKEVIRTUAL; } return new CallableMethod(owner, signature, opcode, valueParameterTypes); }