diff --git a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java index 83cd3d48531..6dc1280629b 100644 --- a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -14,6 +14,7 @@ public class CallableMethod { private final Method signature; private final int invokeOpcode; private final List valueParameterTypes; + private boolean acceptsTypeArguments = false; public CallableMethod(String owner, Method signature, int invokeOpcode, List valueParameterTypes) { this.owner = owner; @@ -42,6 +43,14 @@ public class CallableMethod { return valueParameterTypes; } + public boolean acceptsTypeArguments() { + return acceptsTypeArguments; + } + + public void setAcceptsTypeArguments(boolean acceptsTypeArguments) { + this.acceptsTypeArguments = acceptsTypeArguments; + } + void invoke(InstructionAdapter v) { v.visitMethodInsn(getInvokeOpcode(), getOwner(), getSignature().getName(), getSignature().getDescriptor()); } diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8278a6534c0..044372e3e82 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -781,22 +781,18 @@ public class ExpressionCodegen extends JetVisitor { throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor); } - - Method methodDescriptor; + CallableMethod callableMethod; if (declarationPsiElement instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod) declarationPsiElement; - CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(psiMethod); + 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; - CallableMethod callableMethod = typeMapper.mapToCallableMethod(jetFunction); + callableMethod = typeMapper.mapToCallableMethod(jetFunction); if (functionParent instanceof NamespaceDescriptorImpl) { if (jetFunction.getReceiverTypeRef() != null) { @@ -806,11 +802,6 @@ public class ExpressionCodegen extends JetVisitor { else if (functionParent instanceof ClassDescriptor) { ensureReceiverOnStack(expression, (ClassDescriptor) functionParent); } - - pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - pushTypeArguments(expression); - callableMethod.invoke(v); - methodDescriptor = callableMethod.getSignature(); } else { gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd))); @@ -820,15 +811,14 @@ public class ExpressionCodegen extends JetVisitor { ensureReceiverOnStack(expression, null); } - CallableMethod callableMethod = ClosureCodegen.asCallableMethod(fd); - pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - callableMethod.invoke(v); - methodDescriptor = callableMethod.getSignature(); + callableMethod = ClosureCodegen.asCallableMethod(fd); } - if (methodDescriptor.getReturnType() != Type.VOID_TYPE) { + invokeMethodWithArguments(callableMethod, expression); + final Type callReturnType = callableMethod.getSignature().getReturnType(); + if (callReturnType != Type.VOID_TYPE) { final Type retType = typeMapper.mapType(fd.getReturnType()); - StackValue.onStack(methodDescriptor.getReturnType()).upcast(retType, v); + StackValue.onStack(callReturnType).upcast(retType, v); myStack.push(StackValue.onStack(retType)); } } @@ -841,6 +831,14 @@ public class ExpressionCodegen extends JetVisitor { } } + private void invokeMethodWithArguments(CallableMethod callableMethod, JetCallExpression expression) { + pushMethodArguments(expression, callableMethod.getValueParameterTypes()); + if (callableMethod.acceptsTypeArguments()) { + pushTypeArguments(expression); + } + callableMethod.invoke(v); + } + private void setOwnerFromCall(CallableMethod callableMethod, JetCallExpression expression) { if (expression.getParent() instanceof JetQualifiedExpression) { final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); @@ -948,15 +946,6 @@ public class ExpressionCodegen extends JetVisitor { return false; } - private void pushMethodArguments(JetCall expression, Method method) { - final Type[] argTypes = method.getArgumentTypes(); - List args = expression.getValueArguments(); - for (int i = 0, argsSize = args.size(); i < argsSize; i++) { - JetArgument arg = args.get(i); - gen(arg.getArgumentExpression(), argTypes[i]); - } - } - private void pushMethodArguments(JetCall expression, List valueParameterTypes) { List args = expression.getValueArguments(); for (int i = 0, argsSize = args.size(); i < argsSize; i++) { @@ -1437,10 +1426,7 @@ public class ExpressionCodegen extends JetVisitor { pushOuterClassArguments(classDecl); CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION); - pushMethodArguments(expression, method.getValueParameterTypes()); - pushTypeArguments(expression); - - method.invoke(v); + invokeMethodWithArguments(method, expression); } } else { @@ -1468,9 +1454,8 @@ public class ExpressionCodegen extends JetVisitor { Type type = JetTypeMapper.psiClassType(javaClass); v.anew(type); v.dup(); - final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructor); - pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - callableMethod.invoke(v); + final CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(constructor); + invokeMethodWithArguments(callableMethod, expression); return type; } diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 5cf0323a913..21c07068b4b 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -397,7 +397,9 @@ public class JetTypeMapper { throw new UnsupportedOperationException("unknown function parent"); } - return new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes); + final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes); + result.setAcceptsTypeArguments(true); + return result; } public Method mapSignature(String name, FunctionDescriptor f) { @@ -488,7 +490,9 @@ public class JetTypeMapper { List valueParameterTypes = new ArrayList(); final Method method = mapConstructorSignature(descriptor, kind, valueParameterTypes); String owner = jvmName(descriptor.getContainingDeclaration(), kind); - return new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes); + final CallableMethod result = new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes); + result.setAcceptsTypeArguments(true); + return result; } static int getAccessModifiers(JetDeclaration p, int defaultFlags) {