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.
20 package com
.intellij
.codeInsight
.intention
.impl
;
22 import com
.intellij
.codeInsight
.CodeInsightBundle
;
23 import com
.intellij
.codeInsight
.CodeInsightUtilBase
;
24 import com
.intellij
.codeInsight
.intention
.PsiElementBaseIntentionAction
;
25 import com
.intellij
.openapi
.diagnostic
.Logger
;
26 import com
.intellij
.openapi
.editor
.Editor
;
27 import com
.intellij
.openapi
.project
.Project
;
28 import com
.intellij
.openapi
.util
.Key
;
29 import com
.intellij
.psi
.*;
30 import com
.intellij
.psi
.impl
.source
.tree
.java
.PsiReferenceExpressionImpl
;
31 import com
.intellij
.psi
.util
.PsiTreeUtil
;
32 import com
.intellij
.psi
.util
.PsiUtil
;
33 import com
.intellij
.util
.IncorrectOperationException
;
34 import org
.jetbrains
.annotations
.NotNull
;
35 import org
.jetbrains
.annotations
.Nullable
;
37 public class AddSingleMemberStaticImportAction
extends PsiElementBaseIntentionAction
{
38 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInsight.intention.impl.AddSingleMemberStaticImportAction");
39 private static final Key
<PsiElement
> TEMP_REFERENT_USER_DATA
= new Key
<PsiElement
>("TEMP_REFERENT_USER_DATA");
42 public String
getFamilyName() {
43 return CodeInsightBundle
.message("intention.add.single.member.static.import.family");
46 public boolean isAvailable(@NotNull Project project
, Editor editor
, @Nullable PsiElement element
) {
47 if (element
== null || !PsiUtil
.isLanguageLevel5OrHigher(element
)) return false;
48 PsiFile file
= element
.getContainingFile();
49 if (element
instanceof PsiIdentifier
&& element
.getParent() instanceof PsiReferenceExpression
&&
50 ((PsiReferenceExpression
)element
.getParent()).getQualifierExpression() != null) {
51 PsiReferenceExpression refExpr
= (PsiReferenceExpression
)element
.getParent();
52 if (refExpr
.getParameterList() != null &&
53 refExpr
.getParameterList().getFirstChild() != null) return false;
54 PsiElement resolved
= refExpr
.resolve();
55 if (resolved
instanceof PsiMember
&&
56 ((PsiModifierListOwner
)resolved
).hasModifierProperty(PsiModifier
.STATIC
)) {
57 PsiClass aClass
= ((PsiMember
)resolved
).getContainingClass();
58 if (aClass
!= null && !PsiTreeUtil
.isAncestor(aClass
, element
, true)) {
59 String qName
= aClass
.getQualifiedName();
61 qName
= qName
+ "." +refExpr
.getReferenceName();
62 if (file
instanceof PsiJavaFile
) {
63 if (((PsiJavaFile
)file
).getImportList().findSingleImportStatement(refExpr
.getReferenceName()) == null) {
64 setText(CodeInsightBundle
.message("intention.add.single.member.static.import.text", qName
));
77 public void invoke(@NotNull final Project project
, final Editor editor
, PsiFile file
) throws IncorrectOperationException
{
78 if (!CodeInsightUtilBase
.prepareFileForWrite(file
)) return;
79 PsiElement element
= file
.findElementAt(editor
.getCaretModel().getOffset());
80 final PsiReferenceExpression refExpr
= (PsiReferenceExpression
)element
.getParent();
81 final PsiElement resolved
= refExpr
.resolve();
83 file
.accept(new JavaRecursiveElementWalkingVisitor() {
84 @Override public void visitReferenceExpression(PsiReferenceExpression expression
) {
85 super.visitReferenceExpression(expression
);
86 if (refExpr
.getReferenceName().equals(expression
.getReferenceName())) {
87 PsiElement resolved
= expression
.resolve();
88 if (resolved
!= null) {
89 expression
.putUserData(TEMP_REFERENT_USER_DATA
, resolved
);
95 ((PsiReferenceExpressionImpl
)refExpr
).bindToElementViaStaticImport(((PsiMember
)resolved
).getContainingClass(), ((PsiNamedElement
)resolved
).getName(), ((PsiJavaFile
)file
).getImportList());
97 file
.accept(new JavaRecursiveElementVisitor() {
98 @Override public void visitReferenceExpression(PsiReferenceExpression expression
) {
99 if (expression
.getParameterList() != null &&
100 expression
.getParameterList().getFirstChild() != null) return;
102 if (refExpr
.getReferenceName().equals(expression
.getReferenceName())) {
103 if (!expression
.isQualified()) {
104 PsiElement referent
= expression
.getUserData(TEMP_REFERENT_USER_DATA
);
106 if (referent
instanceof PsiMember
&& referent
!= expression
.resolve()) {
107 PsiElementFactory factory
= JavaPsiFacade
.getInstance(expression
.getProject()).getElementFactory();
109 PsiReferenceExpression copy
= (PsiReferenceExpression
)factory
.createExpressionFromText("A." + expression
.getReferenceName(), null);
110 expression
= (PsiReferenceExpression
)expression
.replace(copy
);
111 ((PsiReferenceExpression
)expression
.getQualifierExpression()).bindToElement(((PsiMember
)referent
).getContainingClass());
113 catch (IncorrectOperationException e
) {
117 expression
.putUserData(TEMP_REFERENT_USER_DATA
, null);
119 if (expression
.getQualifierExpression() instanceof PsiReferenceExpression
) {
120 PsiElement aClass
= ((PsiReferenceExpression
)expression
.getQualifierExpression()).resolve();
121 if (aClass
== ((PsiMember
)resolved
).getContainingClass()) {
123 expression
.getQualifierExpression().delete();
125 catch (IncorrectOperationException e
) {
131 expression
.putUserData(TEMP_REFERENT_USER_DATA
, null);
134 super.visitReferenceExpression(expression
);