@Nullable @Override protected RefactoringEventData getBeforeData() { RefactoringEventData data = new RefactoringEventData(); data.addElements(new PsiElement[] {myLocalVariable, myExpressionToSearch}); return data; }
@Nullable @Override protected RefactoringEventData getBeforeData() { final RefactoringEventData beforeData = new RefactoringEventData(); beforeData.addElements(myElements); return beforeData; }
protected boolean showConflicts( @NotNull MultiMap<PsiElement, String> conflicts, @Nullable final UsageInfo[] usages) { if (!conflicts.isEmpty() && ApplicationManager.getApplication().isUnitTestMode()) { if (!ConflictsInTestsException.isTestIgnore()) throw new ConflictsInTestsException(conflicts.values()); return true; } if (myPrepareSuccessfulSwingThreadCallback != null && !conflicts.isEmpty()) { final String refactoringId = getRefactoringId(); if (refactoringId != null) { RefactoringEventData conflictUsages = new RefactoringEventData(); conflictUsages.putUserData(RefactoringEventData.CONFLICTS_KEY, conflicts.values()); myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .conflictsDetected(refactoringId, conflictUsages); } final ConflictsDialog conflictsDialog = prepareConflictsDialog(conflicts, usages); if (!conflictsDialog.showAndGet()) { if (conflictsDialog.isShowConflicts()) prepareSuccessful(); return false; } } prepareSuccessful(); return true; }
@Nullable @Override protected RefactoringEventData getAfterData(@NotNull UsageInfo[] usages) { final RefactoringEventData data = new RefactoringEventData(); data.addElement(myTargetSuperClass); return data; }
@Override protected void moveOffsetAfter(boolean success) { if (getLocalVariable() != null && getLocalVariable().isValid()) { myEditor.getCaretModel().moveToOffset(getLocalVariable().getTextOffset()); myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); } else if (getExprMarker() != null) { final RangeMarker exprMarker = getExprMarker(); if (exprMarker.isValid()) { myEditor.getCaretModel().moveToOffset(exprMarker.getStartOffset()); myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); } } super.moveOffsetAfter(success); if (myLocalMarker != null && !isRestart()) { myLocalMarker.dispose(); } if (success) { performPostIntroduceTasks(); final String refactoringId = getRefactoringId(); if (refactoringId != null) { final RefactoringEventData afterData = new RefactoringEventData(); afterData.addElement(getVariable()); myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringDone(refactoringId, afterData); } } }
@Override protected boolean performRefactoring() { if (!ensureValid()) return false; CommandProcessor.getInstance() .executeCommand( myProject, () -> { final String refactoringId = getRefactoringId(); if (refactoringId != null) { final RefactoringEventData beforeData = new RefactoringEventData(); final V localVariable = getLocalVariable(); if (localVariable != null) { beforeData.addElement(localVariable); } else { final E beforeExpr = getBeforeExpr(); if (beforeExpr != null) { beforeData.addElement(beforeExpr); } } myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringStarted(refactoringId, beforeData); } performIntroduce(); }, getCommandName(), getCommandName()); V variable = getVariable(); if (variable != null) { saveSettings(variable); } return false; }
@Nullable @Override protected RefactoringEventData getBeforeData() { RefactoringEventData data = new RefactoringEventData(); data.addElement(mySourceClass); data.addMembers(myMembersToMove, info -> info.getMember()); return data; }
@Nullable @Override protected RefactoringEventData getBeforeData() { RefactoringEventData data = new RefactoringEventData(); final List<PsiElement> fields = new ArrayList<PsiElement>(); for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { fields.add(fieldDescriptor.getField()); } data.addElements(fields); return data; }
@Nullable @Override protected RefactoringEventData getAfterData(UsageInfo[] usages) { RefactoringEventData data = new RefactoringEventData(); List<PsiElement> elements = new ArrayList<PsiElement>(); if (myNameToGetter != null) { elements.addAll(myNameToGetter.values()); } if (myNameToSetter != null) { elements.addAll(myNameToSetter.values()); } data.addElements(elements); return data; }
@Override protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) { UsageInfo[] usages = refUsages.get(); ArrayList<String> conflicts = new ArrayList<String>(); for (PsiElement element : myElements) { for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { if (delegate.handlesElement(element)) { Collection<String> foundConflicts = delegate instanceof SafeDeleteProcessorDelegateBase ? ((SafeDeleteProcessorDelegateBase) delegate) .findConflicts(element, myElements, usages) : delegate.findConflicts(element, myElements); if (foundConflicts != null) { conflicts.addAll(foundConflicts); } break; } } } final HashMap<PsiElement, UsageHolder> elementsToUsageHolders = sortUsages(usages); final Collection<UsageHolder> usageHolders = elementsToUsageHolders.values(); for (UsageHolder usageHolder : usageHolders) { if (usageHolder.hasUnsafeUsagesInCode()) { conflicts.add(usageHolder.getDescription()); } } if (!conflicts.isEmpty()) { final RefactoringEventData conflictData = new RefactoringEventData(); conflictData.putUserData(RefactoringEventData.CONFLICTS_KEY, conflicts); myProject .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .conflictsDetected("refactoring.safeDelete", conflictData); if (ApplicationManager.getApplication().isUnitTestMode()) { if (!ConflictsInTestsException.isTestIgnore()) throw new ConflictsInTestsException(conflicts); } else { UnsafeUsagesDialog dialog = new UnsafeUsagesDialog(ArrayUtil.toStringArray(conflicts), myProject); if (!dialog.showAndGet()) { final int exitCode = dialog.getExitCode(); prepareSuccessful(); // dialog is always dismissed; if (exitCode == UnsafeUsagesDialog.VIEW_USAGES_EXIT_CODE) { showUsages( Arrays.stream(usages) .filter( usage -> usage instanceof SafeDeleteReferenceUsageInfo && !((SafeDeleteReferenceUsageInfo) usage).isSafeDelete()) .toArray(UsageInfo[]::new)); } return false; } else { myPreviewNonCodeUsages = false; } } } UsageInfo[] preprocessedUsages = usages; for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { preprocessedUsages = delegate.preprocessUsages(myProject, preprocessedUsages); if (preprocessedUsages == null) return false; } final UsageInfo[] filteredUsages = UsageViewUtil.removeDuplicatedUsages(preprocessedUsages); prepareSuccessful(); // dialog is always dismissed if (filteredUsages == null) { return false; } refUsages.set(filteredUsages); return true; }
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<PsiExpression>(); final Ref<PsiExpression> refConstantInitializer = new Ref<PsiExpression>(); final Ref<PsiCallExpression> refMethodCall = new Ref<PsiCallExpression>(); final List<PsiReference> occurrences = Collections.synchronizedList(new ArrayList<PsiReference>()); final Collection<PsiFile> containingFiles = Collections.synchronizedSet(new HashSet<PsiFile>()); containingFiles.add(psiParameter.getContainingFile()); boolean result = ReferencesSearch.search(method) .forEach( new Processor<PsiReference>() { public boolean process(final PsiReference 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; } }); final int offset = editor.getCaretModel().getOffset(); final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset); 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) { final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr); if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) { new WriteCommandAction(project) { @Override protected void run(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) { 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<Boolean>(); 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("occurences.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); dialog.show(); if (!dialog.isOK()) { return; } } final RefactoringEventData data = new RefactoringEventData(); data.addElement(psiElement.copy()); 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); }