| OLD | NEW |
| 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 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1767 @override | 1767 @override |
| 1768 JS.Block visitBlockFunctionBody(BlockFunctionBody node) { | 1768 JS.Block visitBlockFunctionBody(BlockFunctionBody node) { |
| 1769 var initArgs = _emitArgumentInitializers(node.parent); | 1769 var initArgs = _emitArgumentInitializers(node.parent); |
| 1770 var block = visitBlock(node.block); | 1770 var block = visitBlock(node.block); |
| 1771 if (initArgs != null) return new JS.Block([initArgs, block]); | 1771 if (initArgs != null) return new JS.Block([initArgs, block]); |
| 1772 return block; | 1772 return block; |
| 1773 } | 1773 } |
| 1774 | 1774 |
| 1775 @override | 1775 @override |
| 1776 JS.Block visitBlock(Block node) => | 1776 JS.Block visitBlock(Block node) => |
| 1777 new JS.Block(_visitList(node.statements) as List<JS.Statement>); | 1777 new JS.Block(_visitList(node.statements) as List<JS.Statement>, |
| 1778 isScope: true); |
| 1778 | 1779 |
| 1779 @override | 1780 @override |
| 1780 visitMethodInvocation(MethodInvocation node) { | 1781 visitMethodInvocation(MethodInvocation node) { |
| 1781 if (node.operator != null && node.operator.lexeme == '?.') { | 1782 if (node.operator != null && node.operator.lexeme == '?.') { |
| 1782 return _emitNullSafe(node); | 1783 return _emitNullSafe(node); |
| 1783 } | 1784 } |
| 1784 | 1785 |
| 1785 var target = _getTarget(node); | 1786 var target = _getTarget(node); |
| 1786 var result = _emitForeignJS(node); | 1787 var result = _emitForeignJS(node); |
| 1787 if (result != null) return result; | 1788 if (result != null) return result; |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2726 | 2727 |
| 2727 @override | 2728 @override |
| 2728 visitRethrowExpression(RethrowExpression node) { | 2729 visitRethrowExpression(RethrowExpression node) { |
| 2729 if (node.parent is ExpressionStatement) { | 2730 if (node.parent is ExpressionStatement) { |
| 2730 return js.statement('throw #;', _visit(_catchParameter)); | 2731 return js.statement('throw #;', _visit(_catchParameter)); |
| 2731 } else { | 2732 } else { |
| 2732 return js.call('throw #', _visit(_catchParameter)); | 2733 return js.call('throw #', _visit(_catchParameter)); |
| 2733 } | 2734 } |
| 2734 } | 2735 } |
| 2735 | 2736 |
| 2737 /// Visits a statement, and ensures the resulting AST handles block scope |
| 2738 /// correctly. Essentially, we need to promote a variable declaration |
| 2739 /// statement into a block in some cases, e.g. |
| 2740 /// |
| 2741 /// do var x = 5; while (false); // Dart |
| 2742 /// do { let x = 5; } while (false); // JS |
| 2743 JS.Statement _visitScope(Statement stmt) { |
| 2744 var result = _visit(stmt); |
| 2745 if (result is JS.ExpressionStatement && |
| 2746 result.expression is JS.VariableDeclarationList) { |
| 2747 return new JS.Block([result]); |
| 2748 } |
| 2749 return result; |
| 2750 } |
| 2751 |
| 2736 @override | 2752 @override |
| 2737 JS.If visitIfStatement(IfStatement node) { | 2753 JS.If visitIfStatement(IfStatement node) { |
| 2738 return new JS.If(notNull(node.condition), _visit(node.thenStatement), | 2754 return new JS.If(notNull(node.condition), _visitScope(node.thenStatement), |
| 2739 _visit(node.elseStatement)); | 2755 _visitScope(node.elseStatement)); |
| 2740 } | 2756 } |
| 2741 | 2757 |
| 2742 @override | 2758 @override |
| 2743 JS.For visitForStatement(ForStatement node) { | 2759 JS.For visitForStatement(ForStatement node) { |
| 2744 var init = _visit(node.initialization); | 2760 var init = _visit(node.initialization); |
| 2745 if (init == null) init = _visit(node.variables); | 2761 if (init == null) init = _visit(node.variables); |
| 2746 var update = _visitListToBinary(node.updaters, ','); | 2762 var update = _visitListToBinary(node.updaters, ','); |
| 2747 if (update != null) update = update.toVoidExpression(); | 2763 if (update != null) update = update.toVoidExpression(); |
| 2748 return new JS.For(init, notNull(node.condition), update, _visit(node.body)); | 2764 return new JS.For( |
| 2765 init, notNull(node.condition), update, _visitScope(node.body)); |
| 2749 } | 2766 } |
| 2750 | 2767 |
| 2751 @override | 2768 @override |
| 2752 JS.While visitWhileStatement(WhileStatement node) { | 2769 JS.While visitWhileStatement(WhileStatement node) { |
| 2753 return new JS.While(notNull(node.condition), _visit(node.body)); | 2770 return new JS.While(notNull(node.condition), _visitScope(node.body)); |
| 2754 } | 2771 } |
| 2755 | 2772 |
| 2756 @override | 2773 @override |
| 2757 JS.Do visitDoStatement(DoStatement node) { | 2774 JS.Do visitDoStatement(DoStatement node) { |
| 2758 return new JS.Do(_visit(node.body), notNull(node.condition)); | 2775 return new JS.Do(_visitScope(node.body), notNull(node.condition)); |
| 2759 } | 2776 } |
| 2760 | 2777 |
| 2761 @override | 2778 @override |
| 2762 JS.Statement visitForEachStatement(ForEachStatement node) { | 2779 JS.Statement visitForEachStatement(ForEachStatement node) { |
| 2763 if (node.awaitKeyword != null) { | 2780 if (node.awaitKeyword != null) { |
| 2764 return _emitAwaitFor(node); | 2781 return _emitAwaitFor(node); |
| 2765 } | 2782 } |
| 2766 | 2783 |
| 2767 var init = _visit(node.identifier); | 2784 var init = _visit(node.identifier); |
| 2768 if (init == null) { | 2785 if (init == null) { |
| 2769 init = js.call('let #', node.loopVariable.identifier.name); | 2786 init = js.call('let #', node.loopVariable.identifier.name); |
| 2770 } | 2787 } |
| 2771 return new JS.ForOf(init, _visit(node.iterable), _visit(node.body)); | 2788 return new JS.ForOf(init, _visit(node.iterable), _visitScope(node.body)); |
| 2772 } | 2789 } |
| 2773 | 2790 |
| 2774 JS.Statement _emitAwaitFor(ForEachStatement node) { | 2791 JS.Statement _emitAwaitFor(ForEachStatement node) { |
| 2775 // Emits `await for (var value in stream) ...`, which desugars as: | 2792 // Emits `await for (var value in stream) ...`, which desugars as: |
| 2776 // | 2793 // |
| 2777 // var iter = new StreamIterator<T>(stream); | 2794 // var iter = new StreamIterator<T>(stream); |
| 2778 // try { | 2795 // try { |
| 2779 // while (await iter.moveNext()) { | 2796 // while (await iter.moveNext()) { |
| 2780 // var value = iter.current; | 2797 // var value = iter.current; |
| 2781 // ... | 2798 // ... |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3291 | 3308 |
| 3292 /// A special kind of element created by the compiler, signifying a temporary | 3309 /// A special kind of element created by the compiler, signifying a temporary |
| 3293 /// variable. These objects use instance equality, and should be shared | 3310 /// variable. These objects use instance equality, and should be shared |
| 3294 /// everywhere in the tree where they are treated as the same variable. | 3311 /// everywhere in the tree where they are treated as the same variable. |
| 3295 class TemporaryVariableElement extends LocalVariableElementImpl { | 3312 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3296 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3313 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3297 | 3314 |
| 3298 int get hashCode => identityHashCode(this); | 3315 int get hashCode => identityHashCode(this); |
| 3299 bool operator ==(Object other) => identical(this, other); | 3316 bool operator ==(Object other) => identical(this, other); |
| 3300 } | 3317 } |
| OLD | NEW |