@@ -15,6 +15,7 @@ import '../migration_visitor.dart';
15
15
import '../migrator.dart' ;
16
16
import '../patch.dart' ;
17
17
import '../utils.dart' ;
18
+ import '../util/dependency_graph.dart' ;
18
19
import '../util/member_declaration.dart' ;
19
20
import '../util/node_modules_importer.dart' ;
20
21
@@ -199,6 +200,29 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
199
200
/// The values of the --forward flag.
200
201
final Set <ForwardType > forwards;
201
202
203
+ /// Dependencies where keys represent source URIs and values represent imported URIs.
204
+ final DependencyGraph _dependencies = DependencyGraph ();
205
+
206
+ /// Checks for dependency loops between source and imported paths.
207
+ ///
208
+ /// This method verifies whether importing a path introduces a circular dependency
209
+ /// by checking if the imported path is already mapped as a dependency of the source path.
210
+ ///
211
+ /// Throws a [MigrationException] if a dependency loop is detected.
212
+ ///
213
+ /// The [source] parameter is the path where the dependency is checked.
214
+ /// The [importedPath] parameter is the path being imported.
215
+ void _checkDependency (Uri source, Uri importedPath, FileSpan span) {
216
+ if (_dependencies.hasDependency (importedPath, source)) {
217
+ // Throw an error indicating a potential loop.
218
+ var (sourceUrl, _) = _absoluteUrlToDependency (source);
219
+ var (importedPathUrl, _) = _absoluteUrlToDependency (importedPath);
220
+ throw MigrationSourceSpanException (
221
+ 'Dependency loop detected: ${sourceUrl } -> ${importedPathUrl }' , span);
222
+ }
223
+ _dependencies.add (source, importedPath);
224
+ }
225
+
202
226
/// Constructs a new module migration visitor.
203
227
///
204
228
/// [importCache] must be the same one used by [references] .
@@ -1224,6 +1248,9 @@ class _ModuleMigrationVisitor extends MigrationVisitor {
1224
1248
var url = declaration.sourceUrl;
1225
1249
if (url == currentUrl) return null ;
1226
1250
1251
+ // Trace dependencies for loop detection.
1252
+ _checkDependency (currentUrl, url, declaration.member.span);
1253
+
1227
1254
// If we can load [declaration] from a library entrypoint URL, do so. Choose
1228
1255
// the shortest one if there are multiple options.
1229
1256
var libraryUrls = references.libraries[declaration];
0 commit comments