use of com.intellij.refactoring.listeners.RefactoringEventData in project intellij-community by JetBrains.
the class EncapsulateFieldsProcessor method getBeforeData.
@Nullable
@Override
protected RefactoringEventData getBeforeData() {
RefactoringEventData data = new RefactoringEventData();
final List<PsiElement> fields = new ArrayList<>();
for (FieldDescriptor fieldDescriptor : myFieldDescriptors) {
fields.add(fieldDescriptor.getField());
}
data.addElements(fields);
return data;
}
use of com.intellij.refactoring.listeners.RefactoringEventData in project intellij-community by JetBrains.
the class PyExtractMethodUtil method extractFromStatements.
public static void extractFromStatements(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PyCodeFragment fragment, @NotNull final PsiElement statement1, @NotNull final PsiElement statement2) {
if (!fragment.getOutputVariables().isEmpty() && fragment.isReturnInstructionInside()) {
CommonRefactoringUtil.showErrorHint(project, editor, PyBundle.message("refactoring.extract.method.error.local.variable.modifications.and.returns"), RefactoringBundle.message("error.title"), "refactoring.extractMethod");
return;
}
final PyFunction function = PsiTreeUtil.getParentOfType(statement1, PyFunction.class);
final PyUtil.MethodFlags flags = function == null ? null : PyUtil.MethodFlags.of(function);
final boolean isClassMethod = flags != null && flags.isClassMethod();
final boolean isStaticMethod = flags != null && flags.isStaticMethod();
// collect statements
final List<PsiElement> elementsRange = PyPsiUtils.collectElements(statement1, statement2);
if (elementsRange.isEmpty()) {
CommonRefactoringUtil.showErrorHint(project, editor, PyBundle.message("refactoring.extract.method.error.empty.fragment"), RefactoringBundle.message("extract.method.title"), "refactoring.extractMethod");
return;
}
final Pair<String, AbstractVariableData[]> data = getNameAndVariableData(project, fragment, statement1, isClassMethod, isStaticMethod);
if (data.first == null || data.second == null) {
return;
}
final String methodName = data.first;
final AbstractVariableData[] variableData = data.second;
final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(statement1, statement2, fragment.getOutputVariables(), variableData);
CommandProcessor.getInstance().executeCommand(project, () -> {
final RefactoringEventData beforeData = new RefactoringEventData();
beforeData.addElements(new PsiElement[] { statement1, statement2 });
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(getRefactoringId(), beforeData);
final StringBuilder builder = new StringBuilder();
final boolean isAsync = fragment.isAsync();
if (isAsync) {
builder.append("async ");
}
builder.append("def f():\n ");
final List<PsiElement> newMethodElements = new ArrayList<>(elementsRange);
final boolean hasOutputVariables = !fragment.getOutputVariables().isEmpty();
final PyElementGenerator generator = PyElementGenerator.getInstance(project);
final LanguageLevel languageLevel = LanguageLevel.forElement(statement1);
if (hasOutputVariables) {
// Generate return modified variables statements
final String outputVariables = StringUtil.join(fragment.getOutputVariables(), ", ");
final String newMethodText = builder + "return " + outputVariables;
builder.append(outputVariables);
final PyFunction function1 = generator.createFromText(languageLevel, PyFunction.class, newMethodText);
final PsiElement returnStatement = function1.getStatementList().getStatements()[0];
newMethodElements.add(returnStatement);
}
// Generate method
final PyFunction generatedMethod = generateMethodFromElements(project, methodName, variableData, newMethodElements, flags, isAsync);
final PyFunction insertedMethod = WriteAction.compute(() -> insertGeneratedMethod(statement1, generatedMethod));
// Process parameters
final PsiElement firstElement = elementsRange.get(0);
final boolean isMethod = PyPsiUtils.isMethodContext(firstElement);
WriteAction.run(() -> {
processParameters(project, insertedMethod, variableData, isMethod, isClassMethod, isStaticMethod);
processGlobalWrites(insertedMethod, fragment);
processNonlocalWrites(insertedMethod, fragment);
});
// Generate call element
if (hasOutputVariables) {
builder.append(" = ");
} else if (fragment.isReturnInstructionInside()) {
builder.append("return ");
}
if (isAsync) {
builder.append("await ");
} else if (fragment.isYieldInside()) {
builder.append("yield from ");
}
if (isMethod) {
appendSelf(firstElement, builder, isStaticMethod);
}
builder.append(methodName).append("(");
builder.append(createCallArgsString(variableData)).append(")");
final PyFunction function1 = generator.createFromText(languageLevel, PyFunction.class, builder.toString());
final PsiElement callElement = function1.getStatementList().getStatements()[0];
// Both statements are used in finder, so should be valid at this moment
PyPsiUtils.assertValid(statement1);
PyPsiUtils.assertValid(statement2);
final List<SimpleMatch> duplicates = collectDuplicates(finder, statement1, insertedMethod);
// replace statements with call
PsiElement insertedCallElement = WriteAction.compute(() -> replaceElements(elementsRange, callElement));
insertedCallElement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(insertedCallElement);
if (insertedCallElement != null) {
processDuplicates(duplicates, insertedCallElement, editor);
}
// Set editor
setSelectionAndCaret(editor, insertedCallElement);
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(insertedMethod);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(getRefactoringId(), afterData);
}, PyBundle.message("refactoring.extract.method"), null);
}
use of com.intellij.refactoring.listeners.RefactoringEventData 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);
}
use of com.intellij.refactoring.listeners.RefactoringEventData in project intellij-community by JetBrains.
the class IntroduceHandler method performReplace.
private PsiElement performReplace(@NotNull final PsiElement declaration, final IntroduceOperation operation) {
final PyExpression expression = operation.getInitializer();
final Project project = operation.getProject();
return new WriteCommandAction<PsiElement>(project, expression.getContainingFile()) {
protected void run(@NotNull final Result<PsiElement> result) throws Throwable {
try {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(declaration);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(getRefactoringId(), afterData);
result.setResult(addDeclaration(operation, declaration));
PyExpression newExpression = createExpression(project, operation.getName(), declaration);
if (operation.isReplaceAll()) {
List<PsiElement> newOccurrences = new ArrayList<>();
for (PsiElement occurrence : operation.getOccurrences()) {
final PsiElement replaced = replaceExpression(occurrence, newExpression, operation);
if (replaced != null) {
newOccurrences.add(replaced);
}
}
operation.setOccurrences(newOccurrences);
} else {
final PsiElement replaced = replaceExpression(expression, newExpression, operation);
operation.setOccurrences(Collections.singletonList(replaced));
}
postRefactoring(operation.getElement());
} finally {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(declaration);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(getRefactoringId(), afterData);
}
}
}.execute().getResultObject();
}
use of com.intellij.refactoring.listeners.RefactoringEventData in project intellij-community by JetBrains.
the class PyMembersRefactoringBaseProcessor method getAfterData.
@Nullable
@Override
protected RefactoringEventData getAfterData(@NotNull UsageInfo[] usages) {
final RefactoringEventData data = new RefactoringEventData();
data.addElements(myTo);
return data;
}
Aggregations