Skip to content

Commit

Permalink
Extend BaselPackageUriResolver to handle files outside of lib.
Browse files Browse the repository at this point in the history
Generated files can exist outside of `lib`.  In a Bazel workspace
these are referred to using `file:` URIs that point to the generated
code directory.  We need to be able to resolve references both from
the generated code to non-generated code and vice versa.

This is blocking the use of the migration tool in Bazel workspaces,
since the migration tool doesn't have the same level of error recovery
as the rest of the analyzer, so it needs to be able to resolve all
files including generated ones.  But it should also improve the user
experience for using the analysis server in general in Bazel
workspaces, by reducing the number of nuisance "URI not resolved"
errors.

Change-Id: I38dababd29f4490746cc6e1eeede9f438526a815
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153520
Reviewed-by: Konstantin Shcheglov <[email protected]>
Commit-Queue: Paul Berry <[email protected]>
  • Loading branch information
stereotype441 authored and [email protected] committed Jul 8, 2020
1 parent 36e89f8 commit 464641f
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
33 changes: 33 additions & 0 deletions pkg/analyzer/lib/src/workspace/bazel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ class BazelPackageUriResolver extends UriResolver {
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
return _sourceCache.putIfAbsent(uri, () {
if (uri.scheme == 'file') {
var pathRelativeToRoot = _workspace._relativeToRoot(uri.path);
if (pathRelativeToRoot == null) return null;
var fullFilePath = _context.join(_workspace.root, pathRelativeToRoot);
File file = _workspace.findFile(fullFilePath);
return file?.createSource(uri);
}
if (uri.scheme != 'package') {
return null;
}
Expand Down Expand Up @@ -306,6 +313,32 @@ class BazelWorkspace extends Workspace
}
}

String _relativeToRoot(String p) {
path.Context context = provider.pathContext;
// genfiles
if (genfiles != null && context.isWithin(genfiles, p)) {
return context.relative(p, from: genfiles);
}
// bin
for (String bin in binPaths) {
if (context.isWithin(bin, p)) {
return context.relative(p, from: bin);
}
}
// READONLY
if (readonly != null) {
if (context.isWithin(readonly, p)) {
return context.relative(p, from: readonly);
}
}
// Not generated
if (context.isWithin(root, p)) {
return context.relative(p, from: root);
}
// Failed reverse lookup
return null;
}

/// Find the Bazel workspace that contains the given [filePath].
///
/// This method walks up the file system from [filePath], looking for various
Expand Down
57 changes: 57 additions & 0 deletions pkg/analyzer/test/src/workspace/bazel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,58 @@ class BazelPackageUriResolverTest with ResourceProviderMixin {
exists: true);
}

void test_resolveAbsolute_file_bin_to_genfiles() {
_addResources([
'/workspace/WORKSPACE',
'/workspace/bazel-genfiles/my/foo/test/foo1.dart',
'/workspace/bazel-bin/'
]);
_assertResolve('file:///workspace/bazel-bin/my/foo/test/foo1.dart',
'/workspace/bazel-genfiles/my/foo/test/foo1.dart',
restore: false);
}

void test_resolveAbsolute_file_genfiles_to_workspace() {
_addResources([
'/workspace/WORKSPACE',
'/workspace/bazel-genfiles/',
'/workspace/my/foo/test/foo1.dart'
]);
_assertResolve('file:///workspace/bazel-genfiles/my/foo/test/foo1.dart',
'/workspace/my/foo/test/foo1.dart',
restore: false);
}

void test_resolveAbsolute_file_not_in_workspace() {
_addResources([
'/workspace/WORKSPACE',
'/workspace/bazel-genfiles/',
'/other/my/foo/test/foo1.dart'
]);
_assertNoResolve('file:///other/my/foo/test/foo1.dart');
}

void test_resolveAbsolute_file_readonly_to_workspace() {
_addResources([
'/workspace/WORKSPACE',
'/READONLY/workspace/',
'/workspace/my/foo/test/foo1.dart'
]);
_assertResolve('file:///READONLY/workspace/my/foo/test/foo1.dart',
'/workspace/my/foo/test/foo1.dart',
restore: false);
}

void test_resolveAbsolute_file_workspace_to_genfiles() {
_addResources([
'/workspace/WORKSPACE',
'/workspace/bazel-genfiles/my/foo/test/foo1.dart'
]);
_assertResolve('file:///workspace/my/foo/test/foo1.dart',
'/workspace/bazel-genfiles/my/foo/test/foo1.dart',
restore: false);
}

void test_resolveAbsolute_genfiles() {
_addResources([
'/workspace/WORKSPACE',
Expand Down Expand Up @@ -465,6 +517,11 @@ class BazelPackageUriResolverTest with ResourceProviderMixin {
resolver = BazelPackageUriResolver(workspace);
}

void _assertNoResolve(String uriStr) {
var uri = Uri.parse(uriStr);
expect(resolver.resolveAbsolute(uri), isNull);
}

void _assertResolve(String uriStr, String posixPath,
{bool exists = true, bool restore = true}) {
Uri uri = Uri.parse(uriStr);
Expand Down

0 comments on commit 464641f

Please sign in to comment.