| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 import '../utils.dart'; | 31 import '../utils.dart'; |
| 32 | 32 |
| 33 import 'code_generator.dart'; | 33 import 'code_generator.dart'; |
| 34 import 'js_field_storage.dart'; | 34 import 'js_field_storage.dart'; |
| 35 import 'js_interop.dart'; | 35 import 'js_interop.dart'; |
| 36 import 'js_names.dart' as JS; | 36 import 'js_names.dart' as JS; |
| 37 import 'js_metalet.dart' as JS; | 37 import 'js_metalet.dart' as JS; |
| 38 import 'js_module_item_order.dart'; | 38 import 'js_module_item_order.dart'; |
| 39 import 'js_names.dart'; | 39 import 'js_names.dart'; |
| 40 import 'js_printer.dart' show writeJsLibrary; | 40 import 'js_printer.dart' show writeJsLibrary; |
| 41 import 'module_builder.dart'; |
| 41 import 'side_effect_analysis.dart'; | 42 import 'side_effect_analysis.dart'; |
| 42 | 43 |
| 43 // Various dynamic helpers we call. | 44 // Various dynamic helpers we call. |
| 44 // If renaming these, make sure to check other places like the | 45 // If renaming these, make sure to check other places like the |
| 45 // _runtime.js file and comments. | 46 // _runtime.js file and comments. |
| 46 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can | 47 // TODO(jmesserly): ideally we'd have a "dynamic call" dart library we can |
| 47 // import and generate calls to, rather than dart_runtime.js | 48 // import and generate calls to, rather than dart_runtime.js |
| 48 const DPUT = 'dput'; | 49 const DPUT = 'dput'; |
| 49 const DLOAD = 'dload'; | 50 const DLOAD = 'dload'; |
| 50 const DINDEX = 'dindex'; | 51 const DINDEX = 'dindex'; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 _flushLibraryProperties(_moduleItems); | 172 _flushLibraryProperties(_moduleItems); |
| 172 | 173 |
| 173 // Mark all qualified names as qualified or not, depending on if they need | 174 // Mark all qualified names as qualified or not, depending on if they need |
| 174 // to be loaded lazily or not. | 175 // to be loaded lazily or not. |
| 175 for (var elementIdPairs in _qualifiedIds) { | 176 for (var elementIdPairs in _qualifiedIds) { |
| 176 var element = elementIdPairs.e0; | 177 var element = elementIdPairs.e0; |
| 177 var id = elementIdPairs.e1; | 178 var id = elementIdPairs.e1; |
| 178 id.setQualified(!_loader.isLoaded(element)); | 179 id.setQualified(!_loader.isLoaded(element)); |
| 179 } | 180 } |
| 180 | 181 |
| 181 if (_exports.isNotEmpty) _moduleItems.add(js.comment('Exports:')); | 182 var moduleBuilder = new ModuleBuilder( |
| 183 compiler.getModuleName(currentLibrary.source.uri), |
| 184 _jsModuleValue, |
| 185 _exportsVar, |
| 186 options.moduleFormat); |
| 182 | 187 |
| 183 // TODO(jmesserly): make these immutable in JS? | 188 _exports.forEach(moduleBuilder.addExport); |
| 184 for (var name in _exports) { | |
| 185 _moduleItems.add(js.statement('#.# = #;', [_exportsVar, name, name])); | |
| 186 } | |
| 187 | 189 |
| 188 var jsPath = compiler.getModuleName(currentLibrary.source.uri); | 190 var items = <JS.ModuleItem>[]; |
| 189 | |
| 190 // TODO(jmesserly): it would be great to run the renamer on the body, | |
| 191 // then figure out if we really need each of these parameters. | |
| 192 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 | |
| 193 var params = [_exportsVar]; | |
| 194 var lazyParams = []; | |
| 195 | |
| 196 var imports = <JS.Expression>[]; | |
| 197 var lazyImports = <JS.Expression>[]; | |
| 198 var moduleStatements = <JS.Statement>[]; | |
| 199 | |
| 200 addImport(String name, JS.Expression libVar, {bool lazy: false}) { | |
| 201 (lazy ? lazyImports : imports).add(js.string(name, "'")); | |
| 202 (lazy ? lazyParams : params).add(libVar); | |
| 203 } | |
| 204 | |
| 205 if (!_isDartRuntime) { | 191 if (!_isDartRuntime) { |
| 206 addImport('dart/_runtime', _runtimeLibVar); | 192 moduleBuilder.addImport('dart/_runtime', _runtimeLibVar); |
| 207 | 193 |
| 208 var dartxImport = | 194 var dartxImport = |
| 209 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); | 195 js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]); |
| 210 moduleStatements.add(dartxImport); | 196 items.add(dartxImport); |
| 211 } | 197 } |
| 198 items.addAll(_moduleItems); |
| 199 |
| 212 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) { | 200 _imports.forEach((LibraryElement lib, JS.TemporaryId temp) { |
| 213 addImport(compiler.getModuleName(lib.source.uri), temp, | 201 moduleBuilder.addImport(compiler.getModuleName(lib.source.uri), temp, |
| 214 lazy: _isDartRuntime || !_loader.libraryIsLoaded(lib)); | 202 isLazy: _isDartRuntime || !_loader.libraryIsLoaded(lib)); |
| 215 }); | 203 }); |
| 216 params.addAll(lazyParams); | |
| 217 | |
| 218 moduleStatements.addAll(_moduleItems); | |
| 219 | |
| 220 var module = | |
| 221 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]); | |
| 222 | |
| 223 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [ | |
| 224 js.string(jsPath, "'"), | |
| 225 _jsModuleValue ?? new JS.LiteralNull(), | |
| 226 js.commentExpression( | |
| 227 "Imports", new JS.ArrayInitializer(imports, multiline: true)), | |
| 228 js.commentExpression("Lazy imports", | |
| 229 new JS.ArrayInitializer(lazyImports, multiline: true)), | |
| 230 module | |
| 231 ]); | |
| 232 | 204 |
| 233 // TODO(jmesserly): scriptTag support. | 205 // TODO(jmesserly): scriptTag support. |
| 234 // Enable this if we know we're targetting command line environment? | 206 // Enable this if we know we're targetting command line environment? |
| 235 // It doesn't work in browser. | 207 // It doesn't work in browser. |
| 236 // var jsBin = compiler.options.runnerOptions.v8Binary; | 208 // var jsBin = compiler.options.runnerOptions.v8Binary; |
| 237 // String scriptTag = null; | 209 // String scriptTag = null; |
| 238 // if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin'; | 210 // if (library.library.scriptTag != null) scriptTag = '/usr/bin/env $jsBin'; |
| 239 return new JS.Program(<JS.Statement>[moduleDef]); | 211 return moduleBuilder.build(items); |
| 240 } | 212 } |
| 241 | 213 |
| 242 void _emitModuleItem(AstNode node) { | 214 void _emitModuleItem(AstNode node) { |
| 243 // Attempt to group adjacent fields/properties. | 215 // Attempt to group adjacent fields/properties. |
| 244 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems); | 216 if (node is! VariableDeclaration) _flushLazyFields(_moduleItems); |
| 245 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); | 217 if (node is! FunctionDeclaration) _flushLibraryProperties(_moduleItems); |
| 246 | 218 |
| 247 var code = _visit(node); | 219 var code = _visit(node); |
| 248 if (code != null) _moduleItems.add(code); | 220 if (code != null) _moduleItems.add(code); |
| 249 } | 221 } |
| (...skipping 3370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3620 | 3592 |
| 3621 /// A special kind of element created by the compiler, signifying a temporary | 3593 /// A special kind of element created by the compiler, signifying a temporary |
| 3622 /// variable. These objects use instance equality, and should be shared | 3594 /// variable. These objects use instance equality, and should be shared |
| 3623 /// everywhere in the tree where they are treated as the same variable. | 3595 /// everywhere in the tree where they are treated as the same variable. |
| 3624 class TemporaryVariableElement extends LocalVariableElementImpl { | 3596 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3625 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3597 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3626 | 3598 |
| 3627 int get hashCode => identityHashCode(this); | 3599 int get hashCode => identityHashCode(this); |
| 3628 bool operator ==(Object other) => identical(this, other); | 3600 bool operator ==(Object other) => identical(this, other); |
| 3629 } | 3601 } |
| OLD | NEW |