d2c292239e906bac239337f8f37acbff756f52d6
[idea/community.git] / platform / core-impl / src / com / intellij / psi / impl / PsiCachedValue.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
17 package com.intellij.psi.impl;
18
19 import com.intellij.psi.PsiManager;
20 import com.intellij.psi.PsiElement;
21 import com.intellij.psi.PsiDirectory;
22 import com.intellij.psi.PsiFile;
23 import com.intellij.psi.util.PsiModificationTracker;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.util.CachedValueBase;
26 import org.jetbrains.annotations.NotNull;
27
28 /**
29  * @author Dmitry Avdeev
30  */
31 public abstract class PsiCachedValue<T> extends CachedValueBase<T> {
32   private final PsiManager myManager;
33   protected long myLastPsiTimeStamp = -1;
34
35   public PsiCachedValue(@NotNull PsiManager manager) {
36     myManager = manager;
37   }
38
39   @Override
40   protected Data<T> computeData(T value, Object[] dependencies) {
41     Data<T> data = super.computeData(value, dependencies);
42
43     myLastPsiTimeStamp = myManager.getModificationTracker().getModificationCount();
44
45     return data;
46   }
47
48   @Override
49   protected boolean isUpToDate(@NotNull Data data) {
50     return !myManager.isDisposed() && super.isUpToDate(data);
51   }
52
53   @Override
54   protected boolean isDependencyOutOfDate(Object dependency, long oldTimeStamp) {
55     if (dependency instanceof PsiElement &&
56         myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount() &&
57         ((PsiElement)dependency).isPhysical()) {
58       return false;
59     }
60
61     return super.isDependencyOutOfDate(dependency, oldTimeStamp);
62   }
63
64   @Override
65   protected long getTimeStamp(Object dependency) {
66
67     if (dependency instanceof PsiDirectory) {
68       return myManager.getModificationTracker().getOutOfCodeBlockModificationCount();
69     }
70
71     if (dependency instanceof PsiElement) {
72       PsiElement element = (PsiElement)dependency;
73       if (!element.isValid()) return -1;
74       PsiFile containingFile = element.getContainingFile();
75       if (containingFile == null) return -1;
76       return containingFile.getModificationStamp();
77     }
78
79     if (dependency == PsiModificationTracker.MODIFICATION_COUNT) {
80       return myManager.getModificationTracker().getModificationCount();
81     }
82     if (dependency == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) {
83       return myManager.getModificationTracker().getOutOfCodeBlockModificationCount();
84     }
85     if (dependency == PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT) {
86       return myManager.getModificationTracker().getJavaStructureModificationCount();
87     }
88
89     return super.getTimeStamp(dependency);
90   }
91
92   @Override
93   public boolean isFromMyProject(Project project) {
94     return myManager.getProject() == project;
95   }
96 }