| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Top level generator object for writing code and keeping track of | 6 * Top level generator object for writing code and keeping track of |
| 7 * dependencies. | 7 * dependencies. |
| 8 * | 8 * |
| 9 * Should have two compilation models, but only one implemented so far. | 9 * Should have two compilation models, but only one implemented so far. |
| 10 * | 10 * |
| (...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 | 1797 |
| 1798 return target.invoke(this, name, position, _makeArgs(node.arguments)); | 1798 return target.invoke(this, name, position, _makeArgs(node.arguments)); |
| 1799 } | 1799 } |
| 1800 | 1800 |
| 1801 visitIndexExpression(IndexExpression node) { | 1801 visitIndexExpression(IndexExpression node) { |
| 1802 var target = visitValue(node.target); | 1802 var target = visitValue(node.target); |
| 1803 var index = visitValue(node.index); | 1803 var index = visitValue(node.index); |
| 1804 return target.invoke(this, ':index', node, new Arguments(null, [index])); | 1804 return target.invoke(this, ':index', node, new Arguments(null, [index])); |
| 1805 } | 1805 } |
| 1806 | 1806 |
| 1807 bool _expressionNeedsParens(Expression e) { |
| 1808 return (e is BinaryExpression || e is ConditionalExpression |
| 1809 || e is PostfixExpression || _isUnaryIncrement(e)); |
| 1810 } |
| 1811 |
| 1807 visitBinaryExpression(BinaryExpression node, [bool isVoid = false]) { | 1812 visitBinaryExpression(BinaryExpression node, [bool isVoid = false]) { |
| 1808 final kind = node.op.kind; | 1813 final kind = node.op.kind; |
| 1809 // TODO(jimhug): Ensure these have same semantics as JS! | 1814 // TODO(jimhug): Ensure these have same semantics as JS! |
| 1810 if (kind == TokenKind.AND || kind == TokenKind.OR) { | 1815 if (kind == TokenKind.AND || kind == TokenKind.OR) { |
| 1811 var x = visitTypedValue(node.x, world.nonNullBool); | 1816 var x = visitTypedValue(node.x, world.nonNullBool); |
| 1812 var y = visitTypedValue(node.y, world.nonNullBool); | 1817 var y = visitTypedValue(node.y, world.nonNullBool); |
| 1813 final code = '${x.code} ${node.op} ${y.code}'; | 1818 final code = '${x.code} ${node.op} ${y.code}'; |
| 1814 if (x.isConst && y.isConst) { | 1819 if (x.isConst && y.isConst) { |
| 1815 var value = (kind == TokenKind.AND) | 1820 var value = (kind == TokenKind.AND) |
| 1816 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue; | 1821 ? x.actualValue && y.actualValue : x.actualValue || y.actualValue; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 final y = visitValue(node.y); | 1868 final y = visitValue(node.y); |
| 1864 var name = TokenKind.binaryMethodName(node.op.kind); | 1869 var name = TokenKind.binaryMethodName(node.op.kind); |
| 1865 if (node.op.kind == TokenKind.NE) { | 1870 if (node.op.kind == TokenKind.NE) { |
| 1866 name = ':ne'; | 1871 name = ':ne'; |
| 1867 } | 1872 } |
| 1868 if (name == null) { | 1873 if (name == null) { |
| 1869 world.internalError('unimplemented binary op ${node.op}', node.span); | 1874 world.internalError('unimplemented binary op ${node.op}', node.span); |
| 1870 return; | 1875 return; |
| 1871 } | 1876 } |
| 1872 return x.invoke(this, name, node, new Arguments(null, [y])); | 1877 return x.invoke(this, name, node, new Arguments(null, [y])); |
| 1873 } else { | 1878 } else if ((assignKind != 0) && _expressionNeedsParens(node.y)) { |
| 1879 return _visitAssign(assignKind, node.x, |
| 1880 new ParenExpression(node.y, node.y.span), node, null, isVoid); |
| 1881 } else { |
| 1874 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid); | 1882 return _visitAssign(assignKind, node.x, node.y, node, null, isVoid); |
| 1875 } | 1883 } |
| 1876 } | 1884 } |
| 1877 | 1885 |
| 1878 /** | 1886 /** |
| 1879 * Visits an assignment expression. | 1887 * Visits an assignment expression. |
| 1880 * Note: captureOriginal can optionally capture the original value of the | 1888 * Note: captureOriginal can optionally capture the original value of the |
| 1881 * left side. This is used by postfix expressions to ensure they return the | 1889 * left side. This is used by postfix expressions to ensure they return the |
| 1882 * original value, before it has been modified. | 1890 * original value, before it has been modified. |
| 1883 */ | 1891 */ |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 if (node.value is List) { | 2389 if (node.value is List) { |
| 2382 var items = []; | 2390 var items = []; |
| 2383 for (var item in node.value) { | 2391 for (var item in node.value) { |
| 2384 var val = visitValue(item); | 2392 var val = visitValue(item); |
| 2385 val.invoke(this, 'toString', item, Arguments.EMPTY); | 2393 val.invoke(this, 'toString', item, Arguments.EMPTY); |
| 2386 | 2394 |
| 2387 // TODO(jimhug): Ensure this solves all precedence problems. | 2395 // TODO(jimhug): Ensure this solves all precedence problems. |
| 2388 // TODO(jmesserly): We could be smarter about prefix/postfix, but we'd | 2396 // TODO(jmesserly): We could be smarter about prefix/postfix, but we'd |
| 2389 // need to know if it will compile to a ++ or to some sort of += form. | 2397 // need to know if it will compile to a ++ or to some sort of += form. |
| 2390 var code = val.code; | 2398 var code = val.code; |
| 2391 if (item is BinaryExpression || item is ConditionalExpression | 2399 if (_expressionNeedsParens(item)) { |
| 2392 || item is PostfixExpression || _isUnaryIncrement(item)) { | |
| 2393 code = '(${code})'; | 2400 code = '(${code})'; |
| 2394 } | 2401 } |
| 2395 // No need to concat empty strings except the first. | 2402 // No need to concat empty strings except the first. |
| 2396 if (items.length == 0 || (code != "''" && code != '""')) { | 2403 if (items.length == 0 || (code != "''" && code != '""')) { |
| 2397 items.add(code); | 2404 items.add(code); |
| 2398 } | 2405 } |
| 2399 } | 2406 } |
| 2400 return new Value(type, '(${Strings.join(items, " + ")})', node.span); | 2407 return new Value(type, '(${Strings.join(items, " + ")})', node.span); |
| 2401 } | 2408 } |
| 2402 | 2409 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2538 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); | 2545 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); |
| 2539 } | 2546 } |
| 2540 for (int i = bareCount; i < length; i++) { | 2547 for (int i = bareCount; i < length; i++) { |
| 2541 var name = getName(i); | 2548 var name = getName(i); |
| 2542 if (name == null) name = '\$$i'; | 2549 if (name == null) name = '\$$i'; |
| 2543 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); | 2550 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); |
| 2544 } | 2551 } |
| 2545 return new Arguments(nodes, result); | 2552 return new Arguments(nodes, result); |
| 2546 } | 2553 } |
| 2547 } | 2554 } |
| OLD | NEW |