1 package com
.intellij
.refactoring
.rename
;
3 import com
.intellij
.featureStatistics
.FeatureUsageTracker
;
4 import com
.intellij
.openapi
.actionSystem
.DataContext
;
5 import com
.intellij
.openapi
.actionSystem
.DataKey
;
6 import com
.intellij
.openapi
.actionSystem
.PlatformDataKeys
;
7 import com
.intellij
.openapi
.application
.ApplicationManager
;
8 import com
.intellij
.openapi
.diagnostic
.Logger
;
9 import com
.intellij
.openapi
.editor
.Editor
;
10 import com
.intellij
.openapi
.editor
.ScrollType
;
11 import com
.intellij
.openapi
.extensions
.ExtensionPointName
;
12 import com
.intellij
.openapi
.extensions
.Extensions
;
13 import com
.intellij
.openapi
.project
.Project
;
14 import com
.intellij
.openapi
.util
.Condition
;
15 import com
.intellij
.psi
.*;
16 import com
.intellij
.psi
.impl
.source
.tree
.injected
.InjectedLanguageUtil
;
17 import com
.intellij
.psi
.meta
.PsiMetaOwner
;
18 import com
.intellij
.psi
.meta
.PsiWritableMetaData
;
19 import com
.intellij
.refactoring
.RefactoringBundle
;
20 import com
.intellij
.refactoring
.actions
.BaseRefactoringAction
;
21 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
22 import com
.intellij
.usageView
.UsageViewUtil
;
23 import com
.intellij
.codeInsight
.daemon
.impl
.CollectHighlightsUtil
;
24 import org
.jetbrains
.annotations
.NotNull
;
25 import org
.jetbrains
.annotations
.Nullable
;
28 * created at Nov 13, 2001
32 public class PsiElementRenameHandler
implements RenameHandler
{
33 private static final Logger LOG
= Logger
.getInstance("#com.intellij.refactoring.rename.PsiElementRenameHandler");
35 public static final ExtensionPointName
<Condition
<PsiElement
>> VETO_RENAME_CONDITION_EP
= ExtensionPointName
.create("com.intellij.vetoRenameCondition");
36 public static DataKey
<String
> DEFAULT_NAME
= DataKey
.create("DEFAULT_NAME");
38 public void invoke(@NotNull Project project
, Editor editor
, PsiFile file
, DataContext dataContext
) {
39 PsiElement element
= getElement(dataContext
);
40 editor
.getScrollingModel().scrollToCaret(ScrollType
.MAKE_VISIBLE
);
41 final PsiElement nameSuggestionContext
= file
.findElementAt(editor
.getCaretModel().getOffset());
42 invoke(element
, project
, nameSuggestionContext
, editor
);
45 public void invoke(@NotNull Project project
, @NotNull PsiElement
[] elements
, DataContext dataContext
) {
46 PsiElement element
= elements
.length
== 1 ? elements
[0] : null;
47 if (element
== null) element
= getElement(dataContext
);
48 LOG
.assertTrue(element
!= null);
49 Editor editor
= PlatformDataKeys
.EDITOR
.getData(dataContext
);
50 if (ApplicationManager
.getApplication().isUnitTestMode()) {
51 final String newName
= DEFAULT_NAME
.getData(dataContext
);
52 LOG
.assertTrue(newName
!= null);
53 rename(element
, project
, element
, editor
, newName
);
56 invoke(element
, project
, element
, editor
);
60 public static void invoke(PsiElement element
, Project project
, PsiElement nameSuggestionContext
, Editor editor
) {
61 if (element
!= null && !canRename(project
, editor
, element
)) {
64 FeatureUsageTracker
.getInstance().triggerFeatureUsed("refactoring.rename");
66 rename(element
, project
, nameSuggestionContext
, editor
);
69 static boolean canRename(Project project
, Editor editor
, PsiElement element
) {
70 if (element
== null) return false;
71 if (!(element
instanceof PsiFile
) && CollectHighlightsUtil
.isOutsideSourceRootJavaFile(element
.getContainingFile())) return false;
72 boolean hasRenameProcessor
= RenamePsiElementProcessor
.forElement(element
) != RenamePsiElementProcessor
.DEFAULT
;
73 boolean hasWritableMetaData
= element
instanceof PsiMetaOwner
&& ((PsiMetaOwner
)element
).getMetaData() instanceof PsiWritableMetaData
;
75 if (!hasRenameProcessor
&& !hasWritableMetaData
&& !(element
instanceof PsiNamedElement
)) {
76 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("error.wrong.caret.position.symbol"));
77 if (!ApplicationManager
.getApplication().isUnitTestMode()) {
78 showErrorMessage(project
, editor
, message
);
83 if (!PsiManager
.getInstance(project
).isInProject(element
) && element
.isPhysical()) {
84 String message
= RefactoringBundle
85 .getCannotRefactorMessage(RefactoringBundle
.message("error.out.of.project.element", UsageViewUtil
.getType(element
)));
86 showErrorMessage(project
, editor
, message
);
90 if (InjectedLanguageUtil
.isInInjectedLanguagePrefixSuffix(element
)) {
91 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("error.in.injected.lang.prefix.suffix", UsageViewUtil
.getType(element
)));
92 showErrorMessage(project
, editor
, message
);
96 return true;//CommonRefactoringUtil.checkReadOnlyStatus(project, element);
99 private static void showErrorMessage(Project project
, Editor editor
, String message
) {
100 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, RefactoringBundle
.message("rename.title"), null);
103 public static void rename(PsiElement element
, final Project project
, PsiElement nameSuggestionContext
, Editor editor
) {
104 rename(element
, project
, nameSuggestionContext
, editor
, null);
107 private static void rename(PsiElement element
, final Project project
, PsiElement nameSuggestionContext
, Editor editor
, final String defaultName
) {
108 RenamePsiElementProcessor processor
= RenamePsiElementProcessor
.forElement(element
);
109 element
= processor
.substituteElementToRename(element
, editor
);
110 if (element
== null) return;
112 final RenameDialog dialog
= new RenameDialog(project
, element
, nameSuggestionContext
, editor
);
113 if (defaultName
!= null) {
114 dialog
.performRename(defaultName
);
121 public boolean isAvailableOnDataContext(DataContext dataContext
) {
122 return !isVetoed(getElement(dataContext
));
125 public static boolean isVetoed(PsiElement element
) {
126 if (element
== null || element
instanceof SyntheticElement
) return true;
127 for(Condition
<PsiElement
> condition
: Extensions
.getExtensions(VETO_RENAME_CONDITION_EP
)) {
128 if (condition
.value(element
)) return true;
134 public static PsiElement
getElement(final DataContext dataContext
) {
135 PsiElement
[] elementArray
= BaseRefactoringAction
.getPsiElementArray(dataContext
);
137 if (elementArray
.length
!= 1) {
140 return elementArray
[0];
143 public boolean isRenaming(DataContext dataContext
) {
144 return isAvailableOnDataContext(dataContext
);