| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 062370e7ea52277cebcd586d6dfde0d03548ff8c..c87123fe86b906f4f16f8ee9f1be0fa7c0662f0a 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -1543,6 +1543,27 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
| }
|
| }
|
|
|
| + JS.Expression _assignableNotNull(Expression expr) {
|
| + if (expr is IndexExpression) {
|
| + IndexExpression i = expr;
|
| + return js.call(
|
| + 'dart.index(#, #).notNull', [_visit(i.target), _visit(i.index)]);
|
| + } else if (expr is PropertyAccess) {
|
| + PropertyAccess p = expr;
|
| + return js.call('dart.prop(#, #).notNull', [
|
| + _visit(p.target),
|
| + _emitMemberName(p.propertyName.name)
|
| + ]);
|
| + } else if (expr is PrefixedIdentifier) {
|
| + PrefixedIdentifier p = expr;
|
| + return js.call('dart.prop(#, #).notNull', [
|
| + _visit(p.prefix),
|
| + _emitMemberName(p.identifier.name)
|
| + ]);
|
| + }
|
| + return null;
|
| + }
|
| +
|
| @override
|
| JS.Expression visitBinaryExpression(BinaryExpression node) {
|
| var op = node.operator;
|
| @@ -1747,9 +1768,16 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
|
|
|
| var dispatchType = rules.getStaticType(expr);
|
| if (unaryOperationIsPrimitive(dispatchType)) {
|
| + JS.Expression lvalue;
|
| if (_isNonNullableExpression(expr)) {
|
| - return js.call('#$op', _visit(expr));
|
| + // TODO(jmesserly): ensure that expr is generated as a lvalue.
|
| + // I think this works today because if the result type is primitive,
|
| + // it can't be a dynamic call. But worth checking.
|
| + lvalue = _visit(expr);
|
| + } else {
|
| + lvalue = _assignableNotNull(expr);
|
| }
|
| + if (lvalue != null) return new JS.Postfix(op.lexeme, lvalue);
|
| }
|
|
|
| assert(op.lexeme == '++' || op.lexeme == '--');
|
|
|