Search in sources :

Example 1 with FragmentVariableInfos

use of org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.FragmentVariableInfos 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

HashSet (com.intellij.util.containers.HashSet)1 ArrayList (java.util.ArrayList)1 NotNull (org.jetbrains.annotations.NotNull)1 GrControlFlowOwner (org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner)1 GrStatement (org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement)1 GrAssignmentExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression)1 GrExpression (org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression)1 GrStatementOwner (org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner)1 Instruction (org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction)1 ControlFlowBuilder (org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder)1 FragmentVariableInfos (org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.FragmentVariableInfos)1 VariableInfo (org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo)1 GrRefactoringError (org.jetbrains.plugins.groovy.refactoring.GrRefactoringError)1