use correct bytecode for calling methods on Java interfaces
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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<String>) { l.add(\"foo\") }");
|
||||
final Method main = generateFunction();
|
||||
final ArrayList<String> list = new ArrayList<String>();
|
||||
main.invoke(null, list);
|
||||
assertEquals("foo", list.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user