Instance function call

This commit is contained in:
Maxim Shafirov
2011-04-25 15:11:08 +04:00
parent 6a178a4940
commit d19c1c165b
2 changed files with 41 additions and 6 deletions
@@ -461,12 +461,16 @@ public class ExpressionCodegen extends JetVisitor {
methodDescriptor.getDescriptor());
}
else {
methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement);
pushMethodArguments(expression, methodDescriptor);
if (functionParent instanceof NamespaceDescriptor && declarationPsiElement instanceof JetFunction) {
methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement);
pushMethodArguments(expression, methodDescriptor);
final String owner = NamespaceCodegen.getJVMClassName(DescriptorUtil.getFQName(functionParent));
v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
}
else if (functionParent instanceof ClassDescriptor && declarationPsiElement instanceof JetFunction) {
final String owner = JetTypeMapper.jvmNameForInterface((ClassDescriptor) functionParent);
v.invokeinterface(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
}
else {
throw new UnsupportedOperationException("don't know how to generate call to " + declarationPsiElement);
}
@@ -965,16 +969,29 @@ public class ExpressionCodegen extends JetVisitor {
public void visitNewExpression(JetNewExpression expression) {
final JetUserType constructorType = (JetUserType) expression.getTypeReference().getTypeElement();
final JetSimpleNameExpression constructorReference = constructorType.getReferenceExpression();
final PsiElement declaration = bindingContext.getDeclarationPsiElement(bindingContext.resolveReferenceExpression(constructorReference));
DeclarationDescriptor constructorDescriptor = bindingContext.resolveReferenceExpression(constructorReference);
final PsiElement declaration = bindingContext.getDeclarationPsiElement(constructorDescriptor);
if (declaration instanceof PsiMethod) {
final PsiMethod constructor = (PsiMethod) declaration;
PsiClass javaClass = constructor.getContainingClass();
Type type = JetTypeMapper.psiClassType(javaClass);
v.anew(type);
v.dup();
final Method constructorDescriptor = getMethodDescriptor(constructor);
pushMethodArguments(expression, constructorDescriptor);
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", constructorDescriptor.getDescriptor());
final Method jvmConstructor = getMethodDescriptor(constructor);
pushMethodArguments(expression, jvmConstructor);
v.invokespecial(JetTypeMapper.jvmName(javaClass), "<init>", jvmConstructor.getDescriptor());
myStack.push(StackValue.onStack(type));
return;
}
else if (constructorDescriptor instanceof ConstructorDescriptor) {
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
Type type = JetTypeMapper.jetImplementationType(classDecl);
v.anew(type);
v.dup();
Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor);
pushMethodArguments(expression, method);
v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "<init>", method.getDescriptor());
myStack.push(StackValue.onStack(type));
return;
}
@@ -35,6 +35,14 @@ public class JetTypeMapper {
return Type.getType("L" + jvmName(psiClass) + ";");
}
static Type jetInterfaceType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForInterface(classDescriptor) + ";");
}
static Type jetImplementationType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForImplementation(classDescriptor) + ";");
}
static String jvmName(JetNamespace namespace) {
return NamespaceCodegen.getJVMClassName(namespace.getFQName());
}
@@ -179,6 +187,16 @@ public class JetTypeMapper {
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType });
}
public Method mapConstructorSignature(ConstructorDescriptor descriptor) {
List<ValueParameterDescriptor> parameters = descriptor.getUnsubstitutedValueParameters();
Type[] parameterTypes = new Type[parameters.size()];
for (int i = 0; i < parameters.size(); i++) {
parameterTypes[i] = mapType(parameters.get(i).getOutType());
}
Type returnType = mapType(descriptor.getUnsubstitutedReturnType());
return new Method("<init>", Type.VOID_TYPE, parameterTypes);
}
static int getAccessModifiers(JetDeclaration p, int defaultFlags) {
int flags = 0;
if (p.hasModifier(JetTokens.PUBLIC_KEYWORD)) {