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
.codeInsight
.daemon
.impl
.quickfix
;
18 import com
.intellij
.codeInsight
.CodeInsightUtilBase
;
19 import com
.intellij
.codeInsight
.ExpectedTypeInfo
;
20 import com
.intellij
.codeInsight
.daemon
.QuickFixBundle
;
21 import com
.intellij
.codeInsight
.template
.Template
;
22 import com
.intellij
.codeInsight
.template
.TemplateBuilderImpl
;
23 import com
.intellij
.openapi
.diagnostic
.Logger
;
24 import com
.intellij
.openapi
.editor
.Editor
;
25 import com
.intellij
.openapi
.project
.Project
;
26 import com
.intellij
.openapi
.util
.TextRange
;
27 import com
.intellij
.psi
.*;
28 import com
.intellij
.psi
.impl
.source
.codeStyle
.CodeEditUtil
;
29 import com
.intellij
.psi
.util
.PsiTreeUtil
;
30 import com
.intellij
.psi
.util
.PsiUtil
;
31 import com
.intellij
.util
.IncorrectOperationException
;
32 import org
.jetbrains
.annotations
.NotNull
;
37 public class CreateFieldFromUsageFix
extends CreateVarFromUsageFix
{
38 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageFix");
40 public CreateFieldFromUsageFix(PsiReferenceExpression referenceElement
) {
41 super(referenceElement
);
44 protected String
getText(String varName
) {
45 return QuickFixBundle
.message("create.field.from.usage.text", varName
);
48 protected boolean createConstantField() {
52 protected void invokeImpl(PsiClass targetClass
) {
53 if (CreateFromUsageUtils
.isValidReference(myReferenceExpression
, true)) {
57 Project project
= myReferenceExpression
.getProject();
58 PsiElementFactory factory
= JavaPsiFacade
.getInstance(project
).getElementFactory();
61 PsiMember enclosingContext
= null;
64 enclosingContext
= PsiTreeUtil
.getParentOfType(enclosingContext
== null ? myReferenceExpression
: enclosingContext
, PsiMethod
.class,
65 PsiField
.class, PsiClassInitializer
.class);
66 parentClass
= enclosingContext
== null ?
null : enclosingContext
.getContainingClass();
68 while (parentClass
instanceof PsiAnonymousClass
);
70 PsiFile targetFile
= targetClass
.getContainingFile();
73 ExpectedTypeInfo
[] expectedTypes
= CreateFromUsageUtils
.guessExpectedTypes(myReferenceExpression
, false);
75 String fieldName
= myReferenceExpression
.getReferenceName();
77 if (!createConstantField()) {
78 field
= factory
.createField(fieldName
, PsiType
.INT
);
80 PsiClass aClass
= factory
.createClassFromText("int i = 0;", null);
81 field
= aClass
.getFields()[0];
82 field
.setName(fieldName
);
84 if (enclosingContext
!= null && enclosingContext
.getParent() == parentClass
&& targetClass
== parentClass
85 && (enclosingContext
instanceof PsiField
)) {
86 field
= (PsiField
)targetClass
.addBefore(field
, enclosingContext
);
88 else if (enclosingContext
!= null && enclosingContext
.getParent() == parentClass
&& targetClass
== parentClass
89 && (enclosingContext
instanceof PsiClassInitializer
)) {
90 field
= (PsiField
)targetClass
.addBefore(field
, enclosingContext
);
91 targetClass
.addBefore(CodeEditUtil
.createLineFeed(field
.getManager()), enclosingContext
);
94 field
= (PsiField
)targetClass
.add(field
);
97 setupVisibility(parentClass
, targetClass
, field
.getModifierList());
99 if (shouldCreateStaticMember(myReferenceExpression
, targetClass
)) {
100 PsiUtil
.setModifierProperty(field
, PsiModifier
.STATIC
, true);
103 if (createConstantField()) {
104 PsiUtil
.setModifierProperty(field
, PsiModifier
.STATIC
, true);
105 PsiUtil
.setModifierProperty(field
, PsiModifier
.FINAL
, true);
108 TemplateBuilderImpl builder
= new TemplateBuilderImpl(field
);
109 PsiElement context
= PsiTreeUtil
.getParentOfType(myReferenceExpression
, PsiClass
.class, PsiMethod
.class);
110 new GuessTypeParameters(factory
).setupTypeElement(field
.getTypeElement(), expectedTypes
, getTargetSubstitutor(myReferenceExpression
),
111 builder
, context
, targetClass
);
113 if (createConstantField()) {
114 builder
.replaceElement(field
.getInitializer(), new EmptyExpression());
117 builder
.setEndVariableAfter(field
.getNameIdentifier());
118 field
= CodeInsightUtilBase
.forcePsiPostprocessAndRestoreElement(field
);
119 Template template
= builder
.buildTemplate();
121 Editor newEditor
= positionCursor(project
, targetFile
, field
);
122 TextRange range
= field
.getTextRange();
123 newEditor
.getDocument().deleteString(range
.getStartOffset(), range
.getEndOffset());
125 startTemplate(newEditor
, template
, project
);
127 catch (IncorrectOperationException e
) {
133 public String
getFamilyName() {
134 return QuickFixBundle
.message("create.field.from.usage.family");