update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / source / resolve / reference / impl / providers / JavaClassReferenceProvider.java
blob7c9004f6f66f0e07a6a1d3e9aff56e1b0c20d9fb
1 /*
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;
35 import java.util.Map;
37 /**
38 * Created by IntelliJ IDEA.
39 * User: ik
40 * Date: 27.03.2003
41 * Time: 17:30:38
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) {
67 myScope = scope;
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);
84 }, false);
87 public JavaClassReferenceProvider(final Project project) {
88 this(null, 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);
98 @Nullable
99 public <T> T getOption(CustomizationKey<T> option) {
100 return myOptions == null ? null : (T)myOptions.get(option);
103 @Nullable
104 public GlobalSearchScope getScope() {
105 return myScope;
108 @NotNull
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);
119 @NotNull
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) {
154 myOptions = options;
157 @Nullable
158 public Map<CustomizationKey, Object> getOptions() {
159 return myOptions;
162 public void setAllowEmpty(final boolean allowEmpty) {
163 myAllowEmpty = allowEmpty;