Search in sources :

Example 71 with GrStatement

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

the class ExtractUtil method collectUsedLocalVarsOrParamsDeclaredOutside.

private static Collection<GrVariable> collectUsedLocalVarsOrParamsDeclaredOutside(ExtractInfoHelper helper) {
    final Collection<GrVariable> result = new HashSet<>();
    final TextRange range = getRangeOfRefactoring(helper);
    final int start = range.getStartOffset();
    final int end = range.getEndOffset();
    final GroovyRecursiveElementVisitor visitor = new GroovyRecursiveElementVisitor() {

        @Override
        public void visitReferenceExpression(@NotNull GrReferenceExpression ref) {
            final PsiElement resolved = ref.resolve();
            if ((resolved instanceof GrParameter || PsiUtil.isLocalVariable(resolved)) && resolved.isPhysical()) {
                final int offset = resolved.getTextRange().getStartOffset();
                //var is declared outside of selected code
                if (offset < start || end <= offset) {
                    result.add((GrVariable) resolved);
                }
            }
        }
    };
    final GrStatement[] statements = helper.getStatements();
    for (GrStatement statement : statements) {
        statement.accept(visitor);
    }
    return result;
}
Also used : GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) TextRange(com.intellij.openapi.util.TextRange) GroovyRecursiveElementVisitor(org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor) GrParameter(org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) GrReferenceExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)

Example 72 with GrStatement

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

the class ExtractUtil method replaceStatement.

public static GrStatement replaceStatement(@Nullable GrStatementOwner declarationOwner, @NotNull ExtractInfoHelper helper) {
    GrStatement realStatement;
    if (declarationOwner != null && !isSingleExpression(helper.getStatements()) && helper.getStringPartInfo() == null) {
        // Replace set of statements
        final GrStatement[] newStatement = createResultStatement(helper);
        // add call statement
        final GrStatement[] statements = helper.getStatements();
        LOG.assertTrue(statements.length > 0);
        realStatement = null;
        for (GrStatement statement : newStatement) {
            realStatement = declarationOwner.addStatementBefore(statement, statements[0]);
            JavaCodeStyleManager.getInstance(realStatement.getProject()).shortenClassReferences(realStatement);
        }
        LOG.assertTrue(realStatement != null);
        // remove old statements
        removeOldStatements(declarationOwner, helper);
        PsiImplUtil.removeNewLineAfter(realStatement);
    } else {
        GrExpression oldExpr;
        if (helper.getStringPartInfo() != null) {
            oldExpr = helper.getStringPartInfo().replaceLiteralWithConcatenation("xyz");
        } else {
            oldExpr = (GrExpression) helper.getStatements()[0];
        }
        // Expression call replace
        GrExpression methodCall = createMethodCall(helper);
        realStatement = oldExpr.replaceWithExpression(methodCall, true);
        JavaCodeStyleManager.getInstance(realStatement.getProject()).shortenClassReferences(realStatement);
    }
    return realStatement;
}
Also used : GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)

Example 73 with GrStatement

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

the class ExtractUtil method mustAddVariableDeclaration.

/*
  To declare or not a variable to which method call result will be assigned.
   */
private static List<VariableInfo> mustAddVariableDeclaration(@NotNull GrStatement[] statements, @NotNull VariableInfo[] vars) {
    Map<String, VariableInfo> names = new HashMap<>();
    for (VariableInfo var : vars) {
        names.put(var.getName(), var);
    }
    List<VariableInfo> result = new ArrayList<>();
    for (GrStatement statement : statements) {
        if (statement instanceof GrVariableDeclaration) {
            GrVariableDeclaration declaration = (GrVariableDeclaration) statement;
            for (GrVariable variable : declaration.getVariables()) {
                final VariableInfo removed = names.remove(variable.getName());
                if (removed != null) {
                    result.add(removed);
                }
            }
        }
    }
    for (String varName : names.keySet()) {
        if (ResolveUtil.resolveProperty(statements[statements.length - 1], varName) == null) {
            result.add(names.get(varName));
        }
    }
    return result;
}
Also used : GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) GrVariableDeclaration(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration) HashMap(com.intellij.util.containers.HashMap) VariableInfo(org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)

Example 74 with GrStatement

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

the class ExtractUtil method generateBody.

public static void generateBody(ExtractInfoHelper helper, boolean isVoid, StringBuilder buffer, boolean forceReturn) {
    VariableInfo[] outputInfos = helper.getOutputVariableInfos();
    ParameterInfo[] infos = helper.getParameterInfos();
    Set<String> declaredVars = new HashSet<>();
    for (ParameterInfo info : infos) {
        declaredVars.add(info.getName());
    }
    for (VariableInfo info : mustAddVariableDeclaration(helper.getStatements(), outputInfos)) {
        declaredVars.add(info.getName());
    }
    List<VariableInfo> genDecl = new ArrayList<>();
    final Collection<GrVariable> outside = collectUsedLocalVarsOrParamsDeclaredOutside(helper);
    for (final GrVariable variable : outside) {
        if (!declaredVars.contains(variable.getName())) {
            genDecl.add(new VariableInfo() {

                @NotNull
                @Override
                public String getName() {
                    return variable.getName();
                }

                @Override
                public PsiType getType() {
                    return variable.getDeclaredType();
                }
            });
        }
    }
    final List<GrStatement> statements = generateVarDeclarations(genDecl, helper.getProject(), null);
    for (GrStatement statement : statements) {
        buffer.append(statement.getText()).append('\n');
    }
    final StringPartInfo stringPartInfo = helper.getStringPartInfo();
    if (!isSingleExpression(helper.getStatements()) && stringPartInfo == null) {
        for (PsiElement element : helper.getInnerElements()) {
            buffer.append(element.getText());
        }
        //append return statement
        if (!isVoid && outputInfos.length > 0) {
            buffer.append('\n');
            if (forceReturn) {
                buffer.append("return ");
            }
            if (outputInfos.length > 1)
                buffer.append('[');
            for (VariableInfo info : outputInfos) {
                buffer.append(info.getName()).append(", ");
            }
            buffer.delete(buffer.length() - 2, buffer.length());
            if (outputInfos.length > 1)
                buffer.append(']');
        }
    } else {
        GrExpression expr = stringPartInfo != null ? stringPartInfo.createLiteralFromSelected() : (GrExpression) PsiUtil.skipParentheses(helper.getStatements()[0], false);
        boolean addReturn = !isVoid && forceReturn && !PsiUtil.isVoidMethodCall(expr);
        if (addReturn) {
            buffer.append("return ");
            final GrExpression methodCall = ApplicationStatementUtil.convertToMethodCallExpression(expr);
            buffer.append(methodCall.getText());
        } else {
            buffer.append(expr != null ? expr.getText() : "");
        }
    }
}
Also used : VariableInfo(org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) NotNull(org.jetbrains.annotations.NotNull) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement) GrVariable(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable) StringPartInfo(org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo) PsiElement(com.intellij.psi.PsiElement) PsiType(com.intellij.psi.PsiType)

Example 75 with GrStatement

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

the class GroovyExtractChooser method buildInfo.

@NotNull
private static InitialInfo buildInfo(@NotNull Project project, @NotNull PsiFile file, int start, int end, boolean forceStatements, @NotNull SelectionModel selectionModel, @Nullable GrVariable variable) throws GrRefactoringError {
    PsiElement[] elements = getElementsInOffset(file, start, end, forceStatements);
    //if (elements.length == 1 && elements[0] instanceof GrExpression) {
    //  selectionModel.setSelection(start, elements[0].getTextRange().getEndOffset());
    //}
    GrStatement[] statements = getStatementsByElements(elements);
    if (statements.length == 0) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.a.statement.set"));
    }
    for (GrStatement statement : statements) {
        if (GroovyRefactoringUtil.isSuperOrThisCall(statement, true, true)) {
            throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.contains.invocation.of.another.class.constructor"));
        }
    }
    GrStatement statement0 = statements[0];
    PsiClass owner = PsiUtil.getContextClass(statement0);
    GrStatementOwner declarationOwner = GroovyRefactoringUtil.getDeclarationOwner(statement0);
    if (owner == null || declarationOwner == null && !ExtractUtil.isSingleExpression(statements)) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context"));
    }
    if (declarationOwner == null && ExtractUtil.isSingleExpression(statements) && statement0 instanceof GrExpression && PsiType.VOID.equals(((GrExpression) statement0).getType())) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.has.void.type"));
    }
    if (ExtractUtil.isSingleExpression(statements) && GrIntroduceHandlerBase.expressionIsIncorrect((GrExpression) statement0, true)) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression"));
    }
    if (ExtractUtil.isSingleExpression(statements) && statement0.getParent() instanceof GrAssignmentExpression && ((GrAssignmentExpression) statement0.getParent()).getLValue() == statement0) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.should.not.be.lvalue"));
    }
    // collect information about return statements in selected statement set
    Set<GrStatement> allReturnStatements = new HashSet<>();
    GrControlFlowOwner controlFlowOwner = ControlFlowUtils.findControlFlowOwner(statement0);
    LOG.assertTrue(controlFlowOwner != null);
    final Instruction[] flow = new ControlFlowBuilder(project, GrAllVarsInitializedPolicy.getInstance()).buildControlFlow(controlFlowOwner);
    allReturnStatements.addAll(ControlFlowUtils.collectReturns(flow, true));
    ArrayList<GrStatement> returnStatements = new ArrayList<>();
    for (GrStatement returnStatement : allReturnStatements) {
        for (GrStatement statement : statements) {
            if (PsiTreeUtil.isAncestor(statement, returnStatement, false)) {
                returnStatements.add(returnStatement);
                break;
            }
        }
    }
    // collect information about variables in selected block
    FragmentVariableInfos fragmentVariableInfos = ReachingDefinitionsCollector.obtainVariableFlowInformation(statement0, statements[statements.length - 1], controlFlowOwner, flow);
    VariableInfo[] inputInfos = fragmentVariableInfos.getInputVariableNames();
    VariableInfo[] outputInfos = fragmentVariableInfos.getOutputVariableNames();
    if (outputInfos.length == 1 && !returnStatements.isEmpty()) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("multiple.output.values"));
    }
    boolean hasInterruptingStatements = false;
    for (GrStatement statement : statements) {
        hasInterruptingStatements = GroovyRefactoringUtil.hasWrongBreakStatements(statement) || GroovyRefactoringUtil.hasWrongContinueStatements(statement);
        if (hasInterruptingStatements)
            break;
    }
    // must be replaced by return statement
    boolean hasReturns = !returnStatements.isEmpty();
    List<GrStatement> returnStatementsCopy = new ArrayList<>(returnStatements.size());
    returnStatementsCopy.addAll(returnStatements);
    boolean isReturnStatement = isReturnStatement(statements[statements.length - 1], returnStatementsCopy);
    boolean isLastStatementOfMethod = isLastStatementOfMethodOrClosure(statements);
    if (hasReturns && !isLastStatementOfMethod && !isReturnStatement || hasInterruptingStatements) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow"));
    }
    return new InitialInfo(inputInfos, outputInfos, elements, statements, returnStatements, null, project, variable);
}
Also used : VariableInfo(org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo) GrRefactoringError(org.jetbrains.plugins.groovy.refactoring.GrRefactoringError) ArrayList(java.util.ArrayList) GrStatementOwner(org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner) GrExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression) Instruction(org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction) GrStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement) GrControlFlowOwner(org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner) FragmentVariableInfos(org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.FragmentVariableInfos) GrAssignmentExpression(org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression) ControlFlowBuilder(org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder) HashSet(com.intellij.util.containers.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

GrStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)113 PsiElement (com.intellij.psi.PsiElement)36 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)26 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)22 GrOpenBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock)21 GrIfStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement)17 TextRange (com.intellij.openapi.util.TextRange)14 Nullable (org.jetbrains.annotations.Nullable)14 GrBlockStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement)13 NotNull (org.jetbrains.annotations.NotNull)12 GrReturnStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement)12 GrMethod (org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)12 GrStatementOwner (org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner)11 GrVariable (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable)10 GrReferenceExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression)10 GrVariableDeclaration (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration)9 GrClosableBlock (org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock)9 GrAssignmentExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression)8 GrMethodCallExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression)8 Document (com.intellij.openapi.editor.Document)6