use CallableMethod also for Java constructor calls
This commit is contained in:
@@ -604,7 +604,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
if (declaration instanceof PsiField) {
|
||||
PsiField psiField = (PsiField) declaration;
|
||||
final String owner = JetTypeMapper.jvmName(psiField.getContainingClass());
|
||||
final Type fieldType = psiTypeToAsm(psiField.getType());
|
||||
final Type fieldType = JetTypeMapper.psiTypeToAsm(psiField.getType());
|
||||
final boolean isStatic = psiField.hasModifierProperty(PsiModifier.STATIC);
|
||||
if (!isStatic) {
|
||||
ensureReceiverOnStack(expression, null);
|
||||
@@ -833,7 +833,7 @@ 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);
|
||||
Method methodDescriptor = JetTypeMapper.getMethodDescriptor(psiMethod);
|
||||
final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC);
|
||||
|
||||
if (!isStatic) {
|
||||
@@ -932,16 +932,6 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getMethodDescriptor(PsiMethod method) {
|
||||
Type returnType = method.isConstructor() ? Type.VOID_TYPE : psiTypeToAsm(method.getReturnType());
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
Type[] parameterTypes = new Type[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameterTypes[i] = psiTypeToAsm(parameters [i].getType());
|
||||
}
|
||||
return new Method(method.getName(), Type.getMethodDescriptor(returnType, parameterTypes));
|
||||
}
|
||||
|
||||
private Type expressionType(JetExpression expr) {
|
||||
return typeMapper.mapType(bindingContext.getExpressionType(expr));
|
||||
}
|
||||
@@ -951,53 +941,6 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
return lookupLocal(declarationDescriptor);
|
||||
}
|
||||
|
||||
private static Type psiTypeToAsm(PsiType type) {
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
if (type == PsiType.VOID) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
if (type == PsiType.INT) {
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
if (type == PsiType.LONG) {
|
||||
return Type.LONG_TYPE;
|
||||
}
|
||||
if (type == PsiType.BOOLEAN) {
|
||||
return Type.BOOLEAN_TYPE;
|
||||
}
|
||||
if (type == PsiType.BYTE) {
|
||||
return Type.BYTE_TYPE;
|
||||
}
|
||||
if (type == PsiType.SHORT) {
|
||||
return Type.SHORT_TYPE;
|
||||
}
|
||||
if (type == PsiType.CHAR) {
|
||||
return Type.CHAR_TYPE;
|
||||
}
|
||||
if (type == PsiType.FLOAT) {
|
||||
return Type.FLOAT_TYPE;
|
||||
}
|
||||
if (type == PsiType.DOUBLE) {
|
||||
return Type.DOUBLE_TYPE;
|
||||
}
|
||||
}
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass psiClass = ((PsiClassType) type).resolve();
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
||||
if (extendsListTypes.length > 0) {
|
||||
throw new UnsupportedOperationException("should return common supertype");
|
||||
}
|
||||
return OBJECT_TYPE;
|
||||
}
|
||||
if (psiClass == null) {
|
||||
throw new UnsupportedOperationException("unresolved PsiClassType: " + type);
|
||||
}
|
||||
return JetTypeMapper.psiClassType(psiClass);
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) {
|
||||
JetExpression receiver = expression.getReceiverExpression();
|
||||
@@ -1492,9 +1435,9 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
Type type = JetTypeMapper.psiClassType(javaClass);
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
final Method jvmConstructor = getMethodDescriptor(constructor);
|
||||
pushMethodArguments(expression, jvmConstructor);
|
||||
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", jvmConstructor.getDescriptor());
|
||||
final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructor);
|
||||
pushMethodArguments(expression, callableMethod.getValueParameterTypes());
|
||||
callableMethod.invoke(v);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.typeinfo.TypeInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,10 +14,7 @@ import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -49,6 +45,78 @@ public class JetTypeMapper {
|
||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
||||
}
|
||||
|
||||
static Type psiTypeToAsm(PsiType type) {
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
if (type == PsiType.VOID) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
if (type == PsiType.INT) {
|
||||
return Type.INT_TYPE;
|
||||
}
|
||||
if (type == PsiType.LONG) {
|
||||
return Type.LONG_TYPE;
|
||||
}
|
||||
if (type == PsiType.BOOLEAN) {
|
||||
return Type.BOOLEAN_TYPE;
|
||||
}
|
||||
if (type == PsiType.BYTE) {
|
||||
return Type.BYTE_TYPE;
|
||||
}
|
||||
if (type == PsiType.SHORT) {
|
||||
return Type.SHORT_TYPE;
|
||||
}
|
||||
if (type == PsiType.CHAR) {
|
||||
return Type.CHAR_TYPE;
|
||||
}
|
||||
if (type == PsiType.FLOAT) {
|
||||
return Type.FLOAT_TYPE;
|
||||
}
|
||||
if (type == PsiType.DOUBLE) {
|
||||
return Type.DOUBLE_TYPE;
|
||||
}
|
||||
}
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass psiClass = ((PsiClassType) type).resolve();
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
|
||||
if (extendsListTypes.length > 0) {
|
||||
throw new UnsupportedOperationException("should return common supertype");
|
||||
}
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
if (psiClass == null) {
|
||||
throw new UnsupportedOperationException("unresolved PsiClassType: " + type);
|
||||
}
|
||||
return psiClassType(psiClass);
|
||||
}
|
||||
throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM");
|
||||
}
|
||||
|
||||
static Method getMethodDescriptor(PsiMethod method) {
|
||||
Type returnType = method.isConstructor() ? Type.VOID_TYPE : psiTypeToAsm(method.getReturnType());
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
Type[] parameterTypes = new Type[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameterTypes[i] = psiTypeToAsm(parameters[i].getType());
|
||||
}
|
||||
return new Method(method.isConstructor() ? "<init>" : method.getName(), Type.getMethodDescriptor(returnType, parameterTypes));
|
||||
}
|
||||
|
||||
static CallableMethod mapToCallableMethod(PsiMethod method) {
|
||||
String owner = jvmName(method.getContainingClass());
|
||||
Method signature = getMethodDescriptor(method);
|
||||
List<Type> valueParameterTypes = new ArrayList<Type>();
|
||||
Collections.addAll(valueParameterTypes, signature.getArgumentTypes());
|
||||
int opcode;
|
||||
if (method.isConstructor()) {
|
||||
opcode = Opcodes.INVOKESPECIAL;
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("TODO");
|
||||
}
|
||||
return new CallableMethod(owner, signature, opcode, valueParameterTypes);
|
||||
}
|
||||
|
||||
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass);
|
||||
if (declaration instanceof PsiClass) {
|
||||
|
||||
Reference in New Issue
Block a user