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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1047023002: use == and != to enable handling null/undefined (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 8 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 unified diff | Download patch
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | test/codegen/expect/BenchmarkBase.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dev_compiler.src.codegen.js_codegen; 5 library dev_compiler.src.codegen.js_codegen;
6 6
7 import 'dart:collection' show HashSet, HashMap; 7 import 'dart:collection' show HashSet, HashMap;
8 import 'dart:io' show Directory, File; 8 import 'dart:io' show Directory, File;
9 9
10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 10 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
(...skipping 1429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 JS.Expression visitBinaryExpression(BinaryExpression node) { 1440 JS.Expression visitBinaryExpression(BinaryExpression node) {
1441 var op = node.operator; 1441 var op = node.operator;
1442 var left = node.leftOperand; 1442 var left = node.leftOperand;
1443 var right = node.rightOperand; 1443 var right = node.rightOperand;
1444 var leftType = rules.getStaticType(left); 1444 var leftType = rules.getStaticType(left);
1445 var rightType = rules.getStaticType(right); 1445 var rightType = rules.getStaticType(right);
1446 1446
1447 var code; 1447 var code;
1448 if (op.type.isEqualityOperator) { 1448 if (op.type.isEqualityOperator) {
1449 // If we statically know LHS or RHS is null we can generate a clean check. 1449 // If we statically know LHS or RHS is null we can generate a clean check.
1450 // We can also do this if the left hand side is a primitive type, because 1450 // We can also do this if both sides are the same primitive type.
1451 // we know then it doesn't have an overridden. 1451 if (_canUsePrimitiveEquality(left, right)) {
1452 if (_isNull(left) || _isNull(right) || typeIsPrimitiveInJS(leftType)) { 1452 code = op.type == TokenType.EQ_EQ ? '# == #' : '# != #';
1453 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-strict-equa lity-comparison
1454 code = op.type == TokenType.EQ_EQ ? '# === #' : '# !== #';
1455 } else { 1453 } else {
1456 var bang = op.type == TokenType.BANG_EQ ? '!' : ''; 1454 var bang = op.type == TokenType.BANG_EQ ? '!' : '';
1457 code = '${bang}dart.equals(#, #)'; 1455 code = '${bang}dart.equals(#, #)';
1458 } 1456 }
1459 return js.call(code, [_visit(left), _visit(right)]); 1457 return js.call(code, [_visit(left), _visit(right)]);
1460 } else if (binaryOperationIsPrimitive(leftType, rightType)) { 1458 } else if (binaryOperationIsPrimitive(leftType, rightType)) {
1461 // special cases where we inline the operation 1459 // special cases where we inline the operation
1462 // these values are assumed to be non-null (determined by the checker) 1460 // these values are assumed to be non-null (determined by the checker)
1463 // TODO(jmesserly): it would be nice to just inline the method from core, 1461 // TODO(jmesserly): it would be nice to just inline the method from core,
1464 // instead of special cases here. 1462 // instead of special cases here.
(...skipping 28 matching lines...) Expand all
1493 _visit(left), 1491 _visit(left),
1494 _visit(right) 1492 _visit(right)
1495 ]); 1493 ]);
1496 } else { 1494 } else {
1497 // Generic static-dispatch, user-defined operator code path. 1495 // Generic static-dispatch, user-defined operator code path.
1498 return js.call('#.#(#)', [_visit(left), opString, _visit(right)]); 1496 return js.call('#.#(#)', [_visit(left), opString, _visit(right)]);
1499 } 1497 }
1500 } 1498 }
1501 } 1499 }
1502 1500
1501 /// If the type [t] is [int] or [double], returns [num].
1502 /// Otherwise returns [t].
1503 DartType _canonicalizeNumTypes(DartType t) {
1504 var numType = rules.provider.numType;
1505 if (t is InterfaceType && t.superclass == numType) return numType;
1506 return t;
1507 }
1508
1509 bool _canUsePrimitiveEquality(Expression left, Expression right) {
1510 if (_isNull(left) || _isNull(right)) return true;
1511
1512 var leftType = _canonicalizeNumTypes(rules.getStaticType(left));
1513 var rightType = _canonicalizeNumTypes(rules.getStaticType(right));
1514 return _isJSBuiltinType(leftType) && leftType == rightType;
1515 }
1516
1503 bool _isNull(Expression expr) => expr is NullLiteral; 1517 bool _isNull(Expression expr) => expr is NullLiteral;
1504 1518
1505 // TODO(jmesserly, vsm): Refactor this logic. 1519 // TODO(jmesserly, vsm): Refactor this logic.
1506 SimpleIdentifier _createTemporary(String name, DartType type) { 1520 SimpleIdentifier _createTemporary(String name, DartType type) {
1507 // We use an invalid source location to signal that this is a temporary. 1521 // We use an invalid source location to signal that this is a temporary.
1508 // See [_isTemporary]. 1522 // See [_isTemporary].
1509 // TODO(jmesserly): alternatives are 1523 // TODO(jmesserly): alternatives are
1510 // * (ab)use Element.isSynthetic, which isn't currently used for 1524 // * (ab)use Element.isSynthetic, which isn't currently used for
1511 // LocalVariableElementImpl, so we could repurpose to mean "temp". 1525 // LocalVariableElementImpl, so we could repurpose to mean "temp".
1512 // * add a new property to LocalVariableElementImpl. 1526 // * add a new property to LocalVariableElementImpl.
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
2353 2367
2354 // TODO(jmesserly): in many cases marking the end will be unncessary. 2368 // TODO(jmesserly): in many cases marking the end will be unncessary.
2355 printer.mark(_location(node.end)); 2369 printer.mark(_location(node.end));
2356 } 2370 }
2357 2371
2358 String _getIdentifier(AstNode node) { 2372 String _getIdentifier(AstNode node) {
2359 if (node is SimpleIdentifier) return node.name; 2373 if (node is SimpleIdentifier) return node.name;
2360 return null; 2374 return null;
2361 } 2375 }
2362 } 2376 }
OLDNEW
« no previous file with comments | « lib/runtime/dart_runtime.js ('k') | test/codegen/expect/BenchmarkBase.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698