Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library dev_compiler.src.codegen.js_codegen; | |
|
Jennifer Messerly
2016/01/22 18:29:01
fix library name here?
BTW, I heard we can delete
ochafik
2016/01/23 12:24:17
Done.
| |
| 6 | |
| 7 import '../js/js_ast.dart' as JS; | |
| 8 import '../js/js_ast.dart' show js; | |
| 9 import '../options.dart' show ModuleFormat; | |
| 10 | |
| 11 abstract class ModuleBuilder { | |
|
Jennifer Messerly
2016/01/22 18:29:01
Perhaps add a doc comment to this?
ochafik
2016/01/23 12:24:17
Done.
| |
| 12 final String _jsPath; | |
| 13 final String _jsModuleValue; | |
| 14 final JS.Identifier _exportsVar; | |
| 15 final List<String> _exports = <String>[]; | |
| 16 final List<_ModuleImport> _imports = <_ModuleImport>[]; | |
| 17 | |
| 18 ModuleBuilder._(this._jsPath, this._jsModuleValue, this._exportsVar); | |
| 19 | |
| 20 factory ModuleBuilder(String jsPath, String _jsModuleValue, | |
| 21 JS.Identifier _exportsVar, ModuleFormat format) { | |
| 22 switch (format) { | |
| 23 case ModuleFormat.dart: | |
| 24 return new DartModuleBuilder(jsPath, _jsModuleValue, _exportsVar); | |
|
Jennifer Messerly
2016/01/22 18:29:01
I wonder if we could factor this so given an enum
ochafik
2016/01/23 12:24:17
Yes, I did that in the first version (https://code
| |
| 25 case ModuleFormat.es6: | |
| 26 return new ES6ModuleBuilder(jsPath, _jsModuleValue, _exportsVar); | |
| 27 default: | |
|
Jennifer Messerly
2016/01/22 18:29:01
I think if you leave off "default", we'll give a w
ochafik
2016/01/23 12:24:17
Ah, sweet!
| |
| 28 throw new ArgumentError("Unsupported format: $format"); | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 void addExport(String name) { | |
| 33 _exports.add(name); | |
| 34 } | |
| 35 | |
| 36 void addImport(String name, JS.Identifier libVar, {bool isLazy: false}) { | |
| 37 _imports.add(new _ModuleImport(name, libVar, isLazy)); | |
| 38 } | |
| 39 | |
| 40 List<JS.ModuleItem> build(List<JS.Statement> moduleItems); | |
| 41 } | |
| 42 | |
| 43 class _ModuleImport { | |
| 44 final String name; | |
| 45 final JS.Identifier libVar; | |
| 46 final bool isLazy; | |
|
Jennifer Messerly
2016/01/22 18:29:01
Maybe we should document that this field is only f
ochafik
2016/01/23 12:24:17
Not sure we can remove it, if only for Closure, ad
| |
| 47 _ModuleImport(this.name, this.libVar, this.isLazy); | |
| 48 } | |
| 49 | |
| 50 /// Generates modules for with DDC's `dart_library.js` loading mechanism. | |
| 51 class DartModuleBuilder extends ModuleBuilder { | |
|
Jennifer Messerly
2016/01/22 18:29:01
Rename to LegacyModuleBuilder?
ochafik
2016/01/23 12:24:17
Done.
| |
| 52 DartModuleBuilder(jsPath, _jsModuleValue, _exportsVar) | |
| 53 : super._(jsPath, _jsModuleValue, _exportsVar); | |
| 54 | |
| 55 List<JS.ModuleItem> build(List<JS.Statement> moduleItems) { | |
| 56 // TODO(jmesserly): it would be great to run the renamer on the body, | |
| 57 // then figure out if we really need each of these parameters. | |
| 58 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 | |
| 59 var params = [_exportsVar]; | |
| 60 var lazyParams = []; | |
| 61 | |
| 62 var imports = <JS.Expression>[]; | |
| 63 var lazyImports = <JS.Expression>[]; | |
| 64 var moduleStatements = <JS.Statement>[]; | |
| 65 | |
| 66 for (var i in _imports) { | |
| 67 (i.isLazy ? lazyImports : imports).add(js.string(i.name, "'")); | |
| 68 (i.isLazy ? lazyParams : params).add(i.libVar); | |
| 69 } | |
| 70 params.addAll(lazyParams); | |
| 71 | |
| 72 moduleStatements.addAll(_flattenBlocks(moduleItems)); | |
| 73 | |
| 74 if (_exports.isNotEmpty) { | |
| 75 moduleStatements.add(js.comment('Exports:')); | |
| 76 // TODO(jmesserly): make these immutable in JS? | |
| 77 for (var name in _exports) { | |
| 78 moduleStatements | |
| 79 .add(js.statement('#.# = #;', [_exportsVar, name, name])); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 var module = | |
| 84 js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]); | |
| 85 | |
| 86 var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [ | |
| 87 js.string(_jsPath, "'"), | |
| 88 _jsModuleValue ?? new JS.LiteralNull(), | |
| 89 js.commentExpression( | |
| 90 "Imports", new JS.ArrayInitializer(imports, multiline: true)), | |
| 91 js.commentExpression("Lazy imports", | |
| 92 new JS.ArrayInitializer(lazyImports, multiline: true)), | |
| 93 module | |
| 94 ]); | |
| 95 return <JS.ModuleItem>[moduleDef]; | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 /// Generates ES6 modules. | |
| 100 /// | |
| 101 /// TODO(ochafik): Break strong dep cycles to accommodate the Closure Compiler. | |
|
Jennifer Messerly
2016/01/22 18:29:01
trivial style nit, TODO should not be in a doc com
ochafik
2016/01/23 12:24:17
Absolutely! I think the only diff between ES6Modul
| |
| 102 class ES6ModuleBuilder extends ModuleBuilder { | |
| 103 ES6ModuleBuilder(jsPath, _jsModuleValue, _exportsVar) | |
| 104 : super._(jsPath, _jsModuleValue, _exportsVar); | |
| 105 | |
| 106 List<JS.ModuleItem> build(List<JS.Statement> moduleItems) { | |
| 107 // TODO(jmesserly): it would be great to run the renamer on the body, | |
|
Jennifer Messerly
2016/01/22 18:29:01
This TODO should move down to the `for (var i in _
ochafik
2016/01/23 12:24:17
Done.
| |
| 108 // then figure out if we really need each of these parameters. | |
| 109 // See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34 | |
| 110 var moduleStatements = <JS.ModuleItem>[]; | |
| 111 | |
| 112 moduleStatements.add(js.statement("'use strict';")); | |
|
Jennifer Messerly
2016/01/22 18:29:01
"use strict" is not needed in ES6 modules:
http://
ochafik
2016/01/23 12:24:17
The power of specs! Thanks!
| |
| 113 // Lazy declarations may reference exports. | |
| 114 moduleStatements.add(js.statement("const # = {};", [_exportsVar])); | |
| 115 | |
| 116 for (var i in _imports) { | |
| 117 // TODO(ochafik): laziness, late binding, etc, to support Closure... | |
|
Jennifer Messerly
2016/01/22 18:29:01
well I hope we don't need lazy imports, because no
ochafik
2016/01/23 12:24:17
So, I think we'll need some combination of lazy cl
| |
| 118 moduleStatements.add(new JS.ImportDeclaration( | |
| 119 defaultBinding: i.libVar, from: js.string(i.name))); | |
| 120 } | |
| 121 | |
| 122 moduleStatements.addAll(_flattenBlocks(moduleItems)); | |
| 123 | |
| 124 if (_exports.isNotEmpty) { | |
| 125 moduleStatements.add(js.comment('Exports:')); | |
| 126 // TODO(jmesserly): make these immutable in JS? | |
| 127 for (var name in _exports) { | |
| 128 moduleStatements | |
| 129 .add(js.statement('#.# = #;', [_exportsVar, name, name])); | |
| 130 } | |
| 131 moduleStatements | |
| 132 .add(new JS.ExportDeclaration(_exportsVar, isDefault: true)); | |
| 133 } | |
| 134 // TODO(ochafik): What to do of _jsModuleValue? | |
| 135 return moduleStatements; | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 Iterable<JS.ModuleItem> _flattenBlocks(List<JS.ModuleItem> stats) => | |
|
Jennifer Messerly
2016/01/22 18:29:01
BTW, I wonder if we should add something like this
ochafik
2016/01/23 12:24:17
On second thought, I think this is wrong *in gener
| |
| 140 stats.expand((item) => item is JS.Block ? item.statements : [item]); | |
| OLD | NEW |