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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 /// package. This includes: | 217 /// package. This includes: |
218 /// | 218 /// |
219 /// * visiting entry-libraries to extract initializers, | 219 /// * visiting entry-libraries to extract initializers, |
220 /// * visiting polymer-expressions to extract getters and setters, | 220 /// * visiting polymer-expressions to extract getters and setters, |
221 /// * looking for published fields of custom elements, and | 221 /// * looking for published fields of custom elements, and |
222 /// * looking for event handlers and callbacks of change notifications. | 222 /// * looking for event handlers and callbacks of change notifications. |
223 /// | 223 /// |
224 void _extractUsesOfMirrors(_) { | 224 void _extractUsesOfMirrors(_) { |
225 // Generate getters and setters needed to evaluate polymer expressions, and | 225 // Generate getters and setters needed to evaluate polymer expressions, and |
226 // extract information about published attributes. | 226 // extract information about published attributes. |
227 new _HtmlExtractor(generator, publishedAttributes).visit(document); | 227 new _HtmlExtractor(logger, generator, publishedAttributes).visit(document); |
228 | 228 |
229 // Create a recorder that uses analyzer data to feed data to [generator]. | 229 // Create a recorder that uses analyzer data to feed data to [generator]. |
230 var recorder = new Recorder(generator, | 230 var recorder = new Recorder(generator, |
231 (lib) => resolver.getImportUri(lib, from: bootstrapId).toString()); | 231 (lib) => resolver.getImportUri(lib, from: bootstrapId).toString()); |
232 | 232 |
233 // Process all classes and top-level functions to include initializers, | 233 // Process all classes and top-level functions to include initializers, |
234 // register custom elements, and include special fields and methods in | 234 // register custom elements, and include special fields and methods in |
235 // custom element classes. | 235 // custom element classes. |
236 for (var id in entryLibraries) { | 236 for (var id in entryLibraries) { |
237 var lib = resolver.getLibrary(id); | 237 var lib = resolver.getLibrary(id); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 | 476 |
477 /// An html visitor that: | 477 /// An html visitor that: |
478 /// * finds all polymer expressions and records the getters and setters that | 478 /// * finds all polymer expressions and records the getters and setters that |
479 /// will be needed to evaluate them at runtime. | 479 /// will be needed to evaluate them at runtime. |
480 /// * extracts all attributes declared in the `attribute` attributes of | 480 /// * extracts all attributes declared in the `attribute` attributes of |
481 /// polymer elements. | 481 /// polymer elements. |
482 class _HtmlExtractor extends TreeVisitor { | 482 class _HtmlExtractor extends TreeVisitor { |
483 final Map<String, List<String>> publishedAttributes; | 483 final Map<String, List<String>> publishedAttributes; |
484 final SmokeCodeGenerator generator; | 484 final SmokeCodeGenerator generator; |
485 final _SubExpressionVisitor visitor; | 485 final _SubExpressionVisitor visitor; |
| 486 final TransformLogger logger; |
486 bool _inTemplate = false; | 487 bool _inTemplate = false; |
487 | 488 |
488 _HtmlExtractor(SmokeCodeGenerator generator, this.publishedAttributes) | 489 _HtmlExtractor(this.logger, SmokeCodeGenerator generator, |
| 490 this.publishedAttributes) |
489 : generator = generator, | 491 : generator = generator, |
490 visitor = new _SubExpressionVisitor(generator); | 492 visitor = new _SubExpressionVisitor(generator); |
491 | 493 |
492 void visitElement(Element node) { | 494 void visitElement(Element node) { |
493 if (_inTemplate) _processNormalElement(node); | 495 if (_inTemplate) _processNormalElement(node); |
494 if (node.localName == 'polymer-element') { | 496 if (node.localName == 'polymer-element') { |
495 _processPolymerElement(node); | 497 _processPolymerElement(node); |
496 _processNormalElement(node); | 498 _processNormalElement(node); |
497 } | 499 } |
498 | 500 |
499 if (node.localName == 'template') { | 501 if (node.localName == 'template') { |
500 var last = _inTemplate; | 502 var last = _inTemplate; |
501 _inTemplate = true; | 503 _inTemplate = true; |
502 super.visitElement(node); | 504 super.visitElement(node); |
503 _inTemplate = last; | 505 _inTemplate = last; |
504 } else { | 506 } else { |
505 super.visitElement(node); | 507 super.visitElement(node); |
506 } | 508 } |
507 } | 509 } |
508 | 510 |
509 void visitText(Text node) { | 511 void visitText(Text node) { |
510 if (!_inTemplate) return; | 512 if (!_inTemplate) return; |
511 var bindings = _Mustaches.parse(node.data); | 513 var bindings = _Mustaches.parse(node.data); |
512 if (bindings == null) return; | 514 if (bindings == null) return; |
513 for (var e in bindings.expressions) { | 515 for (var e in bindings.expressions) { |
514 _addExpression(e, false, false); | 516 _addExpression(e, false, false, node.sourceSpan); |
515 } | 517 } |
516 } | 518 } |
517 | 519 |
518 /// Registers getters and setters for all published attributes. | 520 /// Registers getters and setters for all published attributes. |
519 void _processPolymerElement(Element node) { | 521 void _processPolymerElement(Element node) { |
520 var tagName = node.attributes['name']; | 522 var tagName = node.attributes['name']; |
521 var value = node.attributes['attributes']; | 523 var value = node.attributes['attributes']; |
522 if (value != null) { | 524 if (value != null) { |
523 publishedAttributes[tagName] = | 525 publishedAttributes[tagName] = |
524 value.split(ATTRIBUTES_REGEX).map((a) => a.trim()).toList(); | 526 value.split(ATTRIBUTES_REGEX).map((a) => a.trim()).toList(); |
(...skipping 14 matching lines...) Expand all Loading... |
539 var isTwoWay = false; | 541 var isTwoWay = false; |
540 if (name is String) { | 542 if (name is String) { |
541 name = name.toLowerCase(); | 543 name = name.toLowerCase(); |
542 isEvent = name.startsWith('on-'); | 544 isEvent = name.startsWith('on-'); |
543 isTwoWay = !isEvent && bindings.isWhole && (isCustomTag || | 545 isTwoWay = !isEvent && bindings.isWhole && (isCustomTag || |
544 tag == 'input' && (name == 'value' || name =='checked') || | 546 tag == 'input' && (name == 'value' || name =='checked') || |
545 tag == 'select' && (name == 'selectedindex' || name == 'value') || | 547 tag == 'select' && (name == 'selectedindex' || name == 'value') || |
546 tag == 'textarea' && name == 'value'); | 548 tag == 'textarea' && name == 'value'); |
547 } | 549 } |
548 for (var exp in bindings.expressions) { | 550 for (var exp in bindings.expressions) { |
549 _addExpression(exp, isEvent, isTwoWay); | 551 _addExpression(exp, isEvent, isTwoWay, node.sourceSpan); |
550 } | 552 } |
551 }); | 553 }); |
552 } | 554 } |
553 | 555 |
554 void _addExpression(String stringExpression, bool inEvent, bool isTwoWay) { | 556 void _addExpression(String stringExpression, bool inEvent, bool isTwoWay, |
| 557 SourceSpan span) { |
| 558 |
555 if (inEvent) { | 559 if (inEvent) { |
556 if (!stringExpression.startsWith("@")) { | 560 if (stringExpression.startsWith('@')) { |
557 if (stringExpression == '') return; | 561 logger.warning('event bindings with @ are no longer supported', |
558 generator.addGetter(stringExpression); | 562 span: span); |
559 generator.addSymbol(stringExpression); | |
560 return; | 563 return; |
561 } | 564 } |
562 stringExpression = stringExpression.substring(1); | 565 |
| 566 if (stringExpression == '') return; |
| 567 generator.addGetter(stringExpression); |
| 568 generator.addSymbol(stringExpression); |
563 } | 569 } |
564 visitor.run(pe.parse(stringExpression), isTwoWay); | 570 visitor.run(pe.parse(stringExpression), isTwoWay); |
565 } | 571 } |
566 } | 572 } |
567 | 573 |
568 /// A polymer-expression visitor that records every getter and setter that will | 574 /// A polymer-expression visitor that records every getter and setter that will |
569 /// be needed to evaluate a single expression at runtime. | 575 /// be needed to evaluate a single expression at runtime. |
570 class _SubExpressionVisitor extends pe.RecursiveVisitor { | 576 class _SubExpressionVisitor extends pe.RecursiveVisitor { |
571 final SmokeCodeGenerator generator; | 577 final SmokeCodeGenerator generator; |
572 bool _includeSetter; | 578 bool _includeSetter; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 for (var e in lib.exports) { | 740 for (var e in lib.exports) { |
735 var exported = e.exportedLibrary.units.expand((u) => u.types).toList(); | 741 var exported = e.exportedLibrary.units.expand((u) => u.types).toList(); |
736 _filter(exported, e.combinators); | 742 _filter(exported, e.combinators); |
737 result.addAll(exported); | 743 result.addAll(exported); |
738 } | 744 } |
739 return result; | 745 return result; |
740 } | 746 } |
741 | 747 |
742 /// Retrieves all top-level methods that are visible if you were to import | 748 /// Retrieves all top-level methods that are visible if you were to import |
743 /// [lib]. This includes exported methods from other libraries too. | 749 /// [lib]. This includes exported methods from other libraries too. |
744 List<ClassElement> _visibleTopLevelMethodsOf(LibraryElement lib) { | 750 List<FunctionElement> _visibleTopLevelMethodsOf(LibraryElement lib) { |
745 var result = []; | 751 var result = []; |
746 result.addAll(lib.units.expand((u) => u.functions)); | 752 result.addAll(lib.units.expand((u) => u.functions)); |
747 for (var e in lib.exports) { | 753 for (var e in lib.exports) { |
748 var exported = e.exportedLibrary.units | 754 var exported = e.exportedLibrary.units |
749 .expand((u) => u.functions).toList(); | 755 .expand((u) => u.functions).toList(); |
750 _filter(exported, e.combinators); | 756 _filter(exported, e.combinators); |
751 result.addAll(exported); | 757 result.addAll(exported); |
752 } | 758 } |
753 return result; | 759 return result; |
754 } | 760 } |
755 | 761 |
756 /// Filters [elements] that come from an export, according to its show/hide | 762 /// Filters [elements] that come from an export, according to its show/hide |
757 /// combinators. This modifies [elements] in place. | 763 /// combinators. This modifies [elements] in place. |
758 void _filter(List<analyzer.Element> elements, | 764 void _filter(List<analyzer.Element> elements, |
759 List<NamespaceCombinator> combinators) { | 765 List<NamespaceCombinator> combinators) { |
760 for (var c in combinators) { | 766 for (var c in combinators) { |
761 if (c is ShowElementCombinator) { | 767 if (c is ShowElementCombinator) { |
762 var show = c.shownNames.toSet(); | 768 var show = c.shownNames.toSet(); |
763 elements.retainWhere((e) => show.contains(e.displayName)); | 769 elements.retainWhere((e) => show.contains(e.displayName)); |
764 } else if (c is HideElementCombinator) { | 770 } else if (c is HideElementCombinator) { |
765 var hide = c.hiddenNames.toSet(); | 771 var hide = c.hiddenNames.toSet(); |
766 elements.removeWhere((e) => hide.contains(e.displayName)); | 772 elements.removeWhere((e) => hide.contains(e.displayName)); |
767 } | 773 } |
768 } | 774 } |
769 } | 775 } |
OLD | NEW |