@Override protected void performRefactoring(@NotNull UsageInfo[] usages) { try { for (UsageInfo usage : usages) { if (usage instanceof SafeDeleteCustomUsageInfo) { ((SafeDeleteCustomUsageInfo) usage).performRefactoring(); } } DumbService.allowStartingDumbModeInside( DumbModePermission.MAY_START_MODAL, () -> { for (PsiElement element : myElements) { for (SafeDeleteProcessorDelegate delegate : Extensions.getExtensions(SafeDeleteProcessorDelegate.EP_NAME)) { if (delegate.handlesElement(element)) { delegate.prepareForDeletion(element); } } element.delete(); } }); } catch (IncorrectOperationException e) { RefactoringUIUtil.processIncorrectOperation(myProject, e); } }
private static void deleteOverrideAnnotationIfFound(PsiMethod oMethod) { final PsiAnnotation annotation = AnnotationUtil.findAnnotation(oMethod, CommonClassNames.JAVA_LANG_OVERRIDE); if (annotation != null) { PsiElement prev = annotation.getPrevSibling(); PsiElement next = annotation.getNextSibling(); if ((prev == null || org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(prev)) && org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isLineFeed(next)) { next.delete(); } annotation.delete(); } }
static void deleteWholeStatement(PsiElement element, PsiElementFactory factory) throws IncorrectOperationException { // just delete it altogether if (element.getParent() instanceof PsiExpressionStatement) { PsiExpressionStatement parent = (PsiExpressionStatement) element.getParent(); if (parent.getParent() instanceof PsiCodeBlock) { parent.delete(); } else { // replace with empty statement (to handle with 'if (..) i=0;' ) parent.replace(createStatementIfNeeded(null, factory, element)); } } else { element.delete(); } }
/** * @param sideEffects if null, delete usages, otherwise collect side effects * @return true if there are at least one unrecoverable side effect found, false if no side * effects, null if read usage found (may happen if interval between fix creation in invoke() * call was long enough) * @throws com.intellij.util.IncorrectOperationException */ static Boolean processUsage( PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode) throws IncorrectOperationException { if (!element.isValid()) return null; PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory(); while (element != null) { if (element instanceof PsiAssignmentExpression) { PsiAssignmentExpression expression = (PsiAssignmentExpression) element; PsiExpression lExpression = expression.getLExpression(); // there should not be read access to the variable, otherwise it is not unused if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression) lExpression).resolve()) { return null; } PsiExpression rExpression = expression.getRExpression(); rExpression = PsiUtil.deparenthesizeExpression(rExpression); if (rExpression == null) return true; // replace assignment with expression and resimplify boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects); if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) { if (deleteMode == MAKE_STATEMENT || deleteMode == DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) { element = replaceElementWithExpression(rExpression, factory, element); while (element.getParent() instanceof PsiParenthesizedExpression) { element = element.getParent().replace(element); } List<PsiElement> references = new ArrayList<PsiElement>(); collectReferences(element, variable, references); deleteReferences(variable, references, deleteMode); } else if (deleteMode == DELETE_ALL) { deleteWholeStatement(element, factory); } return true; } else { if (deleteMode != CANCEL) { deleteWholeStatement(element, factory); } return !sideEffectFound; } } else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) { final PsiElement parent = element.getParent(); if (parent instanceof PsiIfStatement || parent instanceof PsiLoopStatement && ((PsiLoopStatement) parent).getBody() == element) { element.replace( JavaPsiFacade.getElementFactory(element.getProject()) .createStatementFromText(";", element)); } else { element.delete(); } break; } else if (element instanceof PsiVariable && element == variable) { PsiExpression expression = variable.getInitializer(); if (expression != null) { expression = PsiUtil.deparenthesizeExpression(expression); } boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects); if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable && !(variable.getParent() instanceof PsiDeclarationStatement && ((PsiDeclarationStatement) variable.getParent()).getDeclaredElements().length > 1)) { if (deleteMode == MAKE_STATEMENT) { element = element.replace(createStatementIfNeeded(expression, factory, element)); List<PsiElement> references = new ArrayList<PsiElement>(); collectReferences(element, variable, references); deleteReferences(variable, references, deleteMode); } else if (deleteMode == DELETE_ALL) { element.delete(); } return true; } else { if (deleteMode != CANCEL) { if (element instanceof PsiField) { ((PsiField) element).normalizeDeclaration(); } element.delete(); } return !sideEffectsFound; } } element = element.getParent(); } return true; }
private void tryToMoveInitializers( PsiMethod constructor, HashSet<PsiMethod> subConstructors, LinkedHashSet<PsiField> movedFields) throws IncorrectOperationException { final LinkedHashMap<PsiField, Initializer> fieldsToInitializers = new LinkedHashMap<PsiField, Initializer>(); boolean anyFound = false; for (PsiField field : movedFields) { PsiStatement commonInitializer = null; final ArrayList<PsiElement> fieldInitializersToRemove = new ArrayList<PsiElement>(); for (PsiMethod subConstructor : subConstructors) { commonInitializer = hasCommonInitializer( commonInitializer, subConstructor, field, fieldInitializersToRemove); if (commonInitializer == null) break; } if (commonInitializer != null) { final ParametersAndMovedFieldsUsedCollector visitor = new ParametersAndMovedFieldsUsedCollector(movedFields); commonInitializer.accept(visitor); fieldsToInitializers.put( field, new Initializer( commonInitializer, visitor.getUsedFields(), visitor.getUsedParameters(), fieldInitializersToRemove)); anyFound = true; } } if (!anyFound) return; { final Set<PsiField> initializedFields = fieldsToInitializers.keySet(); Set<PsiField> unmovable = RefactoringUtil.transitiveClosure( new RefactoringUtil.Graph<PsiField>() { public Set<PsiField> getVertices() { return initializedFields; } public Set<PsiField> getTargets(PsiField source) { return fieldsToInitializers.get(source).movedFieldsUsed; } }, new Condition<PsiField>() { public boolean value(PsiField object) { return !initializedFields.contains(object); } }); for (PsiField psiField : unmovable) { fieldsToInitializers.remove(psiField); } } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructor == null) { constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); final String visibilityModifier = VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList()); PsiUtil.setModifierProperty(constructor, visibilityModifier, true); } ArrayList<PsiField> initializedFields = new ArrayList<PsiField>(fieldsToInitializers.keySet()); Collections.sort( initializedFields, new Comparator<PsiField>() { public int compare(PsiField field1, PsiField field2) { Initializer i1 = fieldsToInitializers.get(field1); Initializer i2 = fieldsToInitializers.get(field2); if (i1.movedFieldsUsed.contains(field2)) return 1; if (i2.movedFieldsUsed.contains(field1)) return -1; return 0; } }); for (final PsiField initializedField : initializedFields) { Initializer initializer = fieldsToInitializers.get(initializedField); // correct constructor parameters and subConstructors super calls final PsiParameterList parameterList = constructor.getParameterList(); for (final PsiParameter parameter : initializer.usedParameters) { parameterList.add(parameter); } for (final PsiMethod subConstructor : subConstructors) { modifySuperCall(subConstructor, initializer.usedParameters); } PsiStatement assignmentStatement = (PsiStatement) constructor.getBody().add(initializer.initializer); PsiManager manager = PsiManager.getInstance(myProject); ChangeContextUtil.decodeContextInfo( assignmentStatement, myTargetSuperClass, RefactoringChangeUtil.createThisExpression(manager, null)); for (PsiElement psiElement : initializer.statementsToRemove) { psiElement.delete(); } } }
// Delete element if it doesn't contain children of a given type public static <T extends PsiElement> void deleteChildlessElement( PsiElement element, Class<T> childClass) { if (PsiTreeUtil.getChildrenOfType(element, childClass) == null) { element.delete(); } }