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.
18 * Created by IntelliJ IDEA.
22 * To change template for new class use
23 * Code Style | Class Templates options (Tools | IDE Options).
25 package com
.intellij
.refactoring
.introduceField
;
27 import com
.intellij
.codeInsight
.AnnotationUtil
;
28 import com
.intellij
.codeInsight
.ChangeContextUtil
;
29 import com
.intellij
.codeInsight
.TestUtil
;
30 import com
.intellij
.codeInsight
.highlighting
.HighlightManager
;
31 import com
.intellij
.ide
.util
.DirectoryChooserUtil
;
32 import com
.intellij
.ide
.util
.PackageUtil
;
33 import com
.intellij
.openapi
.application
.ApplicationManager
;
34 import com
.intellij
.openapi
.command
.CommandProcessor
;
35 import com
.intellij
.openapi
.diagnostic
.Logger
;
36 import com
.intellij
.openapi
.editor
.Editor
;
37 import com
.intellij
.openapi
.editor
.colors
.EditorColors
;
38 import com
.intellij
.openapi
.editor
.colors
.EditorColorsManager
;
39 import com
.intellij
.openapi
.editor
.markup
.RangeHighlighter
;
40 import com
.intellij
.openapi
.editor
.markup
.TextAttributes
;
41 import com
.intellij
.openapi
.project
.Project
;
42 import com
.intellij
.openapi
.util
.Pass
;
43 import com
.intellij
.openapi
.util
.text
.StringUtil
;
44 import com
.intellij
.openapi
.wm
.WindowManager
;
45 import com
.intellij
.psi
.*;
46 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
47 import com
.intellij
.psi
.codeStyle
.JavaCodeStyleManager
;
48 import com
.intellij
.psi
.impl
.source
.codeStyle
.CodeEditUtil
;
49 import com
.intellij
.psi
.search
.GlobalSearchScope
;
50 import com
.intellij
.psi
.util
.PsiTreeUtil
;
51 import com
.intellij
.psi
.util
.PsiUtil
;
52 import com
.intellij
.refactoring
.IntroduceHandlerBase
;
53 import com
.intellij
.refactoring
.RefactoringActionHandler
;
54 import com
.intellij
.refactoring
.RefactoringBundle
;
55 import com
.intellij
.refactoring
.introduceVariable
.IntroduceVariableBase
;
56 import com
.intellij
.refactoring
.rename
.RenameJavaVariableProcessor
;
57 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
58 import com
.intellij
.refactoring
.util
.EnumConstantsUtil
;
59 import com
.intellij
.refactoring
.util
.RefactoringUtil
;
60 import com
.intellij
.refactoring
.util
.occurences
.OccurenceManager
;
61 import com
.intellij
.util
.IncorrectOperationException
;
62 import org
.jetbrains
.annotations
.NonNls
;
63 import org
.jetbrains
.annotations
.NotNull
;
64 import org
.jetbrains
.annotations
.Nullable
;
66 import java
.util
.ArrayList
;
67 import java
.util
.HashMap
;
68 import java
.util
.List
;
70 public abstract class BaseExpressionToFieldHandler
extends IntroduceHandlerBase
implements RefactoringActionHandler
{
71 private static final Logger LOG
= Logger
.getInstance("#com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler");
73 public enum InitializationPlace
{
80 private PsiClass myParentClass
;
82 protected boolean invokeImpl(final Project project
, @NotNull final PsiExpression selectedExpr
, final Editor editor
) {
83 final PsiElement element
= getPhysicalElement(selectedExpr
);
85 final PsiFile file
= element
.getContainingFile();
86 LOG
.assertTrue(file
!= null, "expr.getContainingFile() == null");
88 if (LOG
.isDebugEnabled()) {
89 LOG
.debug("expression:" + selectedExpr
);
92 myParentClass
= getParentClass(selectedExpr
);
93 if (myParentClass
== null) {
94 if (JspPsiUtil
.isInJspFile(file
)) {
95 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactoringBundle
.message("error.not.supported.for.jsp", getRefactoringName()),
96 getRefactoringName(), getHelpID());
100 LOG
.assertTrue(false);
105 if (!validClass(myParentClass
, editor
)) {
109 PsiType tempType
= getTypeByExpression(selectedExpr
);
110 if (tempType
== null) {
111 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("unknown.expression.type"));
112 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, getRefactoringName(), getHelpID());
116 if (PsiType
.VOID
.equals(tempType
)) {
117 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("selected.expression.has.void.type"));
118 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, getRefactoringName(), getHelpID());
123 if (!CommonRefactoringUtil
.checkReadOnlyStatus(project
, file
)) return false;
125 final PsiClass parentClass
= myParentClass
;
126 final OccurenceManager occurenceManager
= createOccurenceManager(selectedExpr
, parentClass
);
127 final PsiExpression
[] occurrences
= occurenceManager
.getOccurences();
128 final PsiElement anchorStatementIfAll
= occurenceManager
.getAnchorStatementForAll();
130 List
<RangeHighlighter
> highlighters
= null;
131 if (editor
!= null) {
132 highlighters
= RefactoringUtil
.highlightAllOccurences(project
, occurrences
, editor
);
135 PsiElement tempAnchorElement
= RefactoringUtil
.getParentExpressionAnchorElement(selectedExpr
);
137 final Settings settings
=
138 showRefactoringDialog(project
, editor
, myParentClass
, selectedExpr
, tempType
,
139 occurrences
, tempAnchorElement
, anchorStatementIfAll
);
141 if (settings
== null) return false;
143 if (settings
.getForcedType() != null) {
144 tempType
= settings
.getForcedType();
146 final PsiType type
= tempType
;
148 final String fieldName
= settings
.getFieldName();
149 final PsiElement anchorElementIfOne
= tempAnchorElement
;
150 final boolean replaceAll
= settings
.isReplaceAll();
152 tempAnchorElement
= anchorStatementIfAll
;
154 final PsiElement anchorElement
= tempAnchorElement
;
157 if (editor
!= null) {
158 HighlightManager highlightManager
= HighlightManager
.getInstance(project
);
159 for (RangeHighlighter highlighter
: highlighters
) {
160 highlightManager
.removeSegmentHighlighter(editor
, highlighter
);
164 PsiElement anchor
= getNormalizedAnchor(anchorElement
);
166 boolean tempDeleteSelf
= false;
167 if (element
.getParent() instanceof PsiExpressionStatement
&& anchor
.equals(anchorElement
)) {
168 PsiStatement statement
= (PsiStatement
)element
.getParent();
169 if (statement
.getParent() instanceof PsiCodeBlock
) {
170 tempDeleteSelf
= true;
173 final boolean deleteSelf
= tempDeleteSelf
;
175 final Runnable runnable
= new Runnable() {
178 PsiExpression expr
= selectedExpr
;
179 InitializationPlace initializerPlace
= settings
.getInitializerPlace();
180 final PsiLocalVariable localVariable
= settings
.getLocalVariable();
181 final boolean deleteLocalVariable
= settings
.isDeleteLocalVariable();
182 PsiExpression initializer
;
183 if (localVariable
!= null) {
184 initializer
= localVariable
.getInitializer();
190 final PsiMethod enclosingConstructor
= getEnclosingConstructor(myParentClass
, anchorElement
);
191 final PsiClass destClass
= settings
.getDestinationClass() == null ? myParentClass
: settings
.getDestinationClass();
193 if (!CommonRefactoringUtil
.checkReadOnlyStatus(project
, destClass
.getContainingFile())) return;
195 ChangeContextUtil
.encodeContextInfo(initializer
, true);
196 PsiField field
= settings
.isIntroduceEnumConstant() ? EnumConstantsUtil
.createEnumConstant(destClass
, fieldName
, initializer
) : createField(fieldName
, type
, initializer
, initializerPlace
== InitializationPlace
.IN_FIELD_DECLARATION
&& initializer
!= null);
197 if (!settings
.isIntroduceEnumConstant()) {
198 PsiUtil
.setModifierProperty(field
, settings
.getFieldVisibility(), true);
199 if (settings
.isDeclareFinal()) {
200 PsiUtil
.setModifierProperty(field
, PsiModifier
.FINAL
, true);
202 if (settings
.isDeclareStatic()) {
203 PsiUtil
.setModifierProperty(field
, PsiModifier
.STATIC
, true);
205 if (settings
.isAnnotateAsNonNls()) {
206 PsiAnnotation annotation
= JavaPsiFacade
.getInstance(myParentClass
.getProject()).getElementFactory()
207 .createAnnotationFromText("@" + AnnotationUtil
.NON_NLS
, myParentClass
);
208 field
.getModifierList().addAfter(annotation
, null);
209 JavaCodeStyleManager
.getInstance(myParentClass
.getProject()).shortenClassReferences(field
.getModifierList());
212 PsiElement finalAnchorElement
= null;
213 if (destClass
== myParentClass
) {
214 for (finalAnchorElement
= anchorElement
;
215 finalAnchorElement
!= null && finalAnchorElement
.getParent() != destClass
;
216 finalAnchorElement
= finalAnchorElement
.getParent()) {
220 PsiMember anchorMember
= finalAnchorElement
instanceof PsiMember ?
(PsiMember
)finalAnchorElement
: null;
222 if ((anchorMember
instanceof PsiField
) &&
223 anchorMember
.hasModifierProperty(PsiModifier
.STATIC
) == field
.hasModifierProperty(PsiModifier
.STATIC
)) {
224 field
= (PsiField
)destClass
.addBefore(field
, anchorMember
);
226 else if (anchorMember
instanceof PsiClassInitializer
) {
227 field
= (PsiField
)destClass
.addBefore(field
, anchorMember
);
228 destClass
.addBefore(CodeEditUtil
.createLineFeed(field
.getManager()), anchorMember
);
231 field
= (PsiField
)destClass
.add(field
);
233 PsiStatement assignStatement
= null;
234 PsiElement anchorElementHere
= null;
235 if (initializerPlace
== InitializationPlace
.IN_CURRENT_METHOD
&& initializer
!= null ||
236 initializerPlace
== InitializationPlace
.IN_CONSTRUCTOR
&& enclosingConstructor
!= null && initializer
!= null) {
238 if (enclosingConstructor
!= null) {
239 final PsiElement anchorInConstructor
= occurenceManager
.getAnchorStatementForAllInScope(enclosingConstructor
);
240 anchorElementHere
= anchorInConstructor
!= null ? anchorInConstructor
: anchorStatementIfAll
;
243 anchorElementHere
= anchorStatementIfAll
;
247 anchorElementHere
= anchorElementIfOne
;
249 assignStatement
= createAssignment(field
, initializer
, anchorElementHere
);
250 if (!IntroduceVariableBase
.isLoopOrIf(anchorElementHere
.getParent())) {
251 anchorElementHere
.getParent().addBefore(assignStatement
, getNormalizedAnchor(anchorElementHere
));
254 if (initializerPlace
== InitializationPlace
.IN_CONSTRUCTOR
&& initializer
!= null) {
255 addInitializationToConstructors(initializer
, field
, enclosingConstructor
);
257 if (initializerPlace
== InitializationPlace
.IN_SETUP_METHOD
&& initializer
!= null) {
258 addInitializationToSetUp(initializer
, field
, occurenceManager
, replaceAll
);
260 if (expr
.getParent() instanceof PsiParenthesizedExpression
) {
261 expr
= (PsiExpression
)expr
.getParent();
264 element
.getParent().delete();
268 List
<PsiElement
> array
= new ArrayList
<PsiElement
>();
269 for (PsiExpression occurrence
: occurrences
) {
270 if (occurrence
instanceof PsiExpression
) {
271 occurrence
= RefactoringUtil
.outermostParenthesizedExpression(occurrence
);
273 if (deleteSelf
&& occurrence
.equals(expr
)) continue;
274 final PsiElement replaced
= RefactoringUtil
.replaceOccurenceWithFieldRef(occurrence
, field
, destClass
);
275 if (replaced
!= null) {
280 if (editor
!= null) {
281 if (!ApplicationManager
.getApplication().isUnitTestMode()) {
282 PsiElement
[] exprsToHighlight
= array
.toArray(new PsiElement
[array
.size()]);
283 HighlightManager highlightManager
= HighlightManager
.getInstance(project
);
284 highlightManager
.addOccurrenceHighlights(editor
, exprsToHighlight
, highlightAttributes(), true, null);
285 WindowManager
.getInstance().getStatusBar(project
).setInfo(RefactoringBundle
.message("press.escape.to.remove.the.highlighting"));
291 expr
= RefactoringUtil
.outermostParenthesizedExpression(expr
);
292 RefactoringUtil
.replaceOccurenceWithFieldRef(expr
, field
, destClass
);
296 if (anchorElementHere
!= null && IntroduceVariableBase
.isLoopOrIf(anchorElementHere
.getParent())) {
297 IntroduceVariableBase
.putStatementInLoopBody(assignStatement
, anchorElementHere
.getParent(), anchorElementHere
);
301 if (localVariable
!= null) {
302 if (deleteLocalVariable
) {
303 localVariable
.normalizeDeclaration();
304 localVariable
.getParent().delete();
308 ChangeContextUtil
.clearContextInfo(initializer
);
310 catch (IncorrectOperationException e
) {
316 CommandProcessor
.getInstance().executeCommand(
320 ApplicationManager
.getApplication().runWriteAction(runnable
);
323 getRefactoringName(), null
329 private static PsiElement
getPhysicalElement(final PsiExpression selectedExpr
) {
330 PsiElement element
= selectedExpr
.getUserData(ElementToWorkOn
.PARENT
);
331 if (element
== null) element
= selectedExpr
;
335 private static TextAttributes
highlightAttributes() {
336 return EditorColorsManager
.getInstance().getGlobalScheme().getAttributes(
337 EditorColors
.SEARCH_RESULT_ATTRIBUTES
341 protected abstract OccurenceManager
createOccurenceManager(PsiExpression selectedExpr
, PsiClass parentClass
);
343 protected final PsiClass
getParentClass() {
344 return myParentClass
;
347 protected abstract boolean validClass(PsiClass parentClass
, Editor editor
);
349 protected boolean isStaticField() {
353 private static PsiElement
getNormalizedAnchor(PsiElement anchorElement
) {
354 PsiElement child
= anchorElement
;
355 while (child
!= null) {
356 PsiElement prev
= child
.getPrevSibling();
357 if (RefactoringUtil
.isExpressionAnchorElement(prev
)) break;
358 if (prev
instanceof PsiJavaToken
&& ((PsiJavaToken
)prev
).getTokenType() == JavaTokenType
.LBRACE
) break;
362 child
= PsiTreeUtil
.skipSiblingsForward(child
, PsiWhiteSpace
.class, PsiComment
.class);
368 anchor
= anchorElement
;
373 protected abstract String
getHelpID();
375 protected abstract Settings
showRefactoringDialog(Project project
, Editor editor
, PsiClass parentClass
, PsiExpression expr
,
376 PsiType type
, PsiExpression
[] occurences
, PsiElement anchorElement
,
377 PsiElement anchorElementIfAll
);
380 private static PsiType
getTypeByExpression(PsiExpression expr
) {
381 return RefactoringUtil
.getTypeByExpressionWithExpectedType(expr
);
384 public PsiClass
getParentClass(PsiExpression initializerExpression
) {
385 PsiElement element
= initializerExpression
.getUserData(ElementToWorkOn
.PARENT
);
386 if (element
== null) element
= initializerExpression
.getParent();
387 PsiElement parent
= element
;
388 while (parent
!= null) {
389 if (parent
instanceof PsiClass
&& !(parent
instanceof PsiAnonymousClass
)) {
390 return (PsiClass
)parent
;
392 parent
= parent
.getParent();
397 public static PsiMethod
getEnclosingConstructor(PsiClass parentClass
, PsiElement element
) {
398 if (element
== null) return null;
399 final PsiMethod
[] constructors
= parentClass
.getConstructors();
400 for (PsiMethod constructor
: constructors
) {
401 if (PsiTreeUtil
.isAncestor(constructor
, element
, false)) return constructor
;
406 private void addInitializationToSetUp(final PsiExpression initializer
,
407 final PsiField field
,
408 final OccurenceManager occurenceManager
, final boolean replaceAll
) throws IncorrectOperationException
{
409 final PsiMethod setupMethod
= TestUtil
.findSetUpMethod(myParentClass
);
411 assert setupMethod
!= null;
413 PsiElement anchor
= null;
414 if (PsiTreeUtil
.isAncestor(setupMethod
, initializer
, true)) {
416 ? occurenceManager
.getAnchorStatementForAllInScope(setupMethod
)
417 : PsiTreeUtil
.getParentOfType(initializer
, PsiStatement
.class);
420 final PsiExpressionStatement expressionStatement
=
421 (PsiExpressionStatement
)JavaPsiFacade
.getInstance(myParentClass
.getProject()).getElementFactory()
422 .createStatementFromText(field
.getName() + "= expr;", null);
423 PsiAssignmentExpression expr
= (PsiAssignmentExpression
)expressionStatement
.getExpression();
424 final PsiExpression rExpression
= expr
.getRExpression();
425 LOG
.assertTrue(rExpression
!= null);
426 rExpression
.replace(initializer
);
428 final PsiCodeBlock body
= setupMethod
.getBody();
430 body
.addBefore(expressionStatement
, anchor
);
433 private void addInitializationToConstructors(PsiExpression initializerExpression
, PsiField field
, PsiMethod enclosingConstructor
) {
435 PsiClass aClass
= field
.getContainingClass();
436 PsiMethod
[] constructors
= aClass
.getConstructors();
438 boolean added
= false;
439 for (PsiMethod constructor
: constructors
) {
440 if (constructor
== enclosingConstructor
) continue;
441 PsiCodeBlock body
= constructor
.getBody();
442 if (body
== null) continue;
443 PsiStatement
[] statements
= body
.getStatements();
444 if (statements
.length
> 0) {
445 PsiStatement first
= statements
[0];
446 if (first
instanceof PsiExpressionStatement
) {
447 PsiExpression expression
= ((PsiExpressionStatement
)first
).getExpression();
448 if (expression
instanceof PsiMethodCallExpression
) {
449 @NonNls String text
= ((PsiMethodCallExpression
)expression
).getMethodExpression().getText();
450 if ("this".equals(text
)) {
456 PsiStatement assignment
= createAssignment(field
, initializerExpression
, body
.getLastChild());
457 assignment
= (PsiStatement
) body
.add(assignment
);
458 ChangeContextUtil
.decodeContextInfo(assignment
, field
.getContainingClass(),
459 RefactoringUtil
.createThisExpression(field
.getManager(), null));
462 if (!added
&& enclosingConstructor
== null) {
463 PsiElementFactory factory
= JavaPsiFacade
.getInstance(field
.getProject()).getElementFactory();
464 PsiMethod constructor
= (PsiMethod
)aClass
.add(factory
.createConstructor());
465 final PsiCodeBlock body
= constructor
.getBody();
466 PsiStatement assignment
= createAssignment(field
, initializerExpression
, body
.getLastChild());
467 assignment
= (PsiStatement
) body
.add(assignment
);
468 ChangeContextUtil
.decodeContextInfo(assignment
, field
.getContainingClass(),
469 RefactoringUtil
.createThisExpression(field
.getManager(), null));
472 catch (IncorrectOperationException e
) {
477 private PsiField
createField(String fieldName
, PsiType type
, PsiExpression initializerExpr
, boolean includeInitializer
) {
478 @NonNls StringBuilder pattern
= new StringBuilder();
479 pattern
.append("private int ");
480 pattern
.append(fieldName
);
481 if (includeInitializer
) {
482 pattern
.append("=0");
485 PsiManager psiManager
= myParentClass
.getManager();
486 PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
488 PsiField field
= factory
.createFieldFromText(pattern
.toString(), null);
489 field
= (PsiField
)CodeStyleManager
.getInstance(psiManager
.getProject()).reformat(field
);
490 field
.getTypeElement().replace(factory
.createTypeElement(type
));
491 if (includeInitializer
) {
492 field
.getInitializer().replace(initializerExpr
);
496 catch (IncorrectOperationException e
) {
502 private PsiStatement
createAssignment(PsiField field
, PsiExpression initializerExpr
, PsiElement context
) {
504 @NonNls String pattern
= "x=0;";
505 PsiManager psiManager
= myParentClass
.getManager();
506 PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
507 PsiExpressionStatement statement
= (PsiExpressionStatement
)factory
.createStatementFromText(pattern
, null);
508 statement
= (PsiExpressionStatement
)CodeStyleManager
.getInstance(psiManager
.getProject()).reformat(statement
);
510 PsiAssignmentExpression expr
= (PsiAssignmentExpression
)statement
.getExpression();
511 final PsiExpression rExpression
= expr
.getRExpression();
512 LOG
.assertTrue(rExpression
!= null);
513 rExpression
.replace(initializerExpr
);
514 final PsiReferenceExpression fieldReference
= RenameJavaVariableProcessor
.createMemberReference(field
, context
);
515 expr
.getLExpression().replace(fieldReference
);
519 catch (IncorrectOperationException e
) {
526 protected Pass
<ElementToWorkOn
> getElementProcessor(final Project project
, final Editor editor
) {
527 return new Pass
<ElementToWorkOn
>() {
529 public void pass(final ElementToWorkOn elementToWorkOn
) {
530 if (elementToWorkOn
== null) return;
532 if (elementToWorkOn
.getExpression() == null) {
533 final PsiLocalVariable localVariable
= elementToWorkOn
.getLocalVariable();
534 final boolean result
= invokeImpl(project
, localVariable
, editor
);
536 editor
.getSelectionModel().removeSelection();
539 else if (invokeImpl(project
, elementToWorkOn
.getExpression(), editor
)) {
540 editor
.getSelectionModel().removeSelection();
546 protected abstract String
getRefactoringName();
548 public static class Settings
{
549 private final String myFieldName
;
550 private final PsiType myForcedType
;
552 private final boolean myReplaceAll
;
553 private final boolean myDeclareStatic
;
554 private final boolean myDeclareFinal
;
555 private final InitializationPlace myInitializerPlace
;
556 @Modifier private final String myVisibility
;
557 private final boolean myDeleteLocalVariable
;
558 private final TargetDestination myTargetClass
;
559 private final boolean myAnnotateAsNonNls
;
560 private final boolean myIntroduceEnumConstant
;
562 public PsiLocalVariable
getLocalVariable() {
563 return myLocalVariable
;
566 public boolean isDeleteLocalVariable() {
567 return myDeleteLocalVariable
;
570 private final PsiLocalVariable myLocalVariable
;
572 public String
getFieldName() {
576 public boolean isDeclareStatic() {
577 return myDeclareStatic
;
580 public boolean isDeclareFinal() {
581 return myDeclareFinal
;
584 public InitializationPlace
getInitializerPlace() {
585 return myInitializerPlace
;
589 public String
getFieldVisibility() {
594 public PsiClass
getDestinationClass() {
595 return myTargetClass
!= null ? myTargetClass
.getTargetClass() : null;
598 public PsiType
getForcedType() {
602 public boolean isReplaceAll() {
606 public boolean isAnnotateAsNonNls() {
607 return myAnnotateAsNonNls
;
610 public boolean isIntroduceEnumConstant() {
611 return myIntroduceEnumConstant
;
614 public Settings(String fieldName
, boolean replaceAll
,
615 boolean declareStatic
, boolean declareFinal
,
616 InitializationPlace initializerPlace
, @Modifier String visibility
, PsiLocalVariable localVariableToRemove
, PsiType forcedType
,
617 boolean deleteLocalVariable
,
618 TargetDestination targetDestination
,
619 final boolean annotateAsNonNls
,
620 final boolean introduceEnumConstant
) {
622 myFieldName
= fieldName
;
623 myReplaceAll
= replaceAll
;
624 myDeclareStatic
= declareStatic
;
625 myDeclareFinal
= declareFinal
;
626 myInitializerPlace
= initializerPlace
;
627 myVisibility
= visibility
;
628 myLocalVariable
= localVariableToRemove
;
629 myDeleteLocalVariable
= deleteLocalVariable
;
630 myForcedType
= forcedType
;
631 myTargetClass
= targetDestination
;
632 myAnnotateAsNonNls
= annotateAsNonNls
;
633 myIntroduceEnumConstant
= introduceEnumConstant
;
636 public Settings(String fieldName
, boolean replaceAll
,
637 boolean declareStatic
, boolean declareFinal
,
638 InitializationPlace initializerPlace
, @Modifier String visibility
, PsiLocalVariable localVariableToRemove
, PsiType forcedType
,
639 boolean deleteLocalVariable
,
640 PsiClass targetClass
,
641 final boolean annotateAsNonNls
,
642 final boolean introduceEnumConstant
) {
644 this(fieldName
, replaceAll
, declareStatic
, declareFinal
, initializerPlace
, visibility
, localVariableToRemove
, forcedType
, deleteLocalVariable
, new TargetDestination(targetClass
), annotateAsNonNls
, introduceEnumConstant
);
649 public static class TargetDestination
{
650 private final String myQualifiedName
;
651 private final Project myProject
;
653 private PsiClass myParentClass
;
654 private PsiClass myTargetClass
;
656 public TargetDestination(String qualifiedName
, PsiClass parentClass
) {
657 myQualifiedName
= qualifiedName
;
658 myParentClass
= parentClass
;
659 myProject
= parentClass
.getProject();
662 public TargetDestination(@NotNull PsiClass targetClass
) {
663 myTargetClass
= targetClass
;
664 myQualifiedName
= targetClass
.getQualifiedName();
665 myProject
= targetClass
.getProject();
669 public PsiClass
getTargetClass() {
670 if (myTargetClass
!= null) return myTargetClass
;
671 final String packageName
= StringUtil
.getPackageName(myQualifiedName
);
672 PsiPackage psiPackage
= JavaPsiFacade
.getInstance(myProject
).findPackage(packageName
);
673 final PsiDirectory psiDirectory
;
674 if (psiPackage
!= null) {
675 final PsiDirectory
[] directories
= psiPackage
.getDirectories(GlobalSearchScope
.allScope(myProject
));
676 psiDirectory
= directories
.length
> 1 ? DirectoryChooserUtil
.chooseDirectory(directories
, null, myProject
, new HashMap
<PsiDirectory
, String
>()) : directories
[0];
678 psiDirectory
= PackageUtil
.findOrCreateDirectoryForPackage(myProject
, packageName
, myParentClass
.getContainingFile().getContainingDirectory(), false);
680 final String shortName
= StringUtil
.getShortName(myQualifiedName
);
681 myTargetClass
= psiDirectory
!= null ? JavaDirectoryService
.getInstance().createClass(psiDirectory
, shortName
) : null;
682 return myTargetClass
;