package org.angularjs.refactoring; import com.intellij.lang.javascript.psi.JSExpression; import com.intellij.lang.javascript.psi.JSProperty; import com.intellij.lang.javascript.psi.stubs.JSImplicitElement; import com.intellij.lang.javascript.refactoring.JSDefaultRenameProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.rename.RenameDialog; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewTypeLocation; import com.intellij.util.IncorrectOperationException; import org.angularjs.codeInsight.DirectiveUtil; import org.angularjs.index.AngularJS2IndexingHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author Dennis.Ushakov */ public class AngularJSDirectiveRenameProcessor extends JSDefaultRenameProcessor { @Override public boolean canProcessElement(@NotNull PsiElement element) { return DirectiveUtil.getDirective(element) != null; } @Nullable @Override public PsiElement substituteElementToRename(PsiElement element, @Nullable Editor editor) { return DirectiveUtil.getDirective(element); } @Override public void renameElement(PsiElement element, String newName, UsageInfo[] usages, @Nullable RefactoringElementListener listener) throws IncorrectOperationException { final boolean isAngular2 = DirectiveUtil.isAngular2Directive(element); final PsiNamedElement directive = (PsiNamedElement)element; final String attributeName = isAngular2 ? newName : DirectiveUtil.getAttributeName(newName); for (UsageInfo usage : usages) { RenameUtil.rename(usage, attributeName); } if (isAngular2) { final JSProperty selector = AngularJS2IndexingHandler.getSelector(element.getParent()); final JSExpression value = selector != null ? selector.getValue() : null; if (value != null) { if (value.getText().contains("[")) newName = "[" + newName + "]"; ElementManipulators.getManipulator(value).handleContentChange(value, newName); } } else { directive.setName(DirectiveUtil.attributeToDirective(element, newName)); } if (listener != null) { listener.elementRenamed(element); } } @Override public RenameDialog createRenameDialog(Project project, final PsiElement element, PsiElement nameSuggestionContext, Editor editor) { final String directiveName = DirectiveUtil.attributeToDirective(element, ((PsiNamedElement)element).getName()); return new RenameDialog(project, element, nameSuggestionContext, editor) { @Override public String[] getSuggestedNames() { return new String[] {directiveName}; } @Override protected boolean areButtonsValid() { return true; } }; } public static class AngularJSDirectiveElementDescriptor implements ElementDescriptionProvider { @Nullable @Override public String getElementDescription(@NotNull PsiElement element, @NotNull ElementDescriptionLocation location) { JSImplicitElement directive = DirectiveUtil.getDirective(element); if (directive != null) { if (location instanceof UsageViewTypeLocation) return "directive"; return DirectiveUtil.attributeToDirective(directive, directive.getName()); } return null; } } }