diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 98ff8fb7caa..686137d2638 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart @@ -1783,6 +1783,11 @@ class AnalysisDriver implements AnalysisDriverGeneric { void _removePotentiallyAffectedLibraries(String path) { var affected = {}; _fsState.collectAffected(path, affected); + + for (var file in affected) { + file.invalidateLibraryCycle(); + } + _libraryContext?.elementFactory.removeLibraries( affected.map((e) => e.uriStr).toSet(), ); diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart index 433d6e37ffd..a275ba243fb 100644 --- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart +++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart @@ -352,6 +352,11 @@ class FileState { _libraryCycle = cycle; } + void invalidateLibraryCycle() { + _libraryCycle?.invalidate(); + _libraryCycle = null; + } + /// Return a new parsed unresolved [CompilationUnit]. CompilationUnitImpl parse([AnalysisErrorListener? errorListener]) { errorListener ??= AnalysisErrorListener.NULL_LISTENER; @@ -765,6 +770,20 @@ class FileSystemState { /// Collected files that transitively reference a file with the [path]. /// These files are potentially affected by the change. void collectAffected(String path, Set affected) { + // TODO(scheglov) This should not be necessary. + // We use affected files to remove library elements, and we can only get + // these library elements when we link or load them, using library cycles. + // And we get library cycles by asking `directReferencedFiles`. + while (true) { + final knownFiles = this.knownFiles.toList(); + for (var file in knownFiles.toList()) { + file.directReferencedFiles; + } + if (this.knownFiles.length == knownFiles.length) { + break; + } + } + collectAffected(FileState file) { if (affected.add(file)) { for (var other in file.referencingFiles) {