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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
119 | 119 |
120 final List<FailedUpdate> _failedUpdates = <FailedUpdate>[]; | 120 final List<FailedUpdate> _failedUpdates = <FailedUpdate>[]; |
121 | 121 |
122 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>(); | 122 final Set<ElementX> _elementsToInvalidate = new Set<ElementX>(); |
123 | 123 |
124 final Set<ElementX> _removedElements = new Set<ElementX>(); | 124 final Set<ElementX> _removedElements = new Set<ElementX>(); |
125 | 125 |
126 final Set<ClassElementX> _classesWithSchemaChanges = | 126 final Set<ClassElementX> _classesWithSchemaChanges = |
127 new Set<ClassElementX>(); | 127 new Set<ClassElementX>(); |
128 | 128 |
129 final Set<ClassElementX> _existingClasses = new Set(); | 129 final Set<ClassElementX> _emittedClasses; |
130 | |
131 final Set<ClassElementX> _directlyInstantiatedClasses; | |
130 | 132 |
131 LibraryUpdater( | 133 LibraryUpdater( |
132 this.compiler, | 134 Compiler compiler, |
133 this.inputProvider, | 135 this.inputProvider, |
134 this.uri, | 136 this.uri, |
135 this.logTime, | 137 this.logTime, |
136 this.logVerbose) { | 138 this.logVerbose) |
137 if (compiler != null) { | 139 : this.compiler = compiler, |
138 _existingClasses.addAll(emitter.neededClasses); | 140 _emittedClasses = new Set.from( |
139 } | 141 compiler == null |
140 } | 142 ? [] : compiler.backend.emitter.neededClasses), |
143 _directlyInstantiatedClasses = new Set.from( | |
144 compiler == null | |
145 ? [] : compiler.codegenWorld.directlyInstantiatedClasses); | |
ahe
2014/12/11 09:40:15
Conflict resolution.
| |
141 | 146 |
142 /// When [true], updates must be applied (using [applyUpdates]) before the | 147 /// When [true], updates must be applied (using [applyUpdates]) before the |
143 /// [compiler]'s state correctly reflects the updated program. | 148 /// [compiler]'s state correctly reflects the updated program. |
144 bool get hasPendingUpdates => !updates.isEmpty; | 149 bool get hasPendingUpdates => !updates.isEmpty; |
145 | 150 |
146 bool get failed => !_failedUpdates.isEmpty; | 151 bool get failed => !_failedUpdates.isEmpty; |
147 | 152 |
148 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. | 153 /// Used as tear-off passed to [LibraryLoaderTask.resetAsync]. |
149 Future<bool> reuseLibrary(LibraryElement library) { | 154 Future<bool> reuseLibrary(LibraryElement library) { |
150 assert(compiler != null); | 155 assert(compiler != null); |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 changedClasses.add(element); | 570 changedClasses.add(element); |
566 } | 571 } |
567 } | 572 } |
568 compiler.processQueue(enqueuer.codegen, null); | 573 compiler.processQueue(enqueuer.codegen, null); |
569 | 574 |
570 // Run through all compiled methods and see if they may apply to | 575 // Run through all compiled methods and see if they may apply to |
571 // newlySeenSelectors. | 576 // newlySeenSelectors. |
572 for (Element e in enqueuer.codegen.generatedCode.keys) { | 577 for (Element e in enqueuer.codegen.generatedCode.keys) { |
573 if (e.isFunction && !e.isConstructor && | 578 if (e.isFunction && !e.isConstructor && |
574 e.functionSignature.hasOptionalParameters) { | 579 e.functionSignature.hasOptionalParameters) { |
575 for (Selector selector in enqueuer.codegen.newlySeenSelectors) { | 580 for (Selector selector in enqueuer.codegen.newlySeenSelectors) { |
ahe
2014/12/11 09:40:15
Conflict resolution here (no change needed as long
| |
576 // TODO(ahe): Group selectors by name at this point for improved | 581 // TODO(ahe): Group selectors by name at this point for improved |
577 // performance. | 582 // performance. |
578 if (e.isInstanceMember && selector.applies(e, compiler.world)) { | 583 if (e.isInstanceMember && selector.applies(e, compiler.world)) { |
579 // TODO(ahe): Don't use | 584 // TODO(ahe): Don't use |
580 // enqueuer.codegen.newlyEnqueuedElements directly like | 585 // enqueuer.codegen.newlyEnqueuedElements directly like |
581 // this, make a copy. | 586 // this, make a copy. |
582 enqueuer.codegen.newlyEnqueuedElements.add(e); | 587 enqueuer.codegen.newlyEnqueuedElements.add(e); |
583 } | 588 } |
584 if (selector.name == namer.closureInvocationSelectorName) { | 589 if (selector.name == namer.closureInvocationSelectorName) { |
585 selector = new Selector.call( | 590 selector = new Selector.call( |
586 e.name, e.library, | 591 e.name, e.library, |
587 selector.argumentCount, selector.namedArguments); | 592 selector.argumentCount, selector.namedArguments); |
588 if (selector.appliesUnnamed(e, compiler.world)) { | 593 if (selector.appliesUnnamed(e, compiler.world)) { |
589 // TODO(ahe): Also make a copy here. | 594 // TODO(ahe): Also make a copy here. |
590 enqueuer.codegen.newlyEnqueuedElements.add(e); | 595 enqueuer.codegen.newlyEnqueuedElements.add(e); |
591 } | 596 } |
592 } | 597 } |
593 } | 598 } |
594 } | 599 } |
595 } | 600 } |
596 | 601 |
597 List<jsAst.Statement> updates = <jsAst.Statement>[]; | 602 List<jsAst.Statement> updates = <jsAst.Statement>[]; |
598 | 603 |
599 // TODO(ahe): allInstantiatedClasses seem to include interfaces that aren't | |
600 // needed. | |
601 Set<ClassElementX> newClasses = new Set.from( | 604 Set<ClassElementX> newClasses = new Set.from( |
602 compiler.codegenWorld.allInstantiatedClasses.where( | 605 compiler.codegenWorld.directlyInstantiatedClasses); |
603 emitter.computeClassFilter())); | 606 newClasses.removeAll(_directlyInstantiatedClasses); |
604 newClasses.removeAll(_existingClasses); | |
605 | 607 |
606 // TODO(ahe): When more than one updated is computed, we need to make sure | 608 if (!newClasses.isEmpty) { |
607 // that existing classes aren't overwritten. No test except the one test | 609 // Ask the emitter to compute "needs" (only) if new classes were |
608 // that tests more than one update is affected by this problem, and only | 610 // instantiated. |
609 // because main is closurized because we always enable tear-off. Is that | 611 emitter.computeAllNeededEntities(); |
610 // really necessary? Also, add a test which tests directly that what | 612 newClasses = new Set.from(emitter.neededClasses); |
611 // happens when tear-off is introduced in second update. | 613 newClasses.removeAll(_emittedClasses); |
612 emitter.neededClasses.addAll(newClasses); | 614 } else { |
615 // Make sure that the set of emitted classes is preserved for subsequent | |
616 // updates. | |
617 // TODO(ahe): This is a bit convoluted, find a better approach. | |
618 emitter.neededClasses | |
619 ..clear() | |
620 ..addAll(_emittedClasses); | |
621 } | |
613 | 622 |
614 List<jsAst.Statement> inherits = <jsAst.Statement>[]; | 623 List<jsAst.Statement> inherits = <jsAst.Statement>[]; |
615 | 624 |
616 for (ClassElementX cls in newClasses) { | 625 for (ClassElementX cls in newClasses) { |
617 jsAst.Node classAccess = emitter.classAccess(cls); | 626 jsAst.Node classAccess = emitter.classAccess(cls); |
618 String name = namer.getNameOfClass(cls); | 627 String name = namer.getNameOfClass(cls); |
619 | 628 |
620 updates.add( | 629 updates.add( |
621 js.statement( | 630 js.statement( |
622 r'# = #', [classAccess, invokeDefineClass(cls)])); | 631 r'# = #', [classAccess, invokeDefineClass(cls)])); |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1226 List<String> computeFields(ClassElement cls) { | 1235 List<String> computeFields(ClassElement cls) { |
1227 // TODO(ahe): Rewrite for new emitter. | 1236 // TODO(ahe): Rewrite for new emitter. |
1228 ClassBuilder builder = new ClassBuilder(cls, namer); | 1237 ClassBuilder builder = new ClassBuilder(cls, namer); |
1229 classEmitter.emitFields(cls, builder); | 1238 classEmitter.emitFields(cls, builder); |
1230 return builder.fields; | 1239 return builder.fields; |
1231 } | 1240 } |
1232 } | 1241 } |
1233 | 1242 |
1234 // TODO(ahe): Remove this method. | 1243 // TODO(ahe): Remove this method. |
1235 NO_WARN(x) => x; | 1244 NO_WARN(x) => x; |
OLD | NEW |