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
.psi
.scope
.conflictResolvers
;
18 import com
.intellij
.psi
.PsiClass
;
19 import com
.intellij
.psi
.PsiElement
;
20 import com
.intellij
.psi
.PsiField
;
21 import com
.intellij
.psi
.PsiLocalVariable
;
22 import com
.intellij
.psi
.infos
.CandidateInfo
;
23 import com
.intellij
.psi
.scope
.PsiConflictResolver
;
25 import java
.util
.List
;
28 * Created by IntelliJ IDEA.
32 * To change this template use Options | File Templates.
34 public class JavaVariableConflictResolver
implements PsiConflictResolver
{
35 public CandidateInfo
resolveConflict(List
<CandidateInfo
> conflicts
){
36 final int size
= conflicts
.size();
38 return conflicts
.get(0);
43 final CandidateInfo
[] uncheckedResult
= conflicts
.toArray(new CandidateInfo
[size
]);
44 CandidateInfo currentResult
= uncheckedResult
[0];
46 PsiElement currentElement
= currentResult
.getElement();
47 if(currentElement
instanceof PsiField
){
48 for (int i
= 1; i
< uncheckedResult
.length
; i
++) {
49 final CandidateInfo candidate
= uncheckedResult
[i
];
50 final PsiElement otherElement
= candidate
.getElement();
51 if (otherElement
== null) continue;
53 if (!(otherElement
instanceof PsiField
)) {
54 if (otherElement
instanceof PsiLocalVariable
) {
58 if (!currentResult
.isAccessible()) return candidate
;
59 conflicts
.remove(candidate
);
64 final PsiClass newClass
= ((PsiField
)otherElement
).getContainingClass();
65 final PsiClass oldClass
= ((PsiField
)currentElement
).getContainingClass();
67 final PsiElement scope
= currentResult
.getCurrentFileResolveScope();
68 Boolean oldClassIsInheritor
= null;
69 if (newClass
.isInheritor(oldClass
, true)) {
70 if (!(scope
instanceof PsiClass
) ||
71 scope
.equals(oldClass
) ||
72 scope
.equals(newClass
) ||
73 !((PsiClass
)scope
).isInheritorDeep(oldClass
, newClass
)) {
74 // candidate is better
75 conflicts
.remove(currentResult
);
76 currentResult
= candidate
;
77 currentElement
= currentResult
.getElement();
81 else if (oldClassIsInheritor
= oldClass
.isInheritor(newClass
, true)) {
82 if (!(scope
instanceof PsiClass
) ||
83 scope
.equals(oldClass
) ||
84 scope
.equals(newClass
) ||
85 !((PsiClass
)scope
).isInheritorDeep(newClass
, oldClass
)) {
87 conflicts
.remove(candidate
);
92 if (!candidate
.isAccessible()) {
93 conflicts
.remove(candidate
);
96 if (!currentResult
.isAccessible()) {
97 conflicts
.remove(currentResult
);
98 currentResult
= candidate
;
99 currentElement
= currentResult
.getElement();
103 //This test should go last
104 if (otherElement
== currentElement
) {
105 conflicts
.remove(candidate
);
109 if (oldClassIsInheritor
== null) {
110 oldClassIsInheritor
= oldClass
.isInheritor(newClass
, true);
112 if (oldClassIsInheritor
) {
113 // both fields are accessible
114 // field in derived hides field in base
115 conflicts
.remove(candidate
);
121 return currentResult
;