| 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 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 logger.warning('unexpected script. The ' | 132 logger.warning('unexpected script. The ' |
| 133 'ScriptCompactor transformer should run after running the ' | 133 'ScriptCompactor transformer should run after running the ' |
| 134 'ImportInliner', span: tag.sourceSpan); | 134 'ImportInliner', span: tag.sourceSpan); |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 | 138 |
| 139 /// Emits the main HTML and Dart bootstrap code for the application. If there | 139 /// Emits the main HTML and Dart bootstrap code for the application. If there |
| 140 /// were not Dart entry point files, then this simply emits the original HTML. | 140 /// were not Dart entry point files, then this simply emits the original HTML. |
| 141 Future _emitNewEntrypoint(_) { | 141 Future _emitNewEntrypoint(_) { |
| 142 if (entryLibraries.isEmpty) { | 142 // If we don't find code, there is nothing to do. |
| 143 // We didn't find code, nothing to do. | 143 if (entryLibraries.isEmpty) return null; |
| 144 transform.addOutput(transform.primaryInput); | |
| 145 return null; | |
| 146 } | |
| 147 | |
| 148 return _initResolver() | 144 return _initResolver() |
| 149 .then(_extractUsesOfMirrors) | 145 .then(_extractUsesOfMirrors) |
| 150 .then(_emitFiles) | 146 .then(_emitFiles) |
| 151 .whenComplete(() { | 147 .whenComplete(() { |
| 152 if (resolver != null) resolver.release(); | 148 if (resolver != null) resolver.release(); |
| 153 }); | 149 }); |
| 154 } | 150 } |
| 155 | 151 |
| 156 /// Load a resolver that computes information for every library in | 152 /// Load a resolver that computes information for every library in |
| 157 /// [entryLibraries], then use it to initialize the [recorder] (for import | 153 /// [entryLibraries], then use it to initialize the [recorder] (for import |
| 158 /// resolution) and to resolve specific elements (for analyzing the user's | 154 /// resolution) and to resolve specific elements (for analyzing the user's |
| 159 /// code). | 155 /// code). |
| 160 Future _initResolver() => resolvers.get(transform, entryLibraries).then((r) { | 156 Future _initResolver() { |
| 161 resolver = r; | 157 // We include 'polymer.dart' to simplify how we do resolution below. This |
| 162 types = new _ResolvedTypes(resolver); | 158 // way we can assume polymer is there, even if the user didn't include an |
| 163 }); | 159 // import to it. If not, the polymer build will fail with an error when |
| 160 // trying to create _ResolvedTypes below. |
| 161 var libsToLoad = [new AssetId('polymer', 'lib/polymer.dart')] |
| 162 ..addAll(entryLibraries); |
| 163 return resolvers.get(transform, libsToLoad).then((r) { |
| 164 resolver = r; |
| 165 types = new _ResolvedTypes(resolver); |
| 166 }); |
| 167 } |
| 164 | 168 |
| 165 /// Inspects the entire program to find out anything that polymer accesses | 169 /// Inspects the entire program to find out anything that polymer accesses |
| 166 /// using mirrors and produces static information that can be used to replace | 170 /// using mirrors and produces static information that can be used to replace |
| 167 /// the mirror-based loader and the uses of mirrors through the `smoke` | 171 /// the mirror-based loader and the uses of mirrors through the `smoke` |
| 168 /// package. This includes: | 172 /// package. This includes: |
| 169 /// | 173 /// |
| 170 /// * visiting entry-libraries to extract initializers, | 174 /// * visiting entry-libraries to extract initializers, |
| 171 /// * visiting polymer-expressions to extract getters and setters, | 175 /// * visiting polymer-expressions to extract getters and setters, |
| 172 /// * looking for published fields of custom elements, and | 176 /// * looking for published fields of custom elements, and |
| 173 /// * looking for event handlers and callbacks of change notifications. | 177 /// * looking for event handlers and callbacks of change notifications. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 code.writeln("import '$url' as i$i;"); | 342 code.writeln("import '$url' as i$i;"); |
| 339 prefixes[id] = 'i$i'; | 343 prefixes[id] = 'i$i'; |
| 340 i++; | 344 i++; |
| 341 } | 345 } |
| 342 | 346 |
| 343 // Include smoke initialization. | 347 // Include smoke initialization. |
| 344 generator.writeImports(code); | 348 generator.writeImports(code); |
| 345 generator.writeTopLevelDeclarations(code); | 349 generator.writeTopLevelDeclarations(code); |
| 346 code.writeln('\nvoid main() {'); | 350 code.writeln('\nvoid main() {'); |
| 347 generator.writeInitCall(code); | 351 generator.writeInitCall(code); |
| 348 code.writeln(' startPolymer(['); | 352 code.write(' startPolymer(['); |
| 349 | 353 |
| 350 // Include initializers to switch from mirrors_loader to static_loader. | 354 // Include initializers to switch from mirrors_loader to static_loader. |
| 351 for (var init in initializers) { | 355 if (!initializers.isEmpty) { |
| 352 var initCode = init.asCode(prefixes[init.assetId]); | 356 code.writeln(); |
| 353 code.write(" $initCode,\n"); | 357 for (var init in initializers) { |
| 358 var initCode = init.asCode(prefixes[init.assetId]); |
| 359 code.write(" $initCode,\n"); |
| 360 } |
| 361 code.writeln(' ]);'); |
| 362 } else { |
| 363 logger.warning(NO_INITIALIZERS_ERROR); |
| 364 code.writeln(']);'); |
| 354 } | 365 } |
| 355 code..writeln(' ]);') | 366 code.writeln('}'); |
| 356 ..writeln('}'); | |
| 357 transform.addOutput(new Asset.fromString(bootstrapId, code.toString())); | 367 transform.addOutput(new Asset.fromString(bootstrapId, code.toString())); |
| 358 | 368 |
| 359 | 369 |
| 360 // Emit the bootstrap .dart file | 370 // Emit the bootstrap .dart file |
| 361 var srcUrl = path.url.basename(bootstrapId.path); | 371 var srcUrl = path.url.basename(bootstrapId.path); |
| 362 document.body.nodes.add(parseFragment( | 372 document.body.nodes.add(parseFragment( |
| 363 '<script type="application/dart" src="$srcUrl"></script>')); | 373 '<script type="application/dart" src="$srcUrl"></script>')); |
| 364 transform.addOutput(new Asset.fromString(docId, document.outerHtml)); | 374 transform.addOutput(new Asset.fromString(docId, document.outerHtml)); |
| 365 } | 375 } |
| 366 | 376 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 397 } | 407 } |
| 398 | 408 |
| 399 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); | 409 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); |
| 400 | 410 |
| 401 const MAIN_HEADER = """ | 411 const MAIN_HEADER = """ |
| 402 library app_bootstrap; | 412 library app_bootstrap; |
| 403 | 413 |
| 404 import 'package:polymer/polymer.dart'; | 414 import 'package:polymer/polymer.dart'; |
| 405 """; | 415 """; |
| 406 | 416 |
| 417 const NO_INITIALIZERS_ERROR = |
| 418 'No polymer initializers were found. Make sure to either ' |
| 419 'annotate your polymer elements with @CustomTag or include a ' |
| 420 'top level method annotated with @initMethod that registers your ' |
| 421 'elements. Both annotations are defined in the polymer library (' |
| 422 'package:polymer/polymer.dart).'; |
| 423 |
| 407 /// An html visitor that: | 424 /// An html visitor that: |
| 408 /// * finds all polymer expressions and records the getters and setters that | 425 /// * finds all polymer expressions and records the getters and setters that |
| 409 /// will be needed to evaluate them at runtime. | 426 /// will be needed to evaluate them at runtime. |
| 410 /// * extracts all attributes declared in the `attribute` attributes of | 427 /// * extracts all attributes declared in the `attribute` attributes of |
| 411 /// polymer elements. | 428 /// polymer elements. |
| 412 class _HtmlExtractor extends TreeVisitor { | 429 class _HtmlExtractor extends TreeVisitor { |
| 413 final Map<String, List<String>> publishedAttributes; | 430 final Map<String, List<String>> publishedAttributes; |
| 414 final SmokeCodeGenerator generator; | 431 final SmokeCodeGenerator generator; |
| 415 final _SubExpressionVisitor visitor; | 432 final _SubExpressionVisitor visitor; |
| 416 bool _inTemplate = false; | 433 bool _inTemplate = false; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 for (var c in combinators) { | 706 for (var c in combinators) { |
| 690 if (c is ShowElementCombinator) { | 707 if (c is ShowElementCombinator) { |
| 691 var show = c.shownNames.toSet(); | 708 var show = c.shownNames.toSet(); |
| 692 elements.retainWhere((e) => show.contains(e.displayName)); | 709 elements.retainWhere((e) => show.contains(e.displayName)); |
| 693 } else if (c is HideElementCombinator) { | 710 } else if (c is HideElementCombinator) { |
| 694 var hide = c.hiddenNames.toSet(); | 711 var hide = c.hiddenNames.toSet(); |
| 695 elements.removeWhere((e) => hide.contains(e.displayName)); | 712 elements.removeWhere((e) => hide.contains(e.displayName)); |
| 696 } | 713 } |
| 697 } | 714 } |
| 698 } | 715 } |
| OLD | NEW |