provision method
Resolves and loads every package: import reachable from the currently
loaded modules (transitively), returning any diagnostics (unresolved
packages, or sources that ApolloVM's Dart subset can't parse).
Implementation
Future<List<ImportDiagnostic>> provision() async {
var diagnostics = <ImportDiagnostic>[];
var seen = <String>{};
var queue = <PackageUri>[];
// Seed from all currently-loaded modules' `package:` imports.
for (var unit in vm.allCodeUnits(language)) {
var root = unit.root;
if (root == null) continue;
for (var uri in _packageImportsOf(root)) {
if (seen.add(uri.moduleId)) queue.add(uri);
}
}
while (queue.isNotEmpty) {
var uri = queue.removeLast();
if (_isLoaded(uri.moduleId)) continue;
PackageSource? pkgSource;
try {
pkgSource = await provider.resolvePackageUri(uri);
} catch (e) {
diagnostics.add(
ImportDiagnostic(
kind: ImportDiagnosticKind.missingModule,
moduleId: uri.moduleId,
message: "Failed to fetch package import '${uri.moduleId}': $e",
importPath: uri.moduleId,
),
);
continue;
}
if (pkgSource == null) {
diagnostics.add(
ImportDiagnostic.missingModule(uri.moduleId, uri.moduleId),
);
continue;
}
var unit = SourceCodeUnit(
language,
pkgSource.source,
id: pkgSource.moduleId,
);
try {
await vm.loadCodeUnit(unit);
} catch (e) {
// Real-world package sources may use Dart features outside ApolloVM's
// supported subset; record and keep going rather than aborting.
diagnostics.add(
ImportDiagnostic(
kind: ImportDiagnosticKind.missingModule,
moduleId: uri.moduleId,
message:
"Loaded package '${uri.moduleId}' but it couldn't be parsed by "
"ApolloVM's Dart subset: $e",
importPath: uri.moduleId,
severity: ImportDiagnosticSeverity.warning,
),
);
continue;
}
// Enqueue the package's own `package:` imports (transitive).
var root = unit.root;
if (root != null) {
for (var next in _packageImportsOf(root)) {
if (seen.add(next.moduleId)) queue.add(next);
}
}
}
return diagnostics;
}