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

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

Issue 1736723002: more function refactoring (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | test/codegen/expect/language-all.js » ('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 e365f91060c3acf128389091de8651711455e9ed..cc3c0a558c3819eb9255299ccc46610bc1f260e4 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -1469,8 +1469,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
_flushLibraryProperties(body);
var name = node.name.name;
-
- var fn = _visit(node.functionExpression);
+ var fn = _emitFunction(node.functionExpression);
if (currentLibrary.source.isInSystemLibrary &&
_isInlineJSFunction(node.functionExpression)) {
@@ -1531,7 +1530,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
JS.Method _emitTopLevelProperty(FunctionDeclaration node) {
var name = node.name.name;
return annotate(
- new JS.Method(_propertyName(name), _visit(node.functionExpression),
+ new JS.Method(
+ _propertyName(name), _emitFunction(node.functionExpression),
isGetter: node.isGetter, isSetter: node.isSetter),
node,
node.element);
@@ -1559,7 +1559,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
return _loader.isLoaded(type.element);
}
- JS.Expression _emitFunctionTagged(JS.Expression clos, DartType type,
+ JS.Expression _emitFunctionTagged(JS.Expression fn, DartType type,
{topLevel: false}) {
var name = type.name;
var lazy = topLevel && !_typeIsLoaded(type);
@@ -1569,64 +1569,76 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
type.optionalParameterTypes.isEmpty &&
type.namedParameterTypes.isEmpty &&
type.normalParameterTypes.every((t) => t.isDynamic)) {
- return js.call('dart.fn(#)', [clos]);
+ return js.call('dart.fn(#)', [fn]);
}
if (lazy) {
- return js.call('dart.fn(#, () => #)', [clos, _emitFunctionRTTI(type)]);
+ return js.call('dart.fn(#, () => #)', [fn, _emitFunctionRTTI(type)]);
}
- return js.call('dart.fn(#, #)', [clos, _emitFunctionTypeParts(type)]);
+ return js.call('dart.fn(#, #)', [fn, _emitFunctionTypeParts(type)]);
}
throw 'Function has non function type: $type';
}
+ /// Emits an arrow FunctionExpression node.
+ ///
+ /// This should be used for all places in Dart's AST where FunctionExpression
+ /// appears and the function is actually in an Expression context. These
+ /// correspond to arrow functions in Dart.
+ ///
+ /// Contrast with [_emitFunction].
@override
JS.Expression visitFunctionExpression(FunctionExpression node) {
- var params = visitFormalParameterList(node.parameters);
+ assert(node.parent is! FunctionDeclaration &&
+ node.parent is! MethodDeclaration);
+ return _emitFunctionTagged(_emitArrowFunction(node), getStaticType(node),
+ topLevel: _executesAtTopLevel(node));
+ }
- var body = node.body;
- var parent = node.parent;
- var inStmt = parent.parent is FunctionDeclarationStatement;
- if (parent is FunctionDeclaration) {
- return _emitFunctionBody(node.element, node.parameters, body);
- }
+ JS.ArrowFun _emitArrowFunction(FunctionExpression node) {
+ List<JS.Parameter> params;
+ var body = node.body;
JS.Node jsBody;
if (body.isGenerator || body.isAsynchronous) {
+ params = visitFormalParameterList(node.parameters, destructure: false);
jsBody = _emitGeneratorFunctionBody(node.element, node.parameters, body);
- } else if (body is ExpressionFunctionBody) {
- jsBody = _visit(body.expression);
- } else {
- jsBody = _visit(body);
- }
-
- var type = node.element.type;
- var typeFormals = _emitTypeFormals(type.typeFormals);
- var returnType = emitTypeRef(type.returnType);
-
- JS.FunctionExpression fn;
- if (node.parameters.parameters
- .every((p) => p.kind != ParameterKind.NAMED)) {
- fn = new JS.ArrowFun(params, jsBody,
- typeParams: typeFormals, returnType: returnType);
} else {
// Chrome Canary does not accept default values with destructuring in
// arrow functions yet (e.g. `({a} = {}) => 1`) but happily accepts them
// with regular functions (e.g. `function({a} = {}) { return 1 }`).
// Note that Firefox accepts both syntaxes just fine.
// TODO(ochafik): Simplify this code when Chrome Canary catches up.
+ bool hasNamedParams =
+ node.parameters.parameters.any((p) => p.kind == ParameterKind.NAMED);
+
+ params = visitFormalParameterList(node.parameters,
+ destructure: !hasNamedParams);
- if (jsBody is JS.Expression) {
- jsBody = js.statement("{ return #; }", [jsBody]);
+ if (body is ExpressionFunctionBody) {
+ // An arrow function can use the expression directly.
+ jsBody = _visit(body.expression);
+ } else {
+ jsBody = _visit(body);
}
- fn = new JS.Fun(params, jsBody,
- typeParams: typeFormals, returnType: returnType);
}
- if (!inStmt) {
- var type = getStaticType(node);
- return _emitFunctionTagged(fn, type, topLevel: _executesAtTopLevel(node));
- }
- return fn;
+ var type = node.element.type;
+ var fn = new JS.ArrowFun(params, jsBody,
+ typeParams: _emitTypeFormals(type.typeFormals),
+ returnType: emitTypeRef(type.returnType));
+ return annotate(fn, node);
+ }
+
+ /// Emits a non-arrow FunctionExpression node.
+ ///
+ /// This should be used for all places in Dart's AST where FunctionExpression
+ /// appears but the function is not actually in an Expression context, such
+ /// as methods, properties, and top-level functions.
+ ///
+ /// Contrast with [visitFunctionExpression].
+ JS.Fun _emitFunction(FunctionExpression node) {
+ var fn = _emitFunctionBody(node.element, node.parameters, node.body);
+ return annotate(fn, node);
}
JS.Fun _emitFunctionBody(ExecutableElement element,
@@ -1717,7 +1729,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
return js.comment('Unimplemented function get/set statement: $node');
}
- var fn = _visit(func.functionExpression);
+ var fn = _emitFunction(func.functionExpression);
var name = new JS.Identifier(func.name.name);
JS.Statement declareFn;
@@ -3499,7 +3511,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
// TODO(jmesserly): this will need to be a generic method, if we ever want to
// self-host strong mode.
vsm 2016/02/25 00:48:04 Probably don't need the TODO anymore. :-)
Jennifer Messerly 2016/02/25 00:53:45 Yup! Have this fixed in a follow up CL I'm working
- List/*<T>*/ _visitList/*<T>*/(Iterable<AstNode> nodes) {
+ List /*<T>*/ _visitList /*<T>*/ (Iterable<AstNode> nodes) {
if (nodes == null) return null;
var result = /*<T>*/ [];
for (var node in nodes) result.add(_visit(node));
« no previous file with comments | « no previous file | test/codegen/expect/language-all.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698