Issue 57043. Fix infinite FileKind recursion when part references itself.
Bug: https://github.com/dart-lang/sdk/issues/57043
Change-Id: I8bde1d5f6b1d2eb9bd3e42ec74261d492e9303e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/393906
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 1b6c850..c3e0b7f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -403,9 +403,15 @@
return;
}
- for (var reference in file.referencingFiles) {
+ // Take referencing files, stop potential recursion.
+ var referencingFiles = file.referencingFiles;
+ file.referencingFiles = {};
+
+ // Iterate and restore.
+ for (var reference in referencingFiles) {
reference.kind.disposeLibraryCycle();
}
+ file.referencingFiles = referencingFiles;
}
bool hasPart(PartFileKind partKind) {
@@ -529,7 +535,7 @@
bool isMacroPart = false;
/// Files that reference this file.
- final Set<FileState> referencingFiles = {};
+ Set<FileState> referencingFiles = {};
/// The flag that shows whether the file has an error or warning that
/// might be fixed by a change to another file.
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index bc6390e..2e468dd 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -3248,6 +3248,57 @@
''');
}
+ test_newFile_partOfUri_cycle_importSelf() async {
+ // https://github.com/dart-lang/sdk/issues/57043
+
+ var a = newFile('$testPackageLibPath/a.dart', r'''
+part 'b.dart';
+''');
+
+ var b = newFile('$testPackageLibPath/b.dart', r'''
+part of 'a.dart';
+import '';
+''');
+
+ fileStateFor(a);
+ var b_state = fileStateFor(b);
+
+ assertDriverStateString(testFile, r'''
+files
+ /home/test/lib/a.dart
+ uri: package:test/a.dart
+ current
+ id: file_0
+ kind: library_0
+ libraryImports
+ library_2 dart:core synthetic
+ partIncludes
+ partOfUriKnown_1
+ fileKinds: library_0 partOfUriKnown_1
+ cycle_0
+ dependencies: dart:core
+ libraries: library_0
+ apiSignature_0
+ unlinkedKey: k00
+ /home/test/lib/b.dart
+ uri: package:test/b.dart
+ current
+ id: file_1
+ kind: partOfUriKnown_1
+ uriFile: file_0
+ library: library_0
+ libraryImports
+ notLibrary file_1
+ referencingFiles: file_0 file_1
+ unlinkedKey: k01
+libraryCycles
+elementFactory
+''');
+
+ // Should not recurse infinitely.
+ b_state.kind.disposeLibraryCycle();
+ }
+
test_newFile_partOfUri_doesNotExist() async {
var a = getFile('$testPackageLibPath/a.dart');