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

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

Issue 961513002: Flesh out dynamic invocation code (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Streamline ++ and -- in fallback case Created 5 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 | « lib/src/codegen/ast_builder.dart ('k') | test/codegen/expect/dart/_interceptors.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 cadeb9090c0f1e429e6bb906ea58913be5bbd7f2..18db8d5ff641723f2de07e1662e76f9b91e86ea9 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -18,6 +18,8 @@ import 'package:source_maps/source_maps.dart' show SourceMapSpan;
import 'package:source_span/source_span.dart' show SourceLocation;
import 'package:path/path.dart' as path;
+import 'package:dev_compiler/src/codegen/ast_builder.dart' show AstBuilder;
+
// TODO(jmesserly): import from its own package
import 'package:dev_compiler/src/js/js_ast.dart' as JS;
import 'package:dev_compiler/src/js/js_ast.dart' show js;
@@ -698,10 +700,27 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
return result;
}
+ JS.Node _emitDPutIfDynamic(
+ Expression target, SimpleIdentifier id, Expression rhs) {
+ if (rules.isDynamicTarget(target)) {
+ return js.call('dart.dput(#, #, #)', [
+ _visit(target),
+ js.string(id.name, "'"),
+ _visit(rhs)
+ ]);
+ } else {
+ return null;
+ }
+ }
+
@override
JS.Node visitAssignmentExpression(AssignmentExpression node) {
var lhs = node.leftHandSide;
var rhs = node.rightHandSide;
+ return _emitAssignment(lhs, rhs, node.parent);
+ }
+
+ JS.Node _emitAssignment(Expression lhs, Expression rhs, [AstNode parent]) {
if (lhs is IndexExpression) {
String code;
var target = _getTarget(lhs);
@@ -714,17 +733,15 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
}
if (lhs is PropertyAccess) {
- var target = _getTarget(lhs);
- if (rules.isDynamicTarget(target)) {
- return js.call('dart.dput(#, #, #)', [
- _visit(target),
- js.string(lhs.propertyName.name, "'"),
- _visit(rhs)
- ]);
- }
+ var result = _emitDPutIfDynamic(_getTarget(lhs), lhs.propertyName, rhs);
+ if (result != null) return result;
+ } else if (lhs is PrefixedIdentifier) {
+ // TODO(vsm): Is this the right code if the prefix is a library?
+ var result = _emitDPutIfDynamic(lhs.prefix, lhs.identifier, rhs);
+ if (result != null) return result;
}
- if (node.parent is ExpressionStatement &&
+ if (parent is ExpressionStatement &&
rhs is CascadeExpression &&
_isStateless(lhs, rhs)) {
// Special case: cascade assignment to a variable in a statement.
@@ -1169,6 +1186,32 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
bool _isNull(Expression expr) => expr is NullLiteral;
+ // TODO(jmesserly, vsm): Refactor this logic.
+ SimpleIdentifier _createTemporary(String name, DartType type) {
+ var id =
+ new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, 0));
+ id.staticElement = new LocalVariableElementImpl.forNode(id);
+ id.staticType = type;
+ return id;
+ }
+
+ JS.Expression _emitPostfixIncrement(Expression expr, Token op) {
+ var tmp = _createTemporary('\$tmp', rules.getStaticType(expr));
+
+ // Increment and write
+ var one = AstBuilder.integerLiteral(1);
+ var increment = AstBuilder.binaryExpression(tmp, op.lexeme[0], one);
+ var write = _emitAssignment(expr, increment);
+
+ var bindThis = _maybeBindThis(expr);
+ return js.call("((#) => (#, #))$bindThis(#)", [
+ tmp.name,
+ write,
+ _visit(tmp),
+ _visit(expr)
+ ]);
+ }
+
@override
JS.Expression visitPostfixExpression(PostfixExpression node) {
var op = node.operator;
@@ -1179,11 +1222,17 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
// TODO(vsm): When do Dart ops not map to JS?
return js.call('#$op', notNull(expr));
} else {
- // TODO(vsm): Figure out operator calling convention / dispatch.
- return visitExpression(node);
+ assert(op.lexeme == '++' || op.lexeme == '--');
+ return _emitPostfixIncrement(expr, op);
}
}
+ JS.Expression _emitPrefixIncrement(Token op, Expression expr) {
+ var one = AstBuilder.integerLiteral(1);
+ var increment = AstBuilder.binaryExpression(expr, op.lexeme[0], one);
+ return _emitAssignment(expr, increment);
+ }
+
@override
JS.Expression visitPrefixExpression(PrefixExpression node) {
var op = node.operator;
@@ -1194,8 +1243,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
// TODO(vsm): When do Dart ops not map to JS?
return js.call('$op#', notNull(expr));
} else {
- // TODO(vsm): Figure out operator calling convention / dispatch.
- return visitExpression(node);
+ // Increment or decrement requires expansion
+ if (op.lexeme == '++' || op.lexeme == '--') {
+ return _emitPrefixIncrement(op, expr);
+ }
+ }
+
+ // Call the operator
+ var opString = _jsMemberName(op.lexeme, unary: true);
+ if (rules.isDynamicTarget(expr)) {
+ // dynamic dispatch
+ return js.call('dart.dunary(#, #)', [opString, _visit(expr)]);
+ } else if (_isJSBuiltinType(dispatchType)) {
+ return js.call(
+ '#.#(#)', [_emitTypeName(dispatchType), opString, _visit(expr)]);
+ } else {
+ // Generic static-dispatch, user-defined operator code path.
+ return js.call('#.#()', [_visit(expr), opString]);
}
}
« no previous file with comments | « lib/src/codegen/ast_builder.dart ('k') | test/codegen/expect/dart/_interceptors.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698