From d824997dcf96ff45e8ee93cb68d2339fa6d2aa01 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 6 Jul 2011 16:02:25 +0200 Subject: [PATCH] refactor visitCallExpression() in preparation for supporting calls in pattern matching --- .../jet/codegen/ExpressionCodegen.java | 159 +++++++++--------- 1 file changed, 83 insertions(+), 76 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 967b2e841e8..e981c3a4440 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -742,99 +742,106 @@ public class ExpressionCodegen extends JetVisitor { @Override public void visitCallExpression(JetCallExpression expression) { - JetExpression callee = expression.getCalleeExpression(); + final JetExpression callee = expression.getCalleeExpression(); + DeclarationDescriptor funDescriptor = resolveCalleeDescriptor(expression); - if (callee instanceof JetSimpleNameExpression) { - DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee); - if (funDescriptor == null) { - throw new CompilationException("Cannot resolve: " + callee.getText()); + if (funDescriptor instanceof ConstructorDescriptor) { + generateConstructorCall(expression, (JetSimpleNameExpression) callee); + } + else if (funDescriptor instanceof FunctionDescriptor) { + final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration(); + if (isNumberPrimitive(functionParent)) { + if (funDescriptor.getName().equals("inv")) { + final StackValue value = myStack.pop(); // HACK we rely on the dot reference handler to put it on the stack + final Type asmType = expressionType(expression); + value.put(asmType, v); + generateInv(asmType); + return; + } } - if (funDescriptor instanceof ConstructorDescriptor) { - generateConstructorCall(expression, (JetSimpleNameExpression) callee); + final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor; + PsiElement declarationPsiElement = resolveCalleeToDeclaration(funDescriptor); + + CallableMethod callableMethod; + if (declarationPsiElement instanceof PsiMethod) { + final PsiMethod psiMethod = (PsiMethod) declarationPsiElement; + callableMethod = JetTypeMapper.mapToCallableMethod(psiMethod); + if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) { + ensureReceiverOnStack(expression, null); + setOwnerFromCall(callableMethod, expression); + } } - else if (funDescriptor instanceof FunctionDescriptor) { - final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration(); - if (isNumberPrimitive(functionParent)) { - if (funDescriptor.getName().equals("inv")) { - final StackValue value = myStack.pop(); // HACK we rely on the dot reference handler to put it on the stack - final Type asmType = expressionType(expression); - value.put(asmType, v); - generateInv(asmType); - return; - } - } + else if (declarationPsiElement instanceof JetNamedFunction) { + final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement; + callableMethod = typeMapper.mapToCallableMethod(jetFunction); - - PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor); - final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor; - if (declarationPsiElement == null && isClass(functionParent, "String")) { - final Project project = expression.getProject(); - PsiClass jlString = JavaPsiFacade.getInstance(project).findClass("java.lang.String", - ProjectScope.getAllScope(project)); - // TODO better overload mapping - final PsiMethod[] methods = jlString.findMethodsByName(funDescriptor.getName(), false); - final int arity = fd.getValueParameters().size(); - for (PsiMethod method : methods) { - if (method.getParameterList().getParametersCount() == arity) { - declarationPsiElement = method; - } - } - } - if (declarationPsiElement == null) { - throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor); - } - - CallableMethod callableMethod; - if (declarationPsiElement instanceof PsiMethod) { - final PsiMethod psiMethod = (PsiMethod) declarationPsiElement; - callableMethod = JetTypeMapper.mapToCallableMethod(psiMethod); - if (!psiMethod.hasModifierProperty(PsiModifier.STATIC)) { - ensureReceiverOnStack(expression, null); - setOwnerFromCall(callableMethod, expression); - } - } - else if (declarationPsiElement instanceof JetNamedFunction) { - final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement; - callableMethod = typeMapper.mapToCallableMethod(jetFunction); - - if (functionParent instanceof NamespaceDescriptorImpl) { - if (jetFunction.getReceiverTypeRef() != null) { - ensureReceiverOnStack(expression, null); - } - } - else if (functionParent instanceof ClassDescriptor) { - ensureReceiverOnStack(expression, (ClassDescriptor) functionParent); - } - } - else { - gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd))); - - boolean isExtensionFunction = fd.getReceiverType() != null; - if (isExtensionFunction) { + if (functionParent instanceof NamespaceDescriptorImpl) { + if (jetFunction.getReceiverTypeRef() != null) { ensureReceiverOnStack(expression, null); } - - callableMethod = ClosureCodegen.asCallableMethod(fd); } - - invokeMethodWithArguments(callableMethod, expression); - final Type callReturnType = callableMethod.getSignature().getReturnType(); - if (callReturnType != Type.VOID_TYPE) { - final Type retType = typeMapper.mapType(fd.getReturnType()); - StackValue.onStack(callReturnType).upcast(retType, v); - myStack.push(StackValue.onStack(retType)); + else if (functionParent instanceof ClassDescriptor) { + ensureReceiverOnStack(expression, (ClassDescriptor) functionParent); } } else { - throw new CompilationException(); + gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd))); + + boolean isExtensionFunction = fd.getReceiverType() != null; + if (isExtensionFunction) { + ensureReceiverOnStack(expression, null); + } + + callableMethod = ClosureCodegen.asCallableMethod(fd); + } + + invokeMethodWithArguments(callableMethod, expression); + final Type callReturnType = callableMethod.getSignature().getReturnType(); + if (callReturnType != Type.VOID_TYPE) { + final Type retType = typeMapper.mapType(fd.getReturnType()); + StackValue.onStack(callReturnType).upcast(retType, v); + myStack.push(StackValue.onStack(retType)); } } else { - throw new UnsupportedOperationException("Don't know how to generate a call"); + throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor); } } + private PsiElement resolveCalleeToDeclaration(DeclarationDescriptor funDescriptor) { + PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor); + if (declarationPsiElement == null && isClass(funDescriptor.getContainingDeclaration(), "String")) { + final Project project = state.getProject(); + PsiClass jlString = JavaPsiFacade.getInstance(project).findClass("java.lang.String", + ProjectScope.getAllScope(project)); + // TODO better overload mapping + final PsiMethod[] methods = jlString.findMethodsByName(funDescriptor.getName(), false); + final int arity = ((FunctionDescriptor) funDescriptor).getValueParameters().size(); + for (PsiMethod method : methods) { + if (method.getParameterList().getParametersCount() == arity) { + declarationPsiElement = method; + } + } + } + if (declarationPsiElement == null) { + throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor); + } + return declarationPsiElement; + } + + private DeclarationDescriptor resolveCalleeDescriptor(JetCallExpression call) { + JetExpression callee = call.getCalleeExpression(); + if (!(callee instanceof JetSimpleNameExpression)) { + throw new UnsupportedOperationException("Don't know how to generate a call to " + callee); + } + DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee); + if (funDescriptor == null) { + throw new CompilationException("Cannot resolve: " + callee.getText()); + } + return funDescriptor; + } + private void invokeMethodWithArguments(CallableMethod callableMethod, JetCallExpression expression) { pushMethodArguments(expression, callableMethod.getValueParameterTypes()); if (callableMethod.acceptsTypeArguments()) {