Version 2.12.0-52.0.dev
Merge commit '95e4e03f8818bf3fd96e356e5c06080f36308fa0' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 527a89b..96b4548 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:collection';
import 'dart:convert';
import 'dart:typed_data';
@@ -136,6 +137,18 @@
/// Return the [uri] string.
String get uriStr => uri.toString();
+ /// Recursively traverse imports, exports, and parts to collect all
+ /// files that are accessed.
+ void collectAllReferencedFiles(Set<String> referencedFiles) {
+ var deps = {...importedFiles, ...exportedFiles, ...partedFiles};
+ for (var file in deps) {
+ if (!referencedFiles.contains(file.path)) {
+ referencedFiles.add(file.path);
+ file.collectAllReferencedFiles(referencedFiles);
+ }
+ }
+ }
+
/// Return the content of the file, the empty string if cannot be read.
String getContent() {
try {
@@ -601,10 +614,34 @@
}
return source.fullName;
}
+
+ /// Computes the set of [FileState]'s used/not used to analyze the given
+ /// [files]. Removes the [FileState]'s of the files not used for analysis from
+ /// the cache. Returns the set of unused [FileState]'s.
+ List<FileState> removeUnusedFiles(List<String> files) {
+ var removedFiles = <FileState>[];
+ var unusedFiles = _pathToFile.keys.toSet();
+ var deps = HashSet<String>();
+ for (var path in files) {
+ unusedFiles.remove(path);
+ _pathToFile[path].collectAllReferencedFiles(deps);
+ }
+ for (var path in deps) {
+ unusedFiles.remove(path);
+ }
+ for (var path in unusedFiles) {
+ var file = _pathToFile.remove(path);
+ _uriToFile.remove(file.uri);
+ removedFiles.add(file);
+ }
+ testView.unusedFiles = unusedFiles;
+ return removedFiles;
+ }
}
class FileSystemStateTestView {
final List<String> refreshedFiles = [];
+ Set<String> unusedFiles = {};
}
class FileSystemStateTimer {
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index b0e1808..26bed2a 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -304,6 +304,17 @@
removedCacheIds.clear();
}
+ /// Remove cached [FileState]'s that were not used in the current analysis
+ /// session. The list of files analyzed is used to compute the set of unused
+ /// [FileState]'s. Adds the cache id's for the removed [FileState]'s to
+ /// [removedCacheIds].
+ void removeFilesNotNecessaryForAnalysisOf(List<String> files) {
+ var removedFiles = fsState.removeUnusedFiles(files);
+ for (var removedFile in removedFiles) {
+ removedCacheIds.add(removedFile.id);
+ }
+ }
+
/// The [completionLine] and [completionColumn] are zero based.
ResolvedUnitResult resolve({
int completionLine,
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 549701d..61f26ab 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -569,4 +569,65 @@
error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 9),
]);
}
+
+ test_unusedFiles() async {
+ var bPath = '/workspace/dart/aaa/lib/b.dart';
+ var cPath = '/workspace/dart/aaa/lib/c.dart';
+
+ newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+
+ newFile(bPath, content: r'''
+import 'a.dart';
+''');
+
+ newFile(cPath, content: r'''
+import 'a.dart';
+''');
+
+ await resolveFile(bPath);
+ await resolveFile(cPath);
+ fileResolver.removeFilesNotNecessaryForAnalysisOf([cPath]);
+ expect(fileResolver.fsState.testView.unusedFiles.contains(bPath), true);
+ expect(fileResolver.fsState.testView.unusedFiles.length, 1);
+ }
+
+ test_unusedFiles_mutilple() async {
+ var dPath = '/workspace/dart/aaa/lib/d.dart';
+ var ePath = '/workspace/dart/aaa/lib/e.dart';
+ var fPath = '/workspace/dart/aaa/lib/f.dart';
+
+ newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+
+ newFile('/workspace/dart/aaa/lib/b.dart', content: r'''
+class B {}
+''');
+
+ newFile('/workspace/dart/aaa/lib/c.dart', content: r'''
+class C {}
+''');
+
+ newFile(dPath, content: r'''
+import 'a.dart';
+''');
+
+ newFile(ePath, content: r'''
+import 'a.dart';
+import 'b.dart';
+''');
+
+ newFile(fPath, content: r'''
+import 'c.dart';
+ ''');
+
+ await resolveFile(dPath);
+ await resolveFile(ePath);
+ await resolveFile(fPath);
+ fileResolver.removeFilesNotNecessaryForAnalysisOf([dPath, fPath]);
+ expect(fileResolver.fsState.testView.unusedFiles.contains(ePath), true);
+ expect(fileResolver.fsState.testView.unusedFiles.length, 2);
+ }
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index 7b21c71..136711e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -122,7 +122,7 @@
/// file, and the analysis_options.yaml file, each only if necessary.
///
/// [neededPackages] is a map whose keys are the names of packages that should
- /// be dependend upon by the package's pubspec, and whose values are the
+ /// be depended upon by the package's pubspec, and whose values are the
/// minimum required versions of those packages.
void processPackage(Folder pkgFolder, Map<String, Version> neededPackages) {
var pubspecFile = pkgFolder.getChildAssumingFile('pubspec.yaml');
@@ -156,7 +156,6 @@
Future<MigrationState> rerun() async {
reset();
var state = await rerunFunction();
- await state.refresh(_logger);
return state;
}
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index f433446..4fabe98 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -364,7 +364,9 @@
Future<void> rerunMigration() async {
migrationState = await rerunFunction();
- reset();
+ if (!migrationState.hasErrors) {
+ reset();
+ }
}
void reset() {
diff --git a/tools/VERSION b/tools/VERSION
index ccc77af..76eb55b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 51
+PRERELEASE 52
PRERELEASE_PATCH 0
\ No newline at end of file