lang-api
[idea/community.git] / platform / lang-api / src / com / intellij / psi / util / ReferenceSetBase.java
1 /*
2  * Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
3  */
4
5 package com.intellij.psi.util;
6
7 import com.intellij.openapi.util.TextRange;
8 import com.intellij.psi.*;
9 import org.jetbrains.annotations.NotNull;
10 import org.jetbrains.annotations.Nullable;
11
12 import java.util.ArrayList;
13 import java.util.List;
14
15 /**
16  * @author Dmitry Avdeev
17  */
18 public abstract class ReferenceSetBase<T extends PsiReference> {
19
20   public static final char DOT_SEPARATOR = '.';
21
22   private final List<T> myReferences;
23   private final PsiElement myElement;
24   private final char mySeparator;
25
26   public ReferenceSetBase(@NotNull PsiElement element) {
27     this(element, ElementManipulators.getOffsetInElement(element));
28   }
29   
30   public ReferenceSetBase(@NotNull PsiElement element, int offset) {
31     this(ElementManipulators.getValueText(element), element, offset, DOT_SEPARATOR);
32   }
33
34   public ReferenceSetBase(final String text, @NotNull PsiElement element, int offset, final char separator) {
35     myElement = element;
36     mySeparator = separator;
37     myReferences = parse(text, offset);
38   }
39
40   public boolean isSoft() {
41     return true;
42   }
43   
44   @NotNull
45   protected List<T> parse(String str, int offset) {
46
47     final List<T> references = new ArrayList<T>();
48     int current = -1;
49     int index = 0;
50     int next;
51     do {
52       next = findNextSeparator(str, current);
53       final TextRange range = new TextRange(offset + current + 1, offset + (next > 0 ? next : str.length()));
54       final T ref = createReference(range, index++);
55       references.add(ref);
56     } while ((current = next) >= 0);
57
58     return references;
59   }
60
61   protected int findNextSeparator(final String str, final int current) {
62     final int next;
63     next = str.indexOf(mySeparator, current + 1);
64     return next;
65   }
66
67   @NotNull
68   protected abstract T createReference(final TextRange range, final int index);
69
70   public PsiElement getElement() {
71     return myElement;
72   }
73
74   public List<T> getReferences() {
75     return myReferences;
76   }
77
78   public PsiReference[] getPsiReferences() {
79     return myReferences.toArray(new PsiReference[myReferences.size()]);
80   }
81
82   public T getReference(int index) {
83     return myReferences.get(index);
84   }
85
86   @Nullable
87   public T getLastReference() {
88     return myReferences.isEmpty() ? null : getReference(myReferences.size() - 1);
89   }
90 }