Skip to content

Commit

Permalink
restart daemon for the whole file when RefCountHolder is GCed and que…
Browse files Browse the repository at this point in the history
…ried back for the file subrange, to fix IDEA-274142 Highlighting glitch: All members are unused sporadically

GitOrigin-RevId: c6e6ed92ba948a8c0ebdadbfa3511949043b42ff
  • Loading branch information
cdracm authored and intellij-monorepo-bot committed Jul 21, 2021
1 parent fe8ee93 commit 119c553
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,13 @@ public boolean analyze(@NotNull PsiFile file, boolean updateWholeFile, @NotNull
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
TextRange dirtyScope = document == null ? null : DaemonCodeAnalyzerEx.getInstanceEx(project).getFileStatusMap().getFileDirtyScope(document, Pass.UPDATE_ALL);
if (dirtyScope == null) dirtyScope = file.getTextRange();
RefCountHolder refCountHolder = RefCountHolder.get(file, dirtyScope.equals(file.getTextRange()));
RefCountHolder refCountHolder = RefCountHolder.get(file, dirtyScope);
if (refCountHolder == null) {
// RefCountHolder was GCed and queried again for some inner code block
// "highlight.run()" can't fill it again because it runs for only a subset of elements,
// so we have to restart the daemon for the whole file
return false;
}
myRefCountHolder = refCountHolder;

highlight.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiMatcherImpl;
Expand Down Expand Up @@ -39,11 +40,16 @@ final class RefCountHolder {

private static final Key<Reference<RefCountHolder>> REF_COUNT_HOLDER_IN_FILE_KEY = Key.create("REF_COUNT_HOLDER_IN_FILE_KEY");
private volatile boolean ready; // true when analysis completed and inner maps can be queried
@NotNull
static RefCountHolder get(@NotNull PsiFile file, boolean alwaysNew) {

static RefCountHolder get(@NotNull PsiFile file, @NotNull TextRange dirtyScope) {
Reference<RefCountHolder> ref = file.getUserData(REF_COUNT_HOLDER_IN_FILE_KEY);
RefCountHolder storedHolder = com.intellij.reference.SoftReference.dereference(ref);
return storedHolder == null || alwaysNew ?
boolean wholeFile = dirtyScope.equals(file.getTextRange());
if (storedHolder == null && !wholeFile) {
// RefCountHolder was GCed and queried for subrange of the file, can't return anything meaningful
return null;
}
return storedHolder == null || wholeFile ?
new RefCountHolder(file, MultiMap.createConcurrentSet(), ConcurrentCollectionFactory.createConcurrentSet(HashingStrategy.canonical()), ConcurrentCollectionFactory.createConcurrentMap())
: storedHolder.removeInvalidRefs();
}
Expand Down

0 comments on commit 119c553

Please sign in to comment.