From e72aec943ef347131ce13bf9552361a1b627111c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 30 Jun 2011 18:03:30 +0200 Subject: [PATCH] use correct bytecode for calling methods on Java interfaces --- .../jet/codegen/ExpressionCodegen.java | 53 +++++++++++-------- .../jet/codegen/NamespaceGenTest.java | 8 +++ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 51735604818..aa0c0d88e4d 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -775,29 +775,7 @@ public class ExpressionCodegen extends JetVisitor { } Method methodDescriptor; if (declarationPsiElement instanceof PsiMethod) { - PsiMethod psiMethod = (PsiMethod) declarationPsiElement; - String owner = JetTypeMapper.jvmName(psiMethod.getContainingClass()); - methodDescriptor = 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(); - } - } - } - pushMethodArguments(expression, methodDescriptor); - - v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, - owner, - methodDescriptor.getName(), - methodDescriptor.getDescriptor()); + methodDescriptor = generateJavaMethodCall(expression, (PsiMethod) declarationPsiElement); } else if (declarationPsiElement instanceof JetNamedFunction) { final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement; @@ -854,6 +832,35 @@ public class ExpressionCodegen extends JetVisitor { } } + private Method generateJavaMethodCall(JetCallExpression expression, PsiMethod psiMethod) { + final PsiClass containingClass = psiMethod.getContainingClass(); + String owner = JetTypeMapper.jvmName(containingClass); + Method methodDescriptor = 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(); + } + } + } + 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) { if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) { final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent(); diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 889f9b4e33d..676730f06e9 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -418,4 +418,12 @@ public class NamespaceGenTest extends CodegenTestCase { public void testIncrementProperty() throws Exception { blackBoxFile("incrementProperty.jet"); } + + public void testJavaInterfaceMethod() throws Exception { + loadText("import java.util.*; fun foo(l: List) { l.add(\"foo\") }"); + final Method main = generateFunction(); + final ArrayList list = new ArrayList(); + main.invoke(null, list); + assertEquals("foo", list.get(0)); + } }