OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library dart2js_incremental.library_updater; | 5 library dart2js_incremental.library_updater; |
6 | 6 |
7 import 'dart:async' show | 7 import 'dart:async' show |
8 Future; | 8 Future; |
9 | 9 |
10 import 'dart:convert' show | 10 import 'dart:convert' show |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 ClassElementX, | 68 ClassElementX, |
69 CompilationUnitElementX, | 69 CompilationUnitElementX, |
70 DeclarationSite, | 70 DeclarationSite, |
71 ElementX, | 71 ElementX, |
72 FieldElementX, | 72 FieldElementX, |
73 LibraryElementX; | 73 LibraryElementX; |
74 | 74 |
75 import 'package:compiler/src/universe/universe.dart' show | 75 import 'package:compiler/src/universe/universe.dart' show |
76 Selector; | 76 Selector; |
77 | 77 |
| 78 import 'package:compiler/src/constants/values.dart' show |
| 79 ConstantValue; |
| 80 |
78 import 'diff.dart' show | 81 import 'diff.dart' show |
79 Difference, | 82 Difference, |
80 computeDifference; | 83 computeDifference; |
81 | 84 |
82 typedef void Logger(message); | 85 typedef void Logger(message); |
83 | 86 |
84 typedef bool Reuser( | 87 typedef bool Reuser( |
85 Token diffToken, | 88 Token diffToken, |
86 PartialElement before, | 89 PartialElement before, |
87 PartialElement after); | 90 PartialElement after); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 125 |
123 final Set<ElementX> _removedElements = new Set<ElementX>(); | 126 final Set<ElementX> _removedElements = new Set<ElementX>(); |
124 | 127 |
125 final Set<ClassElementX> _classesWithSchemaChanges = | 128 final Set<ClassElementX> _classesWithSchemaChanges = |
126 new Set<ClassElementX>(); | 129 new Set<ClassElementX>(); |
127 | 130 |
128 final Set<ClassElementX> _emittedClasses; | 131 final Set<ClassElementX> _emittedClasses; |
129 | 132 |
130 final Set<ClassElementX> _directlyInstantiatedClasses; | 133 final Set<ClassElementX> _directlyInstantiatedClasses; |
131 | 134 |
| 135 final Set<ConstantValue> _compiledConstants; |
| 136 |
| 137 bool _hasComputedNeeds = false; |
| 138 |
132 LibraryUpdater( | 139 LibraryUpdater( |
133 Compiler compiler, | 140 Compiler compiler, |
134 this.inputProvider, | 141 this.inputProvider, |
135 this.uri, | 142 this.uri, |
136 this.logTime, | 143 this.logTime, |
137 this.logVerbose) | 144 this.logVerbose) |
138 : this.compiler = compiler, | 145 : this.compiler = compiler, |
139 _emittedClasses = new Set.from(compiler.backend.emitter.neededClasses), | 146 _emittedClasses = new Set.from(compiler.backend.emitter.neededClasses), |
140 _directlyInstantiatedClasses = new Set.from( | 147 _directlyInstantiatedClasses = new Set.from( |
141 compiler.codegenWorld.directlyInstantiatedClasses); | 148 compiler.codegenWorld.directlyInstantiatedClasses), |
| 149 _compiledConstants = new Set<ConstantValue>.identity()..addAll( |
| 150 compiler.backend.constants.compiledConstants); |
142 | 151 |
143 /// When [true], updates must be applied (using [applyUpdates]) before the | 152 /// When [true], updates must be applied (using [applyUpdates]) before the |
144 /// [compiler]'s state correctly reflects the updated program. | 153 /// [compiler]'s state correctly reflects the updated program. |
145 bool get hasPendingUpdates => !updates.isEmpty; | 154 bool get hasPendingUpdates => !updates.isEmpty; |
146 | 155 |
147 bool get failed => !_failedUpdates.isEmpty; | 156 bool get failed => !_failedUpdates.isEmpty; |
148 | 157 |
149 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. | 158 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. |
150 Future<bool> reuseLibrary(LibraryElement library) { | 159 Future<bool> reuseLibrary(LibraryElement library) { |
151 assert(compiler != null); | 160 assert(compiler != null); |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 604 |
596 List<jsAst.Statement> updates = <jsAst.Statement>[]; | 605 List<jsAst.Statement> updates = <jsAst.Statement>[]; |
597 | 606 |
598 Set<ClassElementX> newClasses = new Set.from( | 607 Set<ClassElementX> newClasses = new Set.from( |
599 compiler.codegenWorld.directlyInstantiatedClasses); | 608 compiler.codegenWorld.directlyInstantiatedClasses); |
600 newClasses.removeAll(_directlyInstantiatedClasses); | 609 newClasses.removeAll(_directlyInstantiatedClasses); |
601 | 610 |
602 if (!newClasses.isEmpty) { | 611 if (!newClasses.isEmpty) { |
603 // Ask the emitter to compute "needs" (only) if new classes were | 612 // Ask the emitter to compute "needs" (only) if new classes were |
604 // instantiated. | 613 // instantiated. |
605 emitter.computeNeeds(); | 614 _ensureNeedsComputed(); |
606 newClasses = new Set.from(emitter.neededClasses); | 615 newClasses = new Set.from(emitter.neededClasses); |
607 newClasses.removeAll(_emittedClasses); | 616 newClasses.removeAll(_emittedClasses); |
608 } else { | 617 } else { |
609 // Make sure that the set of emitted classes is preserved for subsequent | 618 // Make sure that the set of emitted classes is preserved for subsequent |
610 // updates. | 619 // updates. |
611 // TODO(ahe): This is a bit convoluted, find a better approach. | 620 // TODO(ahe): This is a bit convoluted, find a better approach. |
612 emitter.neededClasses | 621 emitter.neededClasses |
613 ..clear() | 622 ..clear() |
614 ..addAll(_emittedClasses); | 623 ..addAll(_emittedClasses); |
615 } | 624 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 update.writeUpdateJsOn(updates); | 663 update.writeUpdateJsOn(updates); |
655 } | 664 } |
656 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 665 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
657 if (element.isField) { | 666 if (element.isField) { |
658 updates.addAll(computeFieldUpdateJs(element)); | 667 updates.addAll(computeFieldUpdateJs(element)); |
659 } else { | 668 } else { |
660 updates.add(computeMethodUpdateJs(element)); | 669 updates.add(computeMethodUpdateJs(element)); |
661 } | 670 } |
662 } | 671 } |
663 | 672 |
| 673 Set<ConstantValue> newConstants = new Set<ConstantValue>.identity()..addAll( |
| 674 compiler.backend.constants.compiledConstants); |
| 675 newConstants.removeAll(_compiledConstants); |
| 676 |
| 677 if (!newConstants.isEmpty) { |
| 678 _ensureNeedsComputed(); |
| 679 List<ConstantValue> constants = |
| 680 emitter.outputConstantLists[compiler.deferredLoadTask.mainOutputUnit]; |
| 681 if (constants != null) { |
| 682 for (ConstantValue constant in constants) { |
| 683 if (newConstants.contains(constant)) { |
| 684 jsAst.Statement constantInitializer = emitter.oldEmitter |
| 685 .buildConstantInitializer(constant).toStatement(); |
| 686 updates.add(constantInitializer); |
| 687 } |
| 688 } |
| 689 } |
| 690 } |
| 691 |
664 updates.add(js.statement(r''' | 692 updates.add(js.statement(r''' |
665 if (self.$dart_unsafe_eval.pendingStubs) { | 693 if (self.$dart_unsafe_eval.pendingStubs) { |
666 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); | 694 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); |
667 self.$dart_unsafe_eval.pendingStubs = void 0; | 695 self.$dart_unsafe_eval.pendingStubs = void 0; |
668 } | 696 } |
669 ''')); | 697 ''')); |
670 | 698 |
671 if (updates.length == 1) { | 699 if (updates.length == 1) { |
672 return prettyPrintJs(updates.single); | 700 return prettyPrintJs(updates.single); |
673 } else { | 701 } else { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 String callNameFor(FunctionElement element) { | 785 String callNameFor(FunctionElement element) { |
758 // TODO(ahe): Call a method in the compiler to obtain this name. | 786 // TODO(ahe): Call a method in the compiler to obtain this name. |
759 String callPrefix = namer.callPrefix; | 787 String callPrefix = namer.callPrefix; |
760 int parameterCount = element.functionSignature.parameterCount; | 788 int parameterCount = element.functionSignature.parameterCount; |
761 return '$callPrefix\$$parameterCount'; | 789 return '$callPrefix\$$parameterCount'; |
762 } | 790 } |
763 | 791 |
764 List<String> computeFields(ClassElement cls) { | 792 List<String> computeFields(ClassElement cls) { |
765 return new EmitterHelper(compiler).computeFields(cls); | 793 return new EmitterHelper(compiler).computeFields(cls); |
766 } | 794 } |
| 795 |
| 796 void _ensureNeedsComputed() { |
| 797 if (_hasComputedNeeds) return; |
| 798 emitter.computeNeeds(); |
| 799 _hasComputedNeeds = true; |
| 800 } |
767 } | 801 } |
768 | 802 |
769 /// Represents an update (aka patch) of [before] to [after]. We use the word | 803 /// Represents an update (aka patch) of [before] to [after]. We use the word |
770 /// "update" to avoid confusion with the compiler feature of "patch" methods. | 804 /// "update" to avoid confusion with the compiler feature of "patch" methods. |
771 abstract class Update { | 805 abstract class Update { |
772 final Compiler compiler; | 806 final Compiler compiler; |
773 | 807 |
774 PartialElement get before; | 808 PartialElement get before; |
775 | 809 |
776 PartialElement get after; | 810 PartialElement get after; |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 List<String> computeFields(ClassElement cls) { | 1274 List<String> computeFields(ClassElement cls) { |
1241 // TODO(ahe): Rewrite for new emitter. | 1275 // TODO(ahe): Rewrite for new emitter. |
1242 ClassBuilder builder = new ClassBuilder(cls, namer); | 1276 ClassBuilder builder = new ClassBuilder(cls, namer); |
1243 classEmitter.emitFields(cls, builder, ""); | 1277 classEmitter.emitFields(cls, builder, ""); |
1244 return builder.fields; | 1278 return builder.fields; |
1245 } | 1279 } |
1246 } | 1280 } |
1247 | 1281 |
1248 // TODO(ahe): Remove this method. | 1282 // TODO(ahe): Remove this method. |
1249 NO_WARN(x) => x; | 1283 NO_WARN(x) => x; |
OLD | NEW |