runResolvedWithCollection method

Future<List<ScanDiagnostic>?> runResolvedWithCollection(
  1. AnalysisContextCollection collection
)

Runs the resolved scan for dartFiles against an already-built collection instead of creating a new one.

runResolved pays the cost of building an AnalysisContextCollection (full package-graph discovery, on the order of a minute on a large project) on every call — fine for a one-shot CLI invocation, ruinous for a save-triggered scan. A long-lived caller (the scan daemon) builds the collection once for the whole project and reuses it across requests; this method notifies the collection of the changed files via AnalysisContext.changeFile/AnalysisContext.applyPendingFileChanges so only the edited units are re-resolved, then scans them.

Implementation

Future<List<ScanDiagnostic>?> runResolvedWithCollection(
  AnalysisContextCollection collection,
) async {
  // Disable the Problems-tab cap when the caller requests complete output.
  if (disableIssueCap) ProgressTracker.setMaxIssues(0);

  final plan = _prepare();
  if (plan == null) return null;
  if (plan.files.isEmpty) return const [];

  // A file the target project's analyzer config excludes (or one outside
  // the collection's roots entirely) makes contextFor throw a StateError.
  // For a save-triggered daemon request that must degrade to a skip — the
  // user saved a file their own config says not to analyze — not an error
  // response, so partition the request into scannable files + skips first.
  final absFiles = <String>[];
  for (final f in plan.files.map(p.absolute).map(p.normalize)) {
    try {
      collection.contextFor(f).changeFile(f);
      absFiles.add(f);
    } on StateError {
      _err('  Skipping (outside analysis roots or excluded): $f');
    }
  }
  if (absFiles.isEmpty) return const [];
  final affectedContexts = {
    for (final f in absFiles) collection.contextFor(f),
  };
  for (final ctx in affectedContexts) {
    await ctx.applyPendingFileChanges();
  }

  final registrations = _registerRules(
    plan.rules,
    () => ResolvedScanRuleContext(definingUnit: _dummyContextUnit()),
  );
  final diagnostics = <ScanDiagnostic>[];
  final visitorRule = _visitorRuleMap(registrations);
  for (final f in absFiles) {
    await _scanSingleFileResolved(
      collection,
      f,
      registrations,
      visitorRule,
      diagnostics,
    );
  }
  return diagnostics;
}