Skip to content

Commit eafcc69

Browse files
Detect dependency loops in module migrator
1 parent 0852083 commit eafcc69

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/src/migrators/module.dart

+22
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
200200
/// The values of the --forward flag.
201201
final Set<ForwardType> forwards;
202202

203+
// Maps direct and indirect dependencies to prevent any potential loops.
204+
final Map<Uri, Uri> _dependencies = {};
205+
206+
void _addDependency(Uri source, Uri importedPath) {
207+
if (_dependencies.containsKey(importedPath) &&
208+
_dependencies[importedPath] == source) {
209+
// Throw an error indicating a potential loop.
210+
var sourceUrl = _absoluteUrlToDependency(source);
211+
var importedPathUrl = _absoluteUrlToDependency(importedPath);
212+
throw MigrationException(
213+
'Dependency loop detected: ${sourceUrl.item1} -> ${importedPathUrl.item1}');
214+
}
215+
_dependencies[source] = importedPath;
216+
}
217+
203218
/// Constructs a new module migration visitor.
204219
///
205220
/// [importCache] must be the same one used by [references].
@@ -1239,6 +1254,13 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
12391254
var url = declaration.sourceUrl;
12401255
if (url == currentUrl) return null;
12411256

1257+
// Trace dependencies for loop detection.
1258+
try {
1259+
_addDependency(currentUrl, url);
1260+
} on Exception catch (e) {
1261+
throw MigrationSourceSpanException(e.toString(), declaration.member.span);
1262+
}
1263+
12421264
// If we can load [declaration] from a library entrypoint URL, do so. Choose
12431265
// the shortest one if there are multiple options.
12441266
var libraryUrls = references.libraries[declaration];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<==> arguments
2+
--migrate-deps
3+
4+
<==> input/entrypoint.scss
5+
@import "ejemplo";
6+
$var: $value;
7+
8+
<==> input/_ejemplo.scss
9+
$value: blue;
10+
a {
11+
color: $var;
12+
}
13+
14+
<==> error.txt
15+
Error: Error: Dependency loop detected: entrypoint -> ejemplo
16+
,
17+
1 | $value: blue;
18+
| ^^^^^^^^^^^^
19+
'
20+
_ejemplo.scss 1:1 root stylesheet
21+
Migration failed!

0 commit comments

Comments
 (0)