OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /// Transfomer that combines multiple dart script tags into a single one. | 5 /// Transfomer that combines multiple dart script tags into a single one. |
6 library polymer.src.build.script_compactor; | 6 library polymer.src.build.script_compactor; |
7 | 7 |
8 import 'dart:async'; | 8 import 'dart:async'; |
9 import 'dart:convert'; | 9 import 'dart:convert'; |
10 | 10 |
11 import 'package:html5lib/dom.dart' show Document, Element, Text; | 11 import 'package:html5lib/dom.dart' show Document, Element, Text; |
12 import 'package:html5lib/dom_parsing.dart'; | 12 import 'package:html5lib/dom_parsing.dart'; |
13 import 'package:html5lib/parser.dart' show parseFragment; | |
13 import 'package:analyzer/src/generated/ast.dart'; | 14 import 'package:analyzer/src/generated/ast.dart'; |
14 import 'package:analyzer/src/generated/element.dart' hide Element; | 15 import 'package:analyzer/src/generated/element.dart' hide Element; |
15 import 'package:analyzer/src/generated/element.dart' as analyzer show Element; | 16 import 'package:analyzer/src/generated/element.dart' as analyzer show Element; |
16 import 'package:barback/barback.dart'; | 17 import 'package:barback/barback.dart'; |
17 import 'package:code_transformers/assets.dart'; | 18 import 'package:code_transformers/assets.dart'; |
18 import 'package:path/path.dart' as path; | 19 import 'package:path/path.dart' as path; |
19 import 'package:source_maps/span.dart' show SourceFile; | 20 import 'package:source_maps/span.dart' show SourceFile; |
20 import 'package:smoke/codegen/generator.dart'; | 21 import 'package:smoke/codegen/generator.dart'; |
21 import 'package:smoke/codegen/recorder.dart'; | 22 import 'package:smoke/codegen/recorder.dart'; |
22 import 'package:code_transformers/resolver.dart'; | 23 import 'package:code_transformers/resolver.dart'; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 final AssetId docId; | 64 final AssetId docId; |
64 final AssetId bootstrapId; | 65 final AssetId bootstrapId; |
65 | 66 |
66 /// HTML document parsed from [docId]. | 67 /// HTML document parsed from [docId]. |
67 Document document; | 68 Document document; |
68 | 69 |
69 /// List of ids for each Dart entry script tag (the main tag and any tag | 70 /// List of ids for each Dart entry script tag (the main tag and any tag |
70 /// included on each custom element definition). | 71 /// included on each custom element definition). |
71 List<AssetId> entryLibraries; | 72 List<AssetId> entryLibraries; |
72 | 73 |
73 /// The id of the main Dart program. | |
74 AssetId mainLibraryId; | |
75 | |
76 /// Script tag that loads the Dart entry point. | |
77 Element mainScriptTag; | |
78 | |
79 /// Initializers that will register custom tags or invoke `initMethod`s. | 74 /// Initializers that will register custom tags or invoke `initMethod`s. |
80 final List<_Initializer> initializers = []; | 75 final List<_Initializer> initializers = []; |
81 | 76 |
82 /// Attributes published on a custom-tag. We make these available via | 77 /// Attributes published on a custom-tag. We make these available via |
83 /// reflection even if @published was not used. | 78 /// reflection even if @published was not used. |
84 final Map<String, List<String>> publishedAttributes = {}; | 79 final Map<String, List<String>> publishedAttributes = {}; |
85 | 80 |
86 /// Hook needed to access the analyzer within barback transformers. | 81 /// Hook needed to access the analyzer within barback transformers. |
87 final Resolvers resolvers; | 82 final Resolvers resolvers; |
88 | 83 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 | 118 |
124 /// Removes unnecessary script tags, and identifies the main entry point Dart | 119 /// Removes unnecessary script tags, and identifies the main entry point Dart |
125 /// script tag (if any). | 120 /// script tag (if any). |
126 void _processHtml(_) { | 121 void _processHtml(_) { |
127 for (var tag in document.querySelectorAll('script')) { | 122 for (var tag in document.querySelectorAll('script')) { |
128 var src = tag.attributes['src']; | 123 var src = tag.attributes['src']; |
129 if (src == 'packages/polymer/boot.js') { | 124 if (src == 'packages/polymer/boot.js') { |
130 tag.remove(); | 125 tag.remove(); |
131 continue; | 126 continue; |
132 } | 127 } |
133 if (tag.attributes['type'] != 'application/dart') continue; | 128 var type = tag.attributes['type']; |
134 if (src == null) { | 129 if (type == 'components/dart') { |
135 logger.warning('unexpected script without a src url. The ' | 130 logger.warning('unexpected script. The ' |
136 'ScriptCompactor transformer should run after running the ' | 131 'ScriptCompactor transformer should run after running the ' |
137 'InlineCodeExtractor', span: tag.sourceSpan); | 132 'ImportInliner', span: tag.sourceSpan); |
138 continue; | |
139 } | 133 } |
140 if (mainLibraryId != null) { | |
141 logger.warning('unexpected script. Only one Dart script tag ' | |
142 'per document is allowed.', span: tag.sourceSpan); | |
143 tag.remove(); | |
144 continue; | |
145 } | |
146 mainLibraryId = uriToAssetId(docId, src, logger, tag.sourceSpan); | |
147 mainScriptTag = tag; | |
148 } | 134 } |
149 } | 135 } |
150 | 136 |
151 /// Emits the main HTML and Dart bootstrap code for the application. If there | 137 /// Emits the main HTML and Dart bootstrap code for the application. If there |
152 /// were not Dart entry point files, then this simply emits the original HTML. | 138 /// were not Dart entry point files, then this simply emits the original HTML. |
153 Future _emitNewEntrypoint(_) { | 139 Future _emitNewEntrypoint(_) { |
154 if (mainScriptTag == null) { | 140 if (entryLibraries.isEmpty) { |
155 // We didn't find any main library, nothing to do. | 141 // We didn't find code, nothing to do. |
156 transform.addOutput(transform.primaryInput); | 142 transform.addOutput(transform.primaryInput); |
157 return null; | 143 return null; |
158 } | 144 } |
159 | 145 |
160 // Emit the bootstrap .dart file | |
161 mainScriptTag.attributes['src'] = path.url.basename(bootstrapId.path); | |
162 entryLibraries.add(mainLibraryId); | |
163 | |
164 return _initResolver() | 146 return _initResolver() |
165 .then(_extractUsesOfMirrors) | 147 .then(_extractUsesOfMirrors) |
166 .then(_emitFiles) | 148 .then(_emitFiles) |
167 .then((_) => resolver.release()); | 149 .whenComplete(() => resolver.release()); |
Jennifer Messerly
2014/04/04 19:39:50
nice catch!
Siggi Cherem (dart-lang)
2014/04/04 21:09:11
yeah, Pete noticed this in code_transformers and t
| |
168 } | 150 } |
169 | 151 |
170 /// Load a resolver that computes information for every library in | 152 /// Load a resolver that computes information for every library in |
171 /// [entryLibraries], then use it to initialize the [recorder] (for import | 153 /// [entryLibraries], then use it to initialize the [recorder] (for import |
172 /// resolution) and to resolve specific elements (for analyzing the user's | 154 /// resolution) and to resolve specific elements (for analyzing the user's |
173 /// code). | 155 /// code). |
174 Future _initResolver() => resolvers.get(transform, entryLibraries).then((r) { | 156 Future _initResolver() => resolvers.get(transform, entryLibraries).then((r) { |
175 resolver = r; | 157 resolver = r; |
176 types = new _ResolvedTypes(resolver); | 158 types = new _ResolvedTypes(resolver); |
177 }); | 159 }); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 code.writeln("import '$url' as i$i;"); | 334 code.writeln("import '$url' as i$i;"); |
353 prefixes[id] = 'i$i'; | 335 prefixes[id] = 'i$i'; |
354 i++; | 336 i++; |
355 } | 337 } |
356 | 338 |
357 // Include smoke initialization. | 339 // Include smoke initialization. |
358 generator.writeImports(code); | 340 generator.writeImports(code); |
359 generator.writeTopLevelDeclarations(code); | 341 generator.writeTopLevelDeclarations(code); |
360 code.writeln('\nvoid main() {'); | 342 code.writeln('\nvoid main() {'); |
361 generator.writeInitCall(code); | 343 generator.writeInitCall(code); |
362 code.writeln(' configureForDeployment(['); | 344 code.writeln(' startPolymer(['); |
363 | 345 |
364 // Include initializers to switch from mirrors_loader to static_loader. | 346 // Include initializers to switch from mirrors_loader to static_loader. |
365 for (var init in initializers) { | 347 for (var init in initializers) { |
366 var initCode = init.asCode(prefixes[init.assetId]); | 348 var initCode = init.asCode(prefixes[init.assetId]); |
367 code.write(" $initCode,\n"); | 349 code.write(" $initCode,\n"); |
368 } | 350 } |
369 code..writeln(' ]);') | 351 code..writeln(' ]);') |
370 ..writeln(' i${entryLibraries.length - 1}.main();') | |
371 ..writeln('}'); | 352 ..writeln('}'); |
372 transform.addOutput(new Asset.fromString(bootstrapId, code.toString())); | 353 transform.addOutput(new Asset.fromString(bootstrapId, code.toString())); |
354 | |
355 | |
356 // Emit the bootstrap .dart file | |
357 var srcUrl = path.url.basename(bootstrapId.path); | |
358 document.body.nodes.add(parseFragment( | |
359 '<script type="application/dart" src="$srcUrl"></script>')); | |
373 transform.addOutput(new Asset.fromString(docId, document.outerHtml)); | 360 transform.addOutput(new Asset.fromString(docId, document.outerHtml)); |
374 } | 361 } |
375 | 362 |
376 _spanForNode(analyzer.Element context, AstNode node) { | 363 _spanForNode(analyzer.Element context, AstNode node) { |
377 var file = resolver.getSourceFile(context); | 364 var file = resolver.getSourceFile(context); |
378 return file.span(node.offset, node.end); | 365 return file.span(node.offset, node.end); |
379 } | 366 } |
380 } | 367 } |
381 | 368 |
382 abstract class _Initializer { | 369 abstract class _Initializer { |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 for (var c in combinators) { | 682 for (var c in combinators) { |
696 if (c is ShowElementCombinator) { | 683 if (c is ShowElementCombinator) { |
697 var show = c.shownNames.toSet(); | 684 var show = c.shownNames.toSet(); |
698 elements.retainWhere((e) => show.contains(e.displayName)); | 685 elements.retainWhere((e) => show.contains(e.displayName)); |
699 } else if (c is HideElementCombinator) { | 686 } else if (c is HideElementCombinator) { |
700 var hide = c.hiddenNames.toSet(); | 687 var hide = c.hiddenNames.toSet(); |
701 elements.removeWhere((e) => hide.contains(e.displayName)); | 688 elements.removeWhere((e) => hide.contains(e.displayName)); |
702 } | 689 } |
703 } | 690 } |
704 } | 691 } |
OLD | NEW |