Chromium Code Reviews| 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; | 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 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1684 ]); | 1684 ]); |
| 1685 } | 1685 } |
| 1686 | 1686 |
| 1687 _cascadeTarget = savedCascadeTemp; | 1687 _cascadeTarget = savedCascadeTemp; |
| 1688 return result; | 1688 return result; |
| 1689 } | 1689 } |
| 1690 | 1690 |
| 1691 /// True is the expression can be evaluated multiple times without causing | 1691 /// True is the expression can be evaluated multiple times without causing |
| 1692 /// code execution. This is true for final fields. This can be true for local | 1692 /// code execution. This is true for final fields. This can be true for local |
| 1693 /// variables, if: | 1693 /// variables, if: |
| 1694 /// * they are not assigned within the [context]. | 1694 /// |
| 1695 /// * they are not assigned within the [context] scope. | |
| 1695 /// * they are not assigned in a function closure anywhere. | 1696 /// * they are not assigned in a function closure anywhere. |
| 1697 /// | |
| 1698 /// This method is used to avoid creating temporaries in cases where we know | |
| 1699 /// we can safely re-evaluate [node] multiple times in [context]. This lets | |
| 1700 /// us generate prettier code. | |
| 1701 /// | |
| 1702 /// This method is conservative: it should never return `true` unless it is | |
| 1703 /// certain the [node] is stateless, because generated code may rely on the | |
| 1704 /// correctness of a `true` value. However it may return `false` for things | |
| 1705 /// that are in fact, stateless. | |
| 1696 bool _isStateless(Expression node, [AstNode context]) { | 1706 bool _isStateless(Expression node, [AstNode context]) { |
| 1697 if (node is SimpleIdentifier) { | 1707 if (node is SimpleIdentifier) { |
| 1698 var e = node.staticElement; | 1708 var e = node.staticElement; |
| 1699 if (e is PropertyAccessorElement) e = e.variable; | 1709 if (e is PropertyAccessorElement) e = e.variable; |
| 1700 if (e is VariableElementImpl && !e.isSynthetic) { | 1710 if (e is VariableElement && !e.isSynthetic) { |
| 1701 if (e.isFinal) return true; | 1711 if (e.isFinal) return true; |
| 1712 | |
| 1713 // TODO(jmesserly): remove this when isPotentiallyMutated* is available | |
| 1714 // without the implementation class. Technically we shouldn't hit the | |
| 1715 // ParameterMember case based on current usage of _isStateless, but this | |
| 1716 // makes it clear we shouldn't rely on *Impl class. | |
| 1717 if (e is Member) e = e.baseElement; | |
| 1718 | |
| 1702 if (e is LocalVariableElementImpl || e is ParameterElementImpl) { | 1719 if (e is LocalVariableElementImpl || e is ParameterElementImpl) { |
| 1703 // make sure the local isn't mutated in the context. | 1720 // make sure the local isn't mutated in the context. |
| 1704 return !_isPotentiallyMutated(e, context); | 1721 return !_isPotentiallyMutated(e, context); |
| 1705 } | 1722 } |
| 1706 } | 1723 } |
| 1707 } | 1724 } |
| 1708 return false; | 1725 return false; |
| 1709 } | 1726 } |
| 1710 | 1727 |
| 1711 @override | 1728 @override |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2182 return new JS.Identifier(jsLibraryName(library)); | 2199 return new JS.Identifier(jsLibraryName(library)); |
| 2183 } | 2200 } |
| 2184 | 2201 |
| 2185 static bool _needsImplicitThis(Element e) => | 2202 static bool _needsImplicitThis(Element e) => |
| 2186 e is PropertyAccessorElement && !e.variable.isStatic || | 2203 e is PropertyAccessorElement && !e.variable.isStatic || |
| 2187 e is ClassMemberElement && !e.isStatic && e is! ConstructorElement; | 2204 e is ClassMemberElement && !e.isStatic && e is! ConstructorElement; |
| 2188 } | 2205 } |
| 2189 | 2206 |
| 2190 /// Returns true if the local variable is potentially mutated within [context]. | 2207 /// Returns true if the local variable is potentially mutated within [context]. |
| 2191 /// This accounts for closures that may have been created outside of [context]. | 2208 /// This accounts for closures that may have been created outside of [context]. |
| 2209 // TODO(jmesserly): change type annotation to not be *Impl once | |
| 2210 // isPotentiallyMutated is available on VariableElement. | |
|
Brian Wilkerson
2015/04/06 16:03:23
I think this support was just published as 0.24.1.
| |
| 2192 bool _isPotentiallyMutated(VariableElementImpl e, [AstNode context]) { | 2211 bool _isPotentiallyMutated(VariableElementImpl e, [AstNode context]) { |
| 2193 if (e.isPotentiallyMutatedInClosure) { | 2212 if (e.isPotentiallyMutatedInClosure) { |
| 2194 // TODO(jmesserly): this returns true incorrectly in some cases, because | 2213 // TODO(jmesserly): this returns true incorrectly in some cases, because |
| 2195 // VariableResolverVisitor only checks that enclosingElement is not the | 2214 // VariableResolverVisitor only checks that enclosingElement is not the |
| 2196 // function element, but enclosingElement can be something else in some | 2215 // function element, but enclosingElement can be something else in some |
| 2197 // cases (the block scope?). So it's more conservative than it could be. | 2216 // cases (the block scope?). So it's more conservative than it could be. |
| 2198 return true; | 2217 return true; |
| 2199 } | 2218 } |
| 2200 if (e.isPotentiallyMutatedInScope) { | 2219 if (e.isPotentiallyMutatedInScope) { |
| 2201 // Need to visit the context looking for assignment to this local. | 2220 // Need to visit the context looking for assignment to this local. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2361 | 2380 |
| 2362 // TODO(jmesserly): in many cases marking the end will be unncessary. | 2381 // TODO(jmesserly): in many cases marking the end will be unncessary. |
| 2363 printer.mark(_location(node.end)); | 2382 printer.mark(_location(node.end)); |
| 2364 } | 2383 } |
| 2365 | 2384 |
| 2366 String _getIdentifier(AstNode node) { | 2385 String _getIdentifier(AstNode node) { |
| 2367 if (node is SimpleIdentifier) return node.name; | 2386 if (node is SimpleIdentifier) return node.name; |
| 2368 return null; | 2387 return null; |
| 2369 } | 2388 } |
| 2370 } | 2389 } |
| OLD | NEW |