// 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.

library;

import 'package:js_ast/js_ast.dart' as js;

typedef PositionPredicate = bool Function(int position);

/// PlaceholderSafetyAnalysis determines which placeholders in a JavaScript
/// template may be replaced with an arbitrary expression. Placeholders may be
/// replaced with an arbitrary expression provided the template ensures the
/// placeholders are evaluated in the same left-to-right order with no
/// additional effects interleaved.
///
/// The result is semi-conservative, giving reasonable results for many simple
/// JS fragments. The non-conservative part is the assumption that arithmetic
/// operators are used on 'good' operands that do not force arbitrary code to be
/// executed via conversions (valueOf() and toString() methods).
class PlaceholderSafetyAnalysis extends js.BaseVisitor<int> {
  final PositionPredicate isNullableInput;
  int nextPosition = 0;
  int maxSafePosition = -1;
  bool safe = true;

  // We do a crude abstract interpretation to find operations that might throw
  // exceptions. The possible values of expressions are represented by
  // integers. Small non-negative integers 0, 1, 2, ... represent the values of
  // the placeholders. Other values are:
  static const int nonNullValue = -1; // Unknown but not null.
  static const int unknownValue = -2; // Unknown and might be null.

  PlaceholderSafetyAnalysis._(this.isNullableInput);

  /// Returns the number of placeholders that can be substituted into the
  /// template AST [node] without changing the order of observable effects.
  /// [isNullableInput] is a function that takes the 0-based index of a
  /// placeholder and returns `true` if expression at run time may be null, and
  /// `false` if the value is never null.
  static int analyze(js.Node node, PositionPredicate isNullableInput) {
    PlaceholderSafetyAnalysis analysis = PlaceholderSafetyAnalysis._(
      isNullableInput,
    );
    analysis.visit(node);
    return analysis.maxSafePosition + 1;
  }

  bool canBeNull(int value) {
    if (value == nonNullValue) return false;
    if (value == unknownValue) return true;
    return isNullableInput(value);
  }

  int unsafe(int value) {
    safe = false;
    return value;
  }

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

  @override
  int visitNode(js.Node node) {
    safe = false;
    node.visitChildren(this);
    return unknownValue;
  }

  @override
  int visitComment(js.Comment node) {
    return unknownValue;
  }

  @override
  int visitLiteralNull(js.LiteralNull node) {
    return unknownValue;
  }

  @override
  int visitLiteral(js.Literal node) {
    return nonNullValue;
  }

  int handleInterpolatedNode(js.InterpolatedNode node) {
    assert(node.isPositional);
    int position = nextPosition++;
    if (safe) maxSafePosition = position;
    return position;
  }

  @override
  int visitInterpolatedExpression(js.InterpolatedExpression node) {
    return handleInterpolatedNode(node);
  }

  @override
  int visitInterpolatedLiteral(js.InterpolatedLiteral node) {
    return handleInterpolatedNode(node);
  }

  @override
  int visitInterpolatedSelector(js.InterpolatedSelector node) {
    return handleInterpolatedNode(node);
  }

  @override
  int visitInterpolatedStatement(js.InterpolatedStatement node) {
    return handleInterpolatedNode(node);
  }

  @override
  int visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
    return handleInterpolatedNode(node);
  }

  @override
  int visitObjectInitializer(js.ObjectInitializer node) {
    for (js.Property property in node.properties) {
      visit(property);
    }
    return nonNullValue;
  }

  @override
  int visitProperty(js.Property node) {
    visit(node.name);
    visit(node.value);
    return unknownValue;
  }

  @override
  int visitArrayInitializer(js.ArrayInitializer node) {
    node.elements.forEach(visit);
    return nonNullValue;
  }

  @override
  int visitArrayHole(js.ArrayHole node) {
    return unknownValue;
  }

  @override
  int visitAccess(js.PropertyAccess node) {
    int first = visit(node.receiver);
    visit(node.selector);
    // TODO(sra): If the JS is annotated as never throwing, we can avoid this.
    if (canBeNull(first)) safe = false;
    return unknownValue;
  }

  @override
  int visitAssignment(js.Assignment node) {
    js.Expression left = node.leftHandSide;
    js.Expression right = node.value;

    int leftToRight() {
      visit(left);
      visit(right);
      return unknownValue;
    }

    if (left is js.InterpolatedNode) {
      // A bare interpolated expression should not be the LHS of an assignment.
      safe = false;
      return leftToRight();
    }

    // Assignment operators dereference the LHS before evaluating the RHS.
    if (node.op != null) return leftToRight();

    // Assignment (1) evaluates the LHS as a Reference `lval`, (2) evaluates the
    // RHS as a value, (3) dereferences the `lval` in PutValue.
    if (left is js.VariableReference) {
      int value = visit(right);
      // Assignment could change an observed global or cause a ReferenceError.
      safe = false;
      return value;
    }
    if (left is js.PropertyAccess) {
      // "a.b.x = c.y" gives a TypeError for null values in this order: `a`,
      // `c`, `a.b`.
      int receiver = visit(left.receiver);
      visit(left.selector);
      int value = visit(right);
      if (canBeNull(receiver)) safe = false;
      return value;
    }
    // Be conservative with unrecognized LHS expressions.
    safe = false;
    return leftToRight();
  }

  @override
  int visitVariableInitialization(js.VariableInitialization node) {
    js.Expression left = node.declaration;
    js.Expression? right = node.value;

    visit(left);
    if (left is js.InterpolatedNode) {
      // A bare interpolated expression should not be the LHS of an initialized
      // variable declaration.
      safe = false;
    }
    if (right != null) {
      return visit(right);
    }
    return unknownValue;
  }

  @override
  int visitCall(js.Call node) {
    // TODO(sra): Recognize JavaScript built-ins like
    // 'Object.prototype.hasOwnProperty.call'.
    visit(node.target);
    node.arguments.forEach(visit);
    return unsafe(unknownValue);
  }

  @override
  int visitNew(js.New node) {
    visit(node.target);
    node.arguments.forEach(visit);
    return unsafe(nonNullValue);
  }

  @override
  int visitBinary(js.Binary node) {
    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 "|":
        visit(node.left);
        visit(node.right);
        return nonNullValue; // Number, String, Boolean.

      case ',':
        visit(node.left);
        int right = visit(node.right);
        return right;

      case "&&":
      case "||":
        visit(node.left);
        // TODO(sra): Might be safe, e.g.  "x || 0".
        safe = false;
        visit(node.right);
        return unknownValue;

      case "instanceof":
      case "in":
        visit(node.left);
        visit(node.right);
        return unknownValue;

      default:
        return unsafe(unknownValue);
    }
  }

  @override
  int visitConditional(js.Conditional node) {
    visit(node.condition);
    // TODO(sra): Might be safe, e.g.  "# ? 1 : 2".
    safe = false;
    visit(node.then);
    visit(node.otherwise);
    return unknownValue;
  }

  @override
  int visitThrow(js.Throw node) {
    visit(node.expression);
    return unsafe(unknownValue);
  }

  @override
  int visitPrefix(js.Prefix node) {
    if (node.op == 'typeof') {
      // "typeof a" first evaluates to a Reference. If the Reference is to a
      // variable that is not present, "undefined" is returned without
      // dereferencing.
      if (node.argument is js.VariableUse) return nonNullValue; // A string.
    }

    visit(node.argument);

    switch (node.op) {
      case '+':
      case '-':
      case '!':
      case '~':
        // Non-conservative assumption that these operators are used on values
        // that do not call arbitrary code via valueOf() or toString().
        return nonNullValue;

      case 'typeof':
        return nonNullValue; // Always a string.

      case 'void':
        return unknownValue;

      case '--':
      case '++':
        return nonNullValue; // Always a number.

      default:
        safe = false;
        return unknownValue;
    }
  }

  @override
  int visitPostfix(js.Postfix node) {
    assert(node.op == '--' || node.op == '++');
    visit(node.argument);
    return nonNullValue; // Always a number, even for "(a=null, a++)".
  }

  @override
  int visitVariableUse(js.VariableUse node) {
    // We could get a ReferenceError unless the variable is in scope.  For JS
    // fragments, the only use of VariableUse outside a `function(){...}` should
    // be for global references. Certain global names are almost certainly not
    // reference errors, e.g 'Array'.
    switch (node.name) {
      case 'Array':
      case 'Date':
      case 'Function':
      case 'Math':
      case 'Number':
      case 'Object':
      case 'RegExp':
      case 'String':
      case 'self':
      case 'window':
        return nonNullValue;
      default:
        return unsafe(unknownValue);
    }
  }

  @override
  int visitFunctionExpression(js.FunctionExpression node) {
    bool oldSafe = safe;
    int oldNextPosition = nextPosition;
    visit(node.body);
    // Creating a function has no effect on order unless there are embedded
    // placeholders.
    safe = (nextPosition == oldNextPosition) && oldSafe;
    return nonNullValue;
  }
}
