diff --git a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java index 9fd608eabcad..cf15c7920414 100644 --- a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java +++ b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java @@ -33,6 +33,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.DependencyScope; @@ -93,13 +94,11 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { public void visitFile(PsiFile file) { fileCount[0]++; final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); - } - progressIndicator.setText(AnalysisScopeBundle.message("scanning.scope.progress.title")); + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); } + progressIndicator.setText(AnalysisScopeBundle.message("scanning.scope.progress.title")); if (!(file instanceof PsiJavaFile)) return; final Module module = ModuleUtilCore.findModuleForPsiElement(file); if (module != null && processed.add(module)) { @@ -181,26 +180,30 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { final int fileCount) { final NullityInferrer inferrer = new NullityInferrer(isAnnotateLocalVariables(), project); final PsiManager psiManager = PsiManager.getInstance(project); - final Runnable searchForUsages = () -> scope.accept(new PsiElementVisitor() { - int myFileCount; + final Runnable searchForUsages = () -> { + ProgressIndicator indicator = ProgressManager.getGlobalProgressIndicator(); + ProgressIndicatorUtils.dropResolveCacheRegularly(indicator, project); + scope.accept(new PsiElementVisitor() { + int myFileCount; - @Override - public void visitFile(final PsiFile file) { - myFileCount++; - final VirtualFile virtualFile = file.getVirtualFile(); - final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); - final Document document = viewProvider == null ? null : viewProvider.getDocument(); - if (document == null || virtualFile.getFileType().isBinary()) return; //do not inspect binary files - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); - progressIndicator.setFraction(((double)myFileCount) / fileCount); + @Override + public void visitFile(final PsiFile file) { + myFileCount++; + final VirtualFile virtualFile = file.getVirtualFile(); + final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); + final Document document = viewProvider == null ? null : viewProvider.getDocument(); + if (document == null || virtualFile.getFileType().isBinary()) return; //do not inspect binary files + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator != null) { + progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); + progressIndicator.setFraction(((double)myFileCount) / fileCount); + } + if (file instanceof PsiJavaFile) { + inferrer.collect(file); + } } - if (file instanceof PsiJavaFile) { - inferrer.collect(file); - } - } - }); + }); + }; if (ApplicationManager.getApplication().isDispatchThread()) { if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(searchForUsages, INFER_NULLITY_ANNOTATIONS, true, project)) { return null; diff --git a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesHandler.java b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesHandler.java index 098649a56516..53d20a892f26 100644 --- a/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesHandler.java +++ b/java/java-impl/src/com/intellij/cyclicDependencies/actions/CyclicDependenciesHandler.java @@ -20,26 +20,34 @@ import com.intellij.analysis.AnalysisScopeBundle; import com.intellij.analysis.PerformAnalysisInBackgroundOption; import com.intellij.cyclicDependencies.CyclicDependenciesBuilder; import com.intellij.cyclicDependencies.ui.CyclicDependenciesPanel; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.Project; import com.intellij.packageDependencies.DependenciesToolWindow; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; +import org.jetbrains.annotations.NotNull; import javax.swing.*; public class CyclicDependenciesHandler { + @NotNull private final Project myProject; private final AnalysisScope myScope; - public CyclicDependenciesHandler(Project project, AnalysisScope scope) { + public CyclicDependenciesHandler(@NotNull Project project, AnalysisScope scope) { myProject = project; myScope = scope; } public void analyze() { final CyclicDependenciesBuilder builder = new CyclicDependenciesBuilder(myProject, myScope); - final Runnable process = () -> builder.analyze(); + final Runnable process = () -> { + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + ProgressIndicatorUtils.dropResolveCacheRegularly(indicator, myProject); + builder.analyze(); + }; final Runnable successRunnable = () -> SwingUtilities.invokeLater(() -> { CyclicDependenciesPanel panel = new CyclicDependenciesPanel(myProject, builder); Content content = ContentFactory.SERVICE.getInstance().createContent(panel, AnalysisScopeBundle.message( diff --git a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java index c9c86150d46d..d4b17010821c 100644 --- a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java +++ b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java @@ -228,7 +228,7 @@ public class AnalysisScope { } else if (myType == DIRECTORY || myType == PROJECT || myType == MODULES || myType == MODULE || myType == CUSTOM) { myFilesSet = new THashSet<>(); - accept(createFileSearcher(), false); + accept(createFileSearcher()); } else if (myType == VIRTUAL_FILES) { myFilesSet = new THashSet<>(); @@ -256,10 +256,6 @@ public class AnalysisScope { public void accept(@NotNull final PsiElementVisitor visitor) { - accept(visitor, true); - } - - private void accept(@NotNull final PsiElementVisitor visitor, final boolean clearResolveCache) { final boolean needReadAction = !ApplicationManager.getApplication().isReadAccessAllowed(); final PsiManager psiManager = PsiManager.getInstance(myProject); final FileIndex fileIndex = getFileIndex(); @@ -268,7 +264,7 @@ public class AnalysisScope { if (ProjectCoreUtil.isProjectOrWorkspaceFile(file)) return true; if (fileIndex.isInContent(file) && !isFilteredOut(file) && !GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(file, myProject)) { - return processFile(file, visitor, psiManager, needReadAction, clearResolveCache); + return processFile(file, visitor, psiManager, needReadAction); } return true; }); @@ -340,13 +336,12 @@ public class AnalysisScope { private static boolean processFile(@NotNull final VirtualFile vFile, @NotNull final PsiElementVisitor visitor, @NotNull final PsiManager psiManager, - final boolean needReadAction, - final boolean clearResolveCache) { + final boolean needReadAction) { if (needReadAction && !ApplicationManager.getApplication().isDispatchThread()) { - commitAndRunInSmartMode(() -> doProcessFile(visitor, psiManager, vFile, clearResolveCache), psiManager.getProject()); + commitAndRunInSmartMode(() -> doProcessFile(visitor, psiManager, vFile), psiManager.getProject()); } else { - doProcessFile(visitor, psiManager, vFile, clearResolveCache); + doProcessFile(visitor, psiManager, vFile); } final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); return indicator == null || !indicator.isCanceled(); @@ -389,18 +384,14 @@ public class AnalysisScope { } } - private static void doProcessFile(@NotNull PsiElementVisitor visitor, @NotNull PsiManager psiManager, @NotNull VirtualFile vFile, - boolean clearResolveCache) { + private static void doProcessFile(@NotNull PsiElementVisitor visitor, @NotNull PsiManager psiManager, @NotNull VirtualFile vFile) { ProgressManager.checkCanceled(); if (!vFile.isValid()) return; PsiFile psiFile = psiManager.findFile(vFile); if (psiFile == null || !shouldHighlightFile(psiFile)) return; psiFile.accept(visitor); - if (clearResolveCache) { - psiManager.dropResolveCaches(); - InjectedLanguageManager.getInstance(psiManager.getProject()).dropFileCaches(psiFile); - } + InjectedLanguageManager.getInstance(psiManager.getProject()).dropFileCaches(psiFile); } protected boolean accept(@NotNull final PsiDirectory dir, @NotNull final Processor processor) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index dee8a22415c7..4318bde685c4 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -431,7 +431,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp final List globalSimpleTools = new ArrayList<>(); initializeTools(globalTools, localTools, globalSimpleTools); appendPairedInspectionsForUnfairTools(globalTools, globalSimpleTools, localTools); - + ProgressIndicatorUtils.dropResolveCacheRegularly(progressIndicator, getProject()); runGlobalTools(scope, inspectionManager, globalTools, isOfflineInspections); if (runGlobalToolsOnly || localTools.isEmpty() && globalSimpleTools.isEmpty()) return; @@ -957,12 +957,12 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp Task task = modal ? new Task.Modal(getProject(), title, true) { @Override public void run(@NotNull ProgressIndicator indicator) { - cleanup(scope, profile, postRunnable, commandName, shouldApplyFix); + cleanup(scope, profile, postRunnable, commandName, shouldApplyFix, indicator); } } : new Task.Backgroundable(getProject(), title, true) { @Override public void run(@NotNull ProgressIndicator indicator) { - cleanup(scope, profile, postRunnable, commandName, shouldApplyFix); + cleanup(scope, profile, postRunnable, commandName, shouldApplyFix, indicator); } }; ProgressManager.getInstance().run(task); @@ -972,14 +972,12 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp @NotNull InspectionProfile profile, @Nullable final Runnable postRunnable, @Nullable final String commandName, - @NotNull Predicate shouldApplyFix) { + @NotNull Predicate shouldApplyFix, + @NotNull ProgressIndicator progressIndicator) { setCurrentScope(scope); final int fileCount = scope.getFileCount(); - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - progressIndicator.setIndeterminate(false); - } - + progressIndicator.setIndeterminate(false); + ProgressIndicatorUtils.dropResolveCacheRegularly(progressIndicator, getProject()); final SearchScope searchScope = ReadAction.compute(scope::toSearchScope); final TextRange range; if (searchScope instanceof LocalSearchScope) { @@ -1003,9 +1001,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp private int myCount; @Override public void visitFile(PsiFile file) { - if (progressIndicator != null) { - progressIndicator.setFraction((double)++myCount / fileCount); - } + progressIndicator.setFraction((double)++myCount / fileCount); if (isBinary(file)) return; final List lTools = new ArrayList<>(); for (final Tools tools : inspectionTools) { diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 22c2d3a57651..844713a9803e 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -28,6 +28,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -39,8 +40,10 @@ import com.intellij.openapi.util.Factory; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.StatusBar; -import com.intellij.openapi.wm.ex.ProgressIndicatorEx; -import com.intellij.psi.*; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiInvalidElementAccessException; import com.intellij.psi.search.*; import com.intellij.ui.LightweightHint; import com.intellij.ui.content.Content; @@ -79,12 +82,12 @@ public class FindUsagesManager { private static final Key KEY_START_USAGE_AGAIN = Key.create("KEY_START_USAGE_AGAIN"); @NonNls private static final String VALUE_START_USAGE_AGAIN = "START_AGAIN"; private final Project myProject; - private final com.intellij.usages.UsageViewManager myAnotherManager; + private final UsageViewManager myAnotherManager; private PsiElement2UsageTargetComposite myLastSearchInFileData; // EDT only private final UsageHistory myHistory = new UsageHistory(); - public FindUsagesManager(@NotNull Project project, @NotNull com.intellij.usages.UsageViewManager anotherManager) { + public FindUsagesManager(@NotNull Project project, @NotNull UsageViewManager anotherManager) { myProject = project; myAnotherManager = anotherManager; } @@ -340,7 +343,9 @@ public class FindUsagesManager { PsiElement[] secondaryElements = ReadAction.compute(() -> PsiElement2UsageTargetAdapter.convertToPsiElements(secondaryTargets)); Project project = ReadAction.compute(() -> scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject()); - dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), project); + ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + LOG.assertTrue(indicator != null, "Must run under progress. see ProgressManager.run*"); + ProgressIndicatorUtils.dropResolveCacheRegularly(indicator, project); if (scopeFile != null) { optionsClone.searchScope = new LocalSearchScope(scopeFile); @@ -427,26 +432,6 @@ public class FindUsagesManager { return usageView; } - private static void dropResolveCacheRegularly(ProgressIndicator indicator, @NotNull final Project project) { - if (indicator instanceof ProgressIndicatorEx) { - ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { - volatile long lastCleared = System.currentTimeMillis(); - - @Override - public void setFraction(double fraction) { - super.setFraction(fraction); - long current = System.currentTimeMillis(); - if (current - lastCleared >= 500) { - lastCleared = current; - // fraction is changed when each file is processed => - // resolve caches used when searching in that file are likely to be not needed anymore - PsiManager.getInstance(project).dropResolveCaches(); - } - } - }); - } - } - @NotNull private static UsageViewPresentation createPresentation(@NotNull PsiElement psiElement, @NotNull FindUsagesOptions options, diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/actions/DependenciesHandlerBase.java b/platform/lang-impl/src/com/intellij/packageDependencies/actions/DependenciesHandlerBase.java index 1f985a739feb..a8776ea3c156 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/actions/DependenciesHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/actions/DependenciesHandlerBase.java @@ -22,6 +22,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -42,11 +43,12 @@ import java.util.Set; * @author nik */ public abstract class DependenciesHandlerBase { + @NotNull protected final Project myProject; private final List myScopes; private final Set myExcluded; - public DependenciesHandlerBase(final Project project, final List scopes, Set excluded) { + public DependenciesHandlerBase(@NotNull Project project, final List scopes, Set excluded) { myScopes = scopes; myExcluded = excluded; myProject = project; @@ -61,7 +63,7 @@ public abstract class DependenciesHandlerBase { @Override public void run(@NotNull final ProgressIndicator indicator) { indicator.setIndeterminate(false); - perform(builders); + perform(builders, indicator); } @Override @@ -74,7 +76,7 @@ public abstract class DependenciesHandlerBase { @Override public void run(@NotNull ProgressIndicator indicator) { indicator.setIndeterminate(false); - perform(builders); + perform(builders, indicator); } @Override @@ -100,7 +102,8 @@ public abstract class DependenciesHandlerBase { protected abstract DependenciesBuilder createDependenciesBuilder(AnalysisScope scope); - private void perform(List builders) { + private void perform(List builders, @NotNull ProgressIndicator indicator) { + ProgressIndicatorUtils.dropResolveCacheRegularly(indicator, myProject); try { PerformanceWatcher.Snapshot snapshot = PerformanceWatcher.takeSnapshot(); for (AnalysisScope scope : myScopes) { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java index cb1137d3a8b0..d54b24ee9abe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java @@ -12,8 +12,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.Ref; +import com.intellij.openapi.wm.ex.ProgressIndicatorEx; +import com.intellij.psi.PsiManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.ide.PooledThreadExecutor; @@ -246,4 +249,25 @@ public class ProgressIndicatorUtils { } application.invokeAndWait(EmptyRunnable.INSTANCE, ModalityState.any()); } + + public static void dropResolveCacheRegularly(@NotNull ProgressIndicator indicator, @NotNull final Project project) { + indicator = ProgressWrapper.unwrap(indicator); + if (indicator instanceof ProgressIndicatorEx) { + ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { + volatile long lastCleared = System.currentTimeMillis(); + + @Override + public void setFraction(double fraction) { + super.setFraction(fraction); + long current = System.currentTimeMillis(); + if (current - lastCleared >= 500) { + lastCleared = current; + // fraction is changed when each file is processed => + // resolve caches used when searching in that file are likely to be not needed anymore + PsiManager.getInstance(project).dropResolveCaches(); + } + } + }); + } + } }