Java Code Examples for com.google.javascript.rhino.Node#getDouble()

The following examples show how to use com.google.javascript.rhino.Node#getDouble() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Closure_78_PeepholeFoldConstants_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Try to evaluate String.indexOf/lastIndexOf:
 *     "abcdef".indexOf("bc") -> 1
 *     "abcdefbc".indexOf("bc", 3) -> 6
 */
private Node tryFoldStringIndexOf(
    Node n, String functionName, Node lstringNode, Node firstArg) {
  Preconditions.checkArgument(n.getType() == Token.CALL);
  Preconditions.checkArgument(lstringNode.getType() == Token.STRING);

  String lstring = NodeUtil.getStringValue(lstringNode);
  boolean isIndexOf = functionName.equals("indexOf");
  Node secondArg = firstArg.getNext();
  String searchValue = NodeUtil.getStringValue(firstArg);
  // searchValue must be a valid string.
  if (searchValue == null) {
    return n;
  }
  int fromIndex = isIndexOf ? 0 : lstring.length();
  if (secondArg != null) {
    // Third-argument and non-numeric second arg are problematic. Discard.
    if ((secondArg.getNext() != null) ||
        (secondArg.getType() != Token.NUMBER)) {
      return n;
    } else {
      fromIndex = (int) secondArg.getDouble();
    }
  }
  int indexVal = isIndexOf ? lstring.indexOf(searchValue, fromIndex)
                           : lstring.lastIndexOf(searchValue, fromIndex);
  Node newNode = Node.newNumber(indexVal);
  n.getParent().replaceChild(n, newNode);

  reportCodeChange();

  return newNode;
}
 
Example 2
Source File: Closure_86_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Gets the value of a node as a String, or null if it cannot be converted.
 * When it returns a non-null String, this method effectively emulates the
 * <code>String()</code> JavaScript cast function.
 */
static String getStringValue(Node n) {
  // TODO(user): Convert constant array, object, and regex literals as well.
  switch (n.getType()) {
    case Token.STRING:
      return n.getString();

    case Token.NAME:
      String name = n.getString();
      if ("undefined".equals(name)
          || "Infinity".equals(name)
          || "NaN".equals(name)) {
        return name;
      }
      break;

    case Token.NUMBER:
      double value = n.getDouble();
      long longValue = (long) value;

      // Return "1" instead of "1.0"
      if (longValue == value) {
        return Long.toString(longValue);
      } else {
        return Double.toString(n.getDouble());
      }

    case Token.FALSE:
    case Token.TRUE:
    case Token.NULL:
      return Node.tokenToName(n.getType());

    case Token.VOID:
      return "undefined";
  }
  return null;
}
 
Example 3
Source File: Closure_23_PeepholeFoldConstants_s.java    From coming with MIT License 5 votes vote down vote up
private Node tryReduceVoid(Node n) {
  Node child = n.getFirstChild();
  if (!child.isNumber() || child.getDouble() != 0.0) {
    if (!mayHaveSideEffects(n)) {
      n.replaceChild(child, IR.number(0));
      reportCodeChange();
    }
  }
  return n;
}
 
Example 4
Source File: Closure_50_PeepholeReplaceKnownMethods_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Try to evaluate String.indexOf/lastIndexOf:
 *     "abcdef".indexOf("bc") -> 1
 *     "abcdefbc".indexOf("bc", 3) -> 6
 */
private Node tryFoldStringIndexOf(
    Node n, String functionName, Node lstringNode, Node firstArg) {
  Preconditions.checkArgument(n.getType() == Token.CALL);
  Preconditions.checkArgument(lstringNode.getType() == Token.STRING);

  String lstring = NodeUtil.getStringValue(lstringNode);
  boolean isIndexOf = functionName.equals("indexOf");
  Node secondArg = firstArg.getNext();
  String searchValue = NodeUtil.getStringValue(firstArg);
  // searchValue must be a valid string.
  if (searchValue == null) {
    return n;
  }
  int fromIndex = isIndexOf ? 0 : lstring.length();
  if (secondArg != null) {
    // Third-argument and non-numeric second arg are problematic. Discard.
    if ((secondArg.getNext() != null) ||
        (secondArg.getType() != Token.NUMBER)) {
      return n;
    } else {
      fromIndex = (int) secondArg.getDouble();
    }
  }
  int indexVal = isIndexOf ? lstring.indexOf(searchValue, fromIndex)
                           : lstring.lastIndexOf(searchValue, fromIndex);
  Node newNode = Node.newNumber(indexVal);
  n.getParent().replaceChild(n, newNode);

  reportCodeChange();

  return newNode;
}
 
Example 5
Source File: Closure_50_PeepholeReplaceKnownMethods_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Try to fold .charCodeAt() calls on strings
 */
private Node tryFoldStringCharCodeAt(Node n, Node stringNode, Node arg1) {
  Preconditions.checkArgument(n.getType() == Token.CALL);
  Preconditions.checkArgument(stringNode.getType() == Token.STRING);

  int index;
  String stringAsString = stringNode.getString();

  if (arg1 != null && arg1.getType() == Token.NUMBER
      && arg1.getNext() == null) {
    index = (int) arg1.getDouble();
  } else {
    return n;
  }

  if (index < 0 || stringAsString.length() <= index) {
    // http://es5.github.com/#x15.5.4.5 says NaN is returned when index is
    // out of bounds but we bail.
    return n;
  }

  Node resultNode = Node.newNumber(stringAsString.charAt(index));
  Node parent = n.getParent();
  parent.replaceChild(n, resultNode);
  reportCodeChange();
  return resultNode;
}
 
Example 6
Source File: AstValidator.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private void validateNumber(Node n) {
  validateNodeType(Token.NUMBER, n);
  validateChildCount(n, 0);
  try {
    // Validate that getDouble doesn't throw
    n.getDouble();
  } catch (UnsupportedOperationException e) {
    violation("Invalid NUMBER node.", n);
  }
}
 
Example 7
Source File: Closure_86_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Gets the value of a node as a Number, or null if it cannot be converted.
 * When it returns a non-null Double, this method effectively emulates the
 * <code>Number()</code> JavaScript cast function.
 */
static Double getNumberValue(Node n) {
  switch (n.getType()) {
    case Token.TRUE:
      return 1.0;
    case Token.FALSE:
    case Token.NULL:
      return 0.0;

    case Token.NUMBER:
      return n.getDouble();

    case Token.VOID:
      return Double.NaN;

    case Token.NAME:
      String name = n.getString();
      if (name.equals("undefined")) {
        return Double.NaN;
      }
      if (name.equals("NaN")) {
        return Double.NaN;
      }
      if (name.equals("Infinity")) {
        return Double.POSITIVE_INFINITY;
      }
      return null;
  }
  return null;
}
 
Example 8
Source File: Closure_20_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Checks if it is safe to fold Array() constructor into []. It can be
 * obviously done, if the initial constructor has either no arguments or
 * at least two. The remaining case may be unsafe since Array(number)
 * actually reserves memory for an empty array which contains number elements.
 */
private FoldArrayAction isSafeToFoldArrayConstructor(Node arg) {
  FoldArrayAction action = FoldArrayAction.NOT_SAFE_TO_FOLD;

  if (arg == null) {
    action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
  } else if (arg.getNext() != null) {
    action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
  } else {
    switch (arg.getType()) {
      case Token.STRING:
        // "Array('a')" --> "['a']"
        action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
        break;
      case Token.NUMBER:
        // "Array(0)" --> "[]"
        if (arg.getDouble() == 0) {
          action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
        }
        break;
      case Token.ARRAYLIT:
        // "Array([args])" --> "[[args]]"
        action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
        break;
      default:
    }
  }
  return action;
}
 
Example 9
Source File: Closure_97_PeepholeFoldConstants_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold arithmetic binary operators
 */
private Node tryFoldArithmetic(Node n, Node left, Node right) {
  if (left.getType() == Token.NUMBER &&
      right.getType() == Token.NUMBER) {
    double result;
    double lval = left.getDouble();
    double rval = right.getDouble();

    switch (n.getType()) {
      case Token.ADD:
        result = lval + rval;
        break;
      case Token.SUB:
        result = lval - rval;
        break;
      case Token.MUL:
        result = lval * rval;
        break;
      case Token.DIV:
        if (rval == 0) {
          error(DIVIDE_BY_0_ERROR, right);
          return n;
        }
        result = lval / rval;
        break;
      default:
        throw new Error("Unknown arithmetic operator");
    }

    // length of the left and right value plus 1 byte for the operator.
    if (String.valueOf(result).length() <=
        String.valueOf(lval).length() + String.valueOf(rval).length() + 1 &&

        // Do not try to fold arithmetic for numbers > 2^53. After that
        // point, fixed-point math starts to break down and become inaccurate.
        Math.abs(result) <= MAX_FOLD_NUMBER) {
      Node newNumber = Node.newNumber(result);
      n.getParent().replaceChild(n, newNumber);
      reportCodeChange();
      return newNumber;
    }
 }
  return n;
}
 
Example 10
Source File: 1_NodeUtil.java    From SimFix with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Gets the value of a node as a String, or null if it cannot be converted.
 * When it returns a non-null String, this method effectively emulates the
 * <code>String()</code> JavaScript cast function.
 */
static String getStringValue(Node n) {
  // TODO(user): regex literals as well.
  switch (n.getType()) {
    case Token.STRING:
      return n.getString();

    case Token.NAME:
      String name = n.getString();
      if ("undefined".equals(name)
          || "Infinity".equals(name)
          || "NaN".equals(name)) {
        return name;
      }
      break;

    case Token.NUMBER:
      double value = n.getDouble();
      long longValue = (long) value;

      // Return "1" instead of "1.0"
      if (longValue == value) {
        return Long.toString(longValue);
      } else {
        return Double.toString(n.getDouble());
      }

    case Token.FALSE:
    case Token.TRUE:
    case Token.NULL:
      return Node.tokenToName(n.getType());

    case Token.VOID:
      return "undefined";

    case Token.NOT:
      TernaryValue child = getBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? "false" : "true"; // reversed.
      }
      break;

    case Token.ARRAYLIT:
      return arrayToString(n);

    case Token.OBJECTLIT:
      return "[object Object]";
  }
  return null;
}
 
Example 11
Source File: Closure_61_NodeUtil_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the value of a node as a Number, or null if it cannot be converted.
 * When it returns a non-null Double, this method effectively emulates the
 * <code>Number()</code> JavaScript cast function.
 */
static Double getNumberValue(Node n) {
  switch (n.getType()) {
    case Token.TRUE:
      return 1.0;

    case Token.FALSE:
    case Token.NULL:
      return 0.0;

    case Token.NUMBER:
      return n.getDouble();

    case Token.VOID:
      if (mayHaveSideEffects(n.getFirstChild())) {
        return null;
      } else {
        return Double.NaN;
      }

    case Token.NAME:
      // Check for known constants
      String name = n.getString();
      if (name.equals("undefined")) {
        return Double.NaN;
      }
      if (name.equals("NaN")) {
        return Double.NaN;
      }
      if (name.equals("Infinity")) {
        return Double.POSITIVE_INFINITY;
      }
      return null;

    case Token.NEG:
      if (n.getChildCount() == 1 && n.getFirstChild().getType() == Token.NAME
          && n.getFirstChild().getString().equals("Infinity")) {
        return Double.NEGATIVE_INFINITY;
      }
      return null;

    case Token.NOT:
      TernaryValue child = getPureBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? 0.0 : 1.0; // reversed.
      }
      break;

    case Token.STRING:
      return getStringNumberValue(n.getString());

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      String value = getStringValue(n);
      return value != null ? getStringNumberValue(value) : null;
  }

  return null;
}
 
Example 12
Source File: Closure_61_NodeUtil_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the value of a node as a Number, or null if it cannot be converted.
 * When it returns a non-null Double, this method effectively emulates the
 * <code>Number()</code> JavaScript cast function.
 */
static Double getNumberValue(Node n) {
  switch (n.getType()) {
    case Token.TRUE:
      return 1.0;

    case Token.FALSE:
    case Token.NULL:
      return 0.0;

    case Token.NUMBER:
      return n.getDouble();

    case Token.VOID:
      if (mayHaveSideEffects(n.getFirstChild())) {
        return null;
      } else {
        return Double.NaN;
      }

    case Token.NAME:
      // Check for known constants
      String name = n.getString();
      if (name.equals("undefined")) {
        return Double.NaN;
      }
      if (name.equals("NaN")) {
        return Double.NaN;
      }
      if (name.equals("Infinity")) {
        return Double.POSITIVE_INFINITY;
      }
      return null;

    case Token.NEG:
      if (n.getChildCount() == 1 && n.getFirstChild().getType() == Token.NAME
          && n.getFirstChild().getString().equals("Infinity")) {
        return Double.NEGATIVE_INFINITY;
      }
      return null;

    case Token.NOT:
      TernaryValue child = getPureBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? 0.0 : 1.0; // reversed.
      }
      break;

    case Token.STRING:
      return getStringNumberValue(n.getString());

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      String value = getStringValue(n);
      return value != null ? getStringNumberValue(value) : null;
  }

  return null;
}
 
Example 13
Source File: Closure_23_PeepholeFoldConstants_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold shift operations
 */
private Node tryFoldShift(Node n, Node left, Node right) {
  if (left.isNumber() &&
      right.isNumber()) {

    double result;
    double lval = left.getDouble();
    double rval = right.getDouble();

    // check ranges.  We do not do anything that would clip the double to
    // a 32-bit range, since the user likely does not intend that.
    if (!(lval >= Integer.MIN_VALUE && lval <= Integer.MAX_VALUE)) {
      error(BITWISE_OPERAND_OUT_OF_RANGE, left);
      return n;
    }

    // only the lower 5 bits are used when shifting, so don't do anything
    // if the shift amount is outside [0,32)
    if (!(rval >= 0 && rval < 32)) {
      error(SHIFT_AMOUNT_OUT_OF_BOUNDS, right);
      return n;
    }

    // Convert the numbers to ints
    int lvalInt = (int) lval;
    if (lvalInt != lval) {
      error(FRACTIONAL_BITWISE_OPERAND, left);
      return n;
    }

    int rvalInt = (int) rval;
    if (rvalInt != rval) {
      error(FRACTIONAL_BITWISE_OPERAND, right);
      return n;
    }

    switch (n.getType()) {
      case Token.LSH:
        result = lvalInt << rvalInt;
        break;
      case Token.RSH:
        result = lvalInt >> rvalInt;
        break;
      case Token.URSH:
        // JavaScript handles zero shifts on signed numbers differently than
        // Java as an Java int can not represent the unsigned 32-bit number
        // where JavaScript can so use a long here.
        long lvalLong = lvalInt & 0xffffffffL;
        result = lvalLong >>> rvalInt;
        break;
      default:
        throw new AssertionError("Unknown shift operator: " +
            Token.name(n.getType()));
    }

    Node newNumber = IR.number(result);
    n.getParent().replaceChild(n, newNumber);
    reportCodeChange();

    return newNumber;
  }

  return n;
}
 
Example 14
Source File: Closure_74_PeepholeFoldConstants_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold .substr() calls on strings
 */
private Node tryFoldStringSubstr(Node n, Node stringNode, Node arg1) {
  Preconditions.checkArgument(n.getType() == Token.CALL);
  Preconditions.checkArgument(stringNode.getType() == Token.STRING);

  int start, length;
  String stringAsString = stringNode.getString();

  // TODO(nicksantos): We really need a NodeUtil.getNumberValue
  // function.
  if (arg1 != null && arg1.getType() == Token.NUMBER) {
    start = (int) arg1.getDouble();
  } else {
    return n;
  }

  Node arg2 = arg1.getNext();
  if (arg2 != null) {
    if (arg2.getType() == Token.NUMBER) {
      length = (int) arg2.getDouble();
    } else {
      return n;
    }

    if (arg2.getNext() != null) {
      // If we got more args than we expected, bail out.
      return n;
    }
  } else {
    // parameter 2 not passed
    length = stringAsString.length() - start;
  }

  // Don't handle these cases. The specification actually does
  // specify the behavior in some of these cases, but we haven't
  // done a thorough investigation that it is correctly implemented
  // in all browsers.
  if ((start + length) > stringAsString.length() ||
      (length < 0) ||
      (start < 0)) {
    return n;
  }

  String result = stringAsString.substring(start, start + length);
  Node resultNode = Node.newString(result);

  Node parent = n.getParent();
  parent.replaceChild(n, resultNode);
  reportCodeChange();
  return resultNode;
}
 
Example 15
Source File: PeepholeFoldConstants.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Try to fold shift operations
 */
private Node tryFoldShift(Node n, Node left, Node right) {
  if (left.isNumber() &&
      right.isNumber()) {

    double result;
    double lval = left.getDouble();
    double rval = right.getDouble();

    // check ranges.  We do not do anything that would clip the double to
    // a 32-bit range, since the user likely does not intend that.
    if (!(lval >= Integer.MIN_VALUE && lval <= Integer.MAX_VALUE)) {
      report(BITWISE_OPERAND_OUT_OF_RANGE, left);
      return n;
    }

    // only the lower 5 bits are used when shifting, so don't do anything
    // if the shift amount is outside [0,32)
    if (!(rval >= 0 && rval < 32)) {
      report(SHIFT_AMOUNT_OUT_OF_BOUNDS, right);
      return n;
    }

    // Convert the numbers to ints
    int lvalInt = (int) lval;
    if (lvalInt != lval) {
      report(FRACTIONAL_BITWISE_OPERAND, left);
      return n;
    }

    int rvalInt = (int) rval;
    if (rvalInt != rval) {
      report(FRACTIONAL_BITWISE_OPERAND, right);
      return n;
    }

    switch (n.getType()) {
      case Token.LSH:
        result = lvalInt << rvalInt;
        break;
      case Token.RSH:
        result = lvalInt >> rvalInt;
        break;
      case Token.URSH:
        // JavaScript handles zero shifts on signed numbers differently than
        // Java as an Java int can not represent the unsigned 32-bit number
        // where JavaScript can so use a long here.
        long lvalLong = lvalInt & 0xffffffffL;
        result = lvalLong >>> rvalInt;
        break;
      default:
        throw new AssertionError("Unknown shift operator: " +
            Token.name(n.getType()));
    }

    Node newNumber = IR.number(result);
    n.getParent().replaceChild(n, newNumber);
    reportCodeChange();

    return newNumber;
  }

  return n;
}
 
Example 16
Source File: Cardumen_00200_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the value of a node as a Number, or null if it cannot be converted.
 * When it returns a non-null Double, this method effectively emulates the
 * <code>Number()</code> JavaScript cast function.
 */
static Double getNumberValue(Node n) {
  switch (n.getType()) {
    case Token.TRUE:
      return 1.0;

    case Token.FALSE:
    case Token.NULL:
      return 0.0;

    case Token.NUMBER:
      return n.getDouble();

    case Token.VOID:
      if (mayHaveSideEffects(n.getFirstChild())) {
        return null;
      } else {
        return Double.NaN;
      }

    case Token.NAME:
      // Check for known constants
      String name = n.getString();
      if (name.equals("undefined")) {
        return Double.NaN;
      }
      if (name.equals("NaN")) {
        return Double.NaN;
      }
      if (name.equals("Infinity")) {
        return Double.POSITIVE_INFINITY;
      }
      return null;

    case Token.NEG:
      if (n.getChildCount() == 1 && n.getFirstChild().isName()
          && n.getFirstChild().getString().equals("Infinity")) {
        return Double.NEGATIVE_INFINITY;
      }
      return null;

    case Token.NOT:
      TernaryValue child = getPureBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? 0.0 : 1.0; // reversed.
      }
      break;

    case Token.STRING:
      return getStringNumberValue(n.getString());

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      String value = getStringValue(n);
      return value != null ? getStringNumberValue(value) : null;
  }

  return null;
}
 
Example 17
Source File: Cardumen_00200_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the value of a node as a Number, or null if it cannot be converted.
 * When it returns a non-null Double, this method effectively emulates the
 * <code>Number()</code> JavaScript cast function.
 */
static Double getNumberValue(Node n) {
  switch (n.getType()) {
    case Token.TRUE:
      return 1.0;

    case Token.FALSE:
    case Token.NULL:
      return 0.0;

    case Token.NUMBER:
      return n.getDouble();

    case Token.VOID:
      if (mayHaveSideEffects(n.getFirstChild())) {
        return null;
      } else {
        return Double.NaN;
      }

    case Token.NAME:
      // Check for known constants
      String name = n.getString();
      if (name.equals("undefined")) {
        return Double.NaN;
      }
      if (name.equals("NaN")) {
        return Double.NaN;
      }
      if (name.equals("Infinity")) {
        return Double.POSITIVE_INFINITY;
      }
      return null;

    case Token.NEG:
      if (n.getChildCount() == 1 && n.getFirstChild().isName()
          && n.getFirstChild().getString().equals("Infinity")) {
        return Double.NEGATIVE_INFINITY;
      }
      return null;

    case Token.NOT:
      TernaryValue child = getPureBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? 0.0 : 1.0; // reversed.
      }
      break;

    case Token.STRING:
      return getStringNumberValue(n.getString());

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      String value = getStringValue(n);
      return value != null ? getStringNumberValue(value) : null;
  }

  return null;
}
 
Example 18
Source File: Closure_23_PeepholeFoldConstants_s.java    From coming with MIT License 4 votes vote down vote up
private Node tryFoldArrayAccess(Node n, Node left, Node right) {
  Node parent = n.getParent();
  // If GETPROP/GETELEM is used as assignment target the array literal is
  // acting as a temporary we can't fold it here:
  //    "[][0] += 1"
  if (isAssignmentTarget(n)) {
    return n;
  }

  if (!right.isNumber()) {
    // Sometimes people like to use complex expressions to index into
    // arrays, or strings to index into array methods.
    return n;
  }

  double index = right.getDouble();
  int intIndex = (int) index;
  if (intIndex != index) {
    error(INVALID_GETELEM_INDEX_ERROR, right);
    return n;
  }

  if (intIndex < 0) {
    error(INDEX_OUT_OF_BOUNDS_ERROR, right);
    return n;
  }

  Node current = left.getFirstChild();
  Node elem = null;
  for (int i = 0; current != null && i < intIndex; i++) {
      elem = current;

    current = current.getNext();
  }

  if (elem == null) {
    error(INDEX_OUT_OF_BOUNDS_ERROR, right);
    return n;
  }

  if (elem.isEmpty()) {
    elem = NodeUtil.newUndefinedNode(elem);
  } else {
    left.removeChild(elem);
  }

  // Replace the entire GETELEM with the value
  n.getParent().replaceChild(n, elem);
  reportCodeChange();
  return elem;
}
 
Example 19
Source File: Closure_75_NodeUtil_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the value of a node as a String, or null if it cannot be converted.
 * When it returns a non-null String, this method effectively emulates the
 * <code>String()</code> JavaScript cast function.
 */
static String getStringValue(Node n) {
  // TODO(user): regex literals as well.
  switch (n.getType()) {
    case Token.STRING:
      return n.getString();

    case Token.NAME:
      String name = n.getString();
      if ("undefined".equals(name)
          || "Infinity".equals(name)
          || "NaN".equals(name)) {
        return name;
      }
      break;

    case Token.NUMBER:
      double value = n.getDouble();
      long longValue = (long) value;

      // Return "1" instead of "1.0"
      if (longValue == value) {
        return Long.toString(longValue);
      } else {
        return Double.toString(n.getDouble());
      }

    case Token.FALSE:
    case Token.TRUE:
    case Token.NULL:
      return Node.tokenToName(n.getType());

    case Token.VOID:
      return "undefined";

    case Token.NOT:
      TernaryValue child = getPureBooleanValue(n.getFirstChild());
      if (child != TernaryValue.UNKNOWN) {
        return child.toBoolean(true) ? "false" : "true"; // reversed.
      }
      break;

    case Token.ARRAYLIT:
      return arrayToString(n);

    case Token.OBJECTLIT:
      return "[object Object]";
  }
  return null;
}
 
Example 20
Source File: Closure_105_FoldConstants_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold array-element. e.g [1, 2, 3][10];
 */
void tryFoldGetElem(NodeTraversal t, Node n, Node left, Node right,
                    Node parent) {
  if (left.getType() == Token.ARRAYLIT) {

    if (right.getType() != Token.NUMBER) {
      // Sometimes people like to use complex expressions to index into
      // arrays, or strings to index into array methods.
      return;
    }

    double index = right.getDouble();
    int intIndex = (int) index;
    if (intIndex != index) {
      t.getCompiler().report(JSError.make(t, right,
          INVALID_GETELEM_INDEX_ERROR, String.valueOf(index)));
      return;
    }

    if (intIndex < 0) {
      t.getCompiler().report(JSError.make(t, n, INDEX_OUT_OF_BOUNDS_ERROR,
          String.valueOf(intIndex)));
      return;
    }

    Node elem = left.getFirstChild();
    for (int i = 0; elem != null && i < intIndex; i++) {
      elem = elem.getNext();
    }

    if (elem == null) {
      t.getCompiler().report(JSError.make(t, n, INDEX_OUT_OF_BOUNDS_ERROR,
          String.valueOf(intIndex)));
      return;
    }

    // Replace the entire GETELEM with the value
    left.removeChild(elem);
    parent.replaceChild(n, elem);
    t.getCompiler().reportCodeChange();
  }
}