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

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

Issue 1139673005: fix temps that have the same name to have different Elements (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 7 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 | « no previous file | lib/src/codegen/js_names.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; 7 import 'dart:collection' show HashSet, HashMap;
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 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 // initializing formal parameter, e.g. `Point(this.x)` 1165 // initializing formal parameter, e.g. `Point(this.x)`
1166 if (element is ParameterElement && 1166 if (element is ParameterElement &&
1167 element.isInitializingFormal && 1167 element.isInitializingFormal &&
1168 element.isPrivate) { 1168 element.isPrivate) {
1169 /// Rename private names so they don't shadow the private field symbol. 1169 /// Rename private names so they don't shadow the private field symbol.
1170 /// The renamer would handle this, but it would prefer to rename the 1170 /// The renamer would handle this, but it would prefer to rename the
1171 /// temporary used for the private symbol. Instead rename the parameter. 1171 /// temporary used for the private symbol. Instead rename the parameter.
1172 return _getTemp(element, '${name.substring(1)}'); 1172 return _getTemp(element, '${name.substring(1)}');
1173 } 1173 }
1174 1174
1175 if (_isTemporary(element)) { 1175 if (element is TemporaryVariableElement) {
1176 if (name[0] == '#') { 1176 if (name[0] == '#') {
1177 return new JS.InterpolatedExpression(name.substring(1)); 1177 return new JS.InterpolatedExpression(name.substring(1));
1178 } else { 1178 } else {
1179 return _getTemp(element, name); 1179 return _getTemp(element, name);
1180 } 1180 }
1181 } 1181 }
1182 1182
1183 return new JS.Identifier(name); 1183 return new JS.Identifier(name);
1184 } 1184 }
1185 1185
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 SimpleIdentifier _createTemporary(String name, DartType type) { 1768 SimpleIdentifier _createTemporary(String name, DartType type) {
1769 // We use an invalid source location to signal that this is a temporary. 1769 // We use an invalid source location to signal that this is a temporary.
1770 // See [_isTemporary]. 1770 // See [_isTemporary].
1771 // TODO(jmesserly): alternatives are 1771 // TODO(jmesserly): alternatives are
1772 // * (ab)use Element.isSynthetic, which isn't currently used for 1772 // * (ab)use Element.isSynthetic, which isn't currently used for
1773 // LocalVariableElementImpl, so we could repurpose to mean "temp". 1773 // LocalVariableElementImpl, so we could repurpose to mean "temp".
1774 // * add a new property to LocalVariableElementImpl. 1774 // * add a new property to LocalVariableElementImpl.
1775 // * create a new subtype of LocalVariableElementImpl to mark a temp. 1775 // * create a new subtype of LocalVariableElementImpl to mark a temp.
1776 var id = 1776 var id =
1777 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); 1777 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1));
1778 id.staticElement = new LocalVariableElementImpl.forNode(id); 1778 id.staticElement = new TemporaryVariableElement.forNode(id);
1779 id.staticType = type; 1779 id.staticType = type;
1780 return id; 1780 return id;
1781 } 1781 }
1782 1782
1783 JS.Expression _const(Expression node, JS.Expression expr, [String nameHint]) { 1783 JS.Expression _const(Expression node, JS.Expression expr, [String nameHint]) {
1784 var value = js.call('dart.const(#)', expr); 1784 var value = js.call('dart.const(#)', expr);
1785 1785
1786 // If we're inside a method or function, capture the value into a 1786 // If we're inside a method or function, capture the value into a
1787 // global temporary, so we don't do the expensive canonicalization step. 1787 // global temporary, so we don't do the expensive canonicalization step.
1788 var ancestor = node.getAncestor((n) => n is FunctionBody || 1788 var ancestor = node.getAncestor((n) => n is FunctionBody ||
1789 (n is FieldDeclaration && n.staticKeyword == null)); 1789 (n is FieldDeclaration && n.staticKeyword == null));
1790 if (ancestor == null) return value; 1790 if (ancestor == null) return value;
1791 1791
1792 if (nameHint == null) { 1792 if (nameHint == null) {
1793 nameHint = 'const_' + getStaticType(node).name; 1793 nameHint = 'const_' + getStaticType(node).name;
1794 } 1794 }
1795 1795
1796 // TODO(jmesserly): enable this once we fix 1796 // TODO(jmesserly): enable this once we fix
1797 // https://github.com/dart-lang/dev_compiler/issues/131 1797 // https://github.com/dart-lang/dev_compiler/issues/131
1798 /*var temp = new JSTemporary(nameHint); 1798 /*var temp = new JSTemporary(nameHint);
1799 _pendingStatements.add(js.statement('let # = #;', [temp, value])); 1799 _pendingStatements.add(js.statement('let # = #;', [temp, value]));
1800 return temp;*/ 1800 return temp;*/
1801 assert(nameHint != null); // so it's not marked unused 1801 assert(nameHint != null); // so it's not marked unused
1802 return value; 1802 return value;
1803 } 1803 }
1804 1804
1805 bool _isTemporary(Element node) => node.nameOffset == -1;
1806
1807 /// Returns a new expression, which can be be used safely *once* on the 1805 /// Returns a new expression, which can be be used safely *once* on the
1808 /// left hand side, and *once* on the right side of an assignment. 1806 /// left hand side, and *once* on the right side of an assignment.
1809 /// For example: `expr1[expr2] += y` can be compiled as 1807 /// For example: `expr1[expr2] += y` can be compiled as
1810 /// `expr1[expr2] = expr1[expr2] + y`. 1808 /// `expr1[expr2] = expr1[expr2] + y`.
1811 /// 1809 ///
1812 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated 1810 /// The temporary scope will ensure `expr1` and `expr2` are only evaluated
1813 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`. 1811 /// once: `((x1, x2) => x1[x2] = x1[x2] + y)(expr1, expr2)`.
1814 /// 1812 ///
1815 /// If the expression does not end up using `x1` or `x2` more than once, or 1813 /// If the expression does not end up using `x1` or `x2` more than once, or
1816 /// if those expressions can be treated as stateless (e.g. they are 1814 /// if those expressions can be treated as stateless (e.g. they are
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 // TODO(jmesserly): validate the library. See issue #135. 2610 // TODO(jmesserly): validate the library. See issue #135.
2613 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName'; 2611 bool _isJsNameAnnotation(DartObjectImpl value) => value.type.name == 'JsName';
2614 2612
2615 bool _isJsPeerInterface(DartObjectImpl value) => 2613 bool _isJsPeerInterface(DartObjectImpl value) =>
2616 value.type.name == 'JsPeerInterface'; 2614 value.type.name == 'JsPeerInterface';
2617 2615
2618 // TODO(jacobr): we would like to do something like the following 2616 // TODO(jacobr): we would like to do something like the following
2619 // but we don't have summary support yet. 2617 // but we don't have summary support yet.
2620 // bool _supportJsExtensionMethod(AnnotatedNode node) => 2618 // bool _supportJsExtensionMethod(AnnotatedNode node) =>
2621 // _getAnnotation(node, "SupportJsExtensionMethod") != null; 2619 // _getAnnotation(node, "SupportJsExtensionMethod") != null;
2620
2621 /// A special kind of element created by the compiler, signifying a temporary
2622 /// variable. These objects use instance equality, and should be shared
2623 /// everywhere in the tree where they are treated as the same variable.
2624 class TemporaryVariableElement extends LocalVariableElementImpl {
2625 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
2626
2627 int get hashCode => identityHashCode(this);
2628 bool operator ==(Object other) => identical(this, other);
2629 }
OLDNEW
« no previous file with comments | « no previous file | lib/src/codegen/js_names.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698