| 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.js_emitter.full_emitter; | 5 library dart2js.js_emitter.full_emitter; |
| 6 | 6 |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:collection' show HashMap; | 8 import 'dart:collection' show HashMap; |
| 9 | 9 |
| 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 final Map<jsAst.Name, String> mangledFieldNames = | 145 final Map<jsAst.Name, String> mangledFieldNames = |
| 146 new HashMap<jsAst.Name, String>(); | 146 new HashMap<jsAst.Name, String>(); |
| 147 final Map<jsAst.Name, String> mangledGlobalFieldNames = | 147 final Map<jsAst.Name, String> mangledGlobalFieldNames = |
| 148 new HashMap<jsAst.Name, String>(); | 148 new HashMap<jsAst.Name, String>(); |
| 149 final Set<jsAst.Name> recordedMangledNames = new Set<jsAst.Name>(); | 149 final Set<jsAst.Name> recordedMangledNames = new Set<jsAst.Name>(); |
| 150 | 150 |
| 151 JavaScriptBackend get backend => compiler.backend; | 151 JavaScriptBackend get backend => compiler.backend; |
| 152 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler; | 152 TypeVariableHandler get typeVariableHandler => backend.typeVariableHandler; |
| 153 | 153 |
| 154 String get _ => space; | 154 String get _ => space; |
| 155 String get space => compiler.enableMinification ? "" : " "; | 155 String get space => compiler.options.enableMinification ? "" : " "; |
| 156 String get n => compiler.enableMinification ? "" : "\n"; | 156 String get n => compiler.options.enableMinification ? "" : "\n"; |
| 157 String get N => compiler.enableMinification ? "\n" : ";\n"; | 157 String get N => compiler.options.enableMinification ? "\n" : ";\n"; |
| 158 | 158 |
| 159 /** | 159 /** |
| 160 * List of expressions and statements that will be included in the | 160 * List of expressions and statements that will be included in the |
| 161 * precompiled function. | 161 * precompiled function. |
| 162 * | 162 * |
| 163 * To save space, dart2js normally generates constructors and accessors | 163 * To save space, dart2js normally generates constructors and accessors |
| 164 * dynamically. This doesn't work in CSP mode, so dart2js emits them directly | 164 * dynamically. This doesn't work in CSP mode, so dart2js emits them directly |
| 165 * when in CSP mode. | 165 * when in CSP mode. |
| 166 */ | 166 */ |
| 167 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = | 167 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 564 } |
| 565 | 565 |
| 566 String namedParametersAsReflectionNames(CallStructure structure) { | 566 String namedParametersAsReflectionNames(CallStructure structure) { |
| 567 if (structure.isUnnamed) return ''; | 567 if (structure.isUnnamed) return ''; |
| 568 String names = structure.getOrderedNamedArguments().join(':'); | 568 String names = structure.getOrderedNamedArguments().join(':'); |
| 569 return ':$names'; | 569 return ':$names'; |
| 570 } | 570 } |
| 571 | 571 |
| 572 jsAst.Statement buildCspPrecompiledFunctionFor( | 572 jsAst.Statement buildCspPrecompiledFunctionFor( |
| 573 OutputUnit outputUnit) { | 573 OutputUnit outputUnit) { |
| 574 if (compiler.useContentSecurityPolicy) { | 574 if (compiler.options.useContentSecurityPolicy) { |
| 575 // TODO(ahe): Compute a hash code. | 575 // TODO(ahe): Compute a hash code. |
| 576 // TODO(sigurdm): Avoid this precompiled function. Generated | 576 // TODO(sigurdm): Avoid this precompiled function. Generated |
| 577 // constructor-functions and getter/setter functions can be stored in the | 577 // constructor-functions and getter/setter functions can be stored in the |
| 578 // library-description table. Setting properties on these can be moved to | 578 // library-description table. Setting properties on these can be moved to |
| 579 // finishClasses. | 579 // finishClasses. |
| 580 return js.statement(r""" | 580 return js.statement(r""" |
| 581 #precompiled = function ($collectedClasses$) { | 581 #precompiled = function ($collectedClasses$) { |
| 582 #norename; | 582 #norename; |
| 583 var $desc; | 583 var $desc; |
| 584 #functions; | 584 #functions; |
| 585 return #result; | 585 return #result; |
| 586 };""", | 586 };""", |
| 587 {'norename': new jsAst.Comment("// ::norenaming:: "), | 587 {'norename': new jsAst.Comment("// ::norenaming:: "), |
| 588 'precompiled': generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), | 588 'precompiled': generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), |
| 589 'functions': cspPrecompiledFunctionFor(outputUnit), | 589 'functions': cspPrecompiledFunctionFor(outputUnit), |
| 590 'result': new jsAst.ArrayInitializer( | 590 'result': new jsAst.ArrayInitializer( |
| 591 cspPrecompiledConstructorNamesFor(outputUnit))}); | 591 cspPrecompiledConstructorNamesFor(outputUnit))}); |
| 592 } else { | 592 } else { |
| 593 return js.comment("Constructors are generated at runtime."); | 593 return js.comment("Constructors are generated at runtime."); |
| 594 } | 594 } |
| 595 } | 595 } |
| 596 | 596 |
| 597 void assembleClass(Class cls, ClassBuilder enclosingBuilder, | 597 void assembleClass(Class cls, ClassBuilder enclosingBuilder, |
| 598 Fragment fragment) { | 598 Fragment fragment) { |
| 599 ClassElement classElement = cls.element; | 599 ClassElement classElement = cls.element; |
| 600 reporter.withCurrentElement(classElement, () { | 600 reporter.withCurrentElement(classElement, () { |
| 601 if (compiler.hasIncrementalSupport) { | 601 if (compiler.options.hasIncrementalSupport) { |
| 602 ClassBuilder cachedBuilder = | 602 ClassBuilder cachedBuilder = |
| 603 cachedClassBuilders.putIfAbsent(classElement, () { | 603 cachedClassBuilders.putIfAbsent(classElement, () { |
| 604 ClassBuilder builder = | 604 ClassBuilder builder = |
| 605 new ClassBuilder.forClass(classElement, namer); | 605 new ClassBuilder.forClass(classElement, namer); |
| 606 classEmitter.emitClass(cls, builder, fragment); | 606 classEmitter.emitClass(cls, builder, fragment); |
| 607 return builder; | 607 return builder; |
| 608 }); | 608 }); |
| 609 invariant(classElement, cachedBuilder.fields.isEmpty); | 609 invariant(classElement, cachedBuilder.fields.isEmpty); |
| 610 invariant(classElement, cachedBuilder.superName == null); | 610 invariant(classElement, cachedBuilder.superName == null); |
| 611 invariant(classElement, cachedBuilder.functionType == null); | 611 invariant(classElement, cachedBuilder.functionType == null); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 704 } |
| 705 } else { | 705 } else { |
| 706 if (#notMinified) { | 706 if (#notMinified) { |
| 707 #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder); | 707 #lazy(fieldName, getterName, lazyValue, staticName, fieldHolder); |
| 708 } else { | 708 } else { |
| 709 #lazy(fieldName, getterName, lazyValue, null, fieldHolder); | 709 #lazy(fieldName, getterName, lazyValue, null, fieldHolder); |
| 710 } | 710 } |
| 711 } | 711 } |
| 712 } | 712 } |
| 713 })(#laziesInfo) | 713 })(#laziesInfo) |
| 714 ''', {'notMinified': !compiler.enableMinification, | 714 ''', {'notMinified': !compiler.options.enableMinification, |
| 715 'laziesInfo': new jsAst.ArrayInitializer(laziesInfo), | 715 'laziesInfo': new jsAst.ArrayInitializer(laziesInfo), |
| 716 'lazy': js(lazyInitializerName), | 716 'lazy': js(lazyInitializerName), |
| 717 'isMainFragment': isMainFragment, | 717 'isMainFragment': isMainFragment, |
| 718 'isDeferredFragment': !isMainFragment}); | 718 'isDeferredFragment': !isMainFragment}); |
| 719 } else { | 719 } else { |
| 720 return js.comment("No lazy statics."); | 720 return js.comment("No lazy statics."); |
| 721 } | 721 } |
| 722 } | 722 } |
| 723 | 723 |
| 724 List<jsAst.Expression> buildLaziesInfo( | 724 List<jsAst.Expression> buildLaziesInfo( |
| 725 Iterable<StaticField> lazies, bool isMainFragment) { | 725 Iterable<StaticField> lazies, bool isMainFragment) { |
| 726 List<jsAst.Expression> laziesInfo = <jsAst.Expression>[]; | 726 List<jsAst.Expression> laziesInfo = <jsAst.Expression>[]; |
| 727 for (StaticField field in lazies) { | 727 for (StaticField field in lazies) { |
| 728 laziesInfo.add(js.quoteName(field.name)); | 728 laziesInfo.add(js.quoteName(field.name)); |
| 729 laziesInfo.add(js.quoteName(namer.deriveLazyInitializerName(field.name))); | 729 laziesInfo.add(js.quoteName(namer.deriveLazyInitializerName(field.name))); |
| 730 laziesInfo.add(field.code); | 730 laziesInfo.add(field.code); |
| 731 if (!compiler.enableMinification) { | 731 if (!compiler.options.enableMinification) { |
| 732 laziesInfo.add(js.quoteName(field.name)); | 732 laziesInfo.add(js.quoteName(field.name)); |
| 733 } | 733 } |
| 734 if (!isMainFragment) { | 734 if (!isMainFragment) { |
| 735 laziesInfo.add(js('#', field.holder.name)); | 735 laziesInfo.add(js('#', field.holder.name)); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 return laziesInfo; | 738 return laziesInfo; |
| 739 } | 739 } |
| 740 | 740 |
| 741 // TODO(sra): Remove this unused function. | 741 // TODO(sra): Remove this unused function. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 756 // in new lazy values. | 756 // in new lazy values. |
| 757 return js('#(#,#,#,#,#)', | 757 return js('#(#,#,#,#,#)', |
| 758 [js(lazyInitializerName), | 758 [js(lazyInitializerName), |
| 759 js.quoteName(namer.globalPropertyName(element)), | 759 js.quoteName(namer.globalPropertyName(element)), |
| 760 js.quoteName(namer.lazyInitializerName(element)), | 760 js.quoteName(namer.lazyInitializerName(element)), |
| 761 code, | 761 code, |
| 762 js.string(element.name), | 762 js.string(element.name), |
| 763 isolateProperties]); | 763 isolateProperties]); |
| 764 } | 764 } |
| 765 | 765 |
| 766 if (compiler.enableMinification) { | 766 if (compiler.options.enableMinification) { |
| 767 return js('#(#,#,#)', | 767 return js('#(#,#,#)', |
| 768 [js(lazyInitializerName), | 768 [js(lazyInitializerName), |
| 769 js.quoteName(namer.globalPropertyName(element)), | 769 js.quoteName(namer.globalPropertyName(element)), |
| 770 js.quoteName(namer.lazyInitializerName(element)), | 770 js.quoteName(namer.lazyInitializerName(element)), |
| 771 code]); | 771 code]); |
| 772 } else { | 772 } else { |
| 773 return js('#(#,#,#,#)', | 773 return js('#(#,#,#,#)', |
| 774 [js(lazyInitializerName), | 774 [js(lazyInitializerName), |
| 775 js.quoteName(namer.globalPropertyName(element)), | 775 js.quoteName(namer.globalPropertyName(element)), |
| 776 js.quoteName(namer.lazyInitializerName(element)), | 776 js.quoteName(namer.lazyInitializerName(element)), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 798 } | 798 } |
| 799 return new jsAst.Block(parts); | 799 return new jsAst.Block(parts); |
| 800 } | 800 } |
| 801 | 801 |
| 802 jsAst.Statement buildCompileTimeConstants(List<Constant> constants, | 802 jsAst.Statement buildCompileTimeConstants(List<Constant> constants, |
| 803 {bool isMainFragment}) { | 803 {bool isMainFragment}) { |
| 804 assert(isMainFragment != null); | 804 assert(isMainFragment != null); |
| 805 | 805 |
| 806 if (constants.isEmpty) return js.comment("No constants in program."); | 806 if (constants.isEmpty) return js.comment("No constants in program."); |
| 807 List<jsAst.Statement> parts = <jsAst.Statement>[]; | 807 List<jsAst.Statement> parts = <jsAst.Statement>[]; |
| 808 if (compiler.hasIncrementalSupport && isMainFragment) { | 808 if (compiler.options.hasIncrementalSupport && isMainFragment) { |
| 809 parts = cachedEmittedConstantsAst; | 809 parts = cachedEmittedConstantsAst; |
| 810 } | 810 } |
| 811 for (Constant constant in constants) { | 811 for (Constant constant in constants) { |
| 812 ConstantValue constantValue = constant.value; | 812 ConstantValue constantValue = constant.value; |
| 813 if (compiler.hasIncrementalSupport && isMainFragment) { | 813 if (compiler.options.hasIncrementalSupport && isMainFragment) { |
| 814 if (cachedEmittedConstants.contains(constantValue)) continue; | 814 if (cachedEmittedConstants.contains(constantValue)) continue; |
| 815 cachedEmittedConstants.add(constantValue); | 815 cachedEmittedConstants.add(constantValue); |
| 816 } | 816 } |
| 817 parts.add(buildConstantInitializer(constantValue)); | 817 parts.add(buildConstantInitializer(constantValue)); |
| 818 } | 818 } |
| 819 | 819 |
| 820 return new jsAst.Block(parts); | 820 return new jsAst.Block(parts); |
| 821 } | 821 } |
| 822 | 822 |
| 823 jsAst.Statement buildConstantInitializer(ConstantValue constant) { | 823 jsAst.Statement buildConstantInitializer(ConstantValue constant) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 'interceptorsByTag': interceptorsByTagAccess, | 1020 'interceptorsByTag': interceptorsByTagAccess, |
| 1021 'leafTags': leafTagsAccess, | 1021 'leafTags': leafTagsAccess, |
| 1022 'finishedClasses': finishedClassesAccess, | 1022 'finishedClasses': finishedClassesAccess, |
| 1023 'needsLazyInitializer': needsLazyInitializer, | 1023 'needsLazyInitializer': needsLazyInitializer, |
| 1024 'lazies': laziesAccess, 'cyclicThrow': cyclicThrow, | 1024 'lazies': laziesAccess, 'cyclicThrow': cyclicThrow, |
| 1025 'isolatePropertiesName': namer.isolatePropertiesName, | 1025 'isolatePropertiesName': namer.isolatePropertiesName, |
| 1026 'outputContainsConstantList': outputContainsConstantList, | 1026 'outputContainsConstantList': outputContainsConstantList, |
| 1027 'makeConstListProperty': makeConstListProperty, | 1027 'makeConstListProperty': makeConstListProperty, |
| 1028 'functionThatReturnsNullProperty': | 1028 'functionThatReturnsNullProperty': |
| 1029 backend.rtiEncoder.getFunctionThatReturnsNullName, | 1029 backend.rtiEncoder.getFunctionThatReturnsNullName, |
| 1030 'hasIncrementalSupport': compiler.hasIncrementalSupport, | 1030 'hasIncrementalSupport': compiler.options.hasIncrementalSupport, |
| 1031 'lazyInitializerProperty': lazyInitializerProperty,}); | 1031 'lazyInitializerProperty': lazyInitializerProperty,}); |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 jsAst.Statement buildConvertToFastObjectFunction() { | 1034 jsAst.Statement buildConvertToFastObjectFunction() { |
| 1035 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; | 1035 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; |
| 1036 if (DEBUG_FAST_OBJECTS) { | 1036 if (DEBUG_FAST_OBJECTS) { |
| 1037 debugCode.add(js.statement(r''' | 1037 debugCode.add(js.statement(r''' |
| 1038 // The following only works on V8 when run with option | 1038 // The following only works on V8 when run with option |
| 1039 // "--allow-natives-syntax". We use'new Function' because the | 1039 // "--allow-natives-syntax". We use'new Function' because the |
| 1040 // miniparser does not understand V8 native syntax. | 1040 // miniparser does not understand V8 native syntax. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1066 // mode. | 1066 // mode. |
| 1067 properties.__MAGIC_SLOW_PROPERTY = 1; | 1067 properties.__MAGIC_SLOW_PROPERTY = 1; |
| 1068 delete properties.__MAGIC_SLOW_PROPERTY; | 1068 delete properties.__MAGIC_SLOW_PROPERTY; |
| 1069 return properties; | 1069 return properties; |
| 1070 }'''); | 1070 }'''); |
| 1071 } | 1071 } |
| 1072 | 1072 |
| 1073 jsAst.Statement buildSupportsDirectProtoAccess() { | 1073 jsAst.Statement buildSupportsDirectProtoAccess() { |
| 1074 jsAst.Statement supportsDirectProtoAccess; | 1074 jsAst.Statement supportsDirectProtoAccess; |
| 1075 | 1075 |
| 1076 if (compiler.hasIncrementalSupport) { | 1076 if (compiler.options.hasIncrementalSupport) { |
| 1077 supportsDirectProtoAccess = js.statement(r''' | 1077 supportsDirectProtoAccess = js.statement(r''' |
| 1078 var supportsDirectProtoAccess = false; | 1078 var supportsDirectProtoAccess = false; |
| 1079 '''); | 1079 '''); |
| 1080 } else { | 1080 } else { |
| 1081 supportsDirectProtoAccess = js.statement(r''' | 1081 supportsDirectProtoAccess = js.statement(r''' |
| 1082 var supportsDirectProtoAccess = (function () { | 1082 var supportsDirectProtoAccess = (function () { |
| 1083 var cls = function () {}; | 1083 var cls = function () {}; |
| 1084 cls.prototype = {'p': {}}; | 1084 cls.prototype = {'p': {}}; |
| 1085 var object = new cls(); | 1085 var object = new cls(); |
| 1086 return object.__proto__ && | 1086 return object.__proto__ && |
| 1087 object.__proto__.p === cls.prototype.p; | 1087 object.__proto__.p === cls.prototype.p; |
| 1088 })(); | 1088 })(); |
| 1089 '''); | 1089 '''); |
| 1090 } | 1090 } |
| 1091 | 1091 |
| 1092 return supportsDirectProtoAccess; | 1092 return supportsDirectProtoAccess; |
| 1093 } | 1093 } |
| 1094 | 1094 |
| 1095 jsAst.Expression generateLibraryDescriptor(LibraryElement library, | 1095 jsAst.Expression generateLibraryDescriptor(LibraryElement library, |
| 1096 Fragment fragment) { | 1096 Fragment fragment) { |
| 1097 var uri = ""; | 1097 var uri = ""; |
| 1098 if (!compiler.enableMinification || backend.mustPreserveUris) { | 1098 if (!compiler.options.enableMinification || backend.mustPreserveUris) { |
| 1099 uri = library.canonicalUri; | 1099 uri = library.canonicalUri; |
| 1100 if (uri.scheme == 'file' && compiler.outputUri != null) { | 1100 if (uri.scheme == 'file' && compiler.options.outputUri != null) { |
| 1101 uri = relativize(compiler.outputUri, library.canonicalUri, false); | 1101 uri = relativize( |
| 1102 compiler.options.outputUri, library.canonicalUri, false); |
| 1102 } | 1103 } |
| 1103 } | 1104 } |
| 1104 | 1105 |
| 1105 String libraryName = | 1106 String libraryName = (!compiler.options.enableMinification || |
| 1106 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? | 1107 backend.mustRetainLibraryNames) ? library.libraryName : ""; |
| 1107 library.libraryName : | |
| 1108 ""; | |
| 1109 | 1108 |
| 1110 jsAst.Fun metadata = task.metadataCollector.buildMetadataFunction(library); | 1109 jsAst.Fun metadata = task.metadataCollector.buildMetadataFunction(library); |
| 1111 | 1110 |
| 1112 ClassBuilder descriptor = elementDescriptors[fragment][library]; | 1111 ClassBuilder descriptor = elementDescriptors[fragment][library]; |
| 1113 | 1112 |
| 1114 jsAst.ObjectInitializer initializer; | 1113 jsAst.ObjectInitializer initializer; |
| 1115 if (descriptor == null) { | 1114 if (descriptor == null) { |
| 1116 // Nothing of the library was emitted. | 1115 // Nothing of the library was emitted. |
| 1117 // TODO(floitsch): this should not happen. We currently have an example | 1116 // TODO(floitsch): this should not happen. We currently have an example |
| 1118 // with language/prefix6_negative_test.dart where we have an instance | 1117 // with language/prefix6_negative_test.dart where we have an instance |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); | 1334 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); |
| 1336 jsAst.ObjectInitializer map = new jsAst.ObjectInitializer(properties); | 1335 jsAst.ObjectInitializer map = new jsAst.ObjectInitializer(properties); |
| 1337 parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map])); | 1336 parts.add(js.statement('# = #', [mangledGlobalNamesAccess, map])); |
| 1338 } | 1337 } |
| 1339 | 1338 |
| 1340 return new jsAst.Block(parts); | 1339 return new jsAst.Block(parts); |
| 1341 } | 1340 } |
| 1342 | 1341 |
| 1343 void checkEverythingEmitted(Iterable<Element> elements) { | 1342 void checkEverythingEmitted(Iterable<Element> elements) { |
| 1344 List<Element> pendingStatics; | 1343 List<Element> pendingStatics; |
| 1345 if (!compiler.hasIncrementalSupport) { | 1344 if (!compiler.options.hasIncrementalSupport) { |
| 1346 pendingStatics = | 1345 pendingStatics = |
| 1347 Elements.sortedByPosition(elements.where((e) => !e.isLibrary)); | 1346 Elements.sortedByPosition(elements.where((e) => !e.isLibrary)); |
| 1348 | 1347 |
| 1349 pendingStatics.forEach((element) => | 1348 pendingStatics.forEach((element) => |
| 1350 reporter.reportInfo( | 1349 reporter.reportInfo( |
| 1351 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); | 1350 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); |
| 1352 } | 1351 } |
| 1353 | 1352 |
| 1354 if (pendingStatics != null && !pendingStatics.isEmpty) { | 1353 if (pendingStatics != null && !pendingStatics.isEmpty) { |
| 1355 reporter.internalError(pendingStatics.first, | 1354 reporter.internalError(pendingStatics.first, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 | 1421 |
| 1423 if (descriptors.isNotEmpty) { | 1422 if (descriptors.isNotEmpty) { |
| 1424 List<Element> remainingLibraries = descriptors.keys | 1423 List<Element> remainingLibraries = descriptors.keys |
| 1425 .where((Element e) => e is LibraryElement) | 1424 .where((Element e) => e is LibraryElement) |
| 1426 .toList(); | 1425 .toList(); |
| 1427 | 1426 |
| 1428 // The remaining descriptors are only accessible through reflection. | 1427 // The remaining descriptors are only accessible through reflection. |
| 1429 // The program builder does not collect libraries that only | 1428 // The program builder does not collect libraries that only |
| 1430 // contain typedefs that are used for reflection. | 1429 // contain typedefs that are used for reflection. |
| 1431 for (LibraryElement element in remainingLibraries) { | 1430 for (LibraryElement element in remainingLibraries) { |
| 1432 assert(element is LibraryElement || compiler.hasIncrementalSupport); | 1431 assert(element is LibraryElement || |
| 1432 compiler.options.hasIncrementalSupport); |
| 1433 if (element is LibraryElement) { | 1433 if (element is LibraryElement) { |
| 1434 parts.add(generateLibraryDescriptor(element, mainFragment)); | 1434 parts.add(generateLibraryDescriptor(element, mainFragment)); |
| 1435 descriptors.remove(element); | 1435 descriptors.remove(element); |
| 1436 } | 1436 } |
| 1437 } | 1437 } |
| 1438 } | 1438 } |
| 1439 jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts); | 1439 jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts); |
| 1440 | 1440 |
| 1441 // Using a named function here produces easier to read stack traces in | 1441 // Using a named function here produces easier to read stack traces in |
| 1442 // Chrome/V8. | 1442 // Chrome/V8. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 | 1545 |
| 1546 #convertGlobalObjectsToFastObjects; | 1546 #convertGlobalObjectsToFastObjects; |
| 1547 #debugFastObjects; | 1547 #debugFastObjects; |
| 1548 | 1548 |
| 1549 #init; | 1549 #init; |
| 1550 | 1550 |
| 1551 #main; | 1551 #main; |
| 1552 })(); | 1552 })(); |
| 1553 """, { | 1553 """, { |
| 1554 "disableVariableRenaming": js.comment("/* ::norenaming:: */"), | 1554 "disableVariableRenaming": js.comment("/* ::norenaming:: */"), |
| 1555 "hasIncrementalSupport": compiler.hasIncrementalSupport, | 1555 "hasIncrementalSupport": compiler.options.hasIncrementalSupport, |
| 1556 "helper": js('this.#', [namer.incrementalHelperName]), | 1556 "helper": js('this.#', [namer.incrementalHelperName]), |
| 1557 "schemaChange": buildSchemaChangeFunction(), | 1557 "schemaChange": buildSchemaChangeFunction(), |
| 1558 "addMethod": buildIncrementalAddMethod(), | 1558 "addMethod": buildIncrementalAddMethod(), |
| 1559 "isProgramSplit": isProgramSplit, | 1559 "isProgramSplit": isProgramSplit, |
| 1560 "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(), | 1560 "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(), |
| 1561 "globalsHolder": globalsHolder, | 1561 "globalsHolder": globalsHolder, |
| 1562 "globalObjectSetup": buildGlobalObjectSetup(isProgramSplit), | 1562 "globalObjectSetup": buildGlobalObjectSetup(isProgramSplit), |
| 1563 "isolateName": namer.isolateName, | 1563 "isolateName": namer.isolateName, |
| 1564 "isolatePropertiesName": js(isolatePropertiesName), | 1564 "isolatePropertiesName": js(isolatePropertiesName), |
| 1565 "initName": initName, | 1565 "initName": initName, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 | 1605 |
| 1606 CodeOutput mainOutput = | 1606 CodeOutput mainOutput = |
| 1607 new StreamCodeOutput(compiler.outputProvider('', 'js'), | 1607 new StreamCodeOutput(compiler.outputProvider('', 'js'), |
| 1608 codeOutputListeners); | 1608 codeOutputListeners); |
| 1609 outputBuffers[mainOutputUnit] = mainOutput; | 1609 outputBuffers[mainOutputUnit] = mainOutput; |
| 1610 | 1610 |
| 1611 | 1611 |
| 1612 mainOutput.addBuffer(jsAst.createCodeBuffer( | 1612 mainOutput.addBuffer(jsAst.createCodeBuffer( |
| 1613 program, compiler, monitor: compiler.dumpInfoTask)); | 1613 program, compiler, monitor: compiler.dumpInfoTask)); |
| 1614 | 1614 |
| 1615 if (compiler.deferredMapUri != null) { | 1615 if (compiler.options.deferredMapUri != null) { |
| 1616 outputDeferredMap(); | 1616 outputDeferredMap(); |
| 1617 } | 1617 } |
| 1618 | 1618 |
| 1619 if (generateSourceMap) { | 1619 if (generateSourceMap) { |
| 1620 mainOutput.add( | 1620 mainOutput.add(generateSourceMapTag( |
| 1621 generateSourceMapTag(compiler.sourceMapUri, compiler.outputUri)); | 1621 compiler.options.sourceMapUri, compiler.options.outputUri)); |
| 1622 } | 1622 } |
| 1623 | 1623 |
| 1624 mainOutput.close(); | 1624 mainOutput.close(); |
| 1625 | 1625 |
| 1626 if (generateSourceMap) { | 1626 if (generateSourceMap) { |
| 1627 outputSourceMap(mainOutput, lineColumnCollector, '', | 1627 outputSourceMap(mainOutput, lineColumnCollector, '', |
| 1628 compiler.sourceMapUri, compiler.outputUri); | 1628 compiler.options.sourceMapUri, compiler.options.outputUri); |
| 1629 } | 1629 } |
| 1630 } | 1630 } |
| 1631 | 1631 |
| 1632 /// Used by incremental compilation to patch up the prototype of | 1632 /// Used by incremental compilation to patch up the prototype of |
| 1633 /// [oldConstructor] for use as prototype of [newConstructor]. | 1633 /// [oldConstructor] for use as prototype of [newConstructor]. |
| 1634 jsAst.Fun buildSchemaChangeFunction() { | 1634 jsAst.Fun buildSchemaChangeFunction() { |
| 1635 if (!compiler.hasIncrementalSupport) return null; | 1635 if (!compiler.options.hasIncrementalSupport) return null; |
| 1636 return js(''' | 1636 return js(''' |
| 1637 function(newConstructor, oldConstructor, superclass) { | 1637 function(newConstructor, oldConstructor, superclass) { |
| 1638 // Invariant: newConstructor.prototype has no interesting properties besides | 1638 // Invariant: newConstructor.prototype has no interesting properties besides |
| 1639 // generated accessors. These are copied to oldPrototype which will be | 1639 // generated accessors. These are copied to oldPrototype which will be |
| 1640 // updated by other incremental changes. | 1640 // updated by other incremental changes. |
| 1641 if (superclass != null) { | 1641 if (superclass != null) { |
| 1642 this.inheritFrom(newConstructor, superclass); | 1642 this.inheritFrom(newConstructor, superclass); |
| 1643 } | 1643 } |
| 1644 var oldPrototype = oldConstructor.prototype; | 1644 var oldPrototype = oldConstructor.prototype; |
| 1645 var newPrototype = newConstructor.prototype; | 1645 var newPrototype = newConstructor.prototype; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1658 } | 1658 } |
| 1659 | 1659 |
| 1660 /// Used by incremental compilation to patch up an object ([holder]) with a | 1660 /// Used by incremental compilation to patch up an object ([holder]) with a |
| 1661 /// new (or updated) method. [arrayOrFunction] is either the new method, or | 1661 /// new (or updated) method. [arrayOrFunction] is either the new method, or |
| 1662 /// an array containing the method (see | 1662 /// an array containing the method (see |
| 1663 /// [ContainerBuilder.addMemberMethodFromInfo]). [name] is the name of the | 1663 /// [ContainerBuilder.addMemberMethodFromInfo]). [name] is the name of the |
| 1664 /// new method. [isStatic] tells if method is static (or | 1664 /// new method. [isStatic] tells if method is static (or |
| 1665 /// top-level). [globalFunctionsAccess] is a reference to | 1665 /// top-level). [globalFunctionsAccess] is a reference to |
| 1666 /// [embeddedNames.GLOBAL_FUNCTIONS]. | 1666 /// [embeddedNames.GLOBAL_FUNCTIONS]. |
| 1667 jsAst.Fun buildIncrementalAddMethod() { | 1667 jsAst.Fun buildIncrementalAddMethod() { |
| 1668 if (!compiler.hasIncrementalSupport) return null; | 1668 if (!compiler.options.hasIncrementalSupport) return null; |
| 1669 return js(r""" | 1669 return js(r""" |
| 1670 function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { | 1670 function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
| 1671 var arrayOrFunction = originalDescriptor[name]; | 1671 var arrayOrFunction = originalDescriptor[name]; |
| 1672 var method; | 1672 var method; |
| 1673 if (arrayOrFunction.constructor === Array) { | 1673 if (arrayOrFunction.constructor === Array) { |
| 1674 var existing = holder[name]; | 1674 var existing = holder[name]; |
| 1675 var array = arrayOrFunction; | 1675 var array = arrayOrFunction; |
| 1676 | 1676 |
| 1677 // Each method may have a number of stubs associated. For example, if an | 1677 // Each method may have a number of stubs associated. For example, if an |
| 1678 // instance method supports multiple arguments, a stub for each matching | 1678 // instance method supports multiple arguments, a stub for each matching |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1985 '#globalsHolder.${namer.isolateName};', | 1985 '#globalsHolder.${namer.isolateName};', |
| 1986 {'globalsHolder': globalsHolder})); | 1986 {'globalsHolder': globalsHolder})); |
| 1987 String typesAccess = | 1987 String typesAccess = |
| 1988 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); | 1988 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); |
| 1989 if (libraryDescriptor != null) { | 1989 if (libraryDescriptor != null) { |
| 1990 // The argument to reflectionDataParser is assigned to a temporary | 1990 // The argument to reflectionDataParser is assigned to a temporary |
| 1991 // 'dart' so that 'dart.' will appear as the prefix to dart methods | 1991 // 'dart' so that 'dart.' will appear as the prefix to dart methods |
| 1992 // in stack traces and profile entries. | 1992 // in stack traces and profile entries. |
| 1993 body.add(js.statement('var dart = #', libraryDescriptor)); | 1993 body.add(js.statement('var dart = #', libraryDescriptor)); |
| 1994 | 1994 |
| 1995 if (compiler.useContentSecurityPolicy) { | 1995 if (compiler.options.useContentSecurityPolicy) { |
| 1996 body.add(buildCspPrecompiledFunctionFor(outputUnit)); | 1996 body.add(buildCspPrecompiledFunctionFor(outputUnit)); |
| 1997 } | 1997 } |
| 1998 body.add( | 1998 body.add( |
| 1999 js.statement('$setupProgramName(dart, ${typesAccess}.length);')); | 1999 js.statement('$setupProgramName(dart, ${typesAccess}.length);')); |
| 2000 } | 2000 } |
| 2001 | 2001 |
| 2002 body..add(buildMetadata(program, outputUnit)) | 2002 body..add(buildMetadata(program, outputUnit)) |
| 2003 ..add(js.statement('${typesAccess}.push.apply(${typesAccess}, ' | 2003 ..add(js.statement('${typesAccess}.push.apply(${typesAccess}, ' |
| 2004 '${namer.deferredTypesName});')); | 2004 '${namer.deferredTypesName});')); |
| 2005 | 2005 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 // Make a unique hash of the code (before the sourcemaps are added) | 2060 // Make a unique hash of the code (before the sourcemaps are added) |
| 2061 // This will be used to retrieve the initializing function from the global | 2061 // This will be used to retrieve the initializing function from the global |
| 2062 // variable. | 2062 // variable. |
| 2063 String hash = hasher.getHash(); | 2063 String hash = hasher.getHash(); |
| 2064 | 2064 |
| 2065 output.add('$N${deferredInitializers}["$hash"]$_=$_' | 2065 output.add('$N${deferredInitializers}["$hash"]$_=$_' |
| 2066 '${deferredInitializers}.current$N'); | 2066 '${deferredInitializers}.current$N'); |
| 2067 | 2067 |
| 2068 if (generateSourceMap) { | 2068 if (generateSourceMap) { |
| 2069 Uri mapUri, partUri; | 2069 Uri mapUri, partUri; |
| 2070 Uri sourceMapUri = compiler.sourceMapUri; | 2070 Uri sourceMapUri = compiler.options.sourceMapUri; |
| 2071 Uri outputUri = compiler.outputUri; | 2071 Uri outputUri = compiler.options.outputUri; |
| 2072 | 2072 |
| 2073 String partName = "$partPrefix.part"; | 2073 String partName = "$partPrefix.part"; |
| 2074 | 2074 |
| 2075 if (sourceMapUri != null) { | 2075 if (sourceMapUri != null) { |
| 2076 String mapFileName = partName + ".js.map"; | 2076 String mapFileName = partName + ".js.map"; |
| 2077 List<String> mapSegments = sourceMapUri.pathSegments.toList(); | 2077 List<String> mapSegments = sourceMapUri.pathSegments.toList(); |
| 2078 mapSegments[mapSegments.length - 1] = mapFileName; | 2078 mapSegments[mapSegments.length - 1] = mapFileName; |
| 2079 mapUri = compiler.sourceMapUri.replace(pathSegments: mapSegments); | 2079 mapUri = compiler.options.sourceMapUri |
| 2080 .replace(pathSegments: mapSegments); |
| 2080 } | 2081 } |
| 2081 | 2082 |
| 2082 if (outputUri != null) { | 2083 if (outputUri != null) { |
| 2083 String partFileName = partName + ".js"; | 2084 String partFileName = partName + ".js"; |
| 2084 List<String> partSegments = outputUri.pathSegments.toList(); | 2085 List<String> partSegments = outputUri.pathSegments.toList(); |
| 2085 partSegments[partSegments.length - 1] = partFileName; | 2086 partSegments[partSegments.length - 1] = partFileName; |
| 2086 partUri = compiler.outputUri.replace(pathSegments: partSegments); | 2087 partUri = compiler.options.outputUri.replace( |
| 2088 pathSegments: partSegments); |
| 2087 } | 2089 } |
| 2088 | 2090 |
| 2089 output.add(generateSourceMapTag(mapUri, partUri)); | 2091 output.add(generateSourceMapTag(mapUri, partUri)); |
| 2090 output.close(); | 2092 output.close(); |
| 2091 outputSourceMap(output, lineColumnCollector, partName, | 2093 outputSourceMap(output, lineColumnCollector, partName, |
| 2092 mapUri, partUri); | 2094 mapUri, partUri); |
| 2093 } else { | 2095 } else { |
| 2094 output.close(); | 2096 output.close(); |
| 2095 } | 2097 } |
| 2096 | 2098 |
| 2097 hunkHashes[outputUnit] = hash; | 2099 hunkHashes[outputUnit] = hash; |
| 2098 } | 2100 } |
| 2099 return hunkHashes; | 2101 return hunkHashes; |
| 2100 } | 2102 } |
| 2101 | 2103 |
| 2102 jsAst.Comment buildGeneratedBy() { | 2104 jsAst.Comment buildGeneratedBy() { |
| 2103 List<String> options = []; | 2105 List<String> options = []; |
| 2104 if (compiler.mirrorsLibrary != null) options.add('mirrors'); | 2106 if (compiler.mirrorsLibrary != null) options.add('mirrors'); |
| 2105 if (compiler.useContentSecurityPolicy) options.add("CSP"); | 2107 if (compiler.options.useContentSecurityPolicy) options.add("CSP"); |
| 2106 return new jsAst.Comment(generatedBy(compiler, flavor: options.join(", "))); | 2108 return new jsAst.Comment(generatedBy(compiler, flavor: options.join(", "))); |
| 2107 } | 2109 } |
| 2108 | 2110 |
| 2109 void outputSourceMap(CodeOutput output, | 2111 void outputSourceMap(CodeOutput output, |
| 2110 LineColumnProvider lineColumnProvider, | 2112 LineColumnProvider lineColumnProvider, |
| 2111 String name, | 2113 String name, |
| 2112 [Uri sourceMapUri, | 2114 [Uri sourceMapUri, |
| 2113 Uri fileUri]) { | 2115 Uri fileUri]) { |
| 2114 if (!generateSourceMap) return; | 2116 if (!generateSourceMap) return; |
| 2115 // Create a source file for the compilation output. This allows using | 2117 // Create a source file for the compilation output. This allows using |
| 2116 // [:getLine:] to transform offsets to line numbers in [SourceMapBuilder]. | 2118 // [:getLine:] to transform offsets to line numbers in [SourceMapBuilder]. |
| 2117 SourceMapBuilder sourceMapBuilder = | 2119 SourceMapBuilder sourceMapBuilder = |
| 2118 new SourceMapBuilder(sourceMapUri, fileUri, lineColumnProvider); | 2120 new SourceMapBuilder(sourceMapUri, fileUri, lineColumnProvider); |
| 2119 output.forEachSourceLocation(sourceMapBuilder.addMapping); | 2121 output.forEachSourceLocation(sourceMapBuilder.addMapping); |
| 2120 String sourceMap = sourceMapBuilder.build(); | 2122 String sourceMap = sourceMapBuilder.build(); |
| 2121 compiler.outputProvider(name, 'js.map') | 2123 compiler.outputProvider(name, 'js.map') |
| 2122 ..add(sourceMap) | 2124 ..add(sourceMap) |
| 2123 ..close(); | 2125 ..close(); |
| 2124 } | 2126 } |
| 2125 | 2127 |
| 2126 void outputDeferredMap() { | 2128 void outputDeferredMap() { |
| 2127 Map<String, dynamic> mapping = new Map<String, dynamic>(); | 2129 Map<String, dynamic> mapping = new Map<String, dynamic>(); |
| 2128 // Json does not support comments, so we embed the explanation in the | 2130 // Json does not support comments, so we embed the explanation in the |
| 2129 // data. | 2131 // data. |
| 2130 mapping["_comment"] = "This mapping shows which compiled `.js` files are " | 2132 mapping["_comment"] = "This mapping shows which compiled `.js` files are " |
| 2131 "needed for a given deferred library import."; | 2133 "needed for a given deferred library import."; |
| 2132 mapping.addAll(compiler.deferredLoadTask.computeDeferredMap()); | 2134 mapping.addAll(compiler.deferredLoadTask.computeDeferredMap()); |
| 2133 compiler.outputProvider(compiler.deferredMapUri.path, 'deferred_map') | 2135 compiler.outputProvider( |
| 2136 compiler.options.deferredMapUri.path, 'deferred_map') |
| 2134 ..add(const JsonEncoder.withIndent(" ").convert(mapping)) | 2137 ..add(const JsonEncoder.withIndent(" ").convert(mapping)) |
| 2135 ..close(); | 2138 ..close(); |
| 2136 } | 2139 } |
| 2137 | 2140 |
| 2138 void invalidateCaches() { | 2141 void invalidateCaches() { |
| 2139 if (!compiler.hasIncrementalSupport) return; | 2142 if (!compiler.options.hasIncrementalSupport) return; |
| 2140 if (cachedElements.isEmpty) return; | 2143 if (cachedElements.isEmpty) return; |
| 2141 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2144 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2142 if (element.isInstanceMember) { | 2145 if (element.isInstanceMember) { |
| 2143 cachedClassBuilders.remove(element.enclosingClass); | 2146 cachedClassBuilders.remove(element.enclosingClass); |
| 2144 | 2147 |
| 2145 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2148 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2146 | 2149 |
| 2147 } | 2150 } |
| 2148 } | 2151 } |
| 2149 } | 2152 } |
| 2150 } | 2153 } |
| OLD | NEW |