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

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

Issue 225043004: Replace bootstrap logic with 'boot.js', use 'component/dart' mime-type and add (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 4
5 /// Contains logic to initialize polymer apps during development. This 5 /// Contains logic to initialize polymer apps during development. This
6 /// implementation uses dart:mirrors to load each library as they are discovered 6 /// implementation uses dart:mirrors to load each library as they are discovered
7 /// through HTML imports. This is only meant to be during development in 7 /// through HTML imports. This is only meant to be during development in
8 /// dartium, and the polymer transformers replace this implementation with 8 /// dartium, and the polymer transformers replace this implementation with
9 /// codege generation in the polymer-build steps. 9 /// codege generation in the polymer-build steps.
10 library polymer.src.mirror_loader; 10 library polymer.src.mirror_loader;
11 11
12 import 'dart:async'; 12 import 'dart:async';
13 import 'dart:html'; 13 import 'dart:html';
14 import 'dart:collection' show LinkedHashMap; 14 import 'dart:collection' show LinkedHashMap;
15 15
16 // Technically, we shouldn't need any @MirrorsUsed, since this is for 16 // Technically, we shouldn't need any @MirrorsUsed, since this is for
17 // development only, but our test bots don't yet run pub-build. See more details 17 // development only, but our test bots don't yet run pub-build. See more details
18 // on the comments of the mirrors import in `lib/polymer.dart`. 18 // on the comments of the mirrors import in `lib/polymer.dart`.
19 @MirrorsUsed(metaTargets: 19 @MirrorsUsed(metaTargets:
20 const [CustomTag, InitMethodAnnotation], 20 const [CustomTag, InitMethodAnnotation],
21 override: const ['smoke.mirrors', 'polymer.src.mirror_loader']) 21 override: const ['smoke.mirrors', 'polymer.src.mirror_loader'])
22 import 'dart:mirrors'; 22 import 'dart:mirrors';
23 23
24 import 'package:logging/logging.dart' show Logger; 24 import 'package:logging/logging.dart' show Logger;
25 import 'package:polymer/polymer.dart' show 25 import 'package:polymer/polymer.dart';
26 InitMethodAnnotation, CustomTag, initMethod, Polymer; 26 import 'package:observe/src/dirty_check.dart';
27 27
28 28
29 void startPolymerInDevelopment(List<String> librariesToLoad) {
30 dirtyCheckZone()..run(() {
31 startPolymer(discoverInitializers(librariesToLoad), false);
32 });
33 }
34
29 /// Set of initializers that are invoked by `initPolymer`. This is computed the 35 /// Set of initializers that are invoked by `initPolymer`. This is computed the
30 /// list by crawling HTML imports, searching for script tags, and including an 36 /// list by crawling HTML imports, searching for script tags, and including an
31 /// initializer for each type tagged with a [CustomTag] annotation and for each 37 /// initializer for each type tagged with a [CustomTag] annotation and for each
32 /// top-level method annotated with [initMethod]. 38 /// top-level method annotated with [initMethod].
33 List<Function> initializers = _discoverInitializers();
34
35 /// True if we're in deployment mode.
36 bool deployMode = false;
37 39
38 /// Discovers what script tags are loaded from HTML pages and collects the 40 /// Discovers what script tags are loaded from HTML pages and collects the
39 /// initializers of their corresponding libraries. 41 /// initializers of their corresponding libraries.
40 List<Function> _discoverInitializers() { 42 // Visible for testing only.
43 List<Function> discoverInitializers(List<String> librariesToLoad) {
41 var initializers = []; 44 var initializers = [];
42 var librariesToLoad = _discoverScripts(document, window.location.href);
43 for (var lib in librariesToLoad) { 45 for (var lib in librariesToLoad) {
44 try { 46 try {
45 _loadLibrary(lib, initializers); 47 _loadLibrary(lib, initializers);
46 } catch (e, s) { 48 } catch (e, s) {
47 // Deliver errors async, so if a single library fails it doesn't prevent 49 // Deliver errors async, so if a single library fails it doesn't prevent
48 // other things from loading. 50 // other things from loading.
49 new Completer().completeError(e, s); 51 new Completer().completeError(e, s);
50 } 52 }
51 } 53 }
52 return initializers; 54 return initializers;
53 } 55 }
54 56
55 /// Walks the HTML import structure to discover all script tags that are
56 /// implicitly loaded. This code is only used in Dartium and should only be
57 /// called after all HTML imports are resolved. Polymer ensures this by asking
58 /// users to put their Dart script tags after all HTML imports (this is checked
59 /// by the linter, and Dartium will otherwise show an error message).
60 List<String> _discoverScripts(Document doc, String baseUri,
61 [Set<Document> seen, List<String> scripts]) {
62 if (seen == null) seen = new Set<Document>();
63 if (scripts == null) scripts = <String>[];
64 if (doc == null) {
65 print('warning: $baseUri not found.');
66 return scripts;
67 }
68 if (seen.contains(doc)) return scripts;
69 seen.add(doc);
70
71 bool scriptSeen = false;
72 for (var node in doc.querySelectorAll('script,link[rel="import"]')) {
73 if (node is LinkElement) {
74 _discoverScripts(node.import, node.href, seen, scripts);
75 } else if (node is ScriptElement && node.type == 'application/dart') {
76 if (!scriptSeen) {
77 var url = node.src;
78 scripts.add(url == '' ? baseUri : url);
79 scriptSeen = true;
80 } else {
81 print('warning: more than one Dart script tag in $baseUri. Dartium '
82 'currently only allows a single Dart script tag per document.');
83 }
84 }
85 }
86 return scripts;
87 }
88
89 /// All libraries in the current isolate. 57 /// All libraries in the current isolate.
90 final _libs = currentMirrorSystem().libraries; 58 final _libs = currentMirrorSystem().libraries;
91 59
92 // TODO(sigmund): explore other (cheaper) ways to resolve URIs relative to the
93 // root library (see dartbug.com/12612)
94 final _rootUri = currentMirrorSystem().isolate.rootLibrary.uri;
95
96 final Logger _loaderLog = new Logger('polymer.src.mirror_loader'); 60 final Logger _loaderLog = new Logger('polymer.src.mirror_loader');
97 61
98 bool _isHttpStylePackageUrl(Uri uri) {
99 var uriPath = uri.path;
100 return uri.scheme == _rootUri.scheme &&
101 // Don't process cross-domain uris.
102 uri.authority == _rootUri.authority &&
103 uriPath.endsWith('.dart') &&
104 (uriPath.contains('/packages/') || uriPath.startsWith('packages/'));
105 }
106
107 /// Reads the library at [uriString] (which can be an absolute URI or a relative 62 /// Reads the library at [uriString] (which can be an absolute URI or a relative
108 /// URI from the root library), and: 63 /// URI from the root library), and:
109 /// 64 ///
110 /// * If present, invokes any top-level and static functions marked 65 /// * If present, invokes any top-level and static functions marked
111 /// with the [initMethod] annotation (in the order they appear). 66 /// with the [initMethod] annotation (in the order they appear).
112 /// 67 ///
113 /// * Registers any [PolymerElement] that is marked with the [CustomTag] 68 /// * Registers any [PolymerElement] that is marked with the [CustomTag]
114 /// annotation. 69 /// annotation.
115 void _loadLibrary(String uriString, List<Function> initializers) { 70 void _loadLibrary(String uriString, List<Function> initializers) {
116 var uri = _rootUri.resolve(uriString); 71 var uri = Uri.parse(uriString);
117 var lib = _libs[uri]; 72 var lib = _libs[uri];
118 if (_isHttpStylePackageUrl(uri)) {
119 // Use package: urls if available. This rule here is more permissive than
120 // how we translate urls in polymer-build, but we expect Dartium to limit
121 // the cases where there are differences. The polymer-build issues an error
122 // when using packages/ inside lib without properly stepping out all the way
123 // to the packages folder. If users don't create symlinks in the source
124 // tree, then Dartium will also complain because it won't find the file seen
125 // in an HTML import.
126 var packagePath = uri.path.substring(
127 uri.path.lastIndexOf('packages/') + 'packages/'.length);
128 var canonicalLib = _libs[Uri.parse('package:$packagePath')];
129 if (canonicalLib != null) {
130 lib = canonicalLib;
131 }
132 }
133 73
134 if (lib == null) { 74 if (lib == null) {
135 _loaderLog.info('$uri library not found'); 75 _loaderLog.info('$uri library not found');
136 return; 76 return;
137 } 77 }
138 78
139 // Search top-level functions marked with @initMethod 79 // Search top-level functions marked with @initMethod
140 for (var f in lib.declarations.values.where((d) => d is MethodMirror)) { 80 for (var f in lib.declarations.values.where((d) => d is MethodMirror)) {
141 _addInitMethod(lib, f, initializers); 81 _addInitMethod(lib, f, initializers);
142 } 82 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 " ${method.simpleName} is not."); 153 " ${method.simpleName} is not.");
214 return; 154 return;
215 } 155 }
216 if (!method.parameters.where((p) => !p.isOptional).isEmpty) { 156 if (!method.parameters.where((p) => !p.isOptional).isEmpty) {
217 print("warning: methods marked with @initMethod should take no " 157 print("warning: methods marked with @initMethod should take no "
218 "arguments, ${method.simpleName} expects some."); 158 "arguments, ${method.simpleName} expects some.");
219 return; 159 return;
220 } 160 }
221 initializers.add(() => obj.invoke(method.simpleName, const [])); 161 initializers.add(() => obj.invoke(method.simpleName, const []));
222 } 162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698