inject el seam
[fedora-idea.git] / lang-impl / src / com / intellij / psi / impl / source / resolve / reference / impl / PsiMultiReference.java
blobd66dfd0d9f9fb9aa62aa28e62a37fe1ea1cd57c2
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;
12 import java.util.Set;
14 /**
15 * Created by IntelliJ IDEA.
16 * User: ik
17 * Date: 02.04.2003
18 * Time: 12:22:03
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;
30 myElement = element;
33 public PsiReference[] getReferences() {
34 return myReferences;
37 private PsiReference chooseReference(){
38 if(myChoosenOne != -1){
39 return myReferences[myChoosenOne];
41 boolean nonSoftFound = false;
42 myChoosenOne = 0;
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){
48 myChoosenOne = i;
49 nonSoftFound = true;
52 if(reference instanceof GenericReference){
53 if(((GenericReference)reference).getContext() != null){
54 myChoosenOne = i;
55 strict = true;
59 if(reference instanceof PsiPolyVariantReference && ((PsiPolyVariantReference)reference).multiResolve(false).length > 0 ||
60 reference.resolve() != null
62 myChoosenOne = i;
63 strict = true;
65 if(!strict){
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()){
71 myChoosenOne = i;
75 return myReferences[myChoosenOne];
78 public PsiElement getElement(){
79 return myElement;
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;
114 return false;
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(){
129 return false;
132 @NotNull
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)));
141 else {
142 final PsiElement resolved = reference.resolve();
143 if (resolved != null) {
144 final PsiElementResolveResult rresult = new PsiElementResolveResult(resolved);
145 if (getElement() == resolved) {
146 selfReference = rresult;
147 } else {
148 result.add(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()]);