// 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/error/listener.dart'
    show AnalysisErrorListener, ErrorReporter;
import 'package:analyzer/src/generated/engine.dart';
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 as PropertyAccessorElement).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(AnalysisContext context, {Source dummySource})
      : constantVisitor = new ConstantVisitor(
            new ConstantEvaluationEngine(
                context.typeProvider, context.declaredVariables),
            new ErrorReporter(
                AnalysisErrorListener.NULL_LISTENER, dummySource));

  // 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.computeConstantValue();
    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);
  }
}
