diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart index 5b6bd923c20e..22e4b567fe94 100644 --- a/pkg/analyzer/lib/src/workspace/bazel.dart +++ b/pkg/analyzer/lib/src/workspace/bazel.dart @@ -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; } @@ -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 diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart index f267f85205b4..6bc5fb90ae3b 100644 --- a/pkg/analyzer/test/src/workspace/bazel_test.dart +++ b/pkg/analyzer/test/src/workspace/bazel_test.dart @@ -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', @@ -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);