mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:01:42 +00:00
Add all SDK libraries, and context files belonging to the package / potions of it.
R=brianwilkerson@google.com Change-Id: I7e5d6cc12657c92f16d65e89f4b60eacf16c51b6 Reviewed-on: https://dart-review.googlesource.com/c/91260 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
f92b816268
commit
d927333c52
|
@ -13,6 +13,7 @@ import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
|||
import 'package:analyzer/src/dart/scanner/reader.dart';
|
||||
import 'package:analyzer/src/dart/scanner/scanner.dart';
|
||||
import 'package:analyzer/src/generated/parser.dart';
|
||||
import 'package:analyzer/src/generated/utilities_dart.dart';
|
||||
import 'package:analyzer/src/string_source.dart';
|
||||
import 'package:analyzer/src/summary/api_signature.dart';
|
||||
import 'package:analyzer/src/summary/format.dart' as idl;
|
||||
|
@ -54,12 +55,23 @@ class DeclarationsContext {
|
|||
/// the root are included into completion, even in 'lib/src' folders.
|
||||
final AnalysisContext _analysisContext;
|
||||
|
||||
/// Map of path prefixes to lists of files from dependencies (both libraries
|
||||
/// and parts, we don't know at the time when we fill this map) that
|
||||
/// libraries with files paths starting with these prefixes can access.
|
||||
/// Packages in the analysis context.
|
||||
///
|
||||
/// Packages are sorted so that inner packages are before outer.
|
||||
final List<_Package> _packages = [];
|
||||
|
||||
/// The list of paths of all files inside the context.
|
||||
final List<String> _contextPathList = [];
|
||||
|
||||
/// The list of paths of all SDK libraries.
|
||||
final List<String> _sdkLibraryPathList = [];
|
||||
|
||||
/// Map of path prefixes to lists of paths of files from dependencies
|
||||
/// (both libraries and parts, we don't know at the time when we fill this
|
||||
/// map) that libraries with paths starting with these prefixes can access.
|
||||
///
|
||||
/// The path prefix keys are sorted so that the longest keys are first.
|
||||
final Map<String, List<String>> _pathPrefixToDependencyFiles = {};
|
||||
final Map<String, List<String>> _pathPrefixToDependencyPathList = {};
|
||||
|
||||
DeclarationsContext(this._tracker, this._analysisContext);
|
||||
|
||||
|
@ -71,20 +83,49 @@ class DeclarationsContext {
|
|||
///
|
||||
/// With `Bazel` sets of accessible libraries are specified explicitly by
|
||||
/// the client using [setDependencies].
|
||||
List<int> getLibraries(String path) {
|
||||
// TODO(scheglov) include context libraries
|
||||
for (var pathPrefix in _pathPrefixToDependencyFiles.keys) {
|
||||
Libraries getLibraries(String path) {
|
||||
var sdkLibraries = <Library>[];
|
||||
_addLibrariesWithPaths(sdkLibraries, _sdkLibraryPathList);
|
||||
|
||||
var dependencyLibraries = <Library>[];
|
||||
for (var pathPrefix in _pathPrefixToDependencyPathList.keys) {
|
||||
if (path.startsWith(pathPrefix)) {
|
||||
var pathList = _pathPrefixToDependencyFiles[pathPrefix];
|
||||
var idList = pathList
|
||||
.map((libPath) => _tracker._pathToFile[libPath])
|
||||
.where((file) => file != null && file.isLibrary)
|
||||
.map((file) => file.id)
|
||||
.toList();
|
||||
return idList;
|
||||
var pathList = _pathPrefixToDependencyPathList[pathPrefix];
|
||||
_addLibrariesWithPaths(dependencyLibraries, pathList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return <int>[];
|
||||
|
||||
_Package package;
|
||||
for (var candidatePackage in _packages) {
|
||||
if (candidatePackage.contains(path)) {
|
||||
package = candidatePackage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var contextPathList = <String>[];
|
||||
if (package != null) {
|
||||
var containingFolder = package.folderInRootContaining(path);
|
||||
if (containingFolder != null) {
|
||||
for (var contextPath in _contextPathList) {
|
||||
// `lib/` can see only libraries in `lib/`.
|
||||
// `test/` can see libraries in `lib/` and in `test/`.
|
||||
if (package.containsInLib(contextPath) ||
|
||||
containingFolder.contains(contextPath)) {
|
||||
contextPathList.add(contextPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not in a package, include all libraries of the context.
|
||||
contextPathList = _contextPathList;
|
||||
}
|
||||
|
||||
var contextLibraries = <Library>[];
|
||||
_addLibrariesWithPaths(contextLibraries, contextPathList);
|
||||
|
||||
return Libraries(sdkLibraries, dependencyLibraries, contextLibraries);
|
||||
}
|
||||
|
||||
/// Set dependencies for path prefixes in this context.
|
||||
|
@ -106,7 +147,7 @@ class DeclarationsContext {
|
|||
/// Every path in the list must be absolute and normalized.
|
||||
void setDependencies(Map<String, List<String>> pathPrefixToPathList) {
|
||||
var rootFolder = _analysisContext.contextRoot.root;
|
||||
_pathPrefixToDependencyFiles.removeWhere((pathPrefix, _) {
|
||||
_pathPrefixToDependencyPathList.removeWhere((pathPrefix, _) {
|
||||
return rootFolder.isOrContains(pathPrefix);
|
||||
});
|
||||
|
||||
|
@ -122,10 +163,68 @@ class DeclarationsContext {
|
|||
var resource = _tracker._resourceProvider.getResource(path);
|
||||
_scheduleDependencyResource(files, resource);
|
||||
}
|
||||
_pathPrefixToDependencyFiles[pathPrefix] = files;
|
||||
_pathPrefixToDependencyPathList[pathPrefix] = files;
|
||||
}
|
||||
}
|
||||
|
||||
void _addLibrariesWithPaths(List<Library> libraries, List<String> pathList) {
|
||||
for (var path in pathList) {
|
||||
var file = _tracker._pathToFile[path];
|
||||
if (file != null && file.isLibrary) {
|
||||
var library = _tracker._idToLibrary[file.id];
|
||||
if (library != null) {
|
||||
libraries.add(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Traverse the folders of this context and fill [_packages]; use
|
||||
/// `pubspec.yaml` files to set `Pub` dependencies.
|
||||
void _findPackages() {
|
||||
var pathContext = _tracker._resourceProvider.pathContext;
|
||||
var pubPathPrefixToPathList = <String, List<String>>{};
|
||||
|
||||
void visitFolder(Folder folder) {
|
||||
var buildFile = folder.getChildAssumingFile('BUILD');
|
||||
var pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
|
||||
if (buildFile.exists) {
|
||||
_packages.add(_Package(folder));
|
||||
} else if (pubspecFile.exists) {
|
||||
var dependencies = _parsePubspecDependencies(pubspecFile);
|
||||
var libPaths = _resolvePackageNamesToLibPaths(dependencies.lib);
|
||||
var devPaths = _resolvePackageNamesToLibPaths(dependencies.dev);
|
||||
|
||||
var packagePath = folder.path;
|
||||
pubPathPrefixToPathList[packagePath] = <String>[]
|
||||
..addAll(libPaths)
|
||||
..addAll(devPaths);
|
||||
|
||||
var libPath = pathContext.join(packagePath, 'lib');
|
||||
pubPathPrefixToPathList[libPath] = libPaths;
|
||||
|
||||
_packages.add(_Package(folder));
|
||||
}
|
||||
|
||||
try {
|
||||
for (var resource in folder.getChildren()) {
|
||||
if (resource is Folder) {
|
||||
visitFolder(resource);
|
||||
}
|
||||
}
|
||||
} on FileSystemException {}
|
||||
}
|
||||
|
||||
visitFolder(_analysisContext.contextRoot.root);
|
||||
setDependencies(pubPathPrefixToPathList);
|
||||
|
||||
_packages.sort((a, b) {
|
||||
var aRoot = a.root.path;
|
||||
var bRoot = b.root.path;
|
||||
return bRoot.compareTo(aRoot);
|
||||
});
|
||||
}
|
||||
|
||||
bool _isLibSrcPath(String path) {
|
||||
var parts = _tracker._resourceProvider.pathContext.split(path);
|
||||
for (var i = 0; i < parts.length - 1; ++i) {
|
||||
|
@ -167,6 +266,7 @@ class DeclarationsContext {
|
|||
void _scheduleContextFiles() {
|
||||
var contextFiles = _analysisContext.contextRoot.analyzedFiles();
|
||||
for (var path in contextFiles) {
|
||||
_contextPathList.add(path);
|
||||
_tracker._addFile(this, path);
|
||||
}
|
||||
}
|
||||
|
@ -189,39 +289,17 @@ class DeclarationsContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// Traverse the folders of this context, and use `pubspec.yaml` files
|
||||
/// to set dependencies for containing folders.
|
||||
void _setPubspecDependencies() {
|
||||
var pathContext = _tracker._resourceProvider.pathContext;
|
||||
var locationToPathList = <String, List<String>>{};
|
||||
|
||||
void visitFolder(Folder folder) {
|
||||
var pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
|
||||
if (pubspecFile.exists) {
|
||||
var dependencies = _parsePubspecDependencies(pubspecFile);
|
||||
var libPaths = _resolvePackageNamesToLibPaths(dependencies.lib);
|
||||
var devPaths = _resolvePackageNamesToLibPaths(dependencies.dev);
|
||||
|
||||
var packagePath = folder.path;
|
||||
locationToPathList[packagePath] = <String>[]
|
||||
..addAll(libPaths)
|
||||
..addAll(devPaths);
|
||||
|
||||
var libPath = pathContext.join(packagePath, 'lib');
|
||||
locationToPathList[libPath] = libPaths;
|
||||
void _scheduleSdkLibraries() {
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
var sdk = _analysisContext.currentSession.sourceFactory.dartSdk;
|
||||
for (var uriStr in sdk.uris) {
|
||||
var uri = Uri.parse(uriStr);
|
||||
var path = _resolveUri(uri);
|
||||
if (path != null) {
|
||||
_sdkLibraryPathList.add(path);
|
||||
_tracker._addFile(this, path);
|
||||
}
|
||||
|
||||
try {
|
||||
for (var resource in folder.getChildren()) {
|
||||
if (resource is Folder) {
|
||||
visitFolder(resource);
|
||||
}
|
||||
}
|
||||
} on FileSystemException {}
|
||||
}
|
||||
|
||||
visitFolder(_analysisContext.contextRoot.root);
|
||||
setDependencies(locationToPathList);
|
||||
}
|
||||
|
||||
static _PubspecDependencies _parsePubspecDependencies(File pubspecFile) {
|
||||
|
@ -257,6 +335,7 @@ class DeclarationsTracker {
|
|||
final Map<AnalysisContext, DeclarationsContext> _contexts = {};
|
||||
final Map<String, _File> _pathToFile = {};
|
||||
final Map<Uri, _File> _uriToFile = {};
|
||||
final Map<int, Library> _idToLibrary = {};
|
||||
|
||||
final _changesController = _StreamController<LibraryChange>();
|
||||
|
||||
|
@ -286,7 +365,8 @@ class DeclarationsTracker {
|
|||
_contexts[analysisContext] = declarationsContext;
|
||||
|
||||
declarationsContext._scheduleContextFiles();
|
||||
declarationsContext._setPubspecDependencies();
|
||||
declarationsContext._scheduleSdkLibraries();
|
||||
declarationsContext._findPackages();
|
||||
return declarationsContext;
|
||||
}
|
||||
|
||||
|
@ -325,6 +405,7 @@ class DeclarationsTracker {
|
|||
file.uri,
|
||||
file.exportedDeclarations,
|
||||
);
|
||||
_idToLibrary[file.id] = library;
|
||||
_changesController.add(
|
||||
LibraryChange._([library], []),
|
||||
);
|
||||
|
@ -385,6 +466,14 @@ class DeclarationsTracker {
|
|||
}
|
||||
}
|
||||
|
||||
class Libraries {
|
||||
final List<Library> sdk;
|
||||
final List<Library> dependencies;
|
||||
final List<Library> context;
|
||||
|
||||
Libraries(this.sdk, this.dependencies, this.context);
|
||||
}
|
||||
|
||||
/// A library with declarations.
|
||||
class Library {
|
||||
/// The unique identifier of a library with the given [path].
|
||||
|
@ -400,6 +489,11 @@ class Library {
|
|||
final List<Declaration> declarations;
|
||||
|
||||
Library._(this.id, this.path, this.uri, this.declarations);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '(uri: $uri, path: $path)';
|
||||
}
|
||||
}
|
||||
|
||||
/// A change to the set of libraries and their declarations.
|
||||
|
@ -607,7 +701,7 @@ class _File {
|
|||
|
||||
/// Return the [_File] for the given [relative] URI, maybe `null`.
|
||||
_File _fileForRelativeUri(DeclarationsContext context, Uri relative) {
|
||||
var absoluteUri = uri.resolveUri(relative);
|
||||
var absoluteUri = resolveRelativeUri(uri, relative);
|
||||
return tracker._getFileByUri(context, absoluteUri);
|
||||
}
|
||||
|
||||
|
@ -810,6 +904,42 @@ class _LibraryWalker extends graph.DependencyWalker<_LibraryNode> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Information about a package: `Pub` or `Bazel`.
|
||||
class _Package {
|
||||
final Folder root;
|
||||
final Folder lib;
|
||||
|
||||
_Package(this.root) : lib = root.getChildAssumingFolder('lib');
|
||||
|
||||
/// Return `true` if the [path] is anywhere in the [root] of the package.
|
||||
///
|
||||
/// Note, that this method does not check if the are nested packages, that
|
||||
/// might actually contain the [path].
|
||||
bool contains(String path) {
|
||||
return root.contains(path);
|
||||
}
|
||||
|
||||
/// Return `true` if the [path] is in the `lib` folder of this package.
|
||||
bool containsInLib(String path) {
|
||||
return lib.contains(path);
|
||||
}
|
||||
|
||||
/// Return the direct child folder of the root, that contains the [path].
|
||||
///
|
||||
/// So, we can know if the [path] is in `lib/`, or `test/`, or `bin/`.
|
||||
Folder folderInRootContaining(String path) {
|
||||
try {
|
||||
var children = root.getChildren();
|
||||
for (var folder in children) {
|
||||
if (folder is Folder && folder.contains(path)) {
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
} on FileSystemException {}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _Part {
|
||||
final Uri uri;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
|||
import 'package:analyzer/src/services/available_declarations.dart';
|
||||
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
|
||||
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
|
@ -25,9 +26,15 @@ class AbstractContextTest with ResourceProviderMixin {
|
|||
|
||||
AnalysisContext testAnalysisContext;
|
||||
|
||||
void addTestPackageDependency(String name, String rootPath) {
|
||||
var packagesFile = getFile('/home/test/.packages');
|
||||
var packagesContent = packagesFile.readAsStringSync();
|
||||
void addDotPackagesDependency(String path, String name, String rootPath) {
|
||||
var packagesFile = getFile(path);
|
||||
|
||||
String packagesContent;
|
||||
try {
|
||||
packagesContent = packagesFile.readAsStringSync();
|
||||
} catch (_) {
|
||||
packagesContent = '';
|
||||
}
|
||||
|
||||
// Ignore if there is already the same package dependency.
|
||||
if (packagesContent.contains('$name:file://')) {
|
||||
|
@ -42,6 +49,10 @@ class AbstractContextTest with ResourceProviderMixin {
|
|||
createAnalysisContexts();
|
||||
}
|
||||
|
||||
void addTestPackageDependency(String name, String rootPath) {
|
||||
addDotPackagesDependency('/home/test/.packages', name, rootPath);
|
||||
}
|
||||
|
||||
/// Create all analysis contexts in `/home`.
|
||||
void createAnalysisContexts() {
|
||||
analysisContextCollection = AnalysisContextCollectionImpl(
|
||||
|
@ -66,8 +77,8 @@ class AbstractContextTest with ResourceProviderMixin {
|
|||
new MockSdk(resourceProvider: resourceProvider);
|
||||
|
||||
newFolder('/home/test');
|
||||
newFile('/home/test/.packages', content: r'''
|
||||
test:file:///home/test/lib
|
||||
newFile('/home/test/.packages', content: '''
|
||||
test:${toUri('/home/test/lib')}
|
||||
''');
|
||||
|
||||
createAnalysisContexts();
|
||||
|
@ -245,133 +256,309 @@ mixin B {}
|
|||
], uriStr: 'package:test/test.dart');
|
||||
}
|
||||
|
||||
test_getLibraries_pub() async {
|
||||
newFile('/home/aaa/lib/a.dart', content: r'''
|
||||
class A {}
|
||||
''');
|
||||
newFile('/home/aaa/lib/src/a2.dart', content: r'''
|
||||
class A2 {}
|
||||
''');
|
||||
test_getLibraries_bazel() async {
|
||||
newFile('/home/aaa/lib/a.dart', content: 'class A {}');
|
||||
newFile('/home/aaa/lib/src/a2.dart', content: 'class A2 {}');
|
||||
|
||||
newFile('/home/bbb/lib/b.dart', content: r'''
|
||||
class B {}
|
||||
''');
|
||||
newFile('/home/bbb/lib/src/b2.dart', content: r'''
|
||||
class B2 {}
|
||||
''');
|
||||
newFile('/home/bbb/lib/b.dart', content: 'class B {}');
|
||||
newFile('/home/bbb/lib/src/b2.dart', content: 'class B2 {}');
|
||||
|
||||
addTestPackageDependency('aaa', '/home/aaa');
|
||||
addTestPackageDependency('bbb', '/home/bbb');
|
||||
newFile('/home/material_button/BUILD', content: '');
|
||||
newFile(
|
||||
'/home/material_button/lib/button.dart',
|
||||
content: 'class MaterialButton {}',
|
||||
);
|
||||
newFile(
|
||||
'/home/material_button/test/button_test.dart',
|
||||
content: 'class MaterialButtonTest {}',
|
||||
);
|
||||
|
||||
newFile('/home/test/pubspec.yaml', content: r'''
|
||||
name: test
|
||||
newFile('/home/material_button/testing/BUILD', content: '');
|
||||
newFile(
|
||||
'/home/material_button/testing/lib/material_button_po.dart',
|
||||
content: 'class MaterialButtonPO {}',
|
||||
);
|
||||
|
||||
dependencies:
|
||||
aaa: any
|
||||
|
||||
dev_dependencies:
|
||||
bbb: any
|
||||
''');
|
||||
|
||||
newFile('/home/test/lib/test.dart', content: '');
|
||||
var context = tracker.addContext(testAnalysisContext);
|
||||
var packagesFilePath = '/home/material_button/.packages';
|
||||
addDotPackagesDependency(packagesFilePath, 'aaa', '/home/aaa');
|
||||
addDotPackagesDependency(packagesFilePath, 'bbb', '/home/bbb');
|
||||
addDotPackagesDependency(
|
||||
packagesFilePath,
|
||||
'material_button',
|
||||
'/home/material_button',
|
||||
);
|
||||
addDotPackagesDependency(
|
||||
packagesFilePath,
|
||||
'material_button_testing',
|
||||
'/home/material_button/testing',
|
||||
);
|
||||
|
||||
var analysisContext = analysisContextCollection.contextFor(
|
||||
convertPath('/home/material_button'),
|
||||
);
|
||||
var context = tracker.addContext(analysisContext);
|
||||
context.setDependencies({
|
||||
convertPath('/home/material_button'): [convertPath('/home/aaa/lib')],
|
||||
convertPath('/home/material_button/testing'): [
|
||||
convertPath('/home/bbb/lib'),
|
||||
convertPath('/home/material_button/lib'),
|
||||
],
|
||||
});
|
||||
await _doAllTrackerWork();
|
||||
|
||||
var aUri = 'package:aaa/a.dart';
|
||||
var bUri = 'package:bbb/b.dart';
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('A'),
|
||||
], uriStr: aUri);
|
||||
], uriStr: 'package:aaa/a.dart');
|
||||
_assertNoLibrary('package:aaa/src/a2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('B'),
|
||||
], uriStr: bUri);
|
||||
], uriStr: 'package:bbb/b.dart');
|
||||
_assertNoLibrary('package:bbb/src/b2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('MaterialButton'),
|
||||
], uriStr: 'package:material_button/button.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('MaterialButtonTest'),
|
||||
], uriStr: toUri('/home/material_button/test/button_test.dart').toString());
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('MaterialButtonPO'),
|
||||
], uriStr: 'package:material_button_testing/material_button_po.dart');
|
||||
|
||||
// package/lib can see only regular dependencies
|
||||
{
|
||||
var path = convertPath('/home/test/lib/a.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, isNot(contains(uriToLibrary[bUri].id)));
|
||||
var path = convertPath('/home/material_button/lib/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:aaa/a.dart'],
|
||||
only: true,
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:material_button/button.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
// package/bin can see regular and dev dependencies
|
||||
{
|
||||
var path = convertPath('/home/test/bin/b.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, contains(uriToLibrary[bUri].id));
|
||||
var path = convertPath('/home/material_button/test/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:aaa/a.dart'],
|
||||
only: true,
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:material_button/button.dart',
|
||||
toUri('/home/material_button/test/button_test.dart').toString(),
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
// package/test can see regular and dev dependencies
|
||||
{
|
||||
var path = convertPath('/home/test/test/c.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, contains(uriToLibrary[bUri].id));
|
||||
var path = convertPath('/home/material_button/testing/lib/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: [
|
||||
'package:bbb/b.dart',
|
||||
'package:material_button/button.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:material_button_testing/material_button_po.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
test_getLibraries_pub_inner() async {
|
||||
newFile('/home/aaa/lib/a.dart', content: r'''
|
||||
class A {}
|
||||
''');
|
||||
newFile('/home/bbb/lib/b.dart', content: r'''
|
||||
class B {}
|
||||
''');
|
||||
test_getLibraries_pub() async {
|
||||
newFile('/home/aaa/lib/a.dart', content: 'class A {}');
|
||||
newFile('/home/aaa/lib/src/a2.dart', content: 'class A2 {}');
|
||||
|
||||
addTestPackageDependency('aaa', '/home/aaa');
|
||||
addTestPackageDependency('bbb', '/home/bbb');
|
||||
newFile('/home/bbb/lib/b.dart', content: 'class B {}');
|
||||
newFile('/home/bbb/lib/src/b2.dart', content: 'class B2 {}');
|
||||
|
||||
newFile('/home/ccc/lib/c.dart', content: 'class C {}');
|
||||
newFile('/home/ccc/lib/src/c2.dart', content: 'class C2 {}');
|
||||
|
||||
newFile('/home/test/pubspec.yaml', content: r'''
|
||||
name: test
|
||||
|
||||
dependencies:
|
||||
aaa: any
|
||||
|
||||
dev_dependencies:
|
||||
bbb: any
|
||||
''');
|
||||
newFile('/home/test/lib/t.dart', content: 'class T {}');
|
||||
newFile('/home/test/lib/src/t2.dart', content: 'class T2 {}');
|
||||
newFile('/home/test/bin/t3.dart', content: 'class T3 {}');
|
||||
newFile('/home/test/test/t4.dart', content: 'class T4 {}');
|
||||
|
||||
newFile('/home/test/examples/basic/pubspec.yaml', content: r'''
|
||||
name: basic
|
||||
|
||||
newFile('/home/test/samples/basic/pubspec.yaml', content: r'''
|
||||
name: test
|
||||
dependencies:
|
||||
bbb: any
|
||||
ccc: any
|
||||
test: any
|
||||
''');
|
||||
newFile('/home/test/samples/basic/lib/s.dart', content: 'class S {}');
|
||||
|
||||
newFile('/home/test/lib/test.dart', content: '');
|
||||
newFile('/home/test/examples/basic/lib/basic.dart', content: '');
|
||||
addTestPackageDependency('aaa', '/home/aaa');
|
||||
addTestPackageDependency('bbb', '/home/bbb');
|
||||
addTestPackageDependency('ccc', '/home/ccc');
|
||||
addTestPackageDependency('basic', '/home/test/samples/basic');
|
||||
|
||||
var context = tracker.addContext(testAnalysisContext);
|
||||
|
||||
await _doAllTrackerWork();
|
||||
|
||||
var aUri = 'package:aaa/a.dart';
|
||||
var bUri = 'package:bbb/b.dart';
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('A'),
|
||||
], uriStr: aUri);
|
||||
], uriStr: 'package:aaa/a.dart');
|
||||
_assertNoLibrary('package:aaa/src/a2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('B'),
|
||||
], uriStr: bUri);
|
||||
], uriStr: 'package:bbb/b.dart');
|
||||
_assertNoLibrary('package:bbb/src/b2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('C'),
|
||||
], uriStr: 'package:ccc/c.dart');
|
||||
_assertNoLibrary('package:ccc/src/c2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('T'),
|
||||
], uriStr: 'package:test/t.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('T2'),
|
||||
], uriStr: 'package:test/src/t2.dart');
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('S'),
|
||||
], uriStr: 'package:basic/s.dart');
|
||||
|
||||
// package/lib can see package:aaa
|
||||
{
|
||||
var path = convertPath('/home/test/lib/a.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, isNot(contains(uriToLibrary[bUri].id)));
|
||||
var path = convertPath('/home/test/lib/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:aaa/a.dart'],
|
||||
only: true,
|
||||
);
|
||||
// Note, no `bin/` or `test/` libraries.
|
||||
// Note, has `lib/src` library.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:test/t.dart',
|
||||
'package:test/src/t2.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
// examples/basic can see package:bbb
|
||||
{
|
||||
var path = convertPath('/home/test/examples/basic/lib/basic.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, isNot(contains(uriToLibrary[aUri].id)));
|
||||
expect(idList, contains(uriToLibrary[bUri].id));
|
||||
var path = convertPath('/home/test/bin/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: [
|
||||
'package:aaa/a.dart',
|
||||
'package:bbb/b.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
// Note, no `test/` libraries.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:test/t.dart',
|
||||
'package:test/src/t2.dart',
|
||||
toUri('/home/test/bin/t3.dart').toString(),
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
var path = convertPath('/home/test/test/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: [
|
||||
'package:aaa/a.dart',
|
||||
'package:bbb/b.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
// Note, no `bin/` libraries.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:test/t.dart',
|
||||
'package:test/src/t2.dart',
|
||||
toUri('/home/test/test/t4.dart').toString(),
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
var path = convertPath('/home/test/samples/basic/lib/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.sdk,
|
||||
uriList: ['dart:core', 'dart:async'],
|
||||
);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: [
|
||||
'package:ccc/c.dart',
|
||||
'package:test/t.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
// Note, no `package:test` libraries.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:basic/s.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,9 +578,9 @@ class B {}
|
|||
addTestPackageDependency('aaa', '/home/aaa');
|
||||
addTestPackageDependency('bbb', '/home/bbb');
|
||||
|
||||
newFile('/home/test/lib/test.dart', content: r'''
|
||||
class C {}
|
||||
''');
|
||||
newFile('/home/test/lib/t.dart', content: 'class T {}');
|
||||
newFile('/home/test/lib/src/t2.dart', content: 'class T2 {}');
|
||||
newFile('/home/test/test/t3.dart', content: 'class T3 {}');
|
||||
|
||||
var context = tracker.addContext(testAnalysisContext);
|
||||
context.setDependencies({
|
||||
|
@ -406,32 +593,67 @@ class C {}
|
|||
|
||||
await _doAllTrackerWork();
|
||||
|
||||
var aUri = 'package:aaa/a.dart';
|
||||
var bUri = 'package:bbb/b.dart';
|
||||
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('A1'),
|
||||
_ExpectedDeclaration.class_('A2'),
|
||||
], uriStr: aUri);
|
||||
], uriStr: 'package:aaa/a.dart');
|
||||
_assertNoLibrary('package:aaa/src/a2.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('B'),
|
||||
], uriStr: bUri);
|
||||
], uriStr: 'package:bbb/b.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('T'),
|
||||
], uriStr: 'package:test/t.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('T2'),
|
||||
], uriStr: 'package:test/src/t2.dart');
|
||||
_assertLibraryDeclarations([
|
||||
_ExpectedDeclaration.class_('T3'),
|
||||
], uriStr: toUri('/home/test/test/t3.dart').toString());
|
||||
|
||||
// package/lib can see only regular dependencies
|
||||
// `lib/` is configured to see `package:aaa`.
|
||||
{
|
||||
var path = convertPath('/home/test/lib/a.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, isNot(contains(uriToLibrary[bUri].id)));
|
||||
var path = convertPath('/home/test/lib/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:aaa/a.dart'],
|
||||
only: true,
|
||||
);
|
||||
// Not in a package, so all context files are visible.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:test/t.dart',
|
||||
'package:test/src/t2.dart',
|
||||
toUri('/home/test/test/t3.dart').toString(),
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
// package/bin can see regular and dev dependencies
|
||||
// `test/` is configured to see `package:aaa` and `package:bbb`.
|
||||
{
|
||||
var path = convertPath('/home/test/bin/b.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(idList, contains(uriToLibrary[bUri].id));
|
||||
var path = convertPath('/home/test/bin/_.dart');
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: [
|
||||
'package:aaa/a.dart',
|
||||
'package:bbb/b.dart',
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
// Not in a package, so all context files are visible.
|
||||
_assertHasLibraries(
|
||||
libraries.context,
|
||||
uriList: [
|
||||
'package:test/t.dart',
|
||||
'package:test/src/t2.dart',
|
||||
toUri('/home/test/test/t3.dart').toString(),
|
||||
],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,9 +690,12 @@ class C {}
|
|||
// The package can see package:aaa, but not package:bbb
|
||||
{
|
||||
var path = convertPath('/home/test/lib/a.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, contains(uriToLibrary[aUri].id));
|
||||
expect(uriToLibrary[bUri], isNull);
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:aaa/a.dart'],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
|
||||
context.setDependencies({
|
||||
|
@ -488,9 +713,12 @@ class C {}
|
|||
// The package can see package:bbb, but not package:aaa
|
||||
{
|
||||
var path = convertPath('/home/test/lib/a.dart');
|
||||
var idList = context.getLibraries(path);
|
||||
expect(idList, isNot(contains(uriToLibrary[aUri].id)));
|
||||
expect(idList, contains(uriToLibrary[bUri].id));
|
||||
var libraries = context.getLibraries(path);
|
||||
_assertHasLibraries(
|
||||
libraries.dependencies,
|
||||
uriList: ['package:bbb/b.dart'],
|
||||
only: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,13 +847,7 @@ class A {}
|
|||
expect(library, isNotNull);
|
||||
expect(library.declarations, hasLength(expectedDeclarations.length));
|
||||
for (var expected in expectedDeclarations) {
|
||||
expect(
|
||||
library.declarations,
|
||||
contains(predicate((Declaration d) {
|
||||
return d.name == expected.name && d.kind == expected.kind;
|
||||
})),
|
||||
reason: '$expected',
|
||||
);
|
||||
_asyncHasDeclaration(library, expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,6 +855,16 @@ class A {}
|
|||
expect(uriToLibrary, isNot(contains(uriStr)));
|
||||
}
|
||||
|
||||
void _asyncHasDeclaration(Library library, _ExpectedDeclaration expected) {
|
||||
expect(
|
||||
library.declarations,
|
||||
contains(predicate((Declaration d) {
|
||||
return d.name == expected.name && d.kind == expected.kind;
|
||||
})),
|
||||
reason: '$expected',
|
||||
);
|
||||
}
|
||||
|
||||
void _createTracker() {
|
||||
uriToLibrary.clear();
|
||||
|
||||
|
@ -663,6 +895,16 @@ class A {}
|
|||
if (times == 0) return new Future.value();
|
||||
return new Future.delayed(Duration.zero, () => pumpEventQueue(times - 1));
|
||||
}
|
||||
|
||||
static void _assertHasLibraries(List<Library> libraries,
|
||||
{@required List<String> uriList, bool only = false}) {
|
||||
var actualUriList = libraries.map((lib) => lib.uri.toString()).toList();
|
||||
if (only) {
|
||||
expect(actualUriList, unorderedEquals(uriList));
|
||||
} else {
|
||||
expect(actualUriList, containsAll(uriList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//class _ExpectedLibrary {
|
||||
|
|
Loading…
Reference in a new issue