// 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/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] 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 = _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 typeProvider, DeclaredVariables declaredVariables,
      {Source dummySource})
      : constantVisitor = ConstantVisitor(
            ConstantEvaluationEngine(typeProvider, declaredVariables),
            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.declaredElement;
    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);
  }
}
