update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / introduceField / IntroduceConstantHandler.java
blob8360a956ca44c948c407200ac1ba96ed3809b471
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.refactoring.introduceField;
18 import com.intellij.codeInsight.highlighting.HighlightManager;
19 import com.intellij.openapi.actionSystem.DataContext;
20 import com.intellij.openapi.editor.Editor;
21 import com.intellij.openapi.editor.colors.EditorColors;
22 import com.intellij.openapi.editor.colors.EditorColorsManager;
23 import com.intellij.openapi.editor.markup.RangeHighlighter;
24 import com.intellij.openapi.editor.markup.TextAttributes;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.util.TextRange;
27 import com.intellij.openapi.wm.WindowManager;
28 import com.intellij.psi.*;
29 import com.intellij.psi.util.PsiTreeUtil;
30 import com.intellij.psi.util.PsiUtil;
31 import com.intellij.refactoring.HelpID;
32 import com.intellij.refactoring.RefactoringBundle;
33 import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
34 import com.intellij.refactoring.util.CommonRefactoringUtil;
35 import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
36 import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager;
37 import com.intellij.refactoring.util.occurences.OccurenceManager;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40 import java.util.ArrayList;
42 public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
43 public static final String REFACTORING_NAME = RefactoringBundle.message("introduce.constant.title");
45 protected String getHelpID() {
46 return HelpID.INTRODUCE_CONSTANT;
49 public void invoke(Project project, PsiExpression[] expressions) {
50 for (PsiExpression expression : expressions) {
51 final PsiFile file = expression.getContainingFile();
52 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return;
54 PsiDocumentManager.getInstance(project).commitAllDocuments();
55 super.invoke(project, expressions, null);
58 public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) {
59 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return;
61 PsiDocumentManager.getInstance(project).commitAllDocuments();
62 ElementToWorkOn.processElementToWorkOn(editor, file, REFACTORING_NAME, getHelpID(), project, getElementProcessor(project, editor));
65 protected boolean invokeImpl(Project project, final PsiLocalVariable localVariable, Editor editor) {
66 final LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, true);
67 return localToFieldHandler.convertLocalToField(localVariable, editor);
71 protected Settings showRefactoringDialog(Project project,
72 Editor editor,
73 PsiClass parentClass,
74 PsiExpression expr,
75 PsiType type,
76 PsiExpression[] occurences,
77 PsiElement anchorElement,
78 PsiElement anchorElementIfAll) {
79 PsiLocalVariable localVariable = null;
80 if (expr instanceof PsiReferenceExpression) {
81 PsiElement ref = ((PsiReferenceExpression)expr).resolve();
82 if (ref instanceof PsiLocalVariable) {
83 localVariable = (PsiLocalVariable)ref;
87 if (localVariable == null) {
88 final PsiElement errorElement = isStaticFinalInitializer(expr);
89 if (errorElement != null) {
90 String message =
91 RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("selected.expression.cannot.be.a.constant.initializer"));
92 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, getHelpID());
93 highlightError(project, editor, errorElement);
94 return null;
97 else {
98 final PsiExpression initializer = localVariable.getInitializer();
99 if (initializer == null) {
100 String message = RefactoringBundle
101 .getCannotRefactorMessage(RefactoringBundle.message("variable.does.not.have.an.initializer", localVariable.getName()));
102 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, getHelpID());
103 return null;
105 final PsiElement errorElement = isStaticFinalInitializer(initializer);
106 if (errorElement != null) {
107 String message = RefactoringBundle.getCannotRefactorMessage(
108 RefactoringBundle.message("initializer.for.variable.cannot.be.a.constant.initializer", localVariable.getName()));
109 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, getHelpID());
110 highlightError(project, editor, errorElement);
111 return null;
115 IntroduceConstantDialog dialog =
116 new IntroduceConstantDialog(project, parentClass, expr, localVariable, false, occurences, getParentClass(),
117 new TypeSelectorManagerImpl(project, type, expr, occurences));
118 dialog.show();
119 if (!dialog.isOK()) {
120 if (occurences.length > 1) {
121 WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
123 return null;
125 return new Settings(dialog.getEnteredName(), dialog.isReplaceAllOccurrences(), true, true,
126 BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, dialog.getFieldVisibility(), localVariable,
127 dialog.getSelectedType(), dialog.isDeleteVariable(), dialog.getDestinationClass(), dialog.isAnnotateAsNonNls(),
128 dialog.introduceEnumConstant());
131 private static void highlightError(Project project, Editor editor, PsiElement errorElement) {
132 if (editor != null) {
133 final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
134 final TextRange textRange = errorElement.getTextRange();
135 HighlightManager.getInstance(project).addRangeHighlight(editor, textRange.getStartOffset(), textRange.getEndOffset(), attributes, true, new ArrayList<RangeHighlighter>());
139 protected String getRefactoringName() {
140 return REFACTORING_NAME;
143 @Nullable
144 private PsiElement isStaticFinalInitializer(PsiExpression expr) {
145 PsiClass parentClass = getParentClass(expr);
146 if (parentClass == null) return null;
147 IsStaticFinalInitializerExpression visitor = new IsStaticFinalInitializerExpression(parentClass, expr);
148 expr.accept(visitor);
149 return visitor.getElementReference();
152 protected OccurenceManager createOccurenceManager(final PsiExpression selectedExpr, final PsiClass parentClass) {
153 return new ExpressionOccurenceManager(selectedExpr, parentClass, null);
156 private static class IsStaticFinalInitializerExpression extends ClassMemberReferencesVisitor {
157 private PsiElement myElementReference = null;
158 private final PsiExpression myInitializer;
160 public IsStaticFinalInitializerExpression(PsiClass aClass, PsiExpression initializer) {
161 super(aClass);
162 myInitializer = initializer;
165 @Override
166 public void visitReferenceExpression(PsiReferenceExpression expression) {
167 final PsiElement psiElement = expression.resolve();
168 if ((psiElement instanceof PsiLocalVariable || psiElement instanceof PsiParameter) &&
169 !PsiTreeUtil.isAncestor(myInitializer, psiElement, false)) {
170 myElementReference = expression;
172 else {
173 super.visitReferenceExpression(expression);
178 protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) {
179 if (!classMember.hasModifierProperty(PsiModifier.STATIC)) {
180 myElementReference = classMemberReference;
184 @Override
185 public void visitElement(PsiElement element) {
186 if (myElementReference != null) return;
187 super.visitElement(element);
190 @Nullable
191 public PsiElement getElementReference() {
192 return myElementReference;
196 public PsiClass getParentClass(PsiExpression initializerExpression) {
197 final PsiType type = initializerExpression.getType();
199 if (type != null && PsiUtil.isConstantExpression(initializerExpression)) {
200 if (type instanceof PsiPrimitiveType ||
201 PsiType.getJavaLangString(initializerExpression.getManager(), initializerExpression.getResolveScope()).equals(type)) {
202 return super.getParentClass(initializerExpression);
206 PsiElement parent = initializerExpression.getUserData(ElementToWorkOn.PARENT);
207 if (parent == null) parent = initializerExpression;
208 PsiClass aClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class);
209 while (aClass != null) {
210 if (aClass.hasModifierProperty(PsiModifier.STATIC)) return aClass;
211 if (aClass.getParent() instanceof PsiJavaFile) return aClass;
212 aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
214 return null;
217 protected boolean validClass(PsiClass parentClass, Editor editor) {
218 return true;
221 protected boolean isStaticField() {
222 return true;