| Index: lib/src/mirror_loader.dart
|
| diff --git a/lib/src/mirror_loader.dart b/lib/src/mirror_loader.dart
|
| index 92a00f84edfe2abb95aae7a4e70bdfd0b420ec4e..e73f0cc419c545fdd368e2682abe2b26d317de0f 100644
|
| --- a/lib/src/mirror_loader.dart
|
| +++ b/lib/src/mirror_loader.dart
|
| @@ -8,6 +8,8 @@ import 'dart:mirrors';
|
| import 'package:path/path.dart' as path;
|
| import 'package:initialize/initialize.dart';
|
|
|
| +final _root = currentMirrorSystem().isolate.rootLibrary;
|
| +
|
| Queue<Function> loadInitializers(
|
| {List<Type> typeFilter, InitializerFilter customFilter}) {
|
| return new InitializationCrawler(typeFilter, customFilter).run();
|
| @@ -28,24 +30,60 @@ class InitializationCrawler {
|
| // function will be processed.
|
| final InitializerFilter customFilter;
|
|
|
| - // The root library that we start parsing from.
|
| - LibraryMirror _root;
|
| -
|
| - InitializationCrawler(this.typeFilter, this.customFilter,
|
| - {LibraryMirror root}) {
|
| - _root = root == null ? currentMirrorSystem().isolate.rootLibrary : root;
|
| - }
|
| + InitializationCrawler(this.typeFilter, this.customFilter);
|
|
|
| // The primary function in this class, invoke it to crawl and collect all the
|
| // annotations into a queue of init functions.
|
| - Queue<Function> run() => _readLibraryDeclarations(_root);
|
| + Queue<Function> run() {
|
| + var librariesSeen = new Set<LibraryMirror>();
|
| + var queue = new Queue<Function>();
|
| +
|
| + var libraries = currentMirrorSystem().libraries;
|
| + var nonDartOrPackageImports = new List.from(libraries.keys.where(
|
| + (uri) => uri.scheme != 'package' && uri.scheme != 'dart'));
|
| +
|
| + for (var import in nonDartOrPackageImports.reversed) {
|
| + // Always load the package: version of a library if available.
|
| + var libToRun;
|
| + if (_isHttpStylePackageUrl(import)) {
|
| + var packageUri = _packageUriFor(import);
|
| + libToRun = libraries[packageUri];
|
| + }
|
| + if (libToRun == null) libToRun = libraries[import];
|
| +
|
| + // Dartium creates an extra trampoline lib that loads the main dart script
|
| + // and breaks our ordering.
|
| + if (librariesSeen.contains(libToRun) ||
|
| + libToRun.uri.path.endsWith('\$trampoline')) {
|
| + continue;
|
| + }
|
| + _readLibraryDeclarations(libToRun, librariesSeen, queue);
|
| + }
|
| +
|
| + return queue;
|
| + }
|
| +
|
| + /// Whether [uri] is an http URI that contains a 'packages' segment, and
|
| + /// therefore could be converted into a 'package:' URI.
|
| + bool _isHttpStylePackageUrl(Uri uri) {
|
| + var uriPath = uri.path;
|
| + return uri.scheme == _root.uri.scheme &&
|
| + // Don't process cross-domain uris.
|
| + uri.authority == _root.uri.authority &&
|
| + uriPath.endsWith('.dart') &&
|
| + (uriPath.contains('/packages/') || uriPath.startsWith('packages/'));
|
| + }
|
| +
|
| + Uri _packageUriFor(Uri httpUri) {
|
| + var packagePath = httpUri.path.substring(
|
| + httpUri.path.lastIndexOf('packages/') + 'packages/'.length);
|
| + return Uri.parse('package:$packagePath');
|
| + }
|
|
|
| // Reads Initializer annotations on this library and all its dependencies in
|
| // post-order.
|
| Queue<Function> _readLibraryDeclarations(LibraryMirror lib,
|
| - [Set<LibraryMirror> librariesSeen, Queue<Function> queue]) {
|
| - if (librariesSeen == null) librariesSeen = new Set<LibraryMirror>();
|
| - if (queue == null) queue = new Queue<Function>();
|
| + Set<LibraryMirror> librariesSeen, Queue<Function> queue) {
|
| librariesSeen.add(lib);
|
|
|
| // First visit all our dependencies.
|
| @@ -148,6 +186,10 @@ class InitializationCrawler {
|
| var package;
|
| var filePath;
|
| Uri uri = declaration.uri;
|
| + // Convert to a package style uri if possible.
|
| + if (_isHttpStylePackageUrl(uri)) {
|
| + uri = _packageUriFor(uri);
|
| + }
|
| if (uri.scheme == 'file' || uri.scheme.startsWith('http')) {
|
| filePath = path.url.relative(uri.path,
|
| from: path.url.dirname(_root.uri.path));
|
|
|