Chromium Code Reviews| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 LinkBuilder; | 65 LinkBuilder; |
| 66 | 66 |
| 67 import 'package:compiler/src/elements/modelx.dart' show | 67 import 'package:compiler/src/elements/modelx.dart' show |
| 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 | |
| 76 Selector; | |
| 77 | |
| 75 import 'diff.dart' show | 78 import 'diff.dart' show |
| 76 Difference, | 79 Difference, |
| 77 computeDifference; | 80 computeDifference; |
| 78 | 81 |
| 79 typedef void Logger(message); | 82 typedef void Logger(message); |
| 80 | 83 |
| 81 typedef bool Reuser( | 84 typedef bool Reuser( |
| 82 Token diffToken, | 85 Token diffToken, |
| 83 PartialElement before, | 86 PartialElement before, |
| 84 PartialElement after); | 87 PartialElement after); |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 new Set<ClassElementX>.from(_classesWithSchemaChanges); | 564 new Set<ClassElementX>.from(_classesWithSchemaChanges); |
| 562 for (Element element in updatedElements) { | 565 for (Element element in updatedElements) { |
| 563 if (!element.isClass) { | 566 if (!element.isClass) { |
| 564 compiler.enqueuer.codegen.addToWorkList(element); | 567 compiler.enqueuer.codegen.addToWorkList(element); |
| 565 } else { | 568 } else { |
| 566 changedClasses.add(element); | 569 changedClasses.add(element); |
| 567 } | 570 } |
| 568 } | 571 } |
| 569 compiler.processQueue(compiler.enqueuer.codegen, null); | 572 compiler.processQueue(compiler.enqueuer.codegen, null); |
| 570 | 573 |
| 574 for (Element e in compiler.enqueuer.codegen.generatedCode.keys) { | |
| 575 if (e.isFunction && e.functionSignature.hasOptionalParameters) { | |
| 576 for (Selector selector in compiler.enqueuer.codegen.newlySeenSelectors) { | |
|
Johnni Winther
2014/12/05 09:48:23
Long line.
ahe
2014/12/09 16:28:23
Done.
| |
| 577 // TODO(ahe): Group selectors by name at this point for improved | |
| 578 // performance. | |
| 579 if (e.name == selector.name && | |
| 580 selector.appliesUnnamed(e, compiler.world)) { | |
|
Johnni Winther
2014/12/05 09:48:23
Isn't this the same as `applies`?
ahe
2014/12/09 16:28:23
Not exactly, but I had misunderstood the assertion
| |
| 581 // TODO(ahe): Don't use | |
| 582 // compiler.enqueuer.codegen.newlyEnqueuedElements directly like | |
| 583 // this, make a copy. | |
| 584 compiler.enqueuer.codegen.newlyEnqueuedElements.add(e); | |
| 585 } | |
| 586 if (selector.name == namer.closureInvocationSelectorName) { | |
| 587 selector = new Selector.call( | |
| 588 e.name, e.library, | |
| 589 selector.argumentCount, selector.namedArguments); | |
| 590 if (selector.appliesUnnamed(e, compiler.world)) { | |
| 591 // TODO(ahe): Also make a copy here. | |
| 592 compiler.enqueuer.codegen.newlyEnqueuedElements.add(e); | |
| 593 } | |
| 594 } | |
| 595 } | |
| 596 } | |
| 597 } | |
| 598 | |
| 571 List<jsAst.Statement> updates = <jsAst.Statement>[]; | 599 List<jsAst.Statement> updates = <jsAst.Statement>[]; |
| 572 | 600 |
| 573 Set newClasses = new Set.from( | 601 // TODO(ahe): allInstantiatedClasses seem to include interfaces that aren't |
| 602 // needed. | |
| 603 Set<ClassElementX> newClasses = new Set.from( | |
| 574 compiler.codegenWorld.allInstantiatedClasses.where( | 604 compiler.codegenWorld.allInstantiatedClasses.where( |
| 575 emitter.computeClassFilter())); | 605 emitter.computeClassFilter())); |
| 576 newClasses.removeAll(_existingClasses); | 606 newClasses.removeAll(_existingClasses); |
| 577 | 607 |
| 608 // TODO(ahe): When more than one updated is computed, we need to make sure | |
| 609 // that existing classes aren't overwritten. No test except the one test | |
| 610 // that tests more than one update is affected by this problem, and only | |
| 611 // because main is closurized because we always enable tear-off. Is that | |
| 612 // really necessary? Also, add a test which tests directly that what | |
| 613 // happens when tear-off is introduced in second update. | |
| 614 emitter.neededClasses.addAll(newClasses); | |
| 615 | |
| 578 List<jsAst.Statement> inherits = <jsAst.Statement>[]; | 616 List<jsAst.Statement> inherits = <jsAst.Statement>[]; |
| 579 | 617 |
| 580 for (ClassElementX cls in newClasses) { | 618 for (ClassElementX cls in newClasses) { |
| 581 jsAst.Node classAccess = namer.elementAccess(cls); | 619 jsAst.Node classAccess = namer.elementAccess(cls); |
| 582 String name = namer.getNameOfClass(cls); | 620 String name = namer.getNameOfClass(cls); |
| 583 | 621 |
| 584 updates.add( | 622 updates.add( |
| 585 js.statement( | 623 js.statement( |
| 586 r'# = #', [classAccess, invokeDefineClass(cls)])); | 624 r'# = #', [classAccess, invokeDefineClass(cls)])); |
| 587 | 625 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 610 r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)', | 648 r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)', |
| 611 [classAccess, invokeDefineClass(cls), classAccess, superAccess])); | 649 [classAccess, invokeDefineClass(cls), classAccess, superAccess])); |
| 612 } | 650 } |
| 613 | 651 |
| 614 for (RemovalUpdate update in removals) { | 652 for (RemovalUpdate update in removals) { |
| 615 update.writeUpdateJsOn(updates); | 653 update.writeUpdateJsOn(updates); |
| 616 } | 654 } |
| 617 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 655 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 618 if (!element.isField) { | 656 if (!element.isField) { |
| 619 updates.add(computeMemberUpdateJs(element)); | 657 updates.add(computeMemberUpdateJs(element)); |
| 658 } else { | |
| 659 if (backend.constants.lazyStatics.contains(element)) { | |
| 660 throw new StateError("$element requires lazy initializer."); | |
| 661 } | |
| 620 } | 662 } |
| 621 } | 663 } |
| 622 | 664 |
| 665 updates.add(js.statement(r''' | |
| 666 if (self.$dart_unsafe_eval.pendingStubs) { | |
| 667 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); | |
| 668 self.$dart_unsafe_eval.pendingStubs = void 0; | |
| 669 } | |
| 670 ''')); | |
| 671 | |
| 623 if (updates.length == 1) { | 672 if (updates.length == 1) { |
| 624 return prettyPrintJs(updates.single); | 673 return prettyPrintJs(updates.single); |
| 625 } else { | 674 } else { |
| 626 return prettyPrintJs(js.statement('{#}', [updates])); | 675 return prettyPrintJs(js.statement('{#}', [updates])); |
| 627 } | 676 } |
| 628 } | 677 } |
| 629 | 678 |
| 630 jsAst.Expression invokeDefineClass(ClassElementX cls) { | 679 jsAst.Expression invokeDefineClass(ClassElementX cls) { |
| 631 String name = namer.getNameOfClass(cls); | 680 String name = namer.getNameOfClass(cls); |
| 632 var descriptor = js('Object.create(null)'); | 681 var descriptor = js('Object.create(null)'); |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1160 List<String> computeFields(ClassElement cls) { | 1209 List<String> computeFields(ClassElement cls) { |
| 1161 // TODO(ahe): Rewrite for new emitter. | 1210 // TODO(ahe): Rewrite for new emitter. |
| 1162 ClassBuilder builder = new ClassBuilder(cls, namer); | 1211 ClassBuilder builder = new ClassBuilder(cls, namer); |
| 1163 classEmitter.emitFields(cls, builder, ""); | 1212 classEmitter.emitFields(cls, builder, ""); |
| 1164 return builder.fields; | 1213 return builder.fields; |
| 1165 } | 1214 } |
| 1166 } | 1215 } |
| 1167 | 1216 |
| 1168 // TODO(ahe): Remove this method. | 1217 // TODO(ahe): Remove this method. |
| 1169 NO_WARN(x) => x; | 1218 NO_WARN(x) => x; |
| OLD | NEW |