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