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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 }); | 291 }); |
292 for (FieldElementX field in fields) { | 292 for (FieldElementX field in fields) { |
293 // TODO(ahe): This only works when there's one field per | 293 // TODO(ahe): This only works when there's one field per |
294 // PartialFieldList. | 294 // PartialFieldList. |
295 addField(field, container); | 295 addField(field, container); |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 void addField(FieldElementX element, ScopeContainerElement container) { | 299 void addField(FieldElementX element, ScopeContainerElement container) { |
300 invalidateScopesAffectedBy(element, container); | 300 invalidateScopesAffectedBy(element, container); |
301 if (!element.isInstanceMember) { | 301 if (element.isInstanceMember) { |
302 cannotReuse(element, "Not an instance field."); | 302 _classesWithSchemaChanges.add(container); |
303 } else { | |
304 addInstanceField(element, container); | |
305 } | 303 } |
306 } | 304 updates.add(new AddedFieldUpdate(compiler, element, container)); |
307 | |
308 void addInstanceField(FieldElementX element, ClassElementX cls) { | |
309 _classesWithSchemaChanges.add(cls); | |
310 | |
311 updates.add(new AddedFieldUpdate(compiler, element, cls)); | |
312 } | 305 } |
313 | 306 |
314 bool canReuseRemovedElement( | 307 bool canReuseRemovedElement( |
315 PartialElement element, | 308 PartialElement element, |
316 ScopeContainerElement container) { | 309 ScopeContainerElement container) { |
317 if (element is PartialFunctionElement) { | 310 if (element is PartialFunctionElement) { |
318 removeFunction(element); | 311 removeFunction(element); |
319 return true; | 312 return true; |
320 } else if (element is PartialClassElement) { | 313 } else if (element is PartialClassElement) { |
321 removeClass(element); | 314 removeClass(element); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 updates.add( | 639 updates.add( |
647 js.statement( | 640 js.statement( |
648 r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)', | 641 r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)', |
649 [classAccess, invokeDefineClass(cls), classAccess, superAccess])); | 642 [classAccess, invokeDefineClass(cls), classAccess, superAccess])); |
650 } | 643 } |
651 | 644 |
652 for (RemovalUpdate update in removals) { | 645 for (RemovalUpdate update in removals) { |
653 update.writeUpdateJsOn(updates); | 646 update.writeUpdateJsOn(updates); |
654 } | 647 } |
655 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 648 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
656 if (!element.isField) { | 649 if (element.isField) { |
657 updates.add(computeMemberUpdateJs(element)); | 650 updates.addAll(computeFieldUpdateJs(element)); |
658 } else { | 651 } else { |
659 if (backend.constants.lazyStatics.contains(element)) { | 652 updates.add(computeMethodUpdateJs(element)); |
660 throw new StateError("$element requires lazy initializer."); | |
661 } | |
662 } | 653 } |
663 } | 654 } |
664 | 655 |
665 updates.add(js.statement(r''' | 656 updates.add(js.statement(r''' |
666 if (self.$dart_unsafe_eval.pendingStubs) { | 657 if (self.$dart_unsafe_eval.pendingStubs) { |
667 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); | 658 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); |
668 self.$dart_unsafe_eval.pendingStubs = void 0; | 659 self.$dart_unsafe_eval.pendingStubs = void 0; |
669 } | 660 } |
670 ''')); | 661 ''')); |
671 | 662 |
(...skipping 10 matching lines...) Expand all Loading... |
682 return js( | 673 return js( |
683 r''' | 674 r''' |
684 (new Function( | 675 (new Function( |
685 "$collectedClasses", "$desc", | 676 "$collectedClasses", "$desc", |
686 self.$dart_unsafe_eval.defineClass(#, #) +"\n;return " + #))({#: #})''', | 677 self.$dart_unsafe_eval.defineClass(#, #) +"\n;return " + #))({#: #})''', |
687 [js.string(name), js.stringArray(computeFields(cls)), | 678 [js.string(name), js.stringArray(computeFields(cls)), |
688 js.string(name), | 679 js.string(name), |
689 js.string(name), descriptor]); | 680 js.string(name), descriptor]); |
690 } | 681 } |
691 | 682 |
692 jsAst.Node computeMemberUpdateJs(Element element) { | 683 jsAst.Node computeMethodUpdateJs(Element element) { |
693 MemberInfo info = containerBuilder.analyzeMemberMethod(element); | 684 MemberInfo info = containerBuilder.analyzeMemberMethod(element); |
694 if (info == null) { | 685 if (info == null) { |
695 compiler.internalError(element, '${element.runtimeType}'); | 686 compiler.internalError(element, '${element.runtimeType}'); |
696 } | 687 } |
697 ClassBuilder builder = new ClassBuilder(element, namer); | 688 ClassBuilder builder = new ClassBuilder(element, namer); |
698 containerBuilder.addMemberMethodFromInfo(info, builder); | 689 containerBuilder.addMemberMethodFromInfo(info, builder); |
699 jsAst.Node partialDescriptor = | 690 jsAst.Node partialDescriptor = |
700 builder.toObjectInitializer(omitClassDescriptor: true); | 691 builder.toObjectInitializer(omitClassDescriptor: true); |
701 | 692 |
702 String name = info.name; | 693 String name = info.name; |
(...skipping 12 matching lines...) Expand all Loading... |
715 | 706 |
716 jsAst.Expression globalFunctionsAccess = | 707 jsAst.Expression globalFunctionsAccess = |
717 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS); | 708 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS); |
718 | 709 |
719 return js.statement( | 710 return js.statement( |
720 r'self.$dart_unsafe_eval.addMethod(#, #, #, #, #)', | 711 r'self.$dart_unsafe_eval.addMethod(#, #, #, #, #)', |
721 [partialDescriptor, js.string(name), holder, | 712 [partialDescriptor, js.string(name), holder, |
722 new jsAst.LiteralBool(isStatic), globalFunctionsAccess]); | 713 new jsAst.LiteralBool(isStatic), globalFunctionsAccess]); |
723 } | 714 } |
724 | 715 |
| 716 List<jsAst.Statement> computeFieldUpdateJs(FieldElementX element) { |
| 717 if (element.isInstanceMember) { |
| 718 // Any initializers are inlined in factory methods, and the field is |
| 719 // declared by adding its class to [_classesWithSchemaChanges]. |
| 720 return const <jsAst.Statement>[]; |
| 721 } |
| 722 // A static (or top-level) field. |
| 723 if (backend.constants.lazyStatics.contains(element)) { |
| 724 jsAst.Expression init = |
| 725 emitter.oldEmitter.buildLazilyInitializedStaticField( |
| 726 element, namer.currentIsolate); |
| 727 if (init == null) { |
| 728 throw new StateError("Initializer optimized away for $element"); |
| 729 } |
| 730 return <jsAst.Statement>[init.toStatement()]; |
| 731 } else { |
| 732 // TODO(ahe): When a field is referenced it is enqueued. If the field has |
| 733 // no initializer, it will not have any associated code, so it will |
| 734 // appear as if it was newly enqueued. |
| 735 if (element.initializer == null) { |
| 736 return const <jsAst.Statement>[]; |
| 737 } else { |
| 738 throw new StateError("Don't know how to compile $element"); |
| 739 } |
| 740 } |
| 741 } |
| 742 |
725 String prettyPrintJs(jsAst.Node node) { | 743 String prettyPrintJs(jsAst.Node node) { |
726 jsAst.Printer printer = new jsAst.Printer(compiler, null); | 744 jsAst.Printer printer = new jsAst.Printer(compiler, null); |
727 printer.blockOutWithoutBraces(node); | 745 printer.blockOutWithoutBraces(node); |
728 return printer.outBuffer.getText(); | 746 return printer.outBuffer.getText(); |
729 } | 747 } |
730 | 748 |
731 String callNameFor(FunctionElement element) { | 749 String callNameFor(FunctionElement element) { |
732 // TODO(ahe): Call a method in the compiler to obtain this name. | 750 // TODO(ahe): Call a method in the compiler to obtain this name. |
733 String callPrefix = namer.callPrefix; | 751 String callPrefix = namer.callPrefix; |
734 int parameterCount = element.functionSignature.parameterCount; | 752 int parameterCount = element.functionSignature.parameterCount; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 final ScopeContainerElement container; | 1081 final ScopeContainerElement container; |
1064 | 1082 |
1065 AddedFieldUpdate(Compiler compiler, this.element, this.container) | 1083 AddedFieldUpdate(Compiler compiler, this.element, this.container) |
1066 : super(compiler); | 1084 : super(compiler); |
1067 | 1085 |
1068 PartialFieldList get before => null; | 1086 PartialFieldList get before => null; |
1069 | 1087 |
1070 PartialFieldList get after => element.declarationSite; | 1088 PartialFieldList get after => element.declarationSite; |
1071 | 1089 |
1072 FieldElementX apply() { | 1090 FieldElementX apply() { |
1073 FieldElementX copy = element.copyWithEnclosing(container); | 1091 Element enclosing = container; |
| 1092 if (enclosing.isLibrary) { |
| 1093 // TODO(ahe): Reuse compilation unit of element instead? |
| 1094 enclosing = enclosing.compilationUnit; |
| 1095 } |
| 1096 FieldElementX copy = element.copyWithEnclosing(enclosing); |
1074 NO_WARN(container).addMember(copy, compiler); | 1097 NO_WARN(container).addMember(copy, compiler); |
1075 return copy; | 1098 return copy; |
1076 } | 1099 } |
1077 } | 1100 } |
1078 | 1101 |
1079 | 1102 |
1080 class ClassUpdate extends Update with JsFeatures { | 1103 class ClassUpdate extends Update with JsFeatures { |
1081 final PartialClassElement before; | 1104 final PartialClassElement before; |
1082 | 1105 |
1083 final PartialClassElement after; | 1106 final PartialClassElement after; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 List<String> computeFields(ClassElement cls) { | 1232 List<String> computeFields(ClassElement cls) { |
1210 // TODO(ahe): Rewrite for new emitter. | 1233 // TODO(ahe): Rewrite for new emitter. |
1211 ClassBuilder builder = new ClassBuilder(cls, namer); | 1234 ClassBuilder builder = new ClassBuilder(cls, namer); |
1212 classEmitter.emitFields(cls, builder, ""); | 1235 classEmitter.emitFields(cls, builder, ""); |
1213 return builder.fields; | 1236 return builder.fields; |
1214 } | 1237 } |
1215 } | 1238 } |
1216 | 1239 |
1217 // TODO(ahe): Remove this method. | 1240 // TODO(ahe): Remove this method. |
1218 NO_WARN(x) => x; | 1241 NO_WARN(x) => x; |
OLD | NEW |