Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: lib/src/mirror_loader.dart

Issue 973073003: fix a few issues around exported libraries (Closed) Base URL: git@github.com:dart-lang/static-init.git@master
Patch Set: comment tweaks Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « CHANGELOG.md ('k') | lib/transformer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 library initialize.mirror_loader; 4 library initialize.mirror_loader;
5 5
6 import 'dart:collection' show Queue; 6 import 'dart:collection' show Queue;
7 import 'dart:mirrors'; 7 import 'dart:mirrors';
8 import 'package:path/path.dart' as path; 8 import 'package:path/path.dart' as path;
9 import 'package:initialize/initialize.dart'; 9 import 'package:initialize/initialize.dart';
10 10
11 final _root = currentMirrorSystem().isolate.rootLibrary;
12
11 Queue<Function> loadInitializers( 13 Queue<Function> loadInitializers(
12 {List<Type> typeFilter, InitializerFilter customFilter}) { 14 {List<Type> typeFilter, InitializerFilter customFilter}) {
13 return new InitializationCrawler(typeFilter, customFilter).run(); 15 return new InitializationCrawler(typeFilter, customFilter).run();
14 } 16 }
15 17
16 // Crawls a library and all its dependencies for `Initializer` annotations using 18 // Crawls a library and all its dependencies for `Initializer` annotations using
17 // mirrors 19 // mirrors
18 class InitializationCrawler { 20 class InitializationCrawler {
19 // Set of all visited annotations, keys are the declarations that were 21 // Set of all visited annotations, keys are the declarations that were
20 // annotated, values are the annotations that have been processed. 22 // annotated, values are the annotations that have been processed.
21 static final _annotationsFound = 23 static final _annotationsFound =
22 new Map<DeclarationMirror, Set<InstanceMirror>>(); 24 new Map<DeclarationMirror, Set<InstanceMirror>>();
23 25
24 // If non-null, then only these annotations should be processed. 26 // If non-null, then only these annotations should be processed.
25 final List<Type> typeFilter; 27 final List<Type> typeFilter;
26 28
27 // If non-null, then only annotations which return true when passed to this 29 // If non-null, then only annotations which return true when passed to this
28 // function will be processed. 30 // function will be processed.
29 final InitializerFilter customFilter; 31 final InitializerFilter customFilter;
30 32
31 // The root library that we start parsing from. 33 InitializationCrawler(this.typeFilter, this.customFilter);
32 LibraryMirror _root;
33
34 InitializationCrawler(this.typeFilter, this.customFilter,
35 {LibraryMirror root}) {
36 _root = root == null ? currentMirrorSystem().isolate.rootLibrary : root;
37 }
38 34
39 // The primary function in this class, invoke it to crawl and collect all the 35 // The primary function in this class, invoke it to crawl and collect all the
40 // annotations into a queue of init functions. 36 // annotations into a queue of init functions.
41 Queue<Function> run() => _readLibraryDeclarations(_root); 37 Queue<Function> run() {
38 var librariesSeen = new Set<LibraryMirror>();
39 var queue = new Queue<Function>();
40
41 var libraries = currentMirrorSystem().libraries;
42 var nonDartOrPackageImports = new List.from(libraries.keys.where(
43 (uri) => uri.scheme != 'package' && uri.scheme != 'dart'));
44
45 for (var import in nonDartOrPackageImports.reversed) {
46 // Always load the package: version of a library if available.
47 var libToRun;
48 if (_isHttpStylePackageUrl(import)) {
49 var packageUri = _packageUriFor(import);
50 libToRun = libraries[packageUri];
51 }
52 if (libToRun == null) libToRun = libraries[import];
53
54 // Dartium creates an extra trampoline lib that loads the main dart script
55 // and breaks our ordering.
56 if (librariesSeen.contains(libToRun) ||
57 libToRun.uri.toString().endsWith('\$trampoline')) {
Siggi Cherem (dart-lang) 2015/03/04 16:43:52 maybe it's enough to do libToRun.uri.path.ends
jakemac 2015/03/04 16:49:49 good point switched to .path
58 continue;
59 }
60 _readLibraryDeclarations(libToRun, librariesSeen, queue);
61 }
62
63 return queue;
64 }
65
66 /// Whether [uri] is an http URI that contains a 'packages' segment, and
67 /// therefore could be converted into a 'package:' URI.
68 bool _isHttpStylePackageUrl(Uri uri) {
69 var uriPath = uri.path;
70 return uri.scheme == _root.uri.scheme &&
71 // Don't process cross-domain uris.
72 uri.authority == _root.uri.authority &&
73 uriPath.endsWith('.dart') &&
74 (uriPath.contains('/packages/') || uriPath.startsWith('packages/'));
75 }
76
77 Uri _packageUriFor(Uri httpUri) {
78 var packagePath = httpUri.path.substring(
79 httpUri.path.lastIndexOf('packages/') + 'packages/'.length);
80 return Uri.parse('package:$packagePath');
81 }
42 82
43 // Reads Initializer annotations on this library and all its dependencies in 83 // Reads Initializer annotations on this library and all its dependencies in
44 // post-order. 84 // post-order.
45 Queue<Function> _readLibraryDeclarations(LibraryMirror lib, 85 Queue<Function> _readLibraryDeclarations(LibraryMirror lib,
46 [Set<LibraryMirror> librariesSeen, Queue<Function> queue]) { 86 Set<LibraryMirror> librariesSeen, Queue<Function> queue) {
47 if (librariesSeen == null) librariesSeen = new Set<LibraryMirror>();
48 if (queue == null) queue = new Queue<Function>();
49 librariesSeen.add(lib); 87 librariesSeen.add(lib);
50 88
51 // First visit all our dependencies. 89 // First visit all our dependencies.
52 for (var dependency in _sortedLibraryDependencies(lib)) { 90 for (var dependency in _sortedLibraryDependencies(lib)) {
53 // Skip dart: imports, they never use this package. 91 // Skip dart: imports, they never use this package.
54 if (dependency.targetLibrary.uri.toString().startsWith('dart:')) continue; 92 if (dependency.targetLibrary.uri.toString().startsWith('dart:')) continue;
55 if (librariesSeen.contains(dependency.targetLibrary)) continue; 93 if (librariesSeen.contains(dependency.targetLibrary)) continue;
56 94
57 _readLibraryDeclarations(dependency.targetLibrary, librariesSeen, queue); 95 _readLibraryDeclarations(dependency.targetLibrary, librariesSeen, queue);
58 } 96 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 if (declaration.owner is! LibraryMirror) { 179 if (declaration.owner is! LibraryMirror) {
142 // TODO(jakemac): Support static class methods. 180 // TODO(jakemac): Support static class methods.
143 throw _TOP_LEVEL_FUNCTIONS_ONLY; 181 throw _TOP_LEVEL_FUNCTIONS_ONLY;
144 } 182 }
145 annotatedValue = (declaration.owner as ObjectMirror) 183 annotatedValue = (declaration.owner as ObjectMirror)
146 .getField(declaration.simpleName).reflectee; 184 .getField(declaration.simpleName).reflectee;
147 } else if (declaration is LibraryMirror) { 185 } else if (declaration is LibraryMirror) {
148 var package; 186 var package;
149 var filePath; 187 var filePath;
150 Uri uri = declaration.uri; 188 Uri uri = declaration.uri;
189 // Convert to a package style uri if possible.
190 if (_isHttpStylePackageUrl(uri)) {
191 uri = _packageUriFor(uri);
192 }
151 if (uri.scheme == 'file' || uri.scheme.startsWith('http')) { 193 if (uri.scheme == 'file' || uri.scheme.startsWith('http')) {
152 filePath = path.url.relative(uri.path, 194 filePath = path.url.relative(uri.path,
153 from: path.url.dirname(_root.uri.path)); 195 from: path.url.dirname(_root.uri.path));
154 } else if (uri.scheme == 'package') { 196 } else if (uri.scheme == 'package') {
155 var segments = uri.pathSegments; 197 var segments = uri.pathSegments;
156 package = segments[0]; 198 package = segments[0];
157 filePath = path.url.joinAll(segments.getRange(1, segments.length)); 199 filePath = path.url.joinAll(segments.getRange(1, segments.length));
158 } else { 200 } else {
159 throw new UnsupportedError('Unsupported uri scheme ${uri.scheme} for ' 201 throw new UnsupportedError('Unsupported uri scheme ${uri.scheme} for '
160 'library ${declaration}.'); 202 'library ${declaration}.');
(...skipping 24 matching lines...) Expand all
185 return true; 227 return true;
186 } 228 }
187 } 229 }
188 230
189 final _TOP_LEVEL_FUNCTIONS_ONLY = new UnsupportedError( 231 final _TOP_LEVEL_FUNCTIONS_ONLY = new UnsupportedError(
190 'Only top level methods are supported for initializers'); 232 'Only top level methods are supported for initializers');
191 233
192 final _UNSUPPORTED_DECLARATION = new UnsupportedError( 234 final _UNSUPPORTED_DECLARATION = new UnsupportedError(
193 'Initializers are only supported on libraries, classes, and top level ' 235 'Initializers are only supported on libraries, classes, and top level '
194 'methods'); 236 'methods');
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | lib/transformer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698