use of com.intellij.refactoring.util.RefactoringMessageDialog in project intellij-community by JetBrains.
the class GroovyInlineLocalHandler method createSettings.
/**
* Returns Settings object for referenced definition in case of local variable
*/
@Nullable
private static InlineLocalVarSettings createSettings(final GrVariable variable, Editor editor, boolean invokedOnReference) {
final String localName = variable.getName();
final Project project = variable.getProject();
GrExpression initializer = null;
Instruction writeInstr = null;
Instruction[] flow = null;
//search for initializer to inline
if (invokedOnReference) {
LOG.assertTrue(editor != null, "null editor but invokedOnReference==true");
final PsiReference ref = TargetElementUtil.findReference(editor);
LOG.assertTrue(ref != null);
PsiElement cur = ref.getElement();
if (cur instanceof GrReferenceExpression) {
GrControlFlowOwner controlFlowOwner;
do {
controlFlowOwner = ControlFlowUtils.findControlFlowOwner(cur);
if (controlFlowOwner == null)
break;
flow = controlFlowOwner.getControlFlow();
final List<BitSet> writes = ControlFlowUtils.inferWriteAccessMap(flow, variable);
final PsiElement finalCur = cur;
Instruction instruction = ControlFlowUtils.findInstruction(finalCur, flow);
LOG.assertTrue(instruction != null);
final BitSet prev = writes.get(instruction.num());
if (prev.cardinality() == 1) {
writeInstr = flow[prev.nextSetBit(0)];
final PsiElement element = writeInstr.getElement();
if (element instanceof GrVariable) {
initializer = ((GrVariable) element).getInitializerGroovy();
} else if (element instanceof GrReferenceExpression) {
initializer = TypeInferenceHelper.getInitializerFor((GrReferenceExpression) element);
}
}
PsiElement old_cur = cur;
if (controlFlowOwner instanceof GrClosableBlock) {
cur = controlFlowOwner;
} else {
PsiElement parent = controlFlowOwner.getParent();
if (parent instanceof GrMember)
cur = ((GrMember) parent).getContainingClass();
}
if (cur == old_cur)
break;
} while (initializer == null);
}
} else {
flow = ControlFlowUtils.findControlFlowOwner(variable).getControlFlow();
initializer = variable.getInitializerGroovy();
writeInstr = ContainerUtil.find(flow, instruction -> instruction.getElement() == variable);
}
if (initializer == null || writeInstr == null) {
String message = GroovyRefactoringBundle.message("cannot.find.a.single.definition.to.inline.local.var");
CommonRefactoringUtil.showErrorHint(variable.getProject(), editor, message, INLINE_VARIABLE, HelpID.INLINE_VARIABLE);
return null;
}
int writeInstructionNumber = writeInstr.num();
if (ApplicationManager.getApplication().isUnitTestMode()) {
return new InlineLocalVarSettings(initializer, writeInstructionNumber, flow);
}
final String question = GroovyRefactoringBundle.message("inline.local.variable.prompt.0.1", localName);
RefactoringMessageDialog dialog = new RefactoringMessageDialog(INLINE_VARIABLE, question, HelpID.INLINE_VARIABLE, "OptionPane.questionIcon", true, project);
if (dialog.showAndGet()) {
return new InlineLocalVarSettings(initializer, writeInstructionNumber, flow);
}
return null;
}
use of com.intellij.refactoring.util.RefactoringMessageDialog in project intellij-community by JetBrains.
the class InlinePropertyHandler method inlineElement.
public void inlineElement(final Project project, Editor editor, PsiElement psiElement) {
if (!(psiElement instanceof IProperty))
return;
IProperty property = (IProperty) psiElement;
final String propertyValue = property.getValue();
if (propertyValue == null)
return;
final List<PsiElement> occurrences = Collections.synchronizedList(ContainerUtil.<PsiElement>newArrayList());
final Collection<PsiFile> containingFiles = Collections.synchronizedSet(new HashSet<PsiFile>());
containingFiles.add(psiElement.getContainingFile());
boolean result = ReferencesSearch.search(psiElement).forEach(psiReference -> {
PsiElement element = psiReference.getElement();
PsiElement parent = element.getParent();
if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiMethodCallExpression) {
if (((PsiExpressionList) parent).getExpressions().length == 1) {
occurrences.add(parent.getParent());
containingFiles.add(element.getContainingFile());
return true;
}
}
return false;
});
if (!result) {
CommonRefactoringUtil.showErrorHint(project, editor, "Property has non-method usages", REFACTORING_NAME, null);
}
if (occurrences.isEmpty()) {
CommonRefactoringUtil.showErrorHint(project, editor, "Property has no usages", REFACTORING_NAME, null);
return;
}
if (!ApplicationManager.getApplication().isUnitTestMode()) {
String occurrencesString = RefactoringBundle.message("occurrences.string", occurrences.size());
String question = PropertiesBundle.message("inline.property.confirmation", property.getName(), propertyValue) + " " + occurrencesString;
RefactoringMessageDialog dialog = new RefactoringMessageDialog(REFACTORING_NAME, question, HelpID.INLINE_VARIABLE, "OptionPane.questionIcon", true, project);
if (!dialog.showAndGet()) {
return;
}
}
final RefactoringEventData data = new RefactoringEventData();
data.addElement(psiElement.copy());
new WriteCommandAction.Simple(project, REFACTORING_NAME, containingFiles.toArray(new PsiFile[containingFiles.size()])) {
@Override
protected void run() throws Throwable {
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, data);
PsiLiteral stringLiteral = (PsiLiteral) JavaPsiFacade.getInstance(getProject()).getElementFactory().createExpressionFromText("\"" + StringUtil.escapeStringCharacters(propertyValue) + "\"", null);
for (PsiElement occurrence : occurrences) {
occurrence.replace(stringLiteral.copy());
}
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, null);
}
}.execute();
}
use of com.intellij.refactoring.util.RefactoringMessageDialog in project intellij-community by JetBrains.
the class InlineParameterHandler method inlineElement.
public void inlineElement(final Project project, final Editor editor, final PsiElement psiElement) {
final PsiParameter psiParameter = (PsiParameter) psiElement;
final PsiParameterList parameterList = (PsiParameterList) psiParameter.getParent();
if (!(parameterList.getParent() instanceof PsiMethod)) {
return;
}
final int index = parameterList.getParameterIndex(psiParameter);
final PsiMethod method = (PsiMethod) parameterList.getParent();
String errorMessage = getCannotInlineMessage(psiParameter, method);
if (errorMessage != null) {
CommonRefactoringUtil.showErrorHint(project, editor, errorMessage, RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
final Ref<PsiExpression> refInitializer = new Ref<>();
final Ref<PsiExpression> refConstantInitializer = new Ref<>();
final Ref<PsiCallExpression> refMethodCall = new Ref<>();
final List<PsiReference> occurrences = Collections.synchronizedList(new ArrayList<PsiReference>());
final Collection<PsiFile> containingFiles = Collections.synchronizedSet(new HashSet<PsiFile>());
containingFiles.add(psiParameter.getContainingFile());
boolean[] result = new boolean[1];
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
result[0] = ReferencesSearch.search(method).forEach(psiReference -> {
PsiElement element = psiReference.getElement();
final PsiElement parent = element.getParent();
if (parent instanceof PsiCallExpression) {
final PsiCallExpression methodCall = (PsiCallExpression) parent;
occurrences.add(psiReference);
containingFiles.add(element.getContainingFile());
final PsiExpression[] expressions = methodCall.getArgumentList().getExpressions();
if (expressions.length <= index)
return false;
PsiExpression argument = expressions[index];
if (!refInitializer.isNull()) {
return argument != null && PsiEquivalenceUtil.areElementsEquivalent(refInitializer.get(), argument) && PsiEquivalenceUtil.areElementsEquivalent(refMethodCall.get(), methodCall);
}
if (InlineToAnonymousConstructorProcessor.isConstant(argument) || getReferencedFinalField(argument) != null) {
if (refConstantInitializer.isNull()) {
refConstantInitializer.set(argument);
} else if (!isSameConstant(argument, refConstantInitializer.get())) {
return false;
}
} else if (!isRecursiveReferencedParameter(argument, psiParameter)) {
if (!refConstantInitializer.isNull())
return false;
refInitializer.set(argument);
refMethodCall.set(methodCall);
}
}
return true;
});
}, "Searching for Method Usages", true, project)) {
return;
}
final PsiReference reference = TargetElementUtil.findReference(editor);
final PsiReferenceExpression refExpr = reference instanceof PsiReferenceExpression ? ((PsiReferenceExpression) reference) : null;
final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class);
if (codeBlock != null) {
final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr);
if (defs.length == 1) {
final PsiElement def = defs[0];
if (def instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression) def)) {
final PsiExpression rExpr = ((PsiAssignmentExpression) def.getParent()).getRExpression();
if (rExpr != null) {
PsiExpression toInline = InlineLocalHandler.getDefToInline(psiParameter, refExpr, codeBlock);
if (toInline != null) {
final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, toInline);
if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) {
new WriteCommandAction(project) {
@Override
protected void run(@NotNull Result result) throws Throwable {
for (final PsiElement ref : refs) {
InlineUtil.inlineVariable(psiParameter, rExpr, (PsiJavaCodeReferenceElement) ref);
}
def.getParent().delete();
}
}.execute();
return;
}
}
}
}
}
}
if (occurrences.isEmpty()) {
CommonRefactoringUtil.showErrorHint(project, editor, "Method has no usages", RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
if (!result[0]) {
CommonRefactoringUtil.showErrorHint(project, editor, "Cannot find constant initializer for parameter", RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
if (!refInitializer.isNull()) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
final InlineParameterExpressionProcessor processor = new InlineParameterExpressionProcessor(refMethodCall.get(), method, psiParameter, refInitializer.get(), method.getProject().getUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS));
processor.run();
} else {
final boolean createLocal = ReferencesSearch.search(psiParameter).findAll().size() > 1;
InlineParameterDialog dlg = new InlineParameterDialog(refMethodCall.get(), method, psiParameter, refInitializer.get(), createLocal);
dlg.show();
}
return;
}
if (refConstantInitializer.isNull()) {
CommonRefactoringUtil.showErrorHint(project, editor, "Cannot find constant initializer for parameter", RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
final Ref<Boolean> isNotConstantAccessible = new Ref<>();
final PsiExpression constantExpression = refConstantInitializer.get();
constantExpression.accept(new JavaRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
final PsiElement resolved = expression.resolve();
if (resolved instanceof PsiMember && !PsiUtil.isAccessible((PsiMember) resolved, method, null)) {
isNotConstantAccessible.set(Boolean.TRUE);
}
}
});
if (!isNotConstantAccessible.isNull() && isNotConstantAccessible.get()) {
CommonRefactoringUtil.showErrorHint(project, editor, "Constant initializer is not accessible in method body", RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
for (PsiReference psiReference : ReferencesSearch.search(psiParameter)) {
final PsiElement element = psiReference.getElement();
if (element instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression) element)) {
CommonRefactoringUtil.showErrorHint(project, editor, "Inline parameter which has write usages is not supported", RefactoringBundle.message("inline.parameter.refactoring"), null);
return;
}
}
if (!ApplicationManager.getApplication().isUnitTestMode()) {
String occurencesString = RefactoringBundle.message("occurrences.string", occurrences.size());
String question = RefactoringBundle.message("inline.parameter.confirmation", psiParameter.getName(), constantExpression.getText()) + " " + occurencesString;
RefactoringMessageDialog dialog = new RefactoringMessageDialog(REFACTORING_NAME, question, HelpID.INLINE_VARIABLE, "OptionPane.questionIcon", true, project);
if (!dialog.showAndGet()) {
return;
}
}
final RefactoringEventData data = new RefactoringEventData();
data.addElement(psiElement.copy());
CommandProcessor.getInstance().executeCommand(project, () -> {
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, data);
SameParameterValueInspection.InlineParameterValueFix.inlineSameParameterValue(method, psiParameter, constantExpression);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, null);
}, REFACTORING_NAME, null);
}
use of com.intellij.refactoring.util.RefactoringMessageDialog 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