Skip to content
This repository was archived by the owner on Mar 27, 2020. It is now read-only.

Commit 0b63bf3

Browse files
committed
1 parent 19d9393 commit 0b63bf3

15 files changed

+1390
-0
lines changed

lib/package_resolver.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
export 'src/package_resolver.dart';
6+
export 'src/sync_package_resolver.dart';

lib/src/async_package_resolver.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package_resolver.dart';
8+
import 'sync_package_resolver.dart';
9+
10+
/// An implementation of [PackageResolver] that wraps a [SyncPackageResolver].
11+
class AsyncPackageResolver implements PackageResolver {
12+
/// The wrapped [SyncPackageResolver].
13+
final SyncPackageResolver _inner;
14+
15+
AsyncPackageResolver(this._inner);
16+
17+
Future<Map<String, Uri>> get packageConfigMap async =>
18+
_inner.packageConfigMap;
19+
20+
Future<Uri> get packageConfigUri async => _inner.packageConfigUri;
21+
Future<Uri> get packageRoot async => _inner.packageRoot;
22+
Future<SyncPackageResolver> get asSync async => _inner;
23+
Future<String> get processArgument async => _inner.processArgument;
24+
25+
Future<Uri> resolveUri(packageUri) async => _inner.resolveUri(packageUri);
26+
Future<Uri> urlFor(String package, [String path]) async =>
27+
_inner.urlFor(package, path);
28+
Future<Uri> packageUriFor(url) async => _inner.packageUriFor(url);
29+
Future<String> packagePath(String package) async =>
30+
_inner.packagePath(package);
31+
}

lib/src/current_isolate_resolver.dart

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:isolate';
7+
8+
import 'package:path/path.dart' as p;
9+
10+
import 'package_config_resolver.dart';
11+
import 'package_resolver.dart';
12+
import 'package_root_resolver.dart';
13+
import 'sync_package_resolver.dart';
14+
import 'utils.dart';
15+
16+
/// The package resolution strategy used by the current isolate.
17+
class CurrentIsolateResolver implements PackageResolver {
18+
Future<Map<String, Uri>> get packageConfigMap async {
19+
if (_packageConfigMap != null) return _packageConfigMap;
20+
21+
var url = await Isolate.packageConfig;
22+
if (url == null) return null;
23+
24+
return await loadConfigMap(url);
25+
}
26+
Map<String, Uri> _packageConfigMap;
27+
28+
Future<Uri> get packageConfigUri => Isolate.packageConfig;
29+
30+
Future<Uri> get packageRoot => Isolate.packageRoot;
31+
32+
Future<SyncPackageResolver> get asSync async {
33+
var root = await packageRoot;
34+
if (root != null) return new PackageRootResolver(root);
35+
36+
var map = await packageConfigMap;
37+
38+
// It's hard to imagine how there would be no package resolution strategy
39+
// for an Isolate that can load the package_resolver package, but it's easy
40+
// to handle that case so we do.
41+
if (map == null) return SyncPackageResolver.none;
42+
43+
return new PackageConfigResolver(map, uri: await packageConfigUri);
44+
}
45+
46+
Future<String> get processArgument async {
47+
var configUri = await packageConfigUri;
48+
if (configUri != null) return "--packages=$configUri";
49+
50+
var root = await packageRoot;
51+
if (root != null) return "--package-root=$root";
52+
53+
return null;
54+
}
55+
56+
Future<Uri> resolveUri(packageUri) =>
57+
Isolate.resolvePackageUri(asPackageUri(packageUri, "packageUri"));
58+
59+
Future<Uri> urlFor(String package, [String path]) =>
60+
Isolate.resolvePackageUri(Uri.parse("package:$package/${path ?? ''}"));
61+
62+
Future<Uri> packageUriFor(url) async => (await asSync).packageUriFor(url);
63+
64+
Future<String> packagePath(String package) async {
65+
var root = await packageRoot;
66+
if (root != null) return new PackageRootResolver(root).packagePath(package);
67+
68+
return p.dirname(p.fromUri(await urlFor(package)));
69+
}
70+
}

lib/src/no_package_resolver.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'async_package_resolver.dart';
6+
import 'package_resolver.dart';
7+
import 'sync_package_resolver.dart';
8+
import 'utils.dart';
9+
10+
/// A package resolution strategy that is unable to resolve any `package:` URIs.
11+
class NoPackageResolver implements SyncPackageResolver {
12+
Map<String, Uri> get packageConfigMap => null;
13+
Uri get packageConfigUri => null;
14+
Uri get packageRoot => null;
15+
String get processArgument => null;
16+
17+
PackageResolver get asAsync => new AsyncPackageResolver(this);
18+
19+
Uri resolveUri(packageUri) {
20+
// Verify that the URI is valid.
21+
asPackageUri(packageUri, "packageUri");
22+
return null;
23+
}
24+
25+
Uri urlFor(String package, [String path]) => null;
26+
27+
Uri packageUriFor(url) {
28+
// Verify that the URI is a valid type.
29+
asUri(url, "url");
30+
return null;
31+
}
32+
33+
String packagePath(String package) => null;
34+
}

lib/src/package_config_resolver.dart

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:collection';
6+
7+
import 'package:collection/collection.dart';
8+
import 'package:package_config/packages_file.dart' as packages_file;
9+
import 'package:path/path.dart' as p;
10+
11+
import 'async_package_resolver.dart';
12+
import 'package_resolver.dart';
13+
import 'sync_package_resolver.dart';
14+
import 'utils.dart';
15+
16+
/// A package resolution strategy based on a package config map.
17+
class PackageConfigResolver implements SyncPackageResolver {
18+
final packageRoot = null;
19+
20+
final Map<String, Uri> packageConfigMap;
21+
22+
Uri get packageConfigUri {
23+
if (_uri != null) return _uri;
24+
25+
var buffer = new StringBuffer();
26+
packages_file.write(buffer, packageConfigMap, comment: "");
27+
_uri = new UriData.fromString(buffer.toString(),
28+
parameters: {"charset": "utf-8"})
29+
.uri;
30+
return _uri;
31+
}
32+
Uri _uri;
33+
34+
PackageResolver get asAsync => new AsyncPackageResolver(this);
35+
36+
String get processArgument => "--packages=$packageConfigUri";
37+
38+
PackageConfigResolver(Map<String, Uri> packageConfigMap, {uri})
39+
: packageConfigMap = _normalizeMap(packageConfigMap),
40+
_uri = uri == null ? null : asUri(uri, "uri");
41+
42+
/// Normalizes the URIs in [map] to ensure that they all end in a trailing
43+
/// slash.
44+
static Map<String, Uri> _normalizeMap(Map<String, Uri> map) =>
45+
new UnmodifiableMapView(
46+
mapMap(map, value: (_, uri) => ensureTrailingSlash(uri)));
47+
48+
Uri resolveUri(packageUri) {
49+
var uri = asPackageUri(packageUri, "packageUri");
50+
51+
var baseUri = packageConfigMap[uri.pathSegments.first];
52+
if (baseUri == null) return null;
53+
54+
var segments = baseUri.pathSegments.toList()
55+
..removeLast(); // Remove the trailing slash.
56+
57+
// Following [Isolate.resolvePackageUri], "package:foo" resolves to null.
58+
if (uri.pathSegments.length == 1) return null;
59+
60+
segments.addAll(uri.pathSegments.skip(1));
61+
return baseUri.replace(pathSegments: segments);
62+
}
63+
64+
Uri urlFor(String package, [String path]) {
65+
var baseUri = packageConfigMap[package];
66+
if (baseUri == null) return null;
67+
if (path == null) return baseUri;
68+
return baseUri.resolve(path);
69+
}
70+
71+
Uri packageUriFor(url) {
72+
url = asUri(url, "url").toString();
73+
74+
// Make sure isWithin works if [url] is exactly the base.
75+
var nested = p.url.join(url, "_");
76+
for (var package in packageConfigMap.keys) {
77+
var base = packageConfigMap[package].toString();
78+
if (!p.url.isWithin(base, nested)) continue;
79+
80+
var relative = p.url.relative(url, from: base);
81+
if (relative == '.') relative = '';
82+
return Uri.parse("package:$package/$relative");
83+
}
84+
85+
return null;
86+
}
87+
88+
String packagePath(String package) {
89+
var lib = packageConfigMap[package];
90+
if (lib == null) return null;
91+
if (lib.scheme != 'file') return null;
92+
return p.dirname(p.fromUri(lib));
93+
}
94+
}

0 commit comments

Comments
 (0)