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

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

Issue 1530563003: Generate all runtime files from dart. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: simplify diff in js_codegen.dart 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
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_interop.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/js_codegen.dart
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index 2f0a0b8ed3b5ef0fa9fb31d0fa4e8b78a07797da..a8f649b725738cee148b6a19ca8fa3e656c84062 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -39,7 +39,6 @@ import 'js_module_item_order.dart';
import 'js_names.dart';
import 'js_printer.dart' show writeJsLibrary;
import 'side_effect_analysis.dart';
-import 'package:collection/equality.dart';
// Various dynamic helpers we call.
// If renaming these, make sure to check other places like the
@@ -53,8 +52,6 @@ const DSETINDEX = 'dsetindex';
const DCALL = 'dcall';
const DSEND = 'dsend';
-const ListEquality _listEquality = const ListEquality();
-
class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
final AbstractCompiler compiler;
final CodegenOptions options;
@@ -109,7 +106,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
/// The default value of the module object. See [visitLibraryDirective].
String _jsModuleValue;
- bool _isDartUtils;
+ bool _isDartRuntime;
JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
this._extensionTypes, this._fieldsNeedingStorage)
@@ -122,7 +119,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
var src = context.sourceFactory.forUri('dart:_interceptors');
var interceptors = context.computeLibraryElement(src);
_jsArray = interceptors.getType('JSArray');
- _isDartUtils = currentLibrary.source.uri.toString() == 'dart:_utils';
+ _isDartRuntime = currentLibrary.source.uri.toString() == 'dart:_runtime';
}
TypeProvider get types => _types;
@@ -193,38 +190,33 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
// 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, _runtimeLibVar];
- var processImport =
- (LibraryElement library, JS.TemporaryId temp, List list) {
- params.add(temp);
- list.add(js.string(compiler.getModuleName(library.source.uri), "'"));
- };
-
- var needsDartRuntime = !_isDartUtils;
+ var params = [_exportsVar];
+ var lazyParams = [];
var imports = <JS.Expression>[];
+ var lazyImports = <JS.Expression>[];
var moduleStatements = <JS.Statement>[];
- if (needsDartRuntime) {
- imports.add(js.string('dart/_runtime'));
+
+ addImport(String name, JS.Expression libVar, {bool lazy: false}) {
+ (lazy ? lazyImports : imports).add(js.string(name, "'"));
+ (lazy ? lazyParams : params).add(libVar);
+ }
+
+ if (!_isDartRuntime) {
+ addImport('dart/_runtime', _runtimeLibVar);
var dartxImport =
js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]);
moduleStatements.add(dartxImport);
}
- moduleStatements.addAll(_moduleItems);
-
- _imports.forEach((library, temp) {
- if (_loader.libraryIsLoaded(library)) {
- processImport(library, temp, imports);
- }
+ _imports.forEach((LibraryElement lib, JS.TemporaryId temp) {
+ addImport(compiler.getModuleName(lib.source.uri), temp,
+ lazy: _isDartRuntime || !_loader.libraryIsLoaded(lib));
});
+ params.addAll(lazyParams);
+
+ moduleStatements.addAll(_moduleItems);
- var lazyImports = <JS.Expression>[];
- _imports.forEach((library, temp) {
- if (!_loader.libraryIsLoaded(library)) {
- processImport(library, temp, lazyImports);
- }
- });
var module =
js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]);
@@ -302,7 +294,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
args.add(new JS.ArrayInitializer(shownNames));
args.add(new JS.ArrayInitializer(hiddenNames));
}
- _moduleItems.add(js.statement('dart.export_(#);', [args]));
+
+ // When we compile _runtime.js, we need to source export_ from _utils.js:
+ _moduleItems.add(js.statement('dart.export(#);', [args]));
}
JS.Identifier _initSymbol(JS.Identifier id) {
@@ -1298,7 +1292,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
/// the SDK), or `null` if there's none. This is used to control the name
/// under which functions are compiled and exported.
String _getJSExportName(Element e) {
- if (e is! FunctionElement || !currentLibrary.source.isInSystemLibrary) {
+ if (!currentLibrary.source.isInSystemLibrary) {
return null;
}
var jsName = findAnnotation(e, isJSExportNameAnnotation);
@@ -1323,17 +1317,15 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
var name = _getJSExportName(node.element) ?? node.name.name;
var fn = _visit(node.functionExpression);
- bool needsTagging = true;
if (currentLibrary.source.isInSystemLibrary &&
_isInlineJSFunction(node.functionExpression)) {
fn = _simplifyPassThroughArrowFunCallBody(fn);
- needsTagging = !_isDartUtils;
}
var id = new JS.Identifier(name);
body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element));
- if (needsTagging) {
+ if (!_isDartRuntime) {
body.add(_emitFunctionTagged(id, node.element.type, topLevel: true)
.toStatement());
}
@@ -1360,23 +1352,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
bool _isJSInvocation(Expression expr) =>
expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
- // Simplify `(args) => ((x, y) => { ... })(x, y)` to `(args) => { ... }`.
- // Note: we don't check if the top-level args match the ones passed through
- // the arrow function, which allows silently passing args through to the
- // body (which only works if we don't do weird renamings of Dart params).
+ // Simplify `(args) => (() => { ... })()` to `(args) => { ... }`.
+ // Note: this allows silently passing args through to the body, which only
+ // works if we don't do weird renamings of Dart params.
JS.Fun _simplifyPassThroughArrowFunCallBody(JS.Fun fn) {
- String getIdent(JS.Node node) => node is JS.Identifier ? node.name : null;
- List<String> getIdents(List params) =>
- params.map(getIdent).toList(growable: false);
-
if (fn.body is JS.Block && fn.body.statements.length == 1) {
var stat = fn.body.statements.single;
if (stat is JS.Return && stat.value is JS.Call) {
JS.Call call = stat.value;
- if (call.target is JS.ArrowFun) {
- var passedArgs = getIdents(call.arguments);
+ if (call.target is JS.ArrowFun && call.arguments.isEmpty) {
JS.ArrowFun innerFun = call.target;
- if (_listEquality.equals(getIdents(innerFun.params), passedArgs)) {
+ if (innerFun.params.isEmpty) {
return new JS.Fun(fn.params, innerFun.body);
}
}
@@ -1911,11 +1897,35 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
new JS.Block(_visitList(node.statements) as List<JS.Statement>,
isScope: true);
+ /// Return the type constructor `_foolib.Bar$` given `Bar` from lib `_foolib`.
+ ///
+ /// This implements / expands the `genericTypeConstructor` intrinsic defined
+ /// in `foreign_helper.dart`:
+ /// `JS('', '#(type)', genericTypeConstructor(List))` will generate
+ /// `core.List$(type)`.
+ JS.Expression _emitGenericTypeConstructor(Expression typeExpression) {
Jennifer Messerly 2016/01/20 23:44:58 we chatted about moving this hack into the generat
ochafik 2016/01/21 00:11:35 So actually, JS('', '$Future\$($type)') is just JS
+ var ref = _visit(typeExpression);
+ if (ref is JS.PropertyAccess) {
+ var name = (ref.selector as JS.LiteralString).valueWithoutQuotes;
+ return new JS.PropertyAccess(
+ ref.receiver, new JS.LiteralString("'$name\$'"));
+ } else if (ref is JS.MaybeQualifiedId) {
+ var name = (ref.name as JS.Identifier).name;
+ return new JS.PropertyAccess(ref.qualifier, new JS.Identifier('$name\$'));
+ } else {
+ throw new ArgumentError('Invalid type ref: $ref (${ref?.runtimeType})');
+ }
+ }
+
@override
visitMethodInvocation(MethodInvocation node) {
if (node.operator != null && node.operator.lexeme == '?.') {
return _emitNullSafe(node);
}
+ if (isGenericTypeConstructorIntrinsic(node)) {
+ assert(currentLibrary.source.isInSystemLibrary);
+ return _emitGenericTypeConstructor(node.argumentList.arguments.single);
+ }
var target = _getTarget(node);
var result = _emitForeignJS(node);
@@ -3461,6 +3471,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
/// declaration) as it doesn't have any meaningful rules enforced.
JS.Identifier _libraryName(LibraryElement library) {
if (library == currentLibrary) return _exportsVar;
+ if (library.name == 'dart._runtime') return _runtimeLibVar;
return _imports.putIfAbsent(
library, () => new JS.TemporaryId(jsLibraryName(library)));
}
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_interop.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698