Skip to content

Commit

Permalink
Detect dependency loops in module migrator
Browse files Browse the repository at this point in the history
  • Loading branch information
pamelalozano16 committed Dec 12, 2023
1 parent 0852083 commit 41d4d36
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lib/src/migrators/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,19 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
/// The values of the --forward flag.
final Set<ForwardType> forwards;

// Maps direct and indirect dependencies to prevent any potential loops.
final Map<Uri, Uri> _dependencies = {};

void _addDependency(Uri source, Uri importedPath) {
if (_dependencies.containsKey(importedPath) && _dependencies[importedPath] == source) {
// Throw an error indicating a potential loop.
var sourceUrl = _absoluteUrlToDependency(source);
var importedPathUrl = _absoluteUrlToDependency(importedPath);
throw MigrationException('Dependency loop detected: ${sourceUrl.item1} -> ${importedPathUrl.item1}');
}
_dependencies[source] = importedPath;
}

/// Constructs a new module migration visitor.
///
/// [importCache] must be the same one used by [references].
Expand Down Expand Up @@ -1239,6 +1252,13 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
var url = declaration.sourceUrl;
if (url == currentUrl) return null;

// Trace dependencies for loop detection.
try {
_addDependency(currentUrl, url);
} on Exception catch (e) {
throw MigrationSourceSpanException(e.toString(), declaration.member.span);
}

// If we can load [declaration] from a library entrypoint URL, do so. Choose
// the shortest one if there are multiple options.
var libraryUrls = references.libraries[declaration];
Expand Down
21 changes: 21 additions & 0 deletions test/migrators/module/namespace_references/loop_error.hrx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<==> arguments
--migrate-deps

<==> input/entrypoint.scss
@import "ejemplo";
$var: $value;

<==> input/_ejemplo.scss
$value: blue;
a {
color: $var;
}

<==> error.txt
Error: Error: Dependency loop detected: entrypoint -> ejemplo
,
1 | $value: blue;
| ^^^^^^^^^^^^
'
_ejemplo.scss 1:1 root stylesheet
Migration failed!

0 comments on commit 41d4d36

Please sign in to comment.