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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 new _HtmlExtractor(logger, generator, publishedAttributes, | 242 new _HtmlExtractor(logger, generator, publishedAttributes, |
243 expressionVisitor).visit(document); | 243 expressionVisitor).visit(document); |
244 | 244 |
245 // Create a recorder that uses analyzer data to feed data to [generator]. | 245 // Create a recorder that uses analyzer data to feed data to [generator]. |
246 var recorder = new Recorder(generator, | 246 var recorder = new Recorder(generator, |
247 (lib) => resolver.getImportUri(lib, from: bootstrapId).toString()); | 247 (lib) => resolver.getImportUri(lib, from: bootstrapId).toString()); |
248 | 248 |
249 // Process all classes and top-level functions to include initializers, | 249 // Process all classes and top-level functions to include initializers, |
250 // register custom elements, and include special fields and methods in | 250 // register custom elements, and include special fields and methods in |
251 // custom element classes. | 251 // custom element classes. |
252 var functionsSeen = new Set<FunctionElement>(); | |
253 var classesSeen = new Set<ClassElement>(); | |
252 for (var id in entryLibraries) { | 254 for (var id in entryLibraries) { |
253 var lib = resolver.getLibrary(id); | 255 var lib = resolver.getLibrary(id); |
254 for (var fun in _visibleTopLevelMethodsOf(lib)) { | 256 for (var fun in _visibleTopLevelMethodsOf(lib, functionsSeen)) { |
255 _processFunction(fun, id); | 257 _processFunction(fun, id); |
256 } | 258 } |
257 | 259 |
258 for (var cls in _visibleClassesOf(lib)) { | 260 for (var cls in _visibleClassesOf(lib, classesSeen)) { |
259 _processClass(cls, id, recorder); | 261 _processClass(cls, id, recorder); |
260 } | 262 } |
261 } | 263 } |
262 } | 264 } |
263 | 265 |
264 /// Process a class ([cls]). If it contains an appropriate [CustomTag] | 266 /// Process a class ([cls]). If it contains an appropriate [CustomTag] |
265 /// annotation, we include an initializer to register this class, and make | 267 /// annotation, we include an initializer to register this class, and make |
266 /// sure to include everything that might be accessed or queried from them | 268 /// sure to include everything that might be accessed or queried from them |
267 /// using the smoke package. In particular, polymer uses smoke for the | 269 /// using the smoke package. In particular, polymer uses smoke for the |
268 /// following: | 270 /// following: |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 } | 802 } |
801 | 803 |
802 static _definitionError(name) { | 804 static _definitionError(name) { |
803 throw new StateError("Internal error in polymer-builder: couldn't find " | 805 throw new StateError("Internal error in polymer-builder: couldn't find " |
804 "definition of $name."); | 806 "definition of $name."); |
805 } | 807 } |
806 } | 808 } |
807 | 809 |
808 /// Retrieves all classses that are visible if you were to import [lib]. This | 810 /// Retrieves all classses that are visible if you were to import [lib]. This |
809 /// includes exported classes from other libraries. | 811 /// includes exported classes from other libraries. |
810 List<ClassElement> _visibleClassesOf(LibraryElement lib) { | 812 List<ClassElement> _visibleClassesOf(LibraryElement lib, |
813 Set<ClassElement> seen) { | |
811 var result = []; | 814 var result = []; |
812 result.addAll(lib.units.expand((u) => u.types)); | 815 addAllNew(list) => list.forEach((e) { |
816 if (!seen.contains(e)) result.add(e); | |
817 }); | |
818 addAllNew(lib.units.expand((u) => u.types)); | |
813 for (var e in lib.exports) { | 819 for (var e in lib.exports) { |
814 var exported = e.exportedLibrary.units.expand((u) => u.types).toList(); | 820 var exportedLibrary = e.exportedLibrary; |
821 if (seen.contains(exportedLibrary)) continue; | |
822 var exported = exportedLibrary.units.expand((u) => u.types).toList(); | |
815 _filter(exported, e.combinators); | 823 _filter(exported, e.combinators); |
816 result.addAll(exported); | 824 addAllNew(exported); |
817 } | 825 } |
826 seen.addAll(result); | |
818 return result; | 827 return result; |
819 } | 828 } |
820 | 829 |
821 /// Retrieves all top-level methods that are visible if you were to import | 830 /// Retrieves all top-level methods that are visible if you were to import |
822 /// [lib]. This includes exported methods from other libraries too. | 831 /// [lib]. This includes exported methods from other libraries too. |
823 List<FunctionElement> _visibleTopLevelMethodsOf(LibraryElement lib) { | 832 List<FunctionElement> _visibleTopLevelMethodsOf( |
833 LibraryElement lib, Set<FunctionElement> seen) { | |
824 var result = []; | 834 var result = []; |
825 result.addAll(lib.units.expand((u) => u.functions)); | 835 addAllNew(list) => list.forEach((e) { |
jakemac
2014/11/04 17:45:54
I would probably break this out into a function th
Siggi Cherem (dart-lang)
2014/11/04 17:55:08
good point - this made me realize that I could jus
| |
836 if (!seen.contains(e)) result.add(e); | |
837 }); | |
838 addAllNew(lib.units.expand((u) => u.functions)); | |
826 for (var e in lib.exports) { | 839 for (var e in lib.exports) { |
827 var exported = e.exportedLibrary.units | 840 var exportedLibrary = e.exportedLibrary; |
828 .expand((u) => u.functions).toList(); | 841 if (seen.contains(exportedLibrary)) continue; |
842 var exported = exportedLibrary.units.expand((u) => u.functions).toList(); | |
829 _filter(exported, e.combinators); | 843 _filter(exported, e.combinators); |
830 result.addAll(exported); | 844 addAllNew(exported); |
831 } | 845 } |
846 seen.addAll(result); | |
832 return result; | 847 return result; |
833 } | 848 } |
834 | 849 |
835 /// Filters [elements] that come from an export, according to its show/hide | 850 /// Filters [elements] that come from an export, according to its show/hide |
836 /// combinators. This modifies [elements] in place. | 851 /// combinators. This modifies [elements] in place. |
837 void _filter(List<analyzer.Element> elements, | 852 void _filter(List<analyzer.Element> elements, |
838 List<NamespaceCombinator> combinators) { | 853 List<NamespaceCombinator> combinators) { |
839 for (var c in combinators) { | 854 for (var c in combinators) { |
840 if (c is ShowElementCombinator) { | 855 if (c is ShowElementCombinator) { |
841 var show = c.shownNames.toSet(); | 856 var show = c.shownNames.toSet(); |
842 elements.retainWhere((e) => show.contains(e.displayName)); | 857 elements.retainWhere((e) => show.contains(e.displayName)); |
843 } else if (c is HideElementCombinator) { | 858 } else if (c is HideElementCombinator) { |
844 var hide = c.hiddenNames.toSet(); | 859 var hide = c.hiddenNames.toSet(); |
845 elements.removeWhere((e) => hide.contains(e.displayName)); | 860 elements.removeWhere((e) => hide.contains(e.displayName)); |
846 } | 861 } |
847 } | 862 } |
848 } | 863 } |
OLD | NEW |