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;
|
Method methodDescriptor;
|
||||||
if (declarationPsiElement instanceof PsiMethod) {
|
if (declarationPsiElement instanceof PsiMethod) {
|
||||||
PsiMethod psiMethod = (PsiMethod) declarationPsiElement;
|
methodDescriptor = generateJavaMethodCall(expression, (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());
|
|
||||||
}
|
}
|
||||||
else if (declarationPsiElement instanceof JetNamedFunction) {
|
else if (declarationPsiElement instanceof JetNamedFunction) {
|
||||||
final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement;
|
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) {
|
private JetExpression getReceiverForSelector(JetElement expression) {
|
||||||
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
||||||
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
||||||
|
|||||||
@@ -418,4 +418,12 @@ public class NamespaceGenTest extends CodegenTestCase {
|
|||||||
public void testIncrementProperty() throws Exception {
|
public void testIncrementProperty() throws Exception {
|
||||||
blackBoxFile("incrementProperty.jet");
|
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