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
.openapi
.actionSystem
.DataContext
;
19 import com
.intellij
.openapi
.editor
.Editor
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.wm
.WindowManager
;
22 import com
.intellij
.psi
.*;
23 import com
.intellij
.psi
.util
.PsiTreeUtil
;
24 import com
.intellij
.psi
.util
.PsiUtil
;
25 import com
.intellij
.refactoring
.HelpID
;
26 import com
.intellij
.refactoring
.RefactoringBundle
;
27 import com
.intellij
.refactoring
.ui
.TypeSelectorManagerImpl
;
28 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
29 import com
.intellij
.refactoring
.util
.occurences
.*;
30 import org
.jetbrains
.annotations
.NotNull
;
32 public class IntroduceFieldHandler
extends BaseExpressionToFieldHandler
{
34 public static final String REFACTORING_NAME
= RefactoringBundle
.message("introduce.field.title");
35 private static final MyOccurenceFilter MY_OCCURENCE_FILTER
= new MyOccurenceFilter();
37 protected String
getRefactoringName() {
38 return REFACTORING_NAME
;
41 protected boolean validClass(PsiClass parentClass
, Editor editor
) {
42 if (parentClass
.isInterface()) {
43 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("cannot.introduce.field.in.interface"));
44 CommonRefactoringUtil
.showErrorHint(parentClass
.getProject(), editor
, message
, REFACTORING_NAME
, getHelpID());
52 protected String
getHelpID() {
53 return HelpID
.INTRODUCE_FIELD
;
56 public void invoke(@NotNull final Project project
, final Editor editor
, PsiFile file
, DataContext dataContext
) {
57 if (!CommonRefactoringUtil
.checkReadOnlyStatus(project
, file
)) return;
58 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
60 ElementToWorkOn
.processElementToWorkOn(editor
, file
, REFACTORING_NAME
, HelpID
.INTRODUCE_FIELD
, project
, getElementProcessor(project
, editor
));
63 protected Settings
showRefactoringDialog(Project project
, Editor editor
, PsiClass parentClass
, PsiExpression expr
,
65 PsiExpression
[] occurences
, PsiElement anchorElement
, PsiElement anchorElementIfAll
) {
66 final PsiMethod containingMethod
= PsiTreeUtil
.getParentOfType(expr
, PsiMethod
.class);
67 PsiElement element
= expr
.getUserData(ElementToWorkOn
.PARENT
);
68 if (element
== null) element
= expr
;
69 final PsiModifierListOwner staticParentElement
= PsiUtil
.getEnclosingStaticElement(element
, parentClass
);
70 boolean declareStatic
= staticParentElement
!= null;
72 boolean isInSuperOrThis
= false;
74 for (int i
= 0; !declareStatic
&& i
< occurences
.length
; i
++) {
75 PsiExpression occurence
= occurences
[i
];
76 isInSuperOrThis
= isInSuperOrThis(occurence
);
77 declareStatic
= isInSuperOrThis
;
81 PsiLocalVariable localVariable
= null;
82 if (expr
instanceof PsiReferenceExpression
) {
83 PsiElement ref
= ((PsiReferenceExpression
)expr
).resolve();
84 if (ref
instanceof PsiLocalVariable
) {
85 localVariable
= (PsiLocalVariable
)ref
;
89 int occurencesNumber
= occurences
.length
;
90 final boolean currentMethodConstructor
= containingMethod
!= null && containingMethod
.isConstructor();
91 final boolean allowInitInMethod
= (!currentMethodConstructor
|| !isInSuperOrThis
) && anchorElement
instanceof PsiStatement
;
92 final boolean allowInitInMethodIfAll
= (!currentMethodConstructor
|| !isInSuperOrThis
) && anchorElementIfAll
instanceof PsiStatement
;
93 IntroduceFieldDialog dialog
= new IntroduceFieldDialog(
94 project
, parentClass
, expr
, localVariable
,
95 currentMethodConstructor
,
96 false, declareStatic
, occurencesNumber
,
97 allowInitInMethod
, allowInitInMethodIfAll
,
98 new TypeSelectorManagerImpl(project
, type
, expr
, occurences
)
102 if (!dialog
.isOK()) {
103 if (occurencesNumber
> 1) {
104 WindowManager
.getInstance().getStatusBar(project
).setInfo(RefactoringBundle
.message("press.escape.to.remove.the.highlighting"));
109 if (!dialog
.isDeleteVariable()) {
110 localVariable
= null;
114 return new Settings(dialog
.getEnteredName(), dialog
.isReplaceAllOccurrences(),
115 declareStatic
, dialog
.isDeclareFinal(),
116 dialog
.getInitializerPlace(), dialog
.getFieldVisibility(),
118 dialog
.getFieldType(), localVariable
!= null, (TargetDestination
)null, false, false);
121 private static boolean isInSuperOrThis(PsiExpression occurence
) {
122 return !NotInSuperCallOccurenceFilter
.INSTANCE
.isOK(occurence
) || !NotInThisCallFilter
.INSTANCE
.isOK(occurence
);
125 protected OccurenceManager
createOccurenceManager(final PsiExpression selectedExpr
, final PsiClass parentClass
) {
126 final OccurenceFilter occurenceFilter
= isInSuperOrThis(selectedExpr
) ?
null : MY_OCCURENCE_FILTER
;
127 return new ExpressionOccurenceManager(selectedExpr
, parentClass
, occurenceFilter
, true);
130 protected boolean invokeImpl(Project project
, PsiLocalVariable localVariable
, Editor editor
) {
131 LocalToFieldHandler localToFieldHandler
= new LocalToFieldHandler(project
, false);
132 return localToFieldHandler
.convertLocalToField(localVariable
, editor
);
135 private static class MyOccurenceFilter
implements OccurenceFilter
{
136 public boolean isOK(PsiExpression occurence
) {
137 return !isInSuperOrThis(occurence
);