one more step of CallableMethod refactoring

This commit is contained in:
Dmitry Jemerov
2011-07-06 12:11:11 +02:00
parent 516738ba2f
commit 5eb2f913b3
3 changed files with 31 additions and 29 deletions
@@ -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<Type> valueParameterTypes;
@@ -26,6 +26,10 @@ public class CallableMethod {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Method getSignature() {
return signature;
}
@@ -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) {
@@ -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<Type> valueParameterTypes = new ArrayList<Type>();
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);
}