http://ea.jetbrains.com/browser/ea_problems/17270 : java class references suppressed...
[idea/community.git] / java / java-impl / src / com / intellij / psi / impl / source / resolve / reference / impl / providers / JavaClassListReferenceProvider.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.psi.impl.source.resolve.reference.impl.providers;
17
18 import com.intellij.openapi.progress.ProgressManager;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.util.NotNullLazyValue;
21 import com.intellij.psi.PsiElement;
22 import com.intellij.psi.PsiPackage;
23 import com.intellij.psi.PsiReference;
24 import com.intellij.psi.search.GlobalSearchScope;
25 import com.intellij.psi.templateLanguages.OuterLanguageElement;
26 import com.intellij.psi.xml.XmlTag;
27 import org.jetbrains.annotations.NotNull;
28
29 import java.util.*;
30
31 /**
32  * Created by IntelliJ IDEA.
33  * User: ik
34  * Date: 05.06.2003
35  * Time: 20:27:59
36  * To change this template use Options | File Templates.
37  */
38 public class JavaClassListReferenceProvider extends JavaClassReferenceProvider {
39
40   public JavaClassListReferenceProvider(final Project project) {
41     super(GlobalSearchScope.allScope(project), project);
42     setOption(ADVANCED_RESOLVE, Boolean.TRUE);
43   }
44
45   @NotNull
46   public PsiReference[] getReferencesByString(String str, PsiElement position, int offsetInPosition){
47     if (position instanceof XmlTag && ((XmlTag)position).getValue().getTextElements().length == 0) {
48       return PsiReference.EMPTY_ARRAY; 
49     }
50
51     if (str.length() < 2) {
52       return PsiReference.EMPTY_ARRAY;
53     }
54
55     if (position != null) {
56       int offset = position.getTextRange().getStartOffset() + offsetInPosition;
57       for(PsiElement child = position.getFirstChild(); child != null; child = child.getNextSibling()){
58         if (child instanceof OuterLanguageElement && child.getTextRange().contains(offset)) {
59           return PsiReference.EMPTY_ARRAY;
60         }
61       }
62     }
63
64     NotNullLazyValue<Set<String>> topLevelPackages = new NotNullLazyValue<Set<String>>() {
65       @NotNull
66       @Override
67       protected Set<String> compute() {
68         final Set<String> knownTopLevelPackages = new HashSet<String>();
69         final List<PsiElement> defaultPackages = getDefaultPackages();
70         for (final PsiElement pack : defaultPackages) {
71           if (pack instanceof PsiPackage) {
72             knownTopLevelPackages.add(((PsiPackage)pack).getName());
73           }
74         }
75         return knownTopLevelPackages;
76       }
77     };
78     final List<PsiReference> results = new ArrayList<PsiReference>();
79
80     for(int dot = str.indexOf('.'); dot > 0; dot = str.indexOf('.', dot + 1)) {
81       int start = dot;
82       while (start > 0 && Character.isLetterOrDigit(str.charAt(start - 1))) start--;
83       if (dot == start) {
84         continue;
85       }
86       String candidate = str.substring(start, dot);
87       if (topLevelPackages.getValue().contains(candidate)) {
88         int end = dot;
89         while (end < str.length() - 1) {
90           end++;
91           char ch = str.charAt(end);
92           if (ch != '.' && !Character.isJavaIdentifierPart(ch)) {
93             break;
94           }
95         }
96         String s = str.substring(start, end + 1);
97         results.addAll(Arrays.asList(new JavaClassReferenceSet(s, position, offsetInPosition + start, false, this){
98           public boolean isSoft(){
99             return true;
100           }
101         }.getAllReferences()));
102         ProgressManager.checkCanceled();
103       }
104     }
105     return results.toArray(new PsiReference[results.size()]);
106   }
107 }