1 package com
.intellij
.refactoring
.removemiddleman
;
3 import com
.intellij
.openapi
.diagnostic
.Logger
;
4 import com
.intellij
.openapi
.project
.Project
;
5 import com
.intellij
.openapi
.util
.Ref
;
6 import com
.intellij
.psi
.*;
7 import com
.intellij
.psi
.presentation
.java
.SymbolPresentationUtil
;
8 import com
.intellij
.psi
.search
.searches
.ReferencesSearch
;
9 import com
.intellij
.psi
.util
.PropertyUtil
;
10 import com
.intellij
.refactoring
.RefactorJBundle
;
11 import com
.intellij
.refactoring
.removemiddleman
.usageInfo
.DeleteMethod
;
12 import com
.intellij
.refactoring
.removemiddleman
.usageInfo
.InlineDelegatingCall
;
13 import com
.intellij
.refactoring
.util
.FixableUsageInfo
;
14 import com
.intellij
.refactoring
.util
.FixableUsagesRefactoringProcessor
;
15 import com
.intellij
.refactoring
.util
.classMembers
.MemberInfo
;
16 import com
.intellij
.usageView
.UsageInfo
;
17 import com
.intellij
.usageView
.UsageViewDescriptor
;
18 import com
.intellij
.util
.IncorrectOperationException
;
19 import org
.jetbrains
.annotations
.NotNull
;
21 import java
.util
.ArrayList
;
22 import java
.util
.List
;
24 public class RemoveMiddlemanProcessor
extends FixableUsagesRefactoringProcessor
{
25 private static final Logger LOG
= Logger
.getInstance("#" + RemoveMiddlemanProcessor
.class.getName());
27 private final PsiField field
;
28 private final PsiClass containingClass
;
29 private final List
<MemberInfo
> myDelegateMethodInfos
;
30 private PsiMethod getter
;
32 public RemoveMiddlemanProcessor(PsiField field
, List
<MemberInfo
> memberInfos
) {
33 super(field
.getProject());
35 containingClass
= field
.getContainingClass();
36 final Project project
= field
.getProject();
37 final String propertyName
= PropertyUtil
.suggestPropertyName(project
, field
);
38 final boolean isStatic
= field
.hasModifierProperty(PsiModifier
.STATIC
);
39 getter
= PropertyUtil
.findPropertyGetter(containingClass
, propertyName
, isStatic
, false);
40 myDelegateMethodInfos
= memberInfos
;
43 protected UsageViewDescriptor
createUsageViewDescriptor(UsageInfo
[] usageInfos
) {
44 return new RemoveMiddlemanUsageViewDescriptor(field
);
48 public void findUsages(@NotNull List
<FixableUsageInfo
> usages
) {
49 for (final MemberInfo memberInfo
: myDelegateMethodInfos
) {
50 if (!memberInfo
.isChecked()) continue;
51 final PsiMethod method
= (PsiMethod
)memberInfo
.getMember();
52 final Project project
= method
.getProject();
53 final String getterName
= PropertyUtil
.suggestGetterName(project
, field
);
54 final int[] paramPermutation
= DelegationUtils
.getParameterPermutation(method
);
55 final PsiMethod delegatedMethod
= DelegationUtils
.getDelegatedMethod(method
);
56 LOG
.assertTrue(!DelegationUtils
.isAbstract(method
));
57 processUsagesForMethod(memberInfo
.isToAbstract(), method
, paramPermutation
, getterName
, delegatedMethod
, usages
);
62 protected boolean preprocessUsages(final Ref
<UsageInfo
[]> refUsages
) {
63 final List
<String
> conflicts
= new ArrayList
<String
>();
64 for (MemberInfo memberInfo
: myDelegateMethodInfos
) {
65 if (memberInfo
.isChecked() && memberInfo
.isToAbstract()) {
66 final PsiMember psiMember
= memberInfo
.getMember();
67 if (psiMember
instanceof PsiMethod
&& ((PsiMethod
)psiMember
).findDeepestSuperMethods().length
> 0) {
68 conflicts
.add(SymbolPresentationUtil
.getSymbolPresentableText(psiMember
) + " will be deleted. Hierarchy will be broken");
72 return showConflicts(conflicts
);
75 private void processUsagesForMethod(final boolean deleteMethodHierarchy
, PsiMethod method
, int[] paramPermutation
, String getterName
, PsiMethod delegatedMethod
,
76 List
<FixableUsageInfo
> usages
) {
77 for (PsiReference reference
: ReferencesSearch
.search(method
)) {
78 final PsiElement referenceElement
= reference
.getElement();
79 final PsiMethodCallExpression call
= (PsiMethodCallExpression
)referenceElement
.getParent();
81 if (call
.getMethodExpression().getQualifierExpression() == null) {
82 access
= field
.getName();
84 access
= getterName
+ "()";
86 getter
= PropertyUtil
.generateGetterPrototype(field
);
89 usages
.add(new InlineDelegatingCall(call
, paramPermutation
, access
, delegatedMethod
.getName()));
91 if (deleteMethodHierarchy
) {
92 usages
.add(new DeleteMethod(method
));
96 protected void performRefactoring(UsageInfo
[] usageInfos
) {
99 if (containingClass
.findMethodBySignature(getter
, false) == null) {
100 containingClass
.add(getter
);
103 catch (IncorrectOperationException e
) {
108 super.performRefactoring(usageInfos
);
111 protected String
getCommandName() {
112 return RefactorJBundle
.message("exposed.delegation.command.name", containingClass
.getName(), '.', field
.getName());