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
.daemon
.QuickFixBundle
;
20 import com
.intellij
.codeInsight
.intention
.IntentionAction
;
21 import com
.intellij
.codeInspection
.LocalQuickFix
;
22 import com
.intellij
.codeInspection
.ProblemDescriptor
;
23 import com
.intellij
.openapi
.command
.undo
.UndoUtil
;
24 import com
.intellij
.openapi
.diagnostic
.Logger
;
25 import com
.intellij
.openapi
.editor
.Editor
;
26 import com
.intellij
.openapi
.project
.Project
;
27 import com
.intellij
.psi
.*;
28 import com
.intellij
.util
.IncorrectOperationException
;
29 import org
.jetbrains
.annotations
.NonNls
;
30 import org
.jetbrains
.annotations
.NotNull
;
32 public class ExtendsListFix
implements IntentionAction
, LocalQuickFix
{
33 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.ExtendsListFix");
35 final PsiClass myClass
;
36 final PsiClass myClassToExtendFrom
;
37 private final boolean myToAdd
;
38 private final PsiClassType myTypeToExtendFrom
;
40 public ExtendsListFix(PsiClass aClass
, PsiClassType typeToExtendFrom
, boolean toAdd
) {
42 myClassToExtendFrom
= typeToExtendFrom
.resolve();
43 myTypeToExtendFrom
= typeToExtendFrom
;
47 public ExtendsListFix(PsiClass aClass
, PsiClass classToExtendFrom
, boolean toAdd
) {
49 myClassToExtendFrom
= classToExtendFrom
;
50 myTypeToExtendFrom
= JavaPsiFacade
.getInstance(aClass
.getProject()).getElementFactory().createType(classToExtendFrom
);
55 public String
getText() {
56 @NonNls final String messageKey
;
57 if (myClass
.isInterface() == myClassToExtendFrom
.isInterface()) {
58 messageKey
= myToAdd ?
"add.class.to.extends.list" : "remove.class.from.extends.list";
61 messageKey
= myToAdd ?
"add.interface.to.implements.list" : "remove.interface.from.implements.list";
64 return QuickFixBundle
.message(messageKey
, myClass
.getName(), myClassToExtendFrom
.getQualifiedName());
68 public String
getName() {
73 public String
getFamilyName() {
74 return QuickFixBundle
.message("change.extends.list.family");
77 public void applyFix(@NotNull final Project project
, @NotNull final ProblemDescriptor descriptor
) {
78 invoke(project
, null, descriptor
.getPsiElement().getContainingFile());
81 public boolean isAvailable(@NotNull Project project
, Editor editor
, PsiFile file
) {
85 && myClass
.getManager().isInProject(myClass
)
86 && myClassToExtendFrom
!= null
87 && myClassToExtendFrom
.isValid()
88 && !myClassToExtendFrom
.hasModifierProperty(PsiModifier
.FINAL
)
89 && (myClassToExtendFrom
.isInterface()
90 || (!myClass
.isInterface()
91 && myClass
.getExtendsList() != null
92 && myClass
.getExtendsList().getReferencedTypes().length
== 0 == myToAdd
))
97 protected void invokeImpl () {
98 if (!CodeInsightUtilBase
.prepareFileForWrite(myClass
.getContainingFile())) return;
99 PsiReferenceList extendsList
= !(myClass
instanceof PsiTypeParameter
) &&
100 myClass
.isInterface() != myClassToExtendFrom
.isInterface() ?
101 myClass
.getImplementsList() : myClass
.getExtendsList();
102 PsiReferenceList otherList
= extendsList
== myClass
.getImplementsList() ?
103 myClass
.getExtendsList() : myClass
.getImplementsList();
105 if (extendsList
!= null) {
106 modifyList(extendsList
, myToAdd
, -1);
108 if (otherList
!= null) {
109 modifyList(otherList
, false, -1);
112 catch (IncorrectOperationException e
) {
117 public void invoke(@NotNull Project project
, Editor editor
, PsiFile file
) {
119 UndoUtil
.markPsiFileForUndo(file
);
123 * @param position to add new class to or -1 if add to the end
125 PsiReferenceList
modifyList(@NotNull PsiReferenceList extendsList
, boolean add
, int position
) throws IncorrectOperationException
{
126 PsiJavaCodeReferenceElement
[] referenceElements
= extendsList
.getReferenceElements();
127 boolean alreadyExtends
= false;
128 for (PsiJavaCodeReferenceElement referenceElement
: referenceElements
) {
129 if (referenceElement
.resolve() == myClassToExtendFrom
) {
130 alreadyExtends
= true;
132 referenceElement
.delete();
136 PsiReferenceList list
= extendsList
;
137 if (add
&& !alreadyExtends
) {
139 if (position
== -1) {
140 anchor
= referenceElements
.length
==0 ?
null : referenceElements
[referenceElements
.length
-1];
142 else if (position
== 0) {
146 anchor
= referenceElements
[position
- 1];
148 PsiJavaCodeReferenceElement classReferenceElement
=
149 JavaPsiFacade
.getInstance(myClass
.getProject()).getElementFactory().createReferenceElementByType(myTypeToExtendFrom
);
151 if (anchor
== null) {
152 if (referenceElements
.length
== 0) {
153 element
= extendsList
.add(classReferenceElement
);
156 element
= extendsList
.addBefore(classReferenceElement
, referenceElements
[0]);
160 element
= extendsList
.addAfter(classReferenceElement
, anchor
);
162 list
= (PsiReferenceList
) element
.getParent();
167 public boolean startInWriteAction() {