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

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

Issue 1147143007: fixes #206, add checking for unary ops (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: merged Created 5 years, 6 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/src/checker/checker.dart ('k') | test/checker/checker_test.dart » ('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, SplayTreeSet; 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet;
8 8
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator;
10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
(...skipping 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 if (expr is Conversion) { 1791 if (expr is Conversion) {
1792 return _isNonNullableExpression(expr.expression); 1792 return _isNonNullableExpression(expr.expression);
1793 } 1793 }
1794 if (expr is SimpleIdentifier) { 1794 if (expr is SimpleIdentifier) {
1795 // Type literals are not null. 1795 // Type literals are not null.
1796 Element e = expr.staticElement; 1796 Element e = expr.staticElement;
1797 if (e is ClassElement || e is FunctionTypeAliasElement) return true; 1797 if (e is ClassElement || e is FunctionTypeAliasElement) return true;
1798 } 1798 }
1799 DartType type = null; 1799 DartType type = null;
1800 if (expr is BinaryExpression) { 1800 if (expr is BinaryExpression) {
1801 switch (expr.operator.type) {
1802 case TokenType.EQ_EQ:
1803 case TokenType.BANG_EQ:
1804 case TokenType.AMPERSAND_AMPERSAND:
1805 case TokenType.BAR_BAR:
1806 return true;
1807 }
1801 type = getStaticType(expr.leftOperand); 1808 type = getStaticType(expr.leftOperand);
1802 } else if (expr is PrefixExpression) { 1809 } else if (expr is PrefixExpression) {
1810 if (expr.operator.type == TokenType.BANG) return true;
1803 type = getStaticType(expr.operand); 1811 type = getStaticType(expr.operand);
1804 } else if (expr is PostfixExpression) { 1812 } else if (expr is PostfixExpression) {
1805 type = getStaticType(expr.operand); 1813 type = getStaticType(expr.operand);
1806 } 1814 }
1807 if (type != null && _isJSBuiltinType(type)) { 1815 if (type != null && _isJSBuiltinType(type)) {
1808 return true; 1816 return true;
1809 } 1817 }
1810 if (expr is MethodInvocation) { 1818 if (expr is MethodInvocation) {
1811 // TODO(vsm): This logic overlaps with the resolver. 1819 // TODO(vsm): This logic overlaps with the resolver.
1812 // Where is the best place to put this? 1820 // Where is the best place to put this?
(...skipping 15 matching lines...) Expand all
1828 if (!types.split('|').contains('Null')) { 1836 if (!types.split('|').contains('Null')) {
1829 return true; 1837 return true;
1830 } 1838 }
1831 } 1839 }
1832 } 1840 }
1833 } 1841 }
1834 return false; 1842 return false;
1835 } 1843 }
1836 1844
1837 JS.Expression notNull(Expression expr) { 1845 JS.Expression notNull(Expression expr) {
1838 if (_isNonNullableExpression(expr)) { 1846 if (expr == null) return null;
1839 return _visit(expr); 1847 var jsExpr = _visit(expr);
1840 } else { 1848 if (_isNonNullableExpression(expr)) return jsExpr;
1841 return js.call('dart.notNull(#)', _visit(expr)); 1849 return js.call('dart.notNull(#)', jsExpr);
1842 }
1843 } 1850 }
1844 1851
1845 @override 1852 @override
1846 JS.Expression visitBinaryExpression(BinaryExpression node) { 1853 JS.Expression visitBinaryExpression(BinaryExpression node) {
1847 var op = node.operator; 1854 var op = node.operator;
1848 var left = node.leftOperand; 1855 var left = node.leftOperand;
1849 var right = node.rightOperand; 1856 var right = node.rightOperand;
1850 var leftType = getStaticType(left); 1857 var leftType = getStaticType(left);
1851 var rightType = getStaticType(right); 1858 var rightType = getStaticType(right);
1852 1859
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 /// Those two nodes are special because they're both allowed on left side of 2202 /// Those two nodes are special because they're both allowed on left side of
2196 /// an assignment expression and cascades. 2203 /// an assignment expression and cascades.
2197 Expression _getTarget(node) { 2204 Expression _getTarget(node) {
2198 assert(node is IndexExpression || node is PropertyAccess); 2205 assert(node is IndexExpression || node is PropertyAccess);
2199 return node.isCascaded ? _cascadeTarget : node.target; 2206 return node.isCascaded ? _cascadeTarget : node.target;
2200 } 2207 }
2201 2208
2202 @override 2209 @override
2203 visitConditionalExpression(ConditionalExpression node) { 2210 visitConditionalExpression(ConditionalExpression node) {
2204 return js.call('# ? # : #', [ 2211 return js.call('# ? # : #', [
2205 _visit(node.condition), 2212 notNull(node.condition),
2206 _visit(node.thenExpression), 2213 _visit(node.thenExpression),
2207 _visit(node.elseExpression) 2214 _visit(node.elseExpression)
2208 ]); 2215 ]);
2209 } 2216 }
2210 2217
2211 @override 2218 @override
2212 visitThrowExpression(ThrowExpression node) { 2219 visitThrowExpression(ThrowExpression node) {
2213 var expr = _visit(node.expression); 2220 var expr = _visit(node.expression);
2214 if (node.parent is ExpressionStatement) { 2221 if (node.parent is ExpressionStatement) {
2215 return js.statement('throw #;', expr); 2222 return js.statement('throw #;', expr);
2216 } else { 2223 } else {
2217 return js.call('dart.throw_(#)', expr); 2224 return js.call('dart.throw_(#)', expr);
2218 } 2225 }
2219 } 2226 }
2220 2227
2221 @override 2228 @override
2222 visitRethrowExpression(RethrowExpression node) { 2229 visitRethrowExpression(RethrowExpression node) {
2223 if (node.parent is ExpressionStatement) { 2230 if (node.parent is ExpressionStatement) {
2224 return js.statement('throw #;', _visit(_catchParameter)); 2231 return js.statement('throw #;', _visit(_catchParameter));
2225 } else { 2232 } else {
2226 return js.call('dart.throw_(#)', _visit(_catchParameter)); 2233 return js.call('dart.throw_(#)', _visit(_catchParameter));
2227 } 2234 }
2228 } 2235 }
2229 2236
2230 @override 2237 @override
2231 JS.If visitIfStatement(IfStatement node) { 2238 JS.If visitIfStatement(IfStatement node) {
2232 return new JS.If(_visit(node.condition), _visit(node.thenStatement), 2239 return new JS.If(notNull(node.condition), _visit(node.thenStatement),
2233 _visit(node.elseStatement)); 2240 _visit(node.elseStatement));
2234 } 2241 }
2235 2242
2236 @override 2243 @override
2237 JS.For visitForStatement(ForStatement node) { 2244 JS.For visitForStatement(ForStatement node) {
2238 var init = _visit(node.initialization); 2245 var init = _visit(node.initialization);
2239 if (init == null) init = _visit(node.variables); 2246 if (init == null) init = _visit(node.variables);
2240 var update = _visitListToBinary(node.updaters, ','); 2247 var update = _visitListToBinary(node.updaters, ',');
2241 if (update != null) update = update.toVoidExpression(); 2248 if (update != null) update = update.toVoidExpression();
2242 return new JS.For(init, _visit(node.condition), update, _visit(node.body)); 2249 return new JS.For(init, notNull(node.condition), update, _visit(node.body));
2243 } 2250 }
2244 2251
2245 @override 2252 @override
2246 JS.While visitWhileStatement(WhileStatement node) { 2253 JS.While visitWhileStatement(WhileStatement node) {
2247 return new JS.While(_visit(node.condition), _visit(node.body)); 2254 return new JS.While(notNull(node.condition), _visit(node.body));
2248 } 2255 }
2249 2256
2250 @override 2257 @override
2251 JS.Do visitDoStatement(DoStatement node) { 2258 JS.Do visitDoStatement(DoStatement node) {
2252 return new JS.Do(_visit(node.body), _visit(node.condition)); 2259 return new JS.Do(_visit(node.body), notNull(node.condition));
2253 } 2260 }
2254 2261
2255 @override 2262 @override
2256 JS.ForOf visitForEachStatement(ForEachStatement node) { 2263 JS.ForOf visitForEachStatement(ForEachStatement node) {
2257 var init = _visit(node.identifier); 2264 var init = _visit(node.identifier);
2258 if (init == null) { 2265 if (init == null) {
2259 init = js.call('let #', node.loopVariable.identifier.name); 2266 init = js.call('let #', node.loopVariable.identifier.name);
2260 } 2267 }
2261 return new JS.ForOf(init, _visit(node.iterable), _visit(node.body)); 2268 return new JS.ForOf(init, _visit(node.iterable), _visit(node.body));
2262 } 2269 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2551 /// Point(x, y) { 2558 /// Point(x, y) {
2552 /// this[_x] = x; 2559 /// this[_x] = x;
2553 /// this[_y] = y; 2560 /// this[_y] = y;
2554 /// } 2561 /// }
2555 /// get x() { return this[_x]; } 2562 /// get x() { return this[_x]; }
2556 /// get y() { return this[_y]; } 2563 /// get y() { return this[_y]; }
2557 /// } 2564 /// }
2558 /// 2565 ///
2559 /// For user-defined operators the following names are allowed: 2566 /// For user-defined operators the following names are allowed:
2560 /// 2567 ///
2561 /// <, >, <=, >=, ==, -, +, /, ˜/, *, %, |, ˆ, &, <<, >>, []=, [], ˜ 2568 /// <, >, <=, >=, ==, -, +, /, ~/, *, %, |, ^, &, <<, >>, []=, [], ~
2562 /// 2569 ///
2563 /// They generate code like: 2570 /// They generate code like:
2564 /// 2571 ///
2565 /// x['+'](y) 2572 /// x['+'](y)
2566 /// 2573 ///
2567 /// There are three exceptions: [], []= and unary -. 2574 /// There are three exceptions: [], []= and unary -.
2568 /// The indexing operators we use `get` and `set` instead: 2575 /// The indexing operators we use `get` and `set` instead:
2569 /// 2576 ///
2570 /// x.get('hi') 2577 /// x.get('hi')
2571 /// x.set('hi', 123) 2578 /// x.set('hi', 123)
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 2706
2700 /// A special kind of element created by the compiler, signifying a temporary 2707 /// A special kind of element created by the compiler, signifying a temporary
2701 /// variable. These objects use instance equality, and should be shared 2708 /// variable. These objects use instance equality, and should be shared
2702 /// everywhere in the tree where they are treated as the same variable. 2709 /// everywhere in the tree where they are treated as the same variable.
2703 class TemporaryVariableElement extends LocalVariableElementImpl { 2710 class TemporaryVariableElement extends LocalVariableElementImpl {
2704 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 2711 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2705 2712
2706 int get hashCode => identityHashCode(this); 2713 int get hashCode => identityHashCode(this);
2707 bool operator ==(Object other) => identical(this, other); 2714 bool operator ==(Object other) => identical(this, other);
2708 } 2715 }
OLDNEW
« no previous file with comments | « lib/src/checker/checker.dart ('k') | test/checker/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698