| 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.new_js_emitter.model_emitter; | 5 library dart2js.new_js_emitter.model_emitter; |
| 6 | 6 |
| 7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; | 7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; |
| 8 import '../../dart2jslib.dart' show Compiler; | 8 import '../../dart2jslib.dart' show Compiler; |
| 9 import '../../elements/elements.dart' show ClassElement, FunctionElement; | 9 import '../../elements/elements.dart' show ClassElement, FunctionElement; |
| 10 import '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
| 11 import '../../js_backend/js_backend.dart' show | 11 import '../../js_backend/js_backend.dart' show |
| 12 JavaScriptBackend, | 12 JavaScriptBackend, |
| 13 Namer, | 13 Namer, |
| 14 ConstantEmitter; | 14 ConstantEmitter; |
| 15 | 15 |
| 16 import '../js_emitter.dart' show | 16 import '../js_emitter.dart' show AstContainer, NativeEmitter; |
| 17 NativeEmitter; | |
| 18 | 17 |
| 19 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show | 18 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show |
| 20 CREATE_NEW_ISOLATE, | 19 CREATE_NEW_ISOLATE, |
| 21 DEFERRED_LIBRARY_URIS, | 20 DEFERRED_LIBRARY_URIS, |
| 22 DEFERRED_LIBRARY_HASHES, | 21 DEFERRED_LIBRARY_HASHES, |
| 23 GET_TYPE_FROM_NAME, | 22 GET_TYPE_FROM_NAME, |
| 24 INITIALIZE_LOADED_HUNK, | 23 INITIALIZE_LOADED_HUNK, |
| 25 INTERCEPTORS_BY_TAG, | 24 INTERCEPTORS_BY_TAG, |
| 26 IS_HUNK_INITIALIZED, | 25 IS_HUNK_INITIALIZED, |
| 27 IS_HUNK_LOADED, | 26 IS_HUNK_LOADED, |
| 28 LEAF_TAGS, | 27 LEAF_TAGS, |
| 29 MANGLED_GLOBAL_NAMES, | 28 MANGLED_GLOBAL_NAMES, |
| 30 METADATA, | 29 METADATA, |
| 31 TYPE_TO_INTERCEPTOR_MAP, | 30 TYPE_TO_INTERCEPTOR_MAP, |
| 32 TYPES; | 31 TYPES; |
| 33 | 32 |
| 34 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode; | 33 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode; |
| 35 import '../model.dart'; | 34 import '../model.dart'; |
| 36 | 35 |
| 36 /// Represents the LiteralString resulting from unparsing [expression]. The |
| 37 /// actual unparsing is done on demand when requesting the [value] of this |
| 38 /// node. |
| 39 class _UnparsedNode extends js.DeferredString |
| 40 implements AstContainer { |
| 41 @override |
| 42 final js.Node ast; |
| 43 final Compiler _compiler; |
| 44 final bool _protectForEval; |
| 45 js.LiteralString _cachedLiteral; |
| 46 |
| 47 /// A [js.Literal] that represents the string result of unparsing [ast]. |
| 48 /// |
| 49 /// When its string [value] is requested, the node pretty-prints the given |
| 50 /// [ast] and, if [protectForEval] is true, wraps the resulting |
| 51 /// string in parenthesis. The result is also escaped. |
| 52 _UnparsedNode(this.ast, this._compiler, this._protectForEval); |
| 53 |
| 54 js.LiteralString get _literal { |
| 55 if (_cachedLiteral == null) { |
| 56 String text = js.prettyPrint(ast, _compiler).getText(); |
| 57 if (_protectForEval) { |
| 58 if (ast is js.Fun) text = '($text)'; |
| 59 if (ast is js.LiteralExpression) { |
| 60 js.LiteralExpression literalExpression = ast; |
| 61 String template = literalExpression.template; |
| 62 if (template.startsWith("function ") || |
| 63 template.startsWith("{")) { |
| 64 text = '($text)'; |
| 65 } |
| 66 } |
| 67 } |
| 68 _cachedLiteral = js.js.escapedString(text); |
| 69 } |
| 70 return _cachedLiteral; |
| 71 } |
| 72 |
| 73 @override |
| 74 String get value => _literal.value; |
| 75 } |
| 37 | 76 |
| 38 class ModelEmitter { | 77 class ModelEmitter { |
| 39 final Compiler compiler; | 78 final Compiler compiler; |
| 40 final Namer namer; | 79 final Namer namer; |
| 41 ConstantEmitter constantEmitter; | 80 ConstantEmitter constantEmitter; |
| 42 final NativeEmitter nativeEmitter; | 81 final NativeEmitter nativeEmitter; |
| 43 | 82 |
| 44 JavaScriptBackend get backend => compiler.backend; | 83 JavaScriptBackend get backend => compiler.backend; |
| 45 | 84 |
| 46 /// For deferred loading we communicate the initializers via this global var. | 85 /// For deferred loading we communicate the initializers via this global var. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 168 |
| 130 int emitProgram(Program program) { | 169 int emitProgram(Program program) { |
| 131 List<Fragment> fragments = program.fragments; | 170 List<Fragment> fragments = program.fragments; |
| 132 MainFragment mainFragment = fragments.first; | 171 MainFragment mainFragment = fragments.first; |
| 133 | 172 |
| 134 int totalSize = 0; | 173 int totalSize = 0; |
| 135 | 174 |
| 136 // We have to emit the deferred fragments first, since we need their | 175 // We have to emit the deferred fragments first, since we need their |
| 137 // deferred hash (which depends on the output) when emitting the main | 176 // deferred hash (which depends on the output) when emitting the main |
| 138 // fragment. | 177 // fragment. |
| 139 fragments.skip(1).forEach((DeferredFragment deferredUnit) { | 178 List<js.Expression> fragmentsCode = fragments.skip(1).map( |
| 179 (DeferredFragment deferredUnit) { |
| 140 js.Expression types = | 180 js.Expression types = |
| 141 program.metadataTypesForOutputUnit(deferredUnit.outputUnit); | 181 program.metadataTypesForOutputUnit(deferredUnit.outputUnit); |
| 142 js.Expression ast = emitDeferredFragment(types, deferredUnit, | 182 return emitDeferredFragment(types, deferredUnit, program.holders); |
| 143 program.holders); | 183 }).toList(); |
| 144 String code = js.prettyPrint(ast, compiler).getText(); | |
| 145 totalSize += code.length; | |
| 146 compiler.outputProvider(deferredUnit.outputFileName, deferredExtension) | |
| 147 ..add(code) | |
| 148 ..close(); | |
| 149 }); | |
| 150 | 184 |
| 151 js.Statement mainAst = emitMainFragment(program); | 185 js.Statement mainAst = emitMainFragment(program); |
| 186 |
| 187 fragmentsCode.forEach(program.metadataFinalizer.countTokensInAst); |
| 188 program.metadataFinalizer.countTokensInAst(mainAst); |
| 189 program.metadataFinalizer.finalizeTokens(); |
| 190 |
| 191 for (int i = 0; i < fragmentsCode.length; ++i) { |
| 192 String code = js.prettyPrint(fragmentsCode[i], compiler).getText(); |
| 193 totalSize += code.length; |
| 194 compiler.outputProvider(fragments[i+1].outputFileName, deferredExtension) |
| 195 ..add(code) |
| 196 ..close(); |
| 197 } |
| 198 |
| 152 String mainCode = js.prettyPrint(mainAst, compiler).getText(); | 199 String mainCode = js.prettyPrint(mainAst, compiler).getText(); |
| 153 compiler.outputProvider(mainFragment.outputFileName, 'js') | 200 compiler.outputProvider(mainFragment.outputFileName, 'js') |
| 154 ..add(buildGeneratedBy(compiler)) | 201 ..add(buildGeneratedBy(compiler)) |
| 155 ..add(mainCode) | 202 ..add(mainCode) |
| 156 ..close(); | 203 ..close(); |
| 157 totalSize += mainCode.length; | 204 totalSize += mainCode.length; |
| 158 | 205 |
| 159 return totalSize; | 206 return totalSize; |
| 160 } | 207 } |
| 161 | 208 |
| 162 /// Unparses the given [value]. | 209 /// Returns a [js.Literal] that represents the string result of unparsing |
| 210 /// [value]. |
| 163 /// | 211 /// |
| 164 /// Pretty-prints the given [value] and, if [protectForEval] is | 212 /// The returned node will, when its string value is requested, pretty-print |
| 165 /// true, wraps the resulting string in parenthesis. The result is escaped | 213 /// the given [value] and, if [protectForEval] is true, wrap the resulting |
| 166 /// and returned. | 214 /// string in parenthesis. The result is also escaped. |
| 167 js.LiteralString unparse(Compiler compiler, js.Node value, | 215 /// |
| 168 {bool protectForEval: true}) { | 216 /// See [_UnparsedNode] for details. |
| 169 String text = js.prettyPrint(value, compiler).getText(); | 217 js.Literal unparse(Compiler compiler, js.Node value, |
| 170 if (protectForEval) { | 218 {bool protectForEval: true}) { |
| 171 if (value is js.Fun) text = '($text)'; | 219 return new _UnparsedNode(value, compiler, protectForEval); |
| 172 if (value is js.LiteralExpression && | |
| 173 (value.template.startsWith("function ") || | |
| 174 value.template.startsWith("{"))) { | |
| 175 text = '($text)'; | |
| 176 } | |
| 177 } | |
| 178 return js.js.escapedString(text); | |
| 179 } | 220 } |
| 180 | 221 |
| 181 String buildGeneratedBy(compiler) { | 222 String buildGeneratedBy(compiler) { |
| 182 var suffix = ''; | 223 var suffix = ''; |
| 183 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}'; | 224 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}'; |
| 184 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n'; | 225 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n'; |
| 185 } | 226 } |
| 186 | 227 |
| 187 js.Statement emitMainFragment(Program program) { | 228 js.Statement emitMainFragment(Program program) { |
| 188 MainFragment fragment = program.fragments.first; | 229 MainFragment fragment = program.fragments.first; |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 | 548 |
| 508 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); | 549 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); |
| 509 | 550 |
| 510 // This is the code that must be evaluated after all deferred classes have | 551 // This is the code that must be evaluated after all deferred classes have |
| 511 // been setup. | 552 // been setup. |
| 512 js.Statement immediateCode = new js.Block([ | 553 js.Statement immediateCode = new js.Block([ |
| 513 emitStaticNonFinalFields(fragment.staticNonFinalFields), | 554 emitStaticNonFinalFields(fragment.staticNonFinalFields), |
| 514 emitEagerClassInitializations(fragment.libraries)]); | 555 emitEagerClassInitializations(fragment.libraries)]); |
| 515 | 556 |
| 516 | 557 |
| 517 js.LiteralString immediateString = unparse(compiler, immediateCode); | 558 js.Literal immediateString = unparse(compiler, immediateCode); |
| 518 | 559 |
| 519 js.ArrayInitializer hunk = | 560 js.ArrayInitializer hunk = |
| 520 new js.ArrayInitializer([deferredArray, immediateString, | 561 new js.ArrayInitializer([deferredArray, immediateString, |
| 521 deferredTypes]); | 562 deferredTypes]); |
| 522 | 563 |
| 523 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); | 564 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); |
| 524 } | 565 } |
| 525 | 566 |
| 526 // This string should be referenced wherever JavaScript code makes assumptions | 567 // This string should be referenced wherever JavaScript code makes assumptions |
| 527 // on the constants format. | 568 // on the constants format. |
| (...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 | 1276 |
| 1236 var end = Date.now(); | 1277 var end = Date.now(); |
| 1237 // print('Setup: ' + (end - start) + ' ms.'); | 1278 // print('Setup: ' + (end - start) + ' ms.'); |
| 1238 | 1279 |
| 1239 #invokeMain; // Start main. | 1280 #invokeMain; // Start main. |
| 1240 | 1281 |
| 1241 }(Date.now(), #code) | 1282 }(Date.now(), #code) |
| 1242 }"""; | 1283 }"""; |
| 1243 | 1284 |
| 1244 } | 1285 } |
| OLD | NEW |