Add isLibraryByUri() to AnalysisDriver.
The package:build develpers told us that they need it.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: Ia48851faac353d5f83e7d6af7d579c2c1d8be1bd
Reviewed-on: https://dart-review.googlesource.com/c/84502
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 2e2bd5a..0ae475b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -859,6 +859,27 @@
}
/**
+ * Return `true` is the file with the given absolute [uri] is a library,
+ * or `false` if it is a part. More specifically, return `true` if the file
+ * is not known to be a part.
+ *
+ * Correspondingly, return `true` if the [uri] does not correspond to a file,
+ * for any reason, e.g. the file does not exist, or the [uri] cannot be
+ * resolved to a file path, or the [uri] is invalid, e.g. a `package:` URI
+ * without a package name. In these cases we cannot prove that the file is
+ * not a part, so it must be a library.
+ */
+ bool isLibraryByUri(Uri uri) {
+ if (_externalSummaries != null) {
+ var uriStr = uri.toString();
+ if (_externalSummaries.unlinkedMap[uriStr] != null) {
+ return _externalSummaries.linkedMap.containsKey(uriStr);
+ }
+ }
+ return !_fsState.getFileForUri(uri).isPart;
+ }
+
+ /**
* Return a [Future] that completes with a [ParseResult] for the file
* with the given [path].
*
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index c1aad81..c308e2e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -220,6 +220,12 @@
bool get isPart => _unlinked.libraryNameOffset == 0 && _unlinked.isPartOf;
/**
+ * Return `true` if the file is the "unresolved" file, which does not have
+ * neither a valid URI, nor a path.
+ */
+ bool get isUnresolved => uri == null;
+
+ /**
* If the file [isPart], return a currently know library the file is a part
* of. Return `null` if a library is not known, for example because we have
* not processed a library file yet.
@@ -834,9 +840,10 @@
}
/**
- * Return the [FileState] for the given absolute [uri]. May return `null` if
- * the [uri] is invalid, e.g. a `package:` URI without a package name. The
- * returned file has the last known state since if was last refreshed.
+ * Return the [FileState] for the given absolute [uri]. May return the
+ * "unresolved" file if the [uri] is invalid, e.g. a `package:` URI without
+ * a package name. The returned file has the last known state since if was
+ * last refreshed.
*/
FileState getFileForUri(Uri uri) {
FileState file = _uriToFile[uri];
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index b0adc84..1afe213 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -10,8 +10,10 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
@@ -24,8 +26,6 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -2322,6 +2322,50 @@
await waitForIdleWithoutExceptions();
}
+ test_isLibraryByUri() async {
+ var a1 = _p('/aaa/lib/a1.dart');
+ var a2 = _p('/aaa/lib/a2.dart');
+ var b1 = _p('/bbb/lib/b1.dart');
+ var b2 = _p('/bbb/lib/b2.dart');
+
+ String a1UriStr = 'package:aaa/a1.dart';
+ String a2UriStr = 'package:aaa/a2.dart';
+ String b1UriStr = 'package:bbb/b1.dart';
+ String b2UriStr = 'package:bbb/b2.dart';
+
+ provider.newFile(a1, "part 'a2.dart';");
+ provider.newFile(a2, "part of 'a1.dart';");
+ provider.newFile(b1, "part 'b2.dart';");
+ provider.newFile(b2, "part of 'b1.dart';");
+
+ // Build the store with the library.
+ var store = await createAnalysisDriver().test.getSummaryStore(a1);
+ expect(store.unlinkedMap.keys, contains(a1UriStr));
+ expect(store.unlinkedMap.keys, contains(a2UriStr));
+ expect(store.linkedMap.keys, contains(a1UriStr));
+
+ // Remove the stored files from the file system.
+ provider.deleteFile(a1);
+ provider.deleteFile(a2);
+
+ // We can ask isLibraryByUri() for both external and local units.
+ AnalysisDriver driver = createAnalysisDriver(externalSummaries: store);
+ expect(driver.isLibraryByUri(Uri.parse(a1UriStr)), isTrue);
+ expect(driver.isLibraryByUri(Uri.parse(a2UriStr)), isFalse);
+ expect(driver.isLibraryByUri(Uri.parse(b1UriStr)), isTrue);
+ expect(driver.isLibraryByUri(Uri.parse(b2UriStr)), isFalse);
+ }
+
+ test_isLibraryByUri_doesNotExist() async {
+ var uri = Uri.parse('file:///test.dart');
+ expect(driver.isLibraryByUri(uri), isTrue);
+ }
+
+ test_isLibraryByUri_invalidUri() async {
+ var uri = Uri.parse('package:aaa');
+ expect(driver.isLibraryByUri(uri), isTrue);
+ }
+
test_issue34619() async {
var a = _p('/test/lib/a.dart');
provider.newFile(a, r'''
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 091ec5c..aeb0e75 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -7,7 +7,9 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart'
@@ -16,8 +18,6 @@
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -567,6 +567,15 @@
expect(file2, same(file1));
}
+ test_getFileForUri_invalidUri() {
+ var uri = Uri.parse('package:x');
+ var file = fileSystemState.getFileForUri(uri);
+ expect(file.isUnresolved, isTrue);
+ expect(file.uri, isNull);
+ expect(file.path, isNull);
+ expect(file.isPart, isFalse);
+ }
+
test_getFileForUri_packageVsFileUri() {
String path = _p('/aaa/lib/a.dart');
var packageUri = Uri.parse('package:aaa/a.dart');