From 0bc7ae621060e6f31cce7bc83f3aa8f34536f96f Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 12 Jan 2015 19:00:18 +0100 Subject: [PATCH] [revert] Platform: race condition in global inspections fixed --- .../reference/RefJavaManagerImpl.java | 28 ++-- .../reference/RefManagerImpl.java | 134 ++++++++---------- 2 files changed, 76 insertions(+), 86 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java index 96bb8becf44a..b03f804fdd45 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java @@ -23,7 +23,10 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; import com.intellij.codeInspection.ex.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.UserDataCache; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; @@ -161,20 +164,21 @@ public class RefJavaManagerImpl extends RefJavaManager { } @Override - public RefParameter getParameterReference(final PsiParameter param, final int index) { + public RefParameter getParameterReference(PsiParameter param, int index) { LOG.assertTrue(myRefManager.isValidPointForReference(), "References may become invalid after process is finished"); - - return myRefManager.getFromRefTableOrCache(param, new NullableFactory() { - @Nullable - @Override - public RefParameter create() { - RefParameter ref = new RefParameterImpl(param, index, myRefManager); - ((RefParameterImpl)ref).initialize(); - return ref; - } - }); + RefElement ref = myRefManager.getFromRefTable(param); + + if (ref == null) { + ref = new RefParameterImpl(param, index, myRefManager); + ((RefParameterImpl)ref).initialize(); + myRefManager.putToRefTable(param, ref); + } + + return (RefParameter)ref; } + + @Override public void iterate(@NotNull final RefVisitor visitor) { if (myPackages != null) { diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index e88eb0098920..aa84edc6b21b 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -44,7 +44,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectUtilCore; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.NullableFactory; import com.intellij.openapi.util.Segment; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; @@ -341,6 +340,11 @@ public class RefManagerImpl extends RefManager { return myRefProject; } + @NotNull + public Map getRefTable() { + return myRefTable; + } + @NotNull public List getSortedElements() { LOG.assertTrue(myRefTable != null); @@ -367,7 +371,7 @@ public class RefManagerImpl extends RefManager { public void removeReference(@NotNull RefElement refElem) { myLock.writeLock().lock(); try { - final Map refTable = myRefTable; + final Map refTable = getRefTable(); final PsiElement element = refElem.getElement(); final RefManagerExtension extension = element != null ? getExtension(element.getLanguage()) : null; if (extension != null) { @@ -456,42 +460,47 @@ public class RefManagerImpl extends RefManager { return null; } - return getFromRefTableOrCache(elem, new NullableFactory() { + RefElement ref = getFromRefTable(elem); + if (ref != null) return ref; + if (!isValidPointForReference()) { + //LOG.assertTrue(true, "References may become invalid after process is finished"); + return null; + } + + final RefElementImpl refElement = ApplicationManager.getApplication().runReadAction(new Computable() { @Override - public RefElement create() { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - @Nullable - public RefElementImpl compute() { - RefElementImpl result = null; - - final RefManagerExtension extension = getExtension(elem.getLanguage()); - if (extension != null) { - final RefElement refElement = extension.createRefElement(elem); - result = (RefElementImpl)refElement; - } - else if (elem instanceof PsiFile) { - result = new RefFileImpl((PsiFile)elem, RefManagerImpl.this); - } - else if (elem instanceof PsiDirectory) { - result = new RefDirectoryImpl((PsiDirectory)elem, RefManagerImpl.this); - } - - if (result == null) { - return null; - } - - result.initialize(); - for (RefManagerExtension each : myExtensions.values()) { - each.onEntityInitialized(result, elem); - } - fireNodeInitialized(result); - - return result; - } - }); + @Nullable + public RefElementImpl compute() { + final RefManagerExtension extension = getExtension(elem.getLanguage()); + if (extension != null) { + final RefElement refElement = extension.createRefElement(elem); + if (refElement != null) return (RefElementImpl)refElement; + } + if (elem instanceof PsiFile) { + return new RefFileImpl((PsiFile)elem, RefManagerImpl.this); + } + if (elem instanceof PsiDirectory) { + return new RefDirectoryImpl((PsiDirectory)elem, RefManagerImpl.this); + } + return null; } }); + if (refElement == null) return null; + + putToRefTable(elem, refElement); + + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + refElement.initialize(); + for (RefManagerExtension extension : myExtensions.values()) { + extension.onEntityInitialized(refElement, elem); + } + fireNodeInitialized(refElement); + } + }); + + return refElement; } private RefManagerExtension getExtension(final Language language) { @@ -526,57 +535,34 @@ public class RefManagerImpl extends RefManager { return null; } - @Nullable - protected T getFromRefTableOrCache(final PsiElement element, NullableFactory factory) { - T result; - + protected RefElement getFromRefTable(final PsiElement element) { myLock.readLock().lock(); try { - //noinspection unchecked - result = (T)myRefTable.get(ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public PsiAnchor compute() { - return PsiAnchor.create(element); + return getRefTable().get(ApplicationManager.getApplication().runReadAction( + new Computable() { + @Override + public PsiAnchor compute() { + return PsiAnchor.create(element); + } } - } )); - if (result != null) return result; } finally { myLock.readLock().unlock(); } + } - if (!isValidPointForReference()) { - //LOG.assertTrue(true, "References may become invalid after process is finished"); - return null; - } - + protected void putToRefTable(final PsiElement element, final RefElement ref) { myLock.writeLock().lock(); try { - //noinspection unchecked - result = (T)myRefTable.get(ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public PsiAnchor compute() { - return PsiAnchor.create(element); + getRefTable().put(ApplicationManager.getApplication().runReadAction( + new Computable() { + @Override + public PsiAnchor compute() { + return PsiAnchor.create(element); + } } - } - )); - if (result != null) return result; - - result = factory.create(); - if (result == null) return null; - - myRefTable.put(ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public PsiAnchor compute() { - return PsiAnchor.create(element); - } - } - ), result); - return result; + ), ref); } finally { myLock.writeLock().unlock();