diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1852765c617..93e0df63f92 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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), "", constructorDescriptor.getDescriptor()); + final Method jvmConstructor = getMethodDescriptor(constructor); + pushMethodArguments(expression, jvmConstructor); + v.invokespecial(JetTypeMapper.jvmName(javaClass), "", 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), "", method.getDescriptor()); myStack.push(StackValue.onStack(type)); return; } diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index dfd45a72987..f97d8919a4f 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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 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("", Type.VOID_TYPE, parameterTypes); + } + static int getAccessModifiers(JetDeclaration p, int defaultFlags) { int flags = 0; if (p.hasModifier(JetTokens.PUBLIC_KEYWORD)) {