1 package com
.intellij
.psi
.impl
.source
.resolve
.reference
.impl
;
3 import com
.intellij
.openapi
.util
.TextRange
;
4 import com
.intellij
.psi
.*;
5 import com
.intellij
.util
.IncorrectOperationException
;
6 import com
.intellij
.util
.containers
.HashSet
;
7 import org
.jetbrains
.annotations
.NotNull
;
9 import java
.util
.ArrayList
;
10 import java
.util
.Arrays
;
11 import java
.util
.List
;
15 * Created by IntelliJ IDEA.
19 * To change this template use Options | File Templates.
22 public class PsiMultiReference
implements PsiPolyVariantReference
{
23 private PsiReference
[] myReferences
;
24 private final PsiElement myElement
;
26 private int myChoosenOne
= -1;
28 public PsiMultiReference(@NotNull PsiReference
[] references
, PsiElement element
){
29 myReferences
= references
;
33 public PsiReference
[] getReferences() {
37 private PsiReference
chooseReference(){
38 if(myChoosenOne
!= -1){
39 return myReferences
[myChoosenOne
];
41 boolean nonSoftFound
= false;
43 boolean strict
= false;
44 for(int i
= 0; i
< myReferences
.length
; i
++){
45 final PsiReference reference
= myReferences
[i
];
46 if(reference
.isSoft() && nonSoftFound
) continue;
47 if(!reference
.isSoft() && !nonSoftFound
){
52 if(reference
instanceof GenericReference
){
53 if(((GenericReference
)reference
).getContext() != null){
59 if(reference
instanceof PsiPolyVariantReference
&& ((PsiPolyVariantReference
)reference
).multiResolve(false).length
> 0 ||
60 reference
.resolve() != null
66 // One reference inside other
67 final TextRange rangeInElement1
= reference
.getRangeInElement();
68 final TextRange rangeInElement2
= myReferences
[myChoosenOne
].getRangeInElement();
69 if(rangeInElement1
.getStartOffset() >= rangeInElement2
.getStartOffset()
70 && rangeInElement1
.getEndOffset() <= rangeInElement2
.getEndOffset()){
75 return myReferences
[myChoosenOne
];
78 public PsiElement
getElement(){
82 public TextRange
getRangeInElement(){
83 final PsiReference chosenRef
= chooseReference();
84 TextRange rangeInElement
= chosenRef
.getRangeInElement();
85 PsiElement element
= chosenRef
.getElement();
86 while(element
!= myElement
) {
87 rangeInElement
= rangeInElement
.shiftRight(element
.getStartOffsetInParent());
88 element
= element
.getParent();
89 if (element
instanceof PsiFile
) break;
91 return rangeInElement
;
94 public PsiElement
resolve(){
95 return chooseReference().resolve();
98 public String
getCanonicalText(){
99 return chooseReference().getCanonicalText();
102 public PsiElement
handleElementRename(String newElementName
) throws IncorrectOperationException
{
103 return chooseReference().handleElementRename(newElementName
);
106 public PsiElement
bindToElement(@NotNull PsiElement element
) throws IncorrectOperationException
{
107 return chooseReference().bindToElement(element
);
110 public boolean isReferenceTo(PsiElement element
){
111 for (PsiReference reference
: myReferences
) {
112 if (reference
.isReferenceTo(element
)) return true;
117 public Object
[] getVariants() {
118 Set
<Object
> variants
= new HashSet
<Object
>();
119 for(PsiReference ref
: myReferences
) {
120 Object
[] refVariants
= ref
.getVariants();
121 for(Object refVariant
: refVariants
) {
122 variants
.add(refVariant
);
125 return variants
.toArray();
128 public boolean isSoft(){
133 public ResolveResult
[] multiResolve(final boolean incompleteCode
) {
134 final PsiReference
[] refs
= getReferences();
135 List
<ResolveResult
> result
= new ArrayList
<ResolveResult
>();
136 PsiElementResolveResult selfReference
= null;
137 for (PsiReference reference
: refs
) {
138 if (reference
instanceof PsiPolyVariantReference
) {
139 result
.addAll(Arrays
.asList(((PsiPolyVariantReference
)reference
).multiResolve(incompleteCode
)));
142 final PsiElement resolved
= reference
.resolve();
143 if (resolved
!= null) {
144 final PsiElementResolveResult rresult
= new PsiElementResolveResult(resolved
);
145 if (getElement() == resolved
) {
146 selfReference
= rresult
;
154 if (result
.size() == 0 && selfReference
!= null) {
155 result
.add(selfReference
); // if i the only one starring at the sun
158 return result
.toArray(new ResolveResult
[result
.size()]);