| 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 |