Search in sources :

Example 21 with GrClosableBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.

the class GroovyMethodInliner method isOnExpressionOrReturnPlace.

/*
  Method call is used as expression in some enclosing expression or
  is method return result
  */
private static boolean isOnExpressionOrReturnPlace(@NotNull GrCallExpression call) {
    PsiElement parent = call.getParent();
    if (!(parent instanceof GrVariableDeclarationOwner)) {
        return true;
    }
    // tail calls in methods and closures
    GrVariableDeclarationOwner owner = (GrVariableDeclarationOwner) parent;
    if (owner instanceof GrClosableBlock || owner instanceof GrOpenBlock && owner.getParent() instanceof GrMethod) {
        GrStatement[] statements = ((GrCodeBlock) owner).getStatements();
        assert statements.length > 0;
        GrStatement last = statements[statements.length - 1];
        if (last == call)
            return true;
        if (last instanceof GrReturnStatement && call == ((GrReturnStatement) last).getReturnValue()) {
            return true;
        }
    }
    return false;
}
Also used : GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) GrReturnStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement) GrVariableDeclarationOwner(org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner) GrCodeBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)

Example 22 with GrClosableBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.

the class GrIntroduceHandlerBase method expressionIsIncorrect.

public static boolean expressionIsIncorrect(@Nullable GrExpression expression, boolean acceptVoidCalls) {
    if (expression instanceof GrParenthesizedExpression)
        return true;
    if (PsiUtil.isSuperReference(expression))
        return true;
    if (expression instanceof GrAssignmentExpression)
        return true;
    if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrCall) {
        final GroovyResolveResult resolveResult = ((GrReferenceExpression) expression).advancedResolve();
        final PsiElement resolved = resolveResult.getElement();
        return resolved instanceof PsiMethod && !resolveResult.isInvokedOnProperty() || resolved instanceof PsiClass;
    }
    if (expression instanceof GrReferenceExpression && expression.getParent() instanceof GrReferenceExpression) {
        return !PsiUtil.isThisReference(expression) && ((GrReferenceExpression) expression).resolve() instanceof PsiClass;
    }
    if (expression instanceof GrClosableBlock && expression.getParent() instanceof GrStringInjection)
        return true;
    if (!acceptVoidCalls && expression instanceof GrMethodCall && PsiType.VOID.equals(expression.getType()))
        return true;
    return false;
}
Also used : GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrStringInjection(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Example 23 with GrClosableBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.

the class GroovyInlineMethodUtil method isTailMethodCall.

/**
   * Checks whether given method call is tail call of other method or closure
   *
   * @param call [tail?] Method call
   * @return
   */
static boolean isTailMethodCall(GrCallExpression call) {
    GrStatement stmt = call;
    PsiElement parent = call.getParent();
    // return statement
    if (parent instanceof GrReturnStatement) {
        stmt = ((GrReturnStatement) parent);
        parent = parent.getParent();
    }
    // method body result
    if (parent instanceof GrOpenBlock) {
        if (parent.getParent() instanceof GrMethod) {
            GrStatement[] statements = ((GrOpenBlock) parent).getStatements();
            return statements.length > 0 && stmt == statements[statements.length - 1];
        }
    }
    // closure result
    if (parent instanceof GrClosableBlock) {
        GrStatement[] statements = ((GrClosableBlock) parent).getStatements();
        return statements.length > 0 && stmt == statements[statements.length - 1];
    }
    // todo test me!
    if (stmt instanceof GrReturnStatement) {
        GrMethod method = PsiTreeUtil.getParentOfType(stmt, GrMethod.class);
        if (method != null) {
            Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(method.getBlock());
            return returnStatements.contains(stmt) && !hasBadReturns(method);
        }
    }
    return false;
}
Also used : GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrOpenBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock) GrReturnStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)

Example 24 with GrClosableBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.

the class AnonymousFromMapGenerator method writeAnonymousMap.

static void writeAnonymousMap(GrListOrMap operand, GrTypeElement typeElement, final StringBuilder builder, ExpressionContext context) {
    final PsiType type = typeElement.getType();
    final PsiClass psiClass;
    final PsiSubstitutor substitutor;
    if (type instanceof PsiClassType) {
        final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) type).resolveGenerics();
        psiClass = resolveResult.getElement();
        substitutor = resolveResult.getSubstitutor();
    } else {
        psiClass = null;
        substitutor = PsiSubstitutor.EMPTY;
    }
    builder.append("new ");
    TypeWriter.writeTypeForNew(builder, type, operand);
    builder.append("() {\n");
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(operand.getProject());
    final GrExpression caller = factory.createExpressionFromText("this");
    for (GrNamedArgument arg : operand.getNamedArguments()) {
        final String name = arg.getLabelName();
        final GrExpression expression = arg.getExpression();
        if (name == null || expression == null || !(expression instanceof GrClosableBlock))
            continue;
        final GrClosableBlock closure = (GrClosableBlock) expression;
        final GrParameter[] allParameters = closure.getAllParameters();
        List<GrParameter> actual = new ArrayList<>(Arrays.asList(allParameters));
        final PsiType clReturnType = context.typeProvider.getReturnType(closure);
        GrExpression[] args = new GrExpression[allParameters.length];
        for (int i = 0; i < allParameters.length; i++) {
            args[i] = factory.createExpressionFromText(allParameters[i].getName());
        }
        for (int param = allParameters.length; param >= 0; param--) {
            if (param < allParameters.length && !actual.get(param).isOptional())
                continue;
            if (param < allParameters.length) {
                final GrParameter opt = actual.remove(param);
                args[param] = opt.getInitializerGroovy();
            }
            final GrParameter[] parameters = actual.toArray(new GrParameter[actual.size()]);
            final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(parameters, clReturnType);
            final GrMethod pattern = factory.createMethodFromSignature(name, signature);
            PsiMethod found = null;
            if (psiClass != null) {
                found = psiClass.findMethodBySignature(pattern, true);
            }
            if (found != null) {
                ModifierListGenerator.writeModifiers(builder, found.getModifierList(), ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT);
            } else {
                builder.append("public ");
            }
            PsiType returnType;
            if (found != null) {
                returnType = substitutor.substitute(context.typeProvider.getReturnType(found));
            } else {
                returnType = signature.getReturnType();
            }
            TypeWriter.writeType(builder, returnType, operand);
            builder.append(' ').append(name);
            GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context);
            final ExpressionContext extended = context.extend();
            extended.setInAnonymousContext(true);
            if (param == allParameters.length) {
                new CodeBlockGenerator(builder, extended).generateCodeBlock(allParameters, closure, false);
            } else {
                builder.append("{\n");
                final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, extended);
                GenerationUtil.invokeMethodByName(caller, name, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, expressionGenerator, arg);
                builder.append(";\n}\n");
            }
        }
    }
    builder.append("}");
}
Also used : GrNamedArgument(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument) ArrayList(java.util.ArrayList) GrMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) GroovyPsiElementFactory(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory) GrClosureSignature(org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature)

Example 25 with GrClosableBlock

use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.

the class ExpressionGenerator method generateMethodCall.

private void generateMethodCall(GrMethodCall methodCallExpression) {
    final GrExpression invoked = methodCallExpression.getInvokedExpression();
    final GrExpression[] exprs = methodCallExpression.getExpressionArguments();
    final GrNamedArgument[] namedArgs = methodCallExpression.getNamedArguments();
    final GrClosableBlock[] clArgs = methodCallExpression.getClosureArguments();
    if (invoked instanceof GrReferenceExpression) {
        final GroovyResolveResult resolveResult = ((GrReferenceExpression) invoked).advancedResolve();
        final PsiElement resolved = resolveResult.getElement();
        if (resolved instanceof PsiMethod) {
            //todo replace null-qualifier with this-reference
            final GrExpression qualifier = ((GrReferenceExpression) invoked).getQualifier();
            invokeMethodOn(((PsiMethod) resolved), qualifier, exprs, namedArgs, clArgs, resolveResult.getSubstitutor(), methodCallExpression);
            return;
        } else if (resolved == null) {
            final GrExpression qualifier = ((GrReferenceExpression) invoked).getQualifier();
            final GrExpression[] args = generateArgsForInvokeMethod(((GrReferenceExpression) invoked).getReferenceName(), exprs, namedArgs, clArgs, methodCallExpression);
            GenerationUtil.invokeMethodByName(qualifier, "invokeMethod", args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, this, methodCallExpression);
            return;
        }
    }
    GenerationUtil.invokeMethodByName(invoked, "call", exprs, namedArgs, clArgs, this, methodCallExpression);
}
Also used : GroovyResolveResult(org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult) GrNamedArgument(org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument) GrClosableBlock(org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock) GroovyPsiElement(org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)

Aggregations

GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)116 PsiElement (com.intellij.psi.PsiElement)32 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)31 GroovyPsiElement (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement)26 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)26 Nullable (org.jetbrains.annotations.Nullable)23 GrParameter (org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter)23 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)18 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)17 GrArgumentList (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList)15 GrMethodCallExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression)15 GrNamedArgument (org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument)14 GrMethodCall (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall)13 GrField (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField)12 ArrayList (java.util.ArrayList)11 NotNull (org.jetbrains.annotations.NotNull)10 GroovyRecursiveElementVisitor (org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor)10 GroovyResolveResult (org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult)10 GrOpenBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)10 GroovyFile (org.jetbrains.plugins.groovy.lang.psi.GroovyFile)9