resolveImportsRecursively function
void
resolveImportsRecursively(})
Recursively collects a Dart source file and its relative imports.
A HOST-SIDE utility, not a sandbox boundary: by default it reads whatever
the host process can read. The script runners above route their reads
through the interpreter's permissions instead; readFile is how
executeFileContinued does that. Hosts use it to bundle trusted sources
(tom_d4rt_flutter's sample loader).
source The Dart source code to analyze.
sourceUri The URI of the source file (used as key in sources map and for
resolving relative imports).
sources The map to populate with URI -> source code pairs.
log Optional logging function for debugging.
readFile Reads one imported file by path; defaults to a plain read.
Implementation
void resolveImportsRecursively(
String source,
String sourceUri,
Map<String, String> sources,
void Function(String)? log, {
String Function(String path)? readFile,
}) {
if (sources.containsKey(sourceUri)) return;
sources[sourceUri] = source;
log?.call('Added to sources: $sourceUri');
final base = Uri.parse(sourceUri);
if (base.scheme != 'file') return;
for (final match in _importRegex.allMatches(source)) {
final importPath = match.group(1)!;
// package: and dart: imports are handled by D4rt's bridge system.
if (importPath.startsWith('package:') || importPath.startsWith('dart:')) {
continue;
}
// `Uri.resolve` handles `.`, `..` and absolute paths per RFC 3986.
final resolved = base.resolve(importPath);
if (resolved.scheme != 'file') continue;
final resolvedUri = resolved.toString();
if (sources.containsKey(resolvedUri)) continue;
final filePath = resolved.toFilePath();
if (!File(filePath).existsSync()) {
log?.call('Warning: Imported file not found: $filePath');
continue;
}
final importedSource = (readFile ?? _readPlain)(filePath);
log?.call('Loading imported file: $filePath');
resolveImportsRecursively(
importedSource,
resolvedUri,
sources,
log,
readFile: readFile,
);
}
}