use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.
the class PyControlFlowBuilder method visitPyContinueStatement.
@Override
public void visitPyContinueStatement(final PyContinueStatement node) {
myBuilder.startNode(node);
final PyLoopStatement loop = node.getLoopStatement();
if (loop != null) {
final Instruction instruction = myBuilder.findInstructionByElement(loop);
if (instruction != null) {
myBuilder.addEdge(myBuilder.prevInstruction, instruction);
} else {
myBuilder.addPendingEdge(null, null);
}
}
myBuilder.flowAbrupted();
}
use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.
the class ScopeUtil method getReadWriteElements.
@NotNull
public static Collection<PsiElement> getReadWriteElements(@NotNull String name, @NotNull ScopeOwner scopeOwner, boolean isReadAccess, boolean isWriteAccess) {
ControlFlow flow = ControlFlowCache.getControlFlow(scopeOwner);
Collection<PsiElement> result = new ArrayList<>();
for (Instruction instr : flow.getInstructions()) {
if (instr instanceof ReadWriteInstruction) {
ReadWriteInstruction rw = (ReadWriteInstruction) instr;
if (name.equals(rw.getName())) {
ReadWriteInstruction.ACCESS access = rw.getAccess();
if ((isReadAccess && access.isReadAccess()) || (isWriteAccess && access.isWriteAccess())) {
result.add(rw.getElement());
}
}
}
}
return result;
}
use of com.intellij.codeInsight.controlflow.Instruction in project intellij-community by JetBrains.
the class PyInlineLocalHandler method invoke.
private static void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PyTargetExpression local, @Nullable PyReferenceExpression refExpr) {
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, local))
return;
final HighlightManager highlightManager = HighlightManager.getInstance(project);
final TextAttributes writeAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES);
final String localName = local.getName();
final ScopeOwner containerBlock = getContext(local);
LOG.assertTrue(containerBlock != null);
final Pair<PyStatement, Boolean> defPair = getAssignmentToInline(containerBlock, refExpr, local, project);
final PyStatement def = defPair.first;
if (def == null || getValue(def) == null) {
final String key = defPair.second ? "variable.has.no.dominating.definition" : "variable.has.no.initializer";
final String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
if (def instanceof PyAssignmentStatement && ((PyAssignmentStatement) def).getTargets().length > 1) {
highlightManager.addOccurrenceHighlights(editor, new PsiElement[] { def }, writeAttributes, true, null);
final String message = RefactoringBundle.getCannotRefactorMessage(PyBundle.message("refactoring.inline.local.multiassignment", localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
final PsiElement[] refsToInline = PyDefUseUtil.getPostRefs(containerBlock, local, getObject(def));
if (refsToInline.length == 0) {
final String message = RefactoringBundle.message("variable.is.never.used", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
highlightManager.addOccurrenceHighlights(editor, refsToInline, attributes, true, null);
final int occurrencesCount = refsToInline.length;
final String occurrencesString = RefactoringBundle.message("occurrences.string", occurrencesCount);
final String question = RefactoringBundle.message("inline.local.variable.prompt", localName) + " " + occurrencesString;
final RefactoringMessageDialog dialog = new RefactoringMessageDialog(REFACTORING_NAME, question, HELP_ID, "OptionPane.questionIcon", true, project);
if (!dialog.showAndGet()) {
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
return;
}
}
final PsiFile workingFile = local.getContainingFile();
for (PsiElement ref : refsToInline) {
final PsiFile otherFile = ref.getContainingFile();
if (!otherFile.equals(workingFile)) {
final String message = RefactoringBundle.message("variable.is.referenced.in.multiple.files", localName);
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
return;
}
}
for (final PsiElement ref : refsToInline) {
final List<PsiElement> elems = new ArrayList<>();
final List<Instruction> latestDefs = PyDefUseUtil.getLatestDefs(containerBlock, local.getName(), ref, false, false);
for (Instruction i : latestDefs) {
elems.add(i.getElement());
}
final PsiElement[] defs = elems.toArray(new PsiElement[elems.size()]);
boolean isSameDefinition = true;
for (PsiElement otherDef : defs) {
isSameDefinition &= isSameDefinition(def, otherDef);
}
if (!isSameDefinition) {
highlightManager.addOccurrenceHighlights(editor, defs, writeAttributes, true, null);
highlightManager.addOccurrenceHighlights(editor, new PsiElement[] { ref }, attributes, true, null);
final String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing.and.used.with.inlined", localName));
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HELP_ID);
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
return;
}
}
CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(() -> {
try {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(local);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(getRefactoringId(), afterData);
final PsiElement[] exprs = new PsiElement[refsToInline.length];
final PyExpression value = prepareValue(def, localName, project);
final PyExpression withParenthesis = PyElementGenerator.getInstance(project).createExpressionFromText("(" + value.getText() + ")");
final PsiElement lastChild = def.getLastChild();
if (lastChild != null && lastChild.getNode().getElementType() == PyTokenTypes.END_OF_LINE_COMMENT) {
final PsiElement parent = def.getParent();
if (parent != null)
parent.addBefore(lastChild, def);
}
for (int i = 0, refsToInlineLength = refsToInline.length; i < refsToInlineLength; i++) {
final PsiElement element = refsToInline[i];
if (PyReplaceExpressionUtil.isNeedParenthesis((PyExpression) element, value)) {
exprs[i] = element.replace(withParenthesis);
} else {
exprs[i] = element.replace(value);
}
}
final PsiElement next = def.getNextSibling();
if (next instanceof PsiWhiteSpace) {
PyPsiUtils.removeElements(next);
}
PyPsiUtils.removeElements(def);
final List<TextRange> ranges = ContainerUtil.mapNotNull(exprs, element -> {
final PyStatement parentalStatement = PsiTreeUtil.getParentOfType(element, PyStatement.class, false);
return parentalStatement != null ? parentalStatement.getTextRange() : null;
});
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
CodeStyleManager.getInstance(project).reformatText(workingFile, ranges);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
highlightManager.addOccurrenceHighlights(editor, exprs, attributes, true, null);
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
}
} finally {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(local);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(getRefactoringId(), afterData);
}
}), RefactoringBundle.message("inline.command", localName), null);
}
Aggregations