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

Unified Diff: lib/src/codegen/module_builder.dart

Issue 1633003002: Add --modules=node support (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: regen sdk and expectations 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 side-by-side diff with in-line comments
Download patch
Index: lib/src/codegen/module_builder.dart
diff --git a/lib/src/codegen/module_builder.dart b/lib/src/codegen/module_builder.dart
index 51478d2d0df703fe4c69e1d77cdee95af926c83d..9c9b8c96daec04494d07d33e1c31b68068afd16e 100644
--- a/lib/src/codegen/module_builder.dart
+++ b/lib/src/codegen/module_builder.dart
@@ -10,13 +10,10 @@ import '../options.dart' show ModuleFormat;
/// Helper that builds JS modules in a given [ModuleFormat].
abstract class ModuleBuilder {
- final String _jsPath;
- final String _jsModuleValue;
- final JS.Identifier _exportsVar;
- final List<String> _exports = <String>[];
- final List<_ModuleImport> _imports = <_ModuleImport>[];
+ final _exports = <String, String>{};
+ final _imports = <_ModuleImport>[];
- ModuleBuilder._(this._jsPath, this._jsModuleValue, this._exportsVar);
+ ModuleBuilder._();
/// Returns a [format]-specific [ModuleBuilder].
/// - [jsPath] is the path of the module being built.
@@ -25,30 +22,34 @@ abstract class ModuleBuilder {
/// library directive). It is null in any other case.
/// - [exportsVar] is the name of the object on which items are exported. Lazy
/// variables and constants are assumed to be declared on this instance.
- factory ModuleBuilder(String jsPath, String jsModuleValue,
- JS.Identifier exportsVar, ModuleFormat format) {
+ factory ModuleBuilder(ModuleFormat format) {
switch (format) {
case ModuleFormat.legacy:
- return new LegacyModuleBuilder(jsPath, jsModuleValue, exportsVar);
+ return new LegacyModuleBuilder();
case ModuleFormat.es6:
- return new ES6ModuleBuilder(jsPath, jsModuleValue, exportsVar);
+ return new ES6ModuleBuilder();
+ case ModuleFormat.node:
+ return new NodeModuleBuilder();
}
}
/// Adds [name] to the list of names to be exported from the module.
- void addExport(String name) {
- _exports.add(name);
+ void addExport(String name, String exportName) {
+ _exports[name] = exportName;
}
/// Adds an import from a module named [name] and locally aliased as [libVar].
- /// When [isLazy] is true, the import should be lazy (i.e. there is some
+ /// When [isLazy] is `true`, the import should be lazy (i.e. there is some
/// cyclic dependency of imports).
+ /// When [libVar] is `null`, the import is there just to force the import
+ /// order.
void addImport(String name, JS.Identifier libVar, {bool isLazy: false}) {
_imports.add(new _ModuleImport(name, libVar, isLazy));
}
/// Builds a program out of menu items.
- JS.Program build(List<JS.ModuleItem> moduleItems);
+ JS.Program build(String jsPath, String jsModuleValue,
+ JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems);
}
class _ModuleImport {
@@ -63,14 +64,14 @@ class _ModuleImport {
/// Generates modules for with DDC's `dart_library.js` loading mechanism.
class LegacyModuleBuilder extends ModuleBuilder {
- LegacyModuleBuilder(jsPath, _jsModuleValue, _exportsVar)
- : super._(jsPath, _jsModuleValue, _exportsVar);
+ LegacyModuleBuilder() : super._();
- JS.Program build(List<JS.ModuleItem> moduleItems) {
+ JS.Program build(String jsPath, String jsModuleValue,
+ JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
// TODO(jmesserly): it would be great to run the renamer on the body,
// then figure out if we really need each of these parameters.
// See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34
- var params = [_exportsVar];
+ var params = [exportsVar];
var lazyParams = [];
var imports = <JS.Expression>[];
@@ -78,6 +79,8 @@ class LegacyModuleBuilder extends ModuleBuilder {
var moduleStatements = <JS.Statement>[];
for (var i in _imports) {
+ // No need to force the import order for the legacy library mechanism.
+ if (i.libVar == null) continue;
(i.isLazy ? lazyImports : imports).add(js.string(i.name, "'"));
(i.isLazy ? lazyParams : params).add(i.libVar);
}
@@ -88,18 +91,18 @@ class LegacyModuleBuilder extends ModuleBuilder {
if (_exports.isNotEmpty) {
moduleStatements.add(js.comment('Exports:'));
// TODO(jmesserly): make these immutable in JS?
- for (var name in _exports) {
+ _exports.forEach((name, exportName) {
moduleStatements
- .add(js.statement('#.# = #;', [_exportsVar, name, name]));
- }
+ .add(js.statement('#.# = #;', [exportsVar, exportName, name]));
+ });
}
var module =
js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]);
var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [
- js.string(_jsPath, "'"),
- _jsModuleValue ?? new JS.LiteralNull(),
+ js.string(jsPath, "'"),
+ jsModuleValue ?? new JS.LiteralNull(),
js.commentExpression(
"Imports", new JS.ArrayInitializer(imports, multiline: true)),
js.commentExpression("Lazy imports",
@@ -113,13 +116,12 @@ class LegacyModuleBuilder extends ModuleBuilder {
/// Generates ES6 modules.
// TODO(ochafik): Break strong dep cycles to accommodate the Closure Compiler.
class ES6ModuleBuilder extends ModuleBuilder {
- ES6ModuleBuilder(jsPath, _jsModuleValue, _exportsVar)
- : super._(jsPath, _jsModuleValue, _exportsVar);
+ ES6ModuleBuilder() : super._();
- JS.Program build(List<JS.ModuleItem> moduleItems) {
+ JS.Program build(String jsPath, String jsModuleValue,
+ JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
var moduleStatements = <JS.ModuleItem>[
- // Lazy declarations may reference exports.
- js.statement("const # = {};", [_exportsVar])
+ js.statement("const # = {};", [exportsVar])
];
// TODO(jmesserly): it would be great to run the renamer on the body,
@@ -127,8 +129,13 @@ class ES6ModuleBuilder extends ModuleBuilder {
// See ES6 modules: https://github.com/dart-lang/dev_compiler/issues/34
for (var i in _imports) {
// TODO(ochafik): laziness, late binding, etc, to support Closure...
- moduleStatements.add(new JS.ImportDeclaration(
- defaultBinding: i.libVar, from: js.string(i.name)));
+ if (i.libVar == null) {
+ moduleStatements.add(new JS.ImportDeclaration(
+ namedImports: [], from: js.string(i.name)));
+ } else {
+ moduleStatements.add(new JS.ImportDeclaration(
+ defaultBinding: i.libVar, from: js.string(i.name)));
+ }
}
moduleStatements.addAll(_flattenBlocks(moduleItems));
@@ -136,14 +143,83 @@ class ES6ModuleBuilder extends ModuleBuilder {
if (_exports.isNotEmpty) {
moduleStatements.add(js.comment('Exports:'));
// TODO(jmesserly): make these immutable in JS?
- for (var name in _exports) {
+ _exports.forEach((name, exportName) {
moduleStatements
- .add(js.statement('#.# = #;', [_exportsVar, name, name]));
- }
+ .add(js.statement('#.# = #;', [exportsVar, exportName, name]));
+ });
moduleStatements
- .add(new JS.ExportDeclaration(_exportsVar, isDefault: true));
+ .add(new JS.ExportDeclaration(exportsVar, isDefault: true));
+ }
+ // TODO(ochafik): What to do of jsModuleValue?
+ return new JS.Program(moduleStatements);
+ }
+}
+
+/// Generates node modules.
+class NodeModuleBuilder extends ModuleBuilder {
+ NodeModuleBuilder() : super._();
+
+ JS.Program build(String jsPath, String jsModuleValue,
+ JS.Identifier exportsVar, Iterable<JS.ModuleItem> moduleItems) {
+ var moduleStatements = <JS.ModuleItem>[
+ js.statement("'use strict';"),
+ // js.statement("console.log('Loading ' + #);", [js.string(jsPath)])
vsm 2016/01/26 14:09:40 Remove?
ochafik 2016/01/26 16:27:37 Done.
+ ];
+
+ moduleItems = _flattenBlocks(moduleItems);
+
+ var prioritaryExportItems = <JS.ModuleItem>[];
vsm 2016/01/26 14:09:41 s/prioritary/priority/ here and below?
ochafik 2016/01/26 16:27:37 Acknowledged.
+ var normalItems = <JS.ModuleItem>[];
+
+ var exported = new Set<String>();
+ emitExport(String name, List<JS.ModuleItem> items) {
vsm 2016/01/26 14:09:41 return type void?
ochafik 2016/01/26 16:27:37 Acknowledged.
+ if (exported.add(name)) {
+ items.add(js.statement('#.# = #;', [exportsVar, _exports[name], name]));
+ }
+ }
+
+ getPrioritaryExportName(JS.ModuleItem item) {
vsm 2016/01/26 14:09:41 return type String?
ochafik 2016/01/26 16:27:37 Acknowledged.
+ if (jsPath == 'dart/core') {
+ if (item is JS.ClassDeclaration) {
+ var name = item.classExpr.name.name;
+ switch (name) {
+ case 'Object':
+ case 'Match':
+ return name;
vsm 2016/01/26 14:09:40 Can you add a comment on why these need special ca
ochafik 2016/01/26 16:27:37 Actually, no longer needed with the forced order,
+ }
+ }
+ }
+ return null;
+ }
+
+ for (var item in moduleItems) {
+ var prioritaryExportName = getPrioritaryExportName(item);
+ if (prioritaryExportName != null) {
+ prioritaryExportItems.add(item);
+ emitExport(prioritaryExportName, prioritaryExportItems);
+ } else {
+ normalItems.add(item);
+ }
+ }
+
+ moduleStatements.addAll(prioritaryExportItems);
+
+ for (var i in _imports) {
+ if (i.libVar == null) {
+ moduleStatements.add(js.statement('require(#);', [js.string(i.name)]));
+ } else {
+ moduleStatements.add(
+ js.statement('let # = require(#);', [i.libVar, js.string(i.name)]));
+ }
+ }
+
+ moduleStatements.addAll(normalItems);
+
+ if (_exports.isNotEmpty) {
+ moduleStatements.add(js.comment('Exports:'));
+ _exports.keys.forEach((name) => emitExport(name, moduleStatements));
}
- // TODO(ochafik): What to do of _jsModuleValue?
+ // TODO(ochafik): What to do of jsModuleValue?
return new JS.Program(moduleStatements);
}
}
@@ -155,4 +231,5 @@ class ES6ModuleBuilder extends ModuleBuilder {
// are generated from [JSCodegenVisitor], instead of composing them with
// [_statements]).
Iterable<JS.ModuleItem> _flattenBlocks(List<JS.ModuleItem> stats) =>
- stats.expand((item) => item is JS.Block ? item.statements : [item]);
+ stats.expand(
+ (item) => item is JS.Block ? _flattenBlocks(item.statements) : [item]);
« no previous file with comments | « lib/src/codegen/js_names.dart ('k') | lib/src/compiler.dart » ('j') | lib/src/compiler.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698