runResolvedWithCollection method
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;
}