ability to change name of method to any string constant. Detection of incorrect usages
[idea/community.git] / java / java-impl / src / com / intellij / refactoring / actions / ChangeSignatureAction.java
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.intellij.refactoring.actions;
17
18 import com.intellij.lang.Language;
19 import com.intellij.lang.LanguageRefactoringSupport;
20 import com.intellij.openapi.actionSystem.DataContext;
21 import com.intellij.openapi.actionSystem.LangDataKeys;
22 import com.intellij.openapi.editor.Document;
23 import com.intellij.openapi.editor.Editor;
24 import com.intellij.openapi.editor.ScrollType;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.psi.*;
27 import com.intellij.refactoring.RefactoringActionHandler;
28 import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
29 import org.jetbrains.annotations.NotNull;
30 import org.jetbrains.annotations.Nullable;
31
32 public class ChangeSignatureAction extends BaseRefactoringAction {
33   public boolean isAvailableInEditorOnly() {
34     return false;
35   }
36
37   public boolean isEnabledOnElements(PsiElement[] elements) {
38     return elements.length == 1 && (elements[0] instanceof PsiMethod || elements[0] instanceof PsiClass);
39   }
40
41   protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) {
42     final Document document = editor.getDocument();
43     final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document);
44     if (file == null) return false;
45     PsiElement targetMember = findTargetMember(file, editor);
46     if (targetMember == null) return false;
47     final ChangeSignatureHandler targetHandler = getChangeSignatureHandler(targetMember.getLanguage());
48     if (targetHandler == null) return false;
49     return true;
50   }
51
52   @Nullable
53   private static PsiElement findTargetMember(PsiFile file, Editor editor) {
54     final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
55     final PsiElement targetMember = findTargetMember(element);
56     if (targetMember != null) return targetMember;
57
58     final PsiReference reference = file.findReferenceAt(editor.getCaretModel().getOffset());
59     if (reference == null) return null;
60     return reference.resolve();
61   }
62
63   @Nullable
64   private static PsiElement findTargetMember(@Nullable PsiElement element) {
65     if (element == null) return null;
66     final ChangeSignatureHandler fileHandler = getChangeSignatureHandler(element.getLanguage());
67     if (fileHandler != null) {
68       final PsiElement targetMember = fileHandler.findTargetMember(element);
69       if (targetMember != null) return targetMember;
70     }
71     final PsiReference reference = element.getReference();
72     if (reference == null) return null;
73     return reference.resolve();
74   }
75
76   public RefactoringActionHandler getHandler(DataContext dataContext) {
77     final Language language = LangDataKeys.LANGUAGE.getData(dataContext);
78     if (language != null) {
79       return new RefactoringActionHandler() {
80         public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
81           editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
82           final PsiElement targetMember = findTargetMember(file, editor);
83           if (targetMember == null) return;
84           final ChangeSignatureHandler handler = getChangeSignatureHandler(targetMember.getLanguage());
85           if (handler == null) return;
86           handler.invoke(project, new PsiElement[]{targetMember}, dataContext);
87         }
88
89         public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
90           if (elements.length != 1) return;
91           final PsiElement targetMember = findTargetMember(elements[0]);
92           if (targetMember == null) return;
93           final ChangeSignatureHandler handler = getChangeSignatureHandler(targetMember.getLanguage());
94           if (handler == null) return;
95           handler.invoke(project, new PsiElement[]{targetMember}, dataContext);
96         }
97       };
98     }
99     return null;
100   }
101
102   @Override
103   protected boolean isAvailableForLanguage(Language language) {
104     return getChangeSignatureHandler(language) != null;
105   }
106
107   @Nullable
108   private static ChangeSignatureHandler getChangeSignatureHandler(Language language) {
109     return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getChangeSignatureHandler();
110   }
111 }