// Copyright (c) 2014, 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 '../js/js.dart' as js;
import '../universe/side_effects.dart' show SideEffects;
import 'native_throw_behavior.dart' show NativeThrowBehavior;

class HasCapturedPlaceholders extends js.BaseVisitorVoid {
  HasCapturedPlaceholders._();

  static bool check(js.Node node) {
    HasCapturedPlaceholders visitor = HasCapturedPlaceholders._();
    node.accept(visitor);
    return visitor.found;
  }

  int enclosingFunctions = 0;
  bool found = false;

  @override
  void visitFunctionExpression(js.FunctionExpression node) {
    ++enclosingFunctions;
    node.visitChildren(this);
    --enclosingFunctions;
  }

  @override
  void visitInterpolatedNode(js.InterpolatedNode node) {
    if (enclosingFunctions > 0) {
      found = true;
    }
  }
}

class SideEffectsVisitor extends js.BaseVisitorVoid {
  final SideEffects sideEffects;
  SideEffectsVisitor(this.sideEffects);

  void visit(js.Node node) {
    node.accept(this);
  }

  @override
  void visitLiteralExpression(js.LiteralExpression node) {
    sideEffects.setAllSideEffects();
    sideEffects.setDependsOnSomething();
    node.visitChildren(this);
  }

  @override
  void visitLiteralStatement(js.LiteralStatement node) {
    sideEffects.setAllSideEffects();
    sideEffects.setDependsOnSomething();
    node.visitChildren(this);
  }

  @override
  void visitAssignment(js.Assignment node) {
    sideEffects.setChangesStaticProperty();
    sideEffects.setChangesInstanceProperty();
    sideEffects.setChangesIndex();
    node.visitChildren(this);
  }

  @override
  void visitVariableInitialization(js.VariableInitialization node) {
    node.visitChildren(this);
  }

  @override
  void visitCall(js.Call node) {
    sideEffects.setAllSideEffects();
    sideEffects.setDependsOnSomething();
    node.visitChildren(this);
  }

  @override
  void visitBinary(js.Binary node) {
    node.visitChildren(this);
  }

  @override
  void visitThrow(js.Throw node) {
    // TODO(ngeoffray): Incorporate a mayThrow flag in the
    // [SideEffects] class.
    sideEffects.setAllSideEffects();
  }

  @override
  void visitNew(js.New node) {
    sideEffects.setAllSideEffects();
    sideEffects.setDependsOnSomething();
    node.visitChildren(this);
  }

  @override
  void visitPrefix(js.Prefix node) {
    if (node.op == 'delete') {
      sideEffects.setChangesStaticProperty();
      sideEffects.setChangesInstanceProperty();
      sideEffects.setChangesIndex();
    }
    node.visitChildren(this);
  }

  @override
  void visitVariableUse(js.VariableUse node) {
    sideEffects.setDependsOnStaticPropertyStore();
  }

  @override
  void visitPostfix(js.Postfix node) {
    node.visitChildren(this);
  }

  @override
  void visitAccess(js.PropertyAccess node) {
    sideEffects.setDependsOnIndexStore();
    sideEffects.setDependsOnInstancePropertyStore();
    sideEffects.setDependsOnStaticPropertyStore();
    node.visitChildren(this);
  }
}

/// ThrowBehaviorVisitor generates a NativeThrowBehavior describing the
/// exception behavior of a JavaScript expression.
///
/// The result is semi-conservative, giving reasonable results for many simple
/// JS fragments. The non-conservative part is the assumption that binary
/// operators are used on 'good' operands that do not force arbitrary code to be
/// executed via conversions (valueOf() and toString() methods).
///
/// In many cases a JS fragment has more precise behavior. In these cases the
/// behavior should be described as a property of the JS fragment. For example,
/// Object.keys(#) has a TypeError on null / undefined, which can only be known
/// in the calling context.
///
class ThrowBehaviorVisitor extends js.BaseVisitor<NativeThrowBehavior> {
  ThrowBehaviorVisitor();

  NativeThrowBehavior analyze(js.Node node) {
    return visit(node);
  }

  /// Returns the combined behavior of sequential execution of code having
  /// behavior [first] followed by code having behavior [second].
  static NativeThrowBehavior sequence(
    NativeThrowBehavior first,
    NativeThrowBehavior second,
  ) {
    return first.then(second);
  }

  /// Returns the combined behavior of a choice between two paths with behaviors
  /// [first] and [second].
  static NativeThrowBehavior choice(
    NativeThrowBehavior first,
    NativeThrowBehavior second,
  ) {
    return first.or(second);
  }

  NativeThrowBehavior visit(js.Node node) {
    return node.accept(this);
  }

  @override
  NativeThrowBehavior visitNode(js.Node node) {
    return NativeThrowBehavior.may;
  }

  @override
  NativeThrowBehavior visitComment(js.Comment node) {
    return NativeThrowBehavior.never;
  }

  @override
  NativeThrowBehavior visitLiteral(js.Literal node) {
    return NativeThrowBehavior.never;
  }

  @override
  NativeThrowBehavior visitInterpolatedExpression(js.InterpolatedNode node) {
    return NativeThrowBehavior.never;
  }

  @override
  NativeThrowBehavior visitInterpolatedSelector(js.InterpolatedNode node) {
    return NativeThrowBehavior.never;
  }

  @override
  NativeThrowBehavior visitArrayInitializer(js.ArrayInitializer node) {
    return node.elements.map(visit).fold(NativeThrowBehavior.never, sequence);
  }

  @override
  NativeThrowBehavior visitArrayHole(js.ArrayHole node) {
    return NativeThrowBehavior.never;
  }

  @override
  NativeThrowBehavior visitObjectInitializer(js.ObjectInitializer node) {
    return node.properties.map(visit).fold(NativeThrowBehavior.never, sequence);
  }

  @override
  NativeThrowBehavior visitProperty(js.Property node) {
    return sequence(visit(node.name), visit(node.value));
  }

  @override
  NativeThrowBehavior visitAssignment(js.Assignment node) {
    // TODO(sra): Can we make "#.p = #" be null(1)?
    return NativeThrowBehavior.may;
  }

  @override
  NativeThrowBehavior visitVariableInitialization(
    js.VariableInitialization node,
  ) {
    final value = node.value;
    if (value == null) return NativeThrowBehavior.never;
    return visit(value);
  }

  @override
  NativeThrowBehavior visitCall(js.Call node) {
    js.Expression target = node.target;
    if (target is js.PropertyAccess && _isFirstInterpolatedProperty(target)) {
      // #.f(...): Evaluate selector 'f', dereference, evaluate arguments, and
      // finally call target.
      NativeThrowBehavior result = sequence(
        visit(target.selector),
        NativeThrowBehavior.nullNsm,
      );
      for (js.Expression argument in node.arguments) {
        result = sequence(result, visit(argument));
      }
      return sequence(result, NativeThrowBehavior.may); // Target may throw.
    }
    return NativeThrowBehavior.may;
  }

  @override
  NativeThrowBehavior visitNew(js.New node) {
    // TODO(sra): `new Array(x)` where `x` is a small number.
    return NativeThrowBehavior.may;
  }

  @override
  NativeThrowBehavior visitBinary(js.Binary node) {
    NativeThrowBehavior left = visit(node.left);
    NativeThrowBehavior right = visit(node.right);
    switch (node.op) {
      // We make the non-conservative assumption that these operations are not
      // used in ways that force calling arbitrary code via valueOf or
      // toString().
      case "*":
      case "/":
      case "%":
      case "+":
      case "-":
      case "<<":
      case ">>":
      case ">>>":
      case "<":
      case ">":
      case "<=":
      case ">=":
      case "==":
      case "===":
      case "!=":
      case "!==":
      case "&":
      case "^":
      case "|":
        return sequence(left, right);

      case ',':
        return sequence(left, right);

      case "&&":
      case "||":
        return choice(left, sequence(left, right));

      case "instanceof":
      case "in":
      default:
        return NativeThrowBehavior.may;
    }
  }

  @override
  NativeThrowBehavior visitThrow(js.Throw node) {
    return sequence(visit(node.expression), NativeThrowBehavior.may);
  }

  @override
  NativeThrowBehavior visitPrefix(js.Prefix node) {
    if (node.op == 'typeof' && node.argument is js.VariableUse) {
      return NativeThrowBehavior.never;
    }
    NativeThrowBehavior result = visit(node.argument);
    switch (node.op) {
      case '+':
      case '-':
      case '!':
      case '~':
      case 'void':
      case 'typeof':
        return result;
      default:
        return NativeThrowBehavior.may;
    }
  }

  @override
  NativeThrowBehavior visitVariableUse(js.VariableUse node) {
    // We could get a ReferenceError unless the variable is in scope. The AST
    // could distinguish in-scope and out-of scope references. For JS fragments,
    // the only use of VariableUse should be for global references. Certain
    // global names are almost certainly not reference errors, e.g 'Array'.
    switch (node.name) {
      case 'Array':
      case 'Math':
      case 'Object':
        return NativeThrowBehavior.never;
      default:
        return NativeThrowBehavior.may;
    }
  }

  @override
  NativeThrowBehavior visitAccess(js.PropertyAccess node) {
    js.Node receiver = node.receiver;
    NativeThrowBehavior first = visit(receiver);
    NativeThrowBehavior second = visit(node.selector);

    if (_isFirstInterpolatedProperty(node)) {
      first = NativeThrowBehavior.nullNsm;
    } else {
      first = NativeThrowBehavior.may;
    }

    return sequence(first, second);
  }

  bool _isFirstInterpolatedProperty(js.PropertyAccess node) {
    js.Node receiver = node.receiver;
    if (receiver is js.InterpolatedExpression &&
        receiver.isPositional &&
        receiver.nameOrPosition == 0) {
      return true;
    }
    return false;
  }
}
