void (@NotNull AnalysisScope scope, @NotNull InspectionManager inspectionManager, @NotNull List<? extends Tools> globalTools, boolean isOfflineInspections) { long timestamp = System.currentTimeMillis(); LOG.assertTrue(!ApplicationManager.getApplication().isReadAccessAllowed() || isOfflineInspections, "Must not run under read action, too unresponsive"); if (isOfflineInspections && System.getProperty("idea.offline.no.global.inspections") != null) { return; } IJTracer tracer = TelemetryManager.getInstance().getTracer(GlobalInspectionScope); long refGraphTimestamp = System.currentTimeMillis(); TraceUtil.runWithSpanThrows(tracer, "refGraphBuilding", (__) -> { buildRefGraphIfNeeded(globalTools); }); long refGraphDuration = System.currentTimeMillis() - refGraphTimestamp; List<InspectionToolWrapper<?, ?>> needRepeatSearchRequest = new ArrayList<>(); SearchScope initialSearchScope = ReadAction.compute(scope::toSearchScope); boolean canBeExternalUsages = !scope.isTotalScope(); TraceUtil.runWithSpanThrows(tracer, "globalInspectionsAnalysis", (__) -> { for (Tools tools : globalTools) { for (ScopeToolState state : tools.getTools()) { if (!state.isEnabled()) continue; NamedScope stateScope = state.getScope(getProject()); if (stateScope == null) continue; SearchScope intersectionScope = ReadAction.compute(() -> GlobalSearchScopesCore.filterScope(getProject(), stateScope) .intersectWith(initialSearchScope)); AnalysisScope scopeForState = new AnalysisScope(intersectionScope, getProject()); InspectionToolWrapper<?, ?> toolWrapper = state.getTool(); GlobalInspectionTool tool = (GlobalInspectionTool)toolWrapper.getTool(); InspectionToolResultExporter toolPresentation = getPresentation(toolWrapper); try { ThrowableRunnable<RuntimeException> runnable = () -> { reportWhenInspectionFinished( getInspectionEventPublisher(), toolWrapper, GLOBAL, null, getProject(), () -> { tool.runInspection(scopeForState, inspectionManager, this, toolPresentation); return toolPresentation.getProblemDescriptors().size(); }); //skip phase when we are sure that scope already contains everything, unused declaration though needs to proceed with its suspicious code if ((canBeExternalUsages || tool.getAdditionalJobs(this) != null) && tool.queryExternalUsagesRequests(inspectionManager, this, toolPresentation)) { needRepeatSearchRequest.add(toolWrapper); } }; if (tool.isReadActionNeeded()) { ReadAction.run(runnable); } else { runnable.run(); } } catch (ProcessCanceledException | IndexNotReadyException e) { throw e; } catch (Throwable e) { LOG.error(e); } } } }); reportWhenActivityFinished( getInspectionEventPublisher(), InspectListener.ActivityKind.GLOBAL_POST_RUN_ACTIVITIES, getProject(), () -> processPostRunActivities(needRepeatSearchRequest)); addProblemsToView(globalTools); logPerformance(refGraphDuration, System.currentTimeMillis() - timestamp, scope.getFileCount(), globalTools.size()); }