3 * Copyright 2000-2009 JetBrains s.r.o.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package com
.intellij
.refactoring
.encapsulateFields
;
19 import com
.intellij
.openapi
.diagnostic
.Logger
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.util
.Ref
;
22 import com
.intellij
.openapi
.util
.text
.StringUtil
;
23 import com
.intellij
.psi
.*;
24 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
25 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
26 import com
.intellij
.psi
.search
.searches
.ClassInheritorsSearch
;
27 import com
.intellij
.psi
.search
.searches
.ReferencesSearch
;
28 import com
.intellij
.psi
.tree
.IElementType
;
29 import com
.intellij
.psi
.util
.InheritanceUtil
;
30 import com
.intellij
.psi
.util
.PsiFormatUtil
;
31 import com
.intellij
.psi
.util
.PsiTreeUtil
;
32 import com
.intellij
.psi
.util
.PsiUtil
;
33 import com
.intellij
.refactoring
.BaseRefactoringProcessor
;
34 import com
.intellij
.refactoring
.RefactoringBundle
;
35 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
36 import com
.intellij
.refactoring
.util
.DocCommentPolicy
;
37 import com
.intellij
.refactoring
.util
.RefactoringUIUtil
;
38 import com
.intellij
.refactoring
.util
.RefactoringUtil
;
39 import com
.intellij
.usageView
.UsageInfo
;
40 import com
.intellij
.usageView
.UsageViewDescriptor
;
41 import com
.intellij
.usageView
.UsageViewUtil
;
42 import com
.intellij
.util
.IncorrectOperationException
;
43 import com
.intellij
.util
.VisibilityUtil
;
44 import com
.intellij
.util
.containers
.HashMap
;
45 import com
.intellij
.util
.containers
.MultiMap
;
46 import org
.jetbrains
.annotations
.NonNls
;
47 import org
.jetbrains
.annotations
.NotNull
;
48 import org
.jetbrains
.annotations
.Nullable
;
52 public class EncapsulateFieldsProcessor
extends BaseRefactoringProcessor
{
53 private static final Logger LOG
= Logger
.getInstance("#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsProcessor");
55 private PsiClass myClass
;
57 private final EncapsulateFieldsDescriptor myDescriptor
;
58 private PsiField
[] myFields
;
60 private HashMap
<String
,PsiMethod
> myNameToGetter
;
61 private HashMap
<String
,PsiMethod
> myNameToSetter
;
63 public EncapsulateFieldsProcessor(Project project
, @NotNull EncapsulateFieldsDescriptor descriptor
) {
65 myDescriptor
= descriptor
;
66 myFields
= myDescriptor
.getSelectedFields();
67 myClass
= myFields
[0].getContainingClass();
70 protected UsageViewDescriptor
createUsageViewDescriptor(UsageInfo
[] usages
) {
71 PsiField
[] fields
= new PsiField
[myFields
.length
];
72 System
.arraycopy(myFields
, 0, fields
, 0, myFields
.length
);
73 return new EncapsulateFieldsViewDescriptor(fields
);
76 protected String
getCommandName() {
77 return RefactoringBundle
.message("encapsulate.fields.command.name", UsageViewUtil
.getDescriptiveName(myClass
));
80 protected boolean preprocessUsages(Ref
<UsageInfo
[]> refUsages
) {
81 final MultiMap
<PsiElement
, String
> conflicts
= new MultiMap
<PsiElement
, String
>();
83 final PsiMethod
[] getterPrototypes
= myDescriptor
.getGetterPrototypes();
84 final PsiMethod
[] setterPrototypes
= myDescriptor
.getSetterPrototypes();
86 checkExistingMethods(getterPrototypes
, conflicts
, true);
87 checkExistingMethods(setterPrototypes
, conflicts
, false);
88 final Collection
<PsiClass
> classes
= ClassInheritorsSearch
.search(myClass
).findAll();
89 for (int i
= 0; i
< myFields
.length
; i
++) {
90 final PsiField field
= myFields
[i
];
91 final Set
<PsiMethod
> setters
= new HashSet
<PsiMethod
>();
92 final Set
<PsiMethod
> getters
= new HashSet
<PsiMethod
>();
94 for (PsiClass aClass
: classes
) {
95 final PsiMethod getterOverrider
= getterPrototypes
!= null ? aClass
.findMethodBySignature(getterPrototypes
[i
], false) : null;
96 if (getterOverrider
!= null) {
97 getters
.add(getterOverrider
);
99 final PsiMethod setterOverrider
= setterPrototypes
!= null ? aClass
.findMethodBySignature(setterPrototypes
[i
], false) : null;
100 if (setterOverrider
!= null) {
101 setters
.add(setterOverrider
);
104 if (!getters
.isEmpty() || !setters
.isEmpty()) {
105 for (PsiReference reference
: ReferencesSearch
.search(field
)) {
106 final PsiElement place
= reference
.getElement();
107 LOG
.assertTrue(place
instanceof PsiReferenceExpression
);
108 final PsiExpression qualifierExpression
= ((PsiReferenceExpression
)place
).getQualifierExpression();
109 final PsiClass ancestor
;
110 if (qualifierExpression
== null) {
111 ancestor
= PsiTreeUtil
.getParentOfType(place
, PsiClass
.class, false);
114 ancestor
= PsiUtil
.resolveClassInType(qualifierExpression
.getType());
117 final boolean isGetter
= !PsiUtil
.isAccessedForWriting((PsiExpression
)place
);
118 for (PsiMethod overridden
: isGetter ? getters
: setters
) {
119 if (InheritanceUtil
.isInheritorOrSelf(myClass
, ancestor
, true)) {
120 conflicts
.putValue(overridden
, "There is already a " +
121 CommonRefactoringUtil
.htmlEmphasize(RefactoringUIUtil
.getDescription(overridden
, true)) +
122 " which would hide generated " +
123 (isGetter ?
"getter" : "setter") + " for " + place
.getText());
130 return showConflicts(conflicts
);
133 private void checkExistingMethods(PsiMethod
[] prototypes
, MultiMap
<PsiElement
, String
> conflicts
, boolean isGetter
) {
134 if(prototypes
== null) return;
135 for (PsiMethod prototype
: prototypes
) {
136 final PsiType prototypeReturnType
= prototype
.getReturnType();
137 PsiMethod existing
= myClass
.findMethodBySignature(prototype
, true);
138 if (existing
!= null) {
139 final PsiType returnType
= existing
.getReturnType();
140 if (!RefactoringUtil
.equivalentTypes(prototypeReturnType
, returnType
, myClass
.getManager())) {
141 final String descr
= PsiFormatUtil
.formatMethod(existing
,
142 PsiSubstitutor
.EMPTY
,
143 PsiFormatUtil
.SHOW_NAME
| PsiFormatUtil
.SHOW_PARAMETERS
| PsiFormatUtil
.SHOW_TYPE
,
144 PsiFormatUtil
.SHOW_TYPE
146 String message
= isGetter ?
147 RefactoringBundle
.message("encapsulate.fields.getter.exists", CommonRefactoringUtil
.htmlEmphasize(descr
),
148 CommonRefactoringUtil
.htmlEmphasize(prototype
.getName())) :
149 RefactoringBundle
.message("encapsulate.fields.setter.exists", CommonRefactoringUtil
.htmlEmphasize(descr
),
150 CommonRefactoringUtil
.htmlEmphasize(prototype
.getName()));
151 conflicts
.putValue(existing
, message
);
154 PsiClass containingClass
= myClass
.getContainingClass();
155 while (containingClass
!= null && existing
== null) {
156 existing
= containingClass
.findMethodBySignature(prototype
, true);
157 if (existing
!= null) {
158 for (PsiReference reference
: ReferencesSearch
.search(existing
)) {
159 final PsiElement place
= reference
.getElement();
160 LOG
.assertTrue(place
instanceof PsiReferenceExpression
);
161 final PsiExpression qualifierExpression
= ((PsiReferenceExpression
)place
).getQualifierExpression();
162 final PsiClass inheritor
;
163 if (qualifierExpression
== null) {
164 inheritor
= PsiTreeUtil
.getParentOfType(place
, PsiClass
.class, false);
166 inheritor
= PsiUtil
.resolveClassInType(qualifierExpression
.getType());
169 if (InheritanceUtil
.isInheritorOrSelf(inheritor
, myClass
, true)) {
170 conflicts
.putValue(existing
, "There is already a " + CommonRefactoringUtil
.htmlEmphasize(RefactoringUIUtil
.getDescription(existing
, true)) + " which would be hidden by generated " + (isGetter ?
"getter" : "setter"));
175 containingClass
= containingClass
.getContainingClass();
181 @NotNull protected UsageInfo
[] findUsages() {
182 boolean findGet
= myDescriptor
.isToEncapsulateGet();
183 boolean findSet
= myDescriptor
.isToEncapsulateSet();
184 PsiModifierList newModifierList
= null;
185 final JavaPsiFacade facade
= JavaPsiFacade
.getInstance(myProject
);
186 if (!myDescriptor
.isToUseAccessorsWhenAccessible()){
187 PsiElementFactory factory
= facade
.getElementFactory();
189 PsiField field
= factory
.createField("a", PsiType
.INT
);
190 setNewFieldVisibility(field
);
191 newModifierList
= field
.getModifierList();
193 catch(IncorrectOperationException e
){
197 PsiMethod
[] getterPrototypes
= myDescriptor
.getGetterPrototypes();
198 PsiMethod
[] setterPrototypes
= myDescriptor
.getSetterPrototypes();
199 ArrayList
<UsageInfo
> array
= new ArrayList
<UsageInfo
>();
200 PsiField
[] fields
= myFields
;
201 for(int i
= 0; i
< fields
.length
; i
++){
202 PsiField field
= fields
[i
];
203 for (final PsiReference reference
: ReferencesSearch
.search(field
)) {
204 if (!(reference
instanceof PsiReferenceExpression
)) continue;
205 PsiReferenceExpression ref
= (PsiReferenceExpression
)reference
;
206 // [Jeka] to avoid recursion in the field's accessors
207 if (findGet
&& isUsedInExistingAccessor(getterPrototypes
[i
], ref
)) continue;
208 if (findSet
&& isUsedInExistingAccessor(setterPrototypes
[i
], ref
)) continue;
210 if (!PsiUtil
.isAccessedForWriting(ref
)) continue;
212 if (!findSet
|| field
.hasModifierProperty(PsiModifier
.FINAL
)) {
213 if (!PsiUtil
.isAccessedForReading(ref
)) continue;
215 if (!myDescriptor
.isToUseAccessorsWhenAccessible()) {
216 PsiClass accessObjectClass
= null;
217 PsiExpression qualifier
= ref
.getQualifierExpression();
218 if (qualifier
!= null) {
219 accessObjectClass
= (PsiClass
)PsiUtil
.getAccessObjectClass(qualifier
).getElement();
221 if (facade
.getResolveHelper()
222 .isAccessible(field
, newModifierList
, ref
, accessObjectClass
, null)) {
226 UsageInfo usageInfo
= new MyUsageInfo(ref
, i
);
227 array
.add(usageInfo
);
230 MyUsageInfo
[] usageInfos
= array
.toArray(new MyUsageInfo
[array
.size()]);
231 return UsageViewUtil
.removeDuplicatedUsages(usageInfos
);
234 protected void refreshElements(PsiElement
[] elements
) {
235 LOG
.assertTrue(elements
.length
== myFields
.length
);
237 for (int idx
= 0; idx
< elements
.length
; idx
++) {
238 PsiElement element
= elements
[idx
];
240 LOG
.assertTrue(element
instanceof PsiField
);
242 myFields
[idx
] = (PsiField
)element
;
245 myClass
= myFields
[0].getContainingClass();
248 protected void performRefactoring(UsageInfo
[] usages
) {
249 // change visibility of fields
250 if (myDescriptor
.getFieldsVisibility() != null){
252 for (PsiField field
: myFields
) {
253 setNewFieldVisibility(field
);
257 // generate accessors
258 myNameToGetter
= new HashMap
<String
, PsiMethod
>();
259 myNameToSetter
= new HashMap
<String
, PsiMethod
>();
260 for(int i
= 0; i
< myFields
.length
; i
++){
261 final DocCommentPolicy
<PsiDocComment
> commentPolicy
= new DocCommentPolicy
<PsiDocComment
>(myDescriptor
.getJavadocPolicy());
262 PsiField field
= myFields
[i
];
263 final PsiDocComment docComment
= field
.getDocComment();
264 if (myDescriptor
.isToEncapsulateGet()){
265 PsiMethod
[] prototypes
= myDescriptor
.getGetterPrototypes();
266 assert prototypes
!= null;
267 final PsiMethod getter
= addOrChangeAccessor(prototypes
[i
], myNameToGetter
);
268 if (docComment
!= null) {
269 final PsiDocComment getterJavadoc
= (PsiDocComment
)getter
.addBefore(docComment
, getter
.getFirstChild());
270 commentPolicy
.processNewJavaDoc(getterJavadoc
);
273 if (myDescriptor
.isToEncapsulateSet() && !field
.hasModifierProperty(PsiModifier
.FINAL
)){
274 PsiMethod
[] prototypes
= myDescriptor
.getSetterPrototypes();
275 assert prototypes
!= null;
276 addOrChangeAccessor(prototypes
[i
], myNameToSetter
);
279 if (docComment
!= null) {
280 commentPolicy
.processOldJavaDoc(docComment
);
284 Map
<PsiFile
, List
<MyUsageInfo
>> usagesInFiles
= new HashMap
<PsiFile
, List
<MyUsageInfo
>>();
285 for (UsageInfo usage
: usages
) {
286 PsiElement element
= usage
.getElement();
287 if (element
== null) continue;
288 final PsiFile file
= element
.getContainingFile();
289 List
<MyUsageInfo
> usagesInFile
= usagesInFiles
.get(file
);
290 if (usagesInFile
== null) {
291 usagesInFile
= new ArrayList
<MyUsageInfo
>();
292 usagesInFiles
.put(file
, usagesInFile
);
294 usagesInFile
.add(((MyUsageInfo
)usage
));
297 for (List
<MyUsageInfo
> usageInfos
: usagesInFiles
.values()) {
298 //this is to avoid elements to become invalid as a result of processUsage
299 final MyUsageInfo
[] infos
= usageInfos
.toArray(new MyUsageInfo
[usageInfos
.size()]);
300 RefactoringUtil
.sortDepthFirstRightLeftOrder(infos
);
302 for (MyUsageInfo info
: infos
) {
308 private void setNewFieldVisibility(PsiField field
) {
310 if (myDescriptor
.getFieldsVisibility() != null){
311 field
.normalizeDeclaration();
312 PsiUtil
.setModifierProperty(field
, myDescriptor
.getFieldsVisibility(), true);
315 catch(IncorrectOperationException e
){
320 private PsiMethod
addOrChangeAccessor(PsiMethod prototype
, HashMap
<String
,PsiMethod
> nameToAncestor
) {
321 PsiMethod existing
= myClass
.findMethodBySignature(prototype
, false);
322 PsiMethod result
= existing
;
324 if (existing
== null){
325 PsiUtil
.setModifierProperty(prototype
, myDescriptor
.getAccessorsVisibility(), true);
326 result
= (PsiMethod
) myClass
.add(prototype
);
329 //TODO : change visibility
331 nameToAncestor
.put(prototype
.getName(), result
);
334 catch(IncorrectOperationException e
){
340 private boolean isUsedInExistingAccessor(PsiMethod prototype
, PsiElement element
) {
341 PsiMethod existingAccessor
= myClass
.findMethodBySignature(prototype
, false);
342 if (existingAccessor
!= null) {
343 PsiElement parent
= element
;
344 while (parent
!= null) {
345 if (existingAccessor
.equals(parent
)) return true;
346 parent
= parent
.getParent();
352 private void processUsage(MyUsageInfo usage
) {
353 PsiField field
= myFields
[usage
.fieldIndex
];
354 boolean processGet
= myDescriptor
.isToEncapsulateGet();
355 boolean processSet
= myDescriptor
.isToEncapsulateSet() && !field
.hasModifierProperty(PsiModifier
.FINAL
);
356 if (!processGet
&& !processSet
) return;
357 PsiElementFactory factory
= JavaPsiFacade
.getInstance(myProject
).getElementFactory();
360 final PsiReferenceExpression expr
= (PsiReferenceExpression
)usage
.getElement();
361 if (expr
== null) return;
362 final PsiElement parent
= expr
.getParent();
363 if (parent
instanceof PsiAssignmentExpression
&& expr
.equals(((PsiAssignmentExpression
)parent
).getLExpression())){
364 PsiAssignmentExpression assignment
= (PsiAssignmentExpression
)parent
;
365 if (assignment
.getRExpression() == null) return;
366 PsiJavaToken opSign
= assignment
.getOperationSign();
367 IElementType opType
= opSign
.getTokenType();
368 if (opType
== JavaTokenType
.EQ
) {
370 if (!processSet
) return;
371 final int fieldIndex
= usage
.fieldIndex
;
372 final PsiExpression setterArgument
= assignment
.getRExpression();
374 PsiMethodCallExpression methodCall
= createSetterCall(fieldIndex
, setterArgument
, expr
);
376 if (methodCall
!= null) {
377 assignment
.replace(methodCall
);
379 //TODO: check if value is used!!!
382 else if (opType
== JavaTokenType
.ASTERISKEQ
|| opType
== JavaTokenType
.DIVEQ
|| opType
== JavaTokenType
.PERCEQ
||
383 opType
== JavaTokenType
.PLUSEQ
||
384 opType
== JavaTokenType
.MINUSEQ
||
385 opType
== JavaTokenType
.LTLTEQ
||
386 opType
== JavaTokenType
.GTGTEQ
||
387 opType
== JavaTokenType
.GTGTGTEQ
||
388 opType
== JavaTokenType
.ANDEQ
||
389 opType
== JavaTokenType
.OREQ
||
390 opType
== JavaTokenType
.XOREQ
) {
392 // Q: side effects of qualifier??!
394 String opName
= opSign
.getText();
395 LOG
.assertTrue(StringUtil
.endsWithChar(opName
, '='));
396 opName
= opName
.substring(0, opName
.length() - 1);
398 PsiExpression getExpr
= expr
;
400 final int fieldIndex
= usage
.fieldIndex
;
401 final PsiMethodCallExpression getterCall
= createGetterCall(fieldIndex
, expr
);
402 if (getterCall
!= null) {
403 getExpr
= getterCall
;
407 @NonNls String text
= "a" + opName
+ "b";
408 PsiBinaryExpression binExpr
= (PsiBinaryExpression
)factory
.createExpressionFromText(text
, expr
);
409 binExpr
= (PsiBinaryExpression
)CodeStyleManager
.getInstance(myProject
).reformat(binExpr
);
410 binExpr
.getLOperand().replace(getExpr
);
411 binExpr
.getROperand().replace(assignment
.getRExpression());
413 PsiExpression setExpr
;
415 setExpr
= createSetterCall(usage
.fieldIndex
, binExpr
, expr
);
419 PsiAssignmentExpression assignment1
= (PsiAssignmentExpression
)factory
.createExpressionFromText(text
, null);
420 assignment1
= (PsiAssignmentExpression
)CodeStyleManager
.getInstance(myProject
).reformat(assignment1
);
421 assignment1
.getLExpression().replace(expr
);
422 assignment1
.getRExpression().replace(binExpr
);
423 setExpr
= assignment1
;
426 assignment
.replace(setExpr
);
427 //TODO: check if value is used!!!
431 else if (RefactoringUtil
.isPlusPlusOrMinusMinus(parent
)){
433 if (parent
instanceof PsiPrefixExpression
){
434 sign
= ((PsiPrefixExpression
)parent
).getOperationSign();
437 sign
= ((PsiPostfixExpression
)parent
).getOperationSign();
439 IElementType tokenType
= sign
.getTokenType();
441 PsiExpression getExpr
= expr
;
443 final int fieldIndex
= usage
.fieldIndex
;
444 final PsiMethodCallExpression getterCall
= createGetterCall(fieldIndex
, expr
);
445 if(getterCall
!= null) {
446 getExpr
= getterCall
;
451 if (tokenType
== JavaTokenType
.PLUSPLUS
){
457 PsiBinaryExpression binExpr
= (PsiBinaryExpression
)factory
.createExpressionFromText(text
, null);
458 binExpr
= (PsiBinaryExpression
)CodeStyleManager
.getInstance(myProject
).reformat(binExpr
);
459 binExpr
.getLOperand().replace(getExpr
);
461 PsiExpression setExpr
;
463 final int fieldIndex
= usage
.fieldIndex
;
464 setExpr
= createSetterCall(fieldIndex
, binExpr
, expr
);
468 PsiAssignmentExpression assignment
= (PsiAssignmentExpression
)factory
.createExpressionFromText(text
, null);
469 assignment
= (PsiAssignmentExpression
)CodeStyleManager
.getInstance(myProject
).reformat(assignment
);
470 assignment
.getLExpression().replace(expr
);
471 assignment
.getRExpression().replace(binExpr
);
472 setExpr
= assignment
;
474 parent
.replace(setExpr
);
477 if (!processGet
) return;
478 PsiMethodCallExpression methodCall
= createGetterCall(usage
.fieldIndex
, expr
);
480 if (methodCall
!= null) {
481 expr
.replace(methodCall
);
485 catch(IncorrectOperationException e
){
490 private PsiMethodCallExpression
createSetterCall(final int fieldIndex
, final PsiExpression setterArgument
, PsiReferenceExpression expr
) throws IncorrectOperationException
{
491 String
[] setterNames
= myDescriptor
.getSetterNames();
492 PsiElementFactory factory
= JavaPsiFacade
.getInstance(expr
.getProject()).getElementFactory();
493 final String setterName
= setterNames
[fieldIndex
];
494 @NonNls String text
= setterName
+ "(a)";
495 PsiExpression qualifier
= expr
.getQualifierExpression();
496 if (qualifier
!= null){
499 PsiMethodCallExpression methodCall
= (PsiMethodCallExpression
)factory
.createExpressionFromText(text
, expr
);
500 methodCall
= (PsiMethodCallExpression
)CodeStyleManager
.getInstance(myProject
).reformat(methodCall
);
502 methodCall
.getArgumentList().getExpressions()[0].replace(setterArgument
);
503 if (qualifier
!= null){
504 methodCall
.getMethodExpression().getQualifierExpression().replace(qualifier
);
506 final PsiMethod targetMethod
= myNameToSetter
.get(setterName
);
507 methodCall
= checkMethodResolvable(methodCall
, targetMethod
, expr
);
508 if (methodCall
== null) {
509 VisibilityUtil
.escalateVisibility(myFields
[fieldIndex
], expr
);
515 private PsiMethodCallExpression
createGetterCall(final int fieldIndex
, PsiReferenceExpression expr
)
516 throws IncorrectOperationException
{
517 String
[] getterNames
= myDescriptor
.getGetterNames();
518 PsiElementFactory factory
= JavaPsiFacade
.getInstance(expr
.getProject()).getElementFactory();
519 final String getterName
= getterNames
[fieldIndex
];
520 @NonNls String text
= getterName
+ "()";
521 PsiExpression qualifier
= expr
.getQualifierExpression();
522 if (qualifier
!= null){
525 PsiMethodCallExpression methodCall
= (PsiMethodCallExpression
)factory
.createExpressionFromText(text
, expr
);
526 methodCall
= (PsiMethodCallExpression
)CodeStyleManager
.getInstance(myProject
).reformat(methodCall
);
528 if (qualifier
!= null){
529 methodCall
.getMethodExpression().getQualifierExpression().replace(qualifier
);
532 final PsiMethod targetMethod
= myNameToGetter
.get(getterName
);
533 methodCall
= checkMethodResolvable(methodCall
, targetMethod
, expr
);
534 if(methodCall
== null) {
535 VisibilityUtil
.escalateVisibility(myFields
[fieldIndex
], expr
);
541 private PsiMethodCallExpression
checkMethodResolvable(PsiMethodCallExpression methodCall
, final PsiMethod targetMethod
, PsiReferenceExpression context
) throws IncorrectOperationException
{
542 PsiElementFactory factory
= JavaPsiFacade
.getInstance(targetMethod
.getProject()).getElementFactory();
543 final PsiElement resolved
= methodCall
.getMethodExpression().resolve();
544 if (resolved
!= targetMethod
) {
545 PsiClass containingClass
;
546 if (resolved
instanceof PsiMethod
) {
547 containingClass
= ((PsiMethod
) resolved
).getContainingClass();
548 } else if (resolved
instanceof PsiClass
) {
549 containingClass
= (PsiClass
)resolved
;
554 if(containingClass
!= null && containingClass
.isInheritor(myClass
, false)) {
555 final PsiExpression newMethodExpression
=
556 factory
.createExpressionFromText("super." + targetMethod
.getName(), context
);
557 methodCall
.getMethodExpression().replace(newMethodExpression
);
567 private static class MyUsageInfo
extends UsageInfo
{
568 public final int fieldIndex
;
570 public MyUsageInfo(PsiJavaCodeReferenceElement ref
, int fieldIndex
) {
572 this.fieldIndex
= fieldIndex
;