update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / source / resolve / JavaResolveCache.java
blobca5a5503ea2d5191f464d676f3d023ebfd29d867
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.
18 * @author max
20 package com.intellij.psi.impl.source.resolve;
22 import com.intellij.openapi.components.ServiceManager;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.util.Key;
26 import com.intellij.psi.PsiEllipsisType;
27 import com.intellij.psi.PsiExpression;
28 import com.intellij.psi.PsiType;
29 import com.intellij.psi.PsiVariable;
30 import com.intellij.psi.impl.PsiManagerEx;
31 import com.intellij.util.ConcurrencyUtil;
32 import com.intellij.util.Function;
33 import com.intellij.util.containers.ConcurrentWeakHashMap;
34 import org.jetbrains.annotations.NonNls;
35 import org.jetbrains.annotations.NotNull;
36 import org.jetbrains.annotations.Nullable;
38 import java.util.Map;
39 import java.util.Set;
40 import java.util.concurrent.ConcurrentMap;
42 public class JavaResolveCache {
43 private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.JavaResolveCache");
45 public static JavaResolveCache getInstance(Project project) {
46 return ServiceManager.getService(project, JavaResolveCache.class);
49 private final ConcurrentMap<PsiExpression, PsiType> myCalculatedTypes = new ConcurrentWeakHashMap<PsiExpression, PsiType>();
50 private static final Key<ResolveCache.MapPair<PsiVariable, Object>> VAR_TO_CONST_VALUE_MAP_KEY = Key.create("ResolveCache.VAR_TO_CONST_VALUE_MAP_KEY");
52 private final Map<PsiVariable,Object> myVarToConstValueMap1;
53 private final Map<PsiVariable,Object> myVarToConstValueMap2;
55 private static final Object NULL = Key.create("NULL");
56 private static final PsiType NULL_TYPE = new PsiEllipsisType(PsiType.NULL){
57 public boolean isValid() {
58 return true;
61 @NonNls
62 public String getPresentableText() {
63 return "FAKE TYPE";
67 public JavaResolveCache(PsiManagerEx manager) {
68 ResolveCache cache = manager.getResolveCache();
70 myVarToConstValueMap1 = cache.getOrCreateWeakMap(VAR_TO_CONST_VALUE_MAP_KEY, true);
71 myVarToConstValueMap2 = cache.getOrCreateWeakMap(VAR_TO_CONST_VALUE_MAP_KEY, false);
73 final Runnable cleanuper = new Runnable() {
74 public void run() {
75 myCalculatedTypes.clear();
79 cache.addRunnableToRunOnDropCaches(cleanuper);
80 manager.registerRunnableToRunOnAnyChange(cleanuper);
83 @Nullable
84 public <T extends PsiExpression> PsiType getType(@NotNull T expr, @NotNull Function<T, PsiType> f) {
85 PsiType type = myCalculatedTypes.get(expr);
86 if (type == null) {
87 type = f.fun(expr);
88 if (type == null) {
89 type = NULL_TYPE;
91 type = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type);
93 if (!type.isValid()) {
94 LOG.error("Type is invalid: " + type+"; expr: '"+expr+"' is "+(expr.isValid() ? "valid":"invalid"));
96 return type == NULL_TYPE ? null : type;
99 @Nullable
100 public Object computeConstantValueWithCaching(PsiVariable variable, ConstValueComputer computer, Set<PsiVariable> visitedVars){
101 boolean physical = variable.isPhysical();
103 Object cached = (physical ? myVarToConstValueMap1 : myVarToConstValueMap2).get(variable);
104 if (cached == NULL) return null;
105 if (cached != null) return cached;
107 Object result = computer.execute(variable, visitedVars);
109 (physical ? myVarToConstValueMap1 : myVarToConstValueMap2).put(variable, result != null ? result : NULL);
111 return result;
114 public interface ConstValueComputer{
115 Object execute(PsiVariable variable, Set<PsiVariable> visitedVars);