Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: lib/src/codegen/module_builder.dart

Issue 1612083002: Initial --modules=es6 support (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: reformat Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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]);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698