From 76ddb43454d12be81d31c1fae9bf10a90379c2f9 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Wed, 17 Nov 2021 23:26:21 +0000 Subject: [PATCH] Try to work around invalidation exceptions. We have a spike in exceptions internally, and I suspect that it was caused by https://dart-review.googlesource.com/c/sdk/+/219942 But I was unable to understand why it happens. So, this workaround is the best I can think of now. Change-Id: I714eb6666706aad457b72e066978aa2d734fb89f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220640 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson --- .../lib/src/dart/analysis/driver.dart | 5 +++++ .../lib/src/dart/analysis/file_state.dart | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) 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) {