update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / introduceField / BaseExpressionToFieldHandler.java
bloba5aae5d453b6e4d5e9288e7eb5216306e1d8bd9f
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.
18 * Created by IntelliJ IDEA.
19 * User: dsl
20 * Date: 29.05.2002
21 * Time: 13:05:34
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 {
74 IN_CURRENT_METHOD,
75 IN_FIELD_DECLARATION,
76 IN_CONSTRUCTOR,
77 IN_SETUP_METHOD
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());
97 return false;
99 else {
100 LOG.assertTrue(false);
101 return false;
105 if (!validClass(myParentClass, editor)) {
106 return false;
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());
113 return false;
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());
119 return false;
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();
151 if (replaceAll) {
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() {
176 public void run() {
177 try {
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();
186 else {
187 initializer = expr;
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);
230 else {
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) {
237 if (replaceAll) {
238 if (enclosingConstructor != null) {
239 final PsiElement anchorInConstructor = occurenceManager.getAnchorStatementForAllInScope(enclosingConstructor);
240 anchorElementHere = anchorInConstructor != null ? anchorInConstructor : anchorStatementIfAll;
242 else {
243 anchorElementHere = anchorStatementIfAll;
246 else {
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();
263 if (deleteSelf) {
264 element.getParent().delete();
267 if (replaceAll) {
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) {
276 array.add(replaced);
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"));
289 else {
290 if (!deleteSelf) {
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) {
311 LOG.error(e);
316 CommandProcessor.getInstance().executeCommand(
317 project,
318 new Runnable() {
319 public void run() {
320 ApplicationManager.getApplication().runWriteAction(runnable);
323 getRefactoringName(), null
326 return true;
329 private static PsiElement getPhysicalElement(final PsiExpression selectedExpr) {
330 PsiElement element = selectedExpr.getUserData(ElementToWorkOn.PARENT);
331 if (element == null) element = selectedExpr;
332 return element;
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() {
350 return false;
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;
359 child = prev;
362 child = PsiTreeUtil.skipSiblingsForward(child, PsiWhiteSpace.class, PsiComment.class);
363 PsiElement anchor;
364 if (child != null) {
365 anchor = child;
367 else {
368 anchor = anchorElement;
370 return anchor;
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();
394 return null;
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;
403 return null;
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)) {
415 anchor = replaceAll
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();
429 assert body != null;
430 body.addBefore(expressionStatement, anchor);
433 private void addInitializationToConstructors(PsiExpression initializerExpression, PsiField field, PsiMethod enclosingConstructor) {
434 try {
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)) {
451 continue;
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));
460 added = true;
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) {
473 LOG.error(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");
484 pattern.append(";");
485 PsiManager psiManager = myParentClass.getManager();
486 PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
487 try {
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);
494 return field;
496 catch (IncorrectOperationException e) {
497 LOG.error(e);
498 return null;
502 private PsiStatement createAssignment(PsiField field, PsiExpression initializerExpr, PsiElement context) {
503 try {
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);
517 return statement;
519 catch (IncorrectOperationException e) {
520 LOG.error(e);
521 return null;
526 protected Pass<ElementToWorkOn> getElementProcessor(final Project project, final Editor editor) {
527 return new Pass<ElementToWorkOn>() {
528 @Override
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);
535 if (result) {
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() {
573 return myFieldName;
576 public boolean isDeclareStatic() {
577 return myDeclareStatic;
580 public boolean isDeclareFinal() {
581 return myDeclareFinal;
584 public InitializationPlace getInitializerPlace() {
585 return myInitializerPlace;
588 @Modifier
589 public String getFieldVisibility() {
590 return myVisibility;
593 @Nullable
594 public PsiClass getDestinationClass() {
595 return myTargetClass != null ? myTargetClass.getTargetClass() : null;
598 public PsiType getForcedType() {
599 return myForcedType;
602 public boolean isReplaceAll() {
603 return myReplaceAll;
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();
668 @Nullable
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];
677 } else {
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;