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