use of org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner in project intellij-community by JetBrains.
the class DumpGroovyControlFlowAction method collectControlFlowOwners.
private static List<GrControlFlowOwner> collectControlFlowOwners(final PsiFile file, final Editor editor, final int offset) {
final PsiElement elementAtCaret = file.findElementAt(offset);
final List<GrControlFlowOwner> result = new ArrayList<>();
for (GrControlFlowOwner owner = ControlFlowUtils.findControlFlowOwner(elementAtCaret); owner != null && !result.contains(owner); owner = ControlFlowUtils.findControlFlowOwner(owner)) {
result.add(owner);
}
return result;
}
use of org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner in project intellij-community by JetBrains.
the class DumpGroovyControlFlowAction method actionPerformed.
@Override
public void actionPerformed(AnActionEvent e) {
final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
if (editor == null)
return;
final PsiFile psiFile = HandlerUtils.getPsiFile(editor, e.getDataContext());
if (!(psiFile instanceof GroovyFile))
return;
int offset = editor.getCaretModel().getOffset();
final List<GrControlFlowOwner> controlFlowOwners = collectControlFlowOwners(psiFile, editor, offset);
if (controlFlowOwners.isEmpty())
return;
if (controlFlowOwners.size() == 1) {
passInner(controlFlowOwners.get(0));
} else {
IntroduceTargetChooser.showChooser(editor, controlFlowOwners, new Pass<GrControlFlowOwner>() {
@Override
public void pass(GrControlFlowOwner grExpression) {
passInner(grExpression);
}
}, flowOwner -> flowOwner.getText());
}
}
use of org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner in project intellij-community by JetBrains.
the class TypeInferenceHelper method getInferredType.
@Nullable
public static PsiType getInferredType(@NotNull PsiElement place, @NotNull String variableName) {
final GrControlFlowOwner scope = ControlFlowUtils.findControlFlowOwner(place);
if (scope == null)
return null;
final Instruction nearest = ControlFlowUtils.findNearestInstruction(place, scope.getControlFlow());
if (nearest == null)
return null;
return getInferenceCache(scope).getInferredType(variableName, nearest);
}
use of org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner in project intellij-community by JetBrains.
the class GrReassignedLocalVarsChecker method isReassignedVarImpl.
private static boolean isReassignedVarImpl(@NotNull final GrVariable resolved) {
final GrControlFlowOwner variableScope = PsiTreeUtil.getParentOfType(resolved, GrCodeBlock.class, GroovyFile.class);
if (variableScope == null)
return false;
final String name = resolved.getName();
final Ref<Boolean> isReassigned = Ref.create(false);
for (PsiElement scope = resolved.getParent().getNextSibling(); scope != null; scope = scope.getNextSibling()) {
if (scope instanceof GroovyPsiElement) {
((GroovyPsiElement) scope).accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitClosure(@NotNull GrClosableBlock closure) {
if (getUsedVarsInsideBlock(closure).contains(name)) {
isReassigned.set(true);
}
}
@Override
public void visitElement(@NotNull GroovyPsiElement element) {
if (isReassigned.get())
return;
super.visitElement(element);
}
});
if (isReassigned.get())
break;
}
}
return isReassigned.get();
}
use of org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner 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);
}
Aggregations