clear cls method hierarchy cache not only on root change (EA-68165 - PIEAE: ClsRepositoryPsiElement.getManager)

This commit is contained in:
peter
2015-05-19 17:10:14 +02:00
parent e4812372b9
commit f668c2bfc4
5 changed files with 32 additions and 9 deletions
@@ -18,7 +18,6 @@ package com.intellij.psi.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootModificationTracker;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
@@ -395,12 +394,10 @@ public class PsiSuperMethodImplUtil {
result = new HierarchicalMethodSignatureImpl((MethodSignatureBackedByPsiMethod)method.getSignature(PsiSubstitutor.EMPTY));
}
Project project = aClass == null ? method.getProject() : aClass.getProject();
// cache Cls method hierarchy until root changed
Object dependency = method instanceof PsiCompiledElement ? ProjectRootModificationTracker.getInstance(project) :
!method.isPhysical() ? method :
PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT;
return CachedValueProvider.Result.create(result, dependency);
if (!method.isPhysical()) {
return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, method);
}
return CachedValueProvider.Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
};
@@ -14,7 +14,9 @@
* limitations under the License.
*/
package com.intellij.psi.resolve
import com.intellij.openapi.application.ex.PathManagerEx
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
@@ -217,4 +219,22 @@ class Testcase {
myFixture.checkHighlighting()
}
public void "test update method hierarchy on class file change"() {
myFixture.testDataPath = PathManagerEx.getTestDataPath() + "/libResolve/methodHierarchy"
myFixture.copyDirectoryToProject("", "lib")
PsiTestUtil.addLibrary(myModule, "lib", myFixture.tempDirFixture.getFile("").path, "lib");
def message = JavaPsiFacade.getInstance(project).findClass('com.google.protobuf.AbstractMessageLite',
GlobalSearchScope.allScope(project))
assert message
def method = message.findMethodsByName("toByteArray", false)[0]
assert method
assert method.hierarchicalMethodSignature.superSignatures.size() == 1
WriteCommandAction.runWriteCommandAction(project) {
message.interfaces[0].containingFile.virtualFile.delete(this)
}
assert method.hierarchicalMethodSignature.superSignatures.size() == 0
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.stubs.PsiFileStubImpl;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.ExceptionUtil;
@@ -143,8 +144,13 @@ public class PsiInvalidElementAccessException extends RuntimeException implement
String m = "parent is null";
if (root instanceof StubBasedPsiElement) {
StubElement stub = ((StubBasedPsiElement)root).getStub();
m += "; stub=" + stub;
if (stub != null) m += "; p.s.=" + stub.getParentStub();
while (stub != null) {
m += "\n each stub=" + stub;
if (stub instanceof PsiFileStubImpl) {
m += "; fileStub.psi=" + stub.getPsi() + "; reason=" + ((PsiFileStubImpl)stub).getInvalidationReason();
}
stub = stub.getParentStub();
}
}
return m;
}