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

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

Issue 1486473002: Convert dart_utils.js to input_sdk/lib/_internal/utils.dart (#310) (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Rebased Created 5 years 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_utils.js ('k') | lib/src/compiler.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 5e1b8a6ca2282f5a9905ca318051bd8d98e33889..9879bd42cd72f1e394626f7626358fdd7f062d68 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -37,6 +37,7 @@ import 'js_metalet.dart' as JS;
import 'js_module_item_order.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
@@ -50,6 +51,8 @@ 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;
@@ -104,6 +107,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
/// The default value of the module object. See [visitLibraryDirective].
String _jsModuleValue;
+ bool _isDartUtils;
+
Map<String, DartType> _objectMembers;
JSCodegenVisitor(AbstractCompiler compiler, this.rules, this.currentLibrary,
@@ -117,6 +122,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';
_objectMembers = getObjectMemberMap(types);
}
@@ -196,7 +202,19 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
list.add(js.string(compiler.getModuleName(library.source.uri), "'"));
};
- var imports = <JS.Expression>[js.string('dart/_runtime')];
+ var needsDartRuntime = !_isDartUtils;
+
+ var imports = <JS.Expression>[];
+ var moduleStatements = <JS.Statement>[];
+ if (needsDartRuntime) {
+ imports.add(js.string('dart/_runtime'));
+
+ 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);
@@ -210,11 +228,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
}
});
- var dartxImport =
- js.statement("let # = #.dartx;", [_dartxVar, _runtimeLibVar]);
-
- var module = js.call("function(#) { 'use strict'; #; #; }",
- [params, dartxImport, _moduleItems]);
+ var module =
+ js.call("function(#) { 'use strict'; #; }", [params, moduleStatements]);
var moduleDef = js.statement("dart_library.library(#, #, #, #, #)", [
js.string(jsPath, "'"),
@@ -289,7 +304,7 @@ 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]));
+ _moduleItems.add(js.statement('dart.export_(#);', [args]));
}
JS.Identifier _initSymbol(JS.Identifier id) {
@@ -1285,17 +1300,69 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
var name = 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, _visit(node.functionExpression)),
- node.element));
- body.add(_emitFunctionTagged(id, node.element.type, topLevel: true)
- .toStatement());
+ body.add(annotate(new JS.FunctionDeclaration(id, fn), node.element));
+ if (needsTagging) {
+ body.add(_emitFunctionTagged(id, node.element.type, topLevel: true)
+ .toStatement());
+ }
if (isPublic(name)) _addExport(name);
return _statement(body);
}
+ bool _isInlineJSFunction(FunctionExpression functionExpression) {
+ bool isJsInvocation(Expression expr) =>
+ expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
+
+ var body = functionExpression.body;
+ if (body is ExpressionFunctionBody) {
+ return isJsInvocation(body.expression);
+ } else if (body is BlockFunctionBody) {
+ if (body.block.statements.length == 1) {
+ var stat = body.block.statements.single;
+ if (stat is ReturnStatement) {
+ return isJsInvocation(stat.expression);
+ }
+ }
+ }
+ return false;
+ }
+
+ // 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).
+ 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);
+ JS.ArrowFun innerFun = call.target;
+ if (_listEquality.equals(getIdents(innerFun.params), passedArgs)) {
+ return new JS.Fun(fn.params, innerFun.body);
+ }
+ }
+ }
+ }
+ return fn;
+ }
+
JS.Method _emitTopLevelProperty(FunctionDeclaration node) {
var name = node.name.name;
return annotate(
« no previous file with comments | « lib/runtime/dart_utils.js ('k') | lib/src/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698