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
.impl
.source
.resolve
.reference
.impl
.providers
;
18 import com
.intellij
.openapi
.project
.Project
;
19 import com
.intellij
.openapi
.util
.text
.StringUtil
;
20 import com
.intellij
.psi
.*;
21 import com
.intellij
.psi
.scope
.ElementClassHint
;
22 import com
.intellij
.psi
.scope
.PsiScopeProcessor
;
23 import com
.intellij
.psi
.search
.GlobalSearchScope
;
24 import com
.intellij
.psi
.util
.*;
25 import com
.intellij
.util
.NullableFunction
;
26 import com
.intellij
.util
.ProcessingContext
;
27 import com
.intellij
.util
.containers
.ContainerUtil
;
28 import gnu
.trove
.THashMap
;
29 import org
.jetbrains
.annotations
.NotNull
;
30 import org
.jetbrains
.annotations
.Nullable
;
32 import java
.util
.ArrayList
;
33 import java
.util
.Collection
;
34 import java
.util
.List
;
38 * Created by IntelliJ IDEA.
42 * To change this template use Options | File Templates.
44 public class JavaClassReferenceProvider
extends GenericReferenceProvider
implements CustomizableReferenceProvider
{
46 public static final CustomizationKey
<Boolean
> RESOLVE_QUALIFIED_CLASS_NAME
=
47 new CustomizationKey
<Boolean
>(PsiBundle
.message("qualified.resolve.class.reference.provider.option"));
48 public static final CustomizationKey
<String
[]> EXTEND_CLASS_NAMES
= new CustomizationKey
<String
[]>("EXTEND_CLASS_NAMES");
49 public static final CustomizationKey
<String
> CLASS_TEMPLATE
= new CustomizationKey
<String
>("CLASS_TEMPLATE");
50 public static final CustomizationKey
<ClassKind
> CLASS_KIND
= new CustomizationKey
<ClassKind
>("CLASS_KIND");
51 public static final CustomizationKey
<Boolean
> INSTANTIATABLE
= new CustomizationKey
<Boolean
>("INSTANTIATABLE");
52 public static final CustomizationKey
<Boolean
> CONCRETE
= new CustomizationKey
<Boolean
>("CONCRETE");
53 public static final CustomizationKey
<Boolean
> NOT_INTERFACE
= new CustomizationKey
<Boolean
>("NOT_INTERFACE");
54 public static final CustomizationKey
<Boolean
> NOT_ENUM
= new CustomizationKey
<Boolean
>("NOT_ENUM");
55 public static final CustomizationKey
<Boolean
> ADVANCED_RESOLVE
= new CustomizationKey
<Boolean
>("RESOLVE_ONLY_CLASSES");
56 public static final CustomizationKey
<Boolean
> JVM_FORMAT
= new CustomizationKey
<Boolean
>("JVM_FORMAT");
57 public static final CustomizationKey
<Boolean
> ALLOW_DOLLAR_NAMES
= new CustomizationKey
<Boolean
>("ALLOW_DOLLAR_NAMES");
58 public static final CustomizationKey
<String
> DEFAULT_PACKAGE
= new CustomizationKey
<String
>("DEFAULT_PACKAGE");
60 @Nullable private Map
<CustomizationKey
, Object
> myOptions
;
61 private boolean myAllowEmpty
;
62 @Nullable private final GlobalSearchScope myScope
;
63 private final CachedValue
<List
<PsiElement
>> myDefaltPackages
;
66 public JavaClassReferenceProvider(GlobalSearchScope scope
, final Project project
) {
68 myDefaltPackages
= PsiManager
.getInstance(project
).getCachedValuesManager().createCachedValue(new CachedValueProvider
<List
<PsiElement
>>() {
69 public Result
<List
<PsiElement
>> compute() {
70 final List
<PsiElement
> psiPackages
= new ArrayList
<PsiElement
>();
71 final String defPackageName
= DEFAULT_PACKAGE
.getValue(myOptions
);
72 if (StringUtil
.isNotEmpty(defPackageName
)) {
73 final PsiPackage defaultPackage
= JavaPsiFacade
.getInstance(project
).findPackage(defPackageName
);
74 if (defaultPackage
!= null) {
75 psiPackages
.addAll(getSubPackages(defaultPackage
));
78 final PsiPackage rootPackage
= JavaPsiFacade
.getInstance(project
).findPackage("");
79 if (rootPackage
!= null) {
80 psiPackages
.addAll(getSubPackages(rootPackage
));
82 return Result
.createSingleDependency(psiPackages
, PsiModificationTracker
.MODIFICATION_COUNT
);
87 public JavaClassReferenceProvider(final Project project
) {
91 public <T
> void setOption(CustomizationKey
<T
> option
, T value
) {
92 if (myOptions
== null) {
93 myOptions
= new THashMap
<CustomizationKey
, Object
>();
95 option
.putValue(myOptions
, value
);
99 public <T
> T
getOption(CustomizationKey
<T
> option
) {
100 return myOptions
== null ?
null : (T
)myOptions
.get(option
);
104 public GlobalSearchScope
getScope() {
109 public PsiReference
[] getReferencesByElement(@NotNull PsiElement element
, @NotNull final ProcessingContext context
) {
110 return getReferencesByElement(element
);
113 public PsiReference
[] getReferencesByElement(@NotNull PsiElement element
) {
114 final int offsetInElement
= ElementManipulators
.getOffsetInElement(element
);
115 final String text
= ElementManipulators
.getValueText(element
);
116 return getReferencesByString(text
, element
, offsetInElement
);
120 public PsiReference
[] getReferencesByString(String str
, PsiElement position
, int offsetInPosition
) {
121 if (myAllowEmpty
&& StringUtil
.isEmpty(str
)) {
122 return PsiReference
.EMPTY_ARRAY
;
124 boolean allowDollars
= Boolean
.TRUE
.equals(getOption(ALLOW_DOLLAR_NAMES
));
125 return new JavaClassReferenceSet(str
, position
, offsetInPosition
, allowDollars
, this).getAllReferences();
128 public void handleEmptyContext(PsiScopeProcessor processor
, PsiElement position
) {
129 final ElementClassHint hint
= processor
.getHint(ElementClassHint
.KEY
);
130 if (position
== null) return;
131 if (hint
== null || hint
.shouldProcess(ElementClassHint
.DeclaractionKind
.PACKAGE
) || hint
.shouldProcess(ElementClassHint
.DeclaractionKind
.CLASS
)) {
132 final List
<PsiElement
> cachedPackages
= getDefaultPackages();
133 for (final PsiElement psiPackage
: cachedPackages
) {
134 if (!processor
.execute(psiPackage
, ResolveState
.initial())) return;
139 protected List
<PsiElement
> getDefaultPackages() {
140 return myDefaltPackages
.getValue();
143 private static Collection
<PsiPackage
> getSubPackages(final PsiPackage defaultPackage
) {
144 return ContainerUtil
.mapNotNull(defaultPackage
.getSubPackages(), new NullableFunction
<PsiPackage
, PsiPackage
>() {
145 public PsiPackage
fun(final PsiPackage psiPackage
) {
146 final String packageName
= psiPackage
.getName();
147 return JavaPsiFacade
.getInstance(psiPackage
.getProject()).getNameHelper()
148 .isIdentifier(packageName
, PsiUtil
.getLanguageLevel(psiPackage
)) ? psiPackage
: null;
153 public void setOptions(@Nullable Map
<CustomizationKey
, Object
> options
) {
158 public Map
<CustomizationKey
, Object
> getOptions() {
162 public void setAllowEmpty(final boolean allowEmpty
) {
163 myAllowEmpty
= allowEmpty
;