| Index: lib/src/codegen/side_effect_analysis.dart
|
| diff --git a/lib/src/codegen/side_effect_analysis.dart b/lib/src/codegen/side_effect_analysis.dart
|
| deleted file mode 100644
|
| index da5de6bf00f5b91042c56c08585d5932e8a44584..0000000000000000000000000000000000000000
|
| --- a/lib/src/codegen/side_effect_analysis.dart
|
| +++ /dev/null
|
| @@ -1,138 +0,0 @@
|
| -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -import 'package:analyzer/dart/ast/ast.dart';
|
| -import 'package:analyzer/dart/ast/visitor.dart';
|
| -import 'package:analyzer/dart/element/element.dart';
|
| -import 'package:analyzer/src/generated/constant.dart';
|
| -import 'package:analyzer/src/generated/error.dart'
|
| - show AnalysisErrorListener, ErrorReporter;
|
| -import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
|
| -import 'package:analyzer/src/generated/source.dart' show Source;
|
| -import 'package:analyzer/src/dart/ast/ast.dart';
|
| -
|
| -/// True is the expression can be evaluated multiple times without causing
|
| -/// code execution. This is true for final fields. This can be true for local
|
| -/// variables, if:
|
| -/// * they are not assigned within the [context].
|
| -/// * they are not assigned in a function closure anywhere.
|
| -/// True is the expression can be evaluated multiple times without causing
|
| -/// code execution. This is true for final fields. This can be true for local
|
| -/// variables, if:
|
| -///
|
| -/// * they are not assigned within the [context] scope.
|
| -/// * they are not assigned in a function closure anywhere.
|
| -///
|
| -/// This method is used to avoid creating temporaries in cases where we know
|
| -/// we can safely re-evaluate [node] multiple times in [context]. This lets
|
| -/// us generate prettier code.
|
| -///
|
| -/// This method is conservative: it should never return `true` unless it is
|
| -/// certain the [node] is stateless, because generated code may rely on the
|
| -/// correctness of a `true` value. However it may return `false` for things
|
| -/// that are in fact, stateless.
|
| -bool isStateless(FunctionBody function, Expression node, [AstNode context]) {
|
| - // `this` and `super` cannot be reassigned.
|
| - if (node is ThisExpression || node is SuperExpression) return true;
|
| - if (node is Identifier) {
|
| - var e = node.staticElement;
|
| - if (e is PropertyAccessorElement) {
|
| - e = e.variable;
|
| - }
|
| - if (e is VariableElement && !e.isSynthetic) {
|
| - if (e.isFinal) return true;
|
| - if (e is LocalVariableElement || e is ParameterElement) {
|
| - // make sure the local isn't mutated in the context.
|
| - return !_isPotentiallyMutated(function, e, context);
|
| - }
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -/// Returns true if the local variable is potentially mutated within [context].
|
| -/// This accounts for closures that may have been created outside of [context].
|
| -bool _isPotentiallyMutated(FunctionBody function, VariableElement e,
|
| - [AstNode context]) {
|
| - if (function is FunctionBodyImpl && function.localVariableInfo == null) {
|
| - // TODO(jmesserly): this is a caching bug in Analyzer. They don't restore
|
| - // this info in some cases.
|
| - return true;
|
| - }
|
| -
|
| - if (function.isPotentiallyMutatedInClosure(e)) return true;
|
| - if (function.isPotentiallyMutatedInScope(e)) {
|
| - // Need to visit the context looking for assignment to this local.
|
| - if (context != null) {
|
| - var visitor = new _AssignmentFinder(e);
|
| - context.accept(visitor);
|
| - return visitor._potentiallyMutated;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -/// Adapted from VariableResolverVisitor. Finds an assignment to a given
|
| -/// local variable.
|
| -class _AssignmentFinder extends RecursiveAstVisitor {
|
| - final VariableElement _variable;
|
| - bool _potentiallyMutated = false;
|
| -
|
| - _AssignmentFinder(this._variable);
|
| -
|
| - @override
|
| - visitSimpleIdentifier(SimpleIdentifier node) {
|
| - // Ignore if qualified.
|
| - AstNode parent = node.parent;
|
| - if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
|
| - return;
|
| - }
|
| - if (parent is PropertyAccess && identical(parent.propertyName, node)) {
|
| - return;
|
| - }
|
| - if (parent is MethodInvocation && identical(parent.methodName, node)) {
|
| - return;
|
| - }
|
| - if (parent is ConstructorName) return;
|
| - if (parent is Label) return;
|
| -
|
| - if (node.inSetterContext() && node.staticElement == _variable) {
|
| - _potentiallyMutated = true;
|
| - }
|
| - }
|
| -}
|
| -
|
| -class ConstFieldVisitor {
|
| - final ConstantVisitor _constantVisitor;
|
| -
|
| - ConstFieldVisitor(TypeProvider types, Source source)
|
| - // TODO(jmesserly): support -D variables on the command line
|
| - : _constantVisitor = new ConstantVisitor(
|
| - new ConstantEvaluationEngine(types, new DeclaredVariables()),
|
| - new ErrorReporter(AnalysisErrorListener.NULL_LISTENER, source));
|
| -
|
| - // TODO(jmesserly): this is used to determine if the field initialization is
|
| - // side effect free. We should make the check more general, as things like
|
| - // list/map literals/regexp are also side effect free and fairly common
|
| - // to use as field initializers.
|
| - bool isFieldInitConstant(VariableDeclaration field) =>
|
| - field.initializer == null || computeConstant(field) != null;
|
| -
|
| - DartObject computeConstant(VariableDeclaration field) {
|
| - // If the constant is already computed by ConstantEvaluator, just return it.
|
| - VariableElement element = field.element;
|
| - var result = element.constantValue;
|
| - if (result != null) return result;
|
| -
|
| - // ConstantEvaluator will not compute constants for non-const fields,
|
| - // so run ConstantVisitor for those to figure out if the initializer is
|
| - // actually a constant (and therefore side effect free to evaluate).
|
| - assert(!field.isConst);
|
| -
|
| - var initializer = field.initializer;
|
| - if (initializer == null) return null;
|
| - return initializer.accept(_constantVisitor);
|
| - }
|
| -}
|
|
|