// 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 js.safety;

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 providied 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 NONNULL_VALUE = -1; // Unknown but not null.
  static const int UNKNOWN_VALUE = -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 == NONNULL_VALUE) return false;
    if (value == UNKNOWN_VALUE) 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 UNKNOWN_VALUE;
  }

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

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

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

  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 NONNULL_VALUE;
  }

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

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

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

  @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 UNKNOWN_VALUE;
  }

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

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

    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 UNKNOWN_VALUE;
  }

  @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(UNKNOWN_VALUE);
  }

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

  @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 NONNULL_VALUE; // 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 UNKNOWN_VALUE;

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

      default:
        return unsafe(UNKNOWN_VALUE);
    }
  }

  @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 UNKNOWN_VALUE;
  }

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

  @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 NONNULL_VALUE; // 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 NONNULL_VALUE;

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

      case 'void':
        return UNKNOWN_VALUE;

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

      default:
        safe = false;
        return UNKNOWN_VALUE;
    }
  }

  @override
  int visitPostfix(js.Postfix node) {
    assert(node.op == '--' || node.op == '++');
    visit(node.argument);
    return NONNULL_VALUE; // 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 NONNULL_VALUE;
      default:
        return unsafe(UNKNOWN_VALUE);
    }
  }

  @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 NONNULL_VALUE;
  }
}
