Java Code Examples for com.google.javascript.rhino.Token#OBJECTLIT

The following examples show how to use com.google.javascript.rhino.Token#OBJECTLIT . 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_94_NodeUtil_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Gets the function's name. This method recognizes the forms:
 * <ul>
 * <li>{@code {'name': function() ...}}</li>
 * <li>{@code {name: function() ...}}</li>
 * <li>{@code function name() ...}</li>
 * <li>{@code var name = function() ...}</li>
 * <li>{@code qualified.name = function() ...}</li>
 * <li>{@code var name2 = function name1() ...}</li>
 * <li>{@code qualified.name2 = function name1() ...}</li>
 * </ul>
 *
 * @param n a node whose type is {@link Token#FUNCTION}
 * @return the function's name, or {@code null} if it has no name
 */
static String getNearestFunctionName(Node n) {
  String name = getFunctionName(n);
  if (name != null) {
    return name;
  }

  // Check for the form { 'x' : function() { } }
  Node parent = n.getParent();
  switch (parent.getType()) {
    case Token.OBJECTLIT:
      // Return the name of the literal's key.
      return getStringValue(parent.getFirstChild());
  }

  return null;
}
 
Example 2
Source File: 1_ClosureCodingConvention.java    From SimFix with GNU General Public License v2.0 6 votes vote down vote up
@Override
public ObjectLiteralCast getObjectLiteralCast(NodeTraversal t,
    Node callNode) {
  Preconditions.checkArgument(callNode.getType() == Token.CALL);
  Node callName = callNode.getFirstChild();
  if (!"goog.reflect.object".equals(callName.getQualifiedName()) ||
      callNode.getChildCount() != 3) {
    return null;
  }

  Node typeNode = callName.getNext();
  if (!typeNode.isQualifiedName()) {
    return null;
  }

  Node objectNode = typeNode.getNext();
  if (objectNode.getType() != Token.OBJECTLIT) {
    // TODO(johnlenz): The coding convention should not be performing checks.
    t.getCompiler().report(JSError.make(t.getSourceName(), callNode,
                                        OBJECTLIT_EXPECTED));
    return null;
  }

  return new ObjectLiteralCast(typeNode.getQualifiedName(),
                               typeNode.getNext());
}
 
Example 3
Source File: Closure_114_NameAnalyzer_t.java    From coming with MIT License 5 votes vote down vote up
@Override
public void remove() {
  // Setters have VAR, FUNCTION, or ASSIGN parent nodes. CALL parent
  // nodes are global refs, and are handled later in this function.
  Node containingNode = parent.getParent();
  switch (parent.getType()) {
    case Token.VAR:
      Preconditions.checkState(parent.hasOneChild());
      replaceWithRhs(containingNode, parent);
      break;
    case Token.FUNCTION:
      replaceWithRhs(containingNode, parent);
      break;
    case Token.ASSIGN:
      if (containingNode.isExprResult()) {
        replaceWithRhs(containingNode.getParent(), containingNode);
      } else {
        replaceWithRhs(containingNode, parent);
      }
      break;
    case Token.OBJECTLIT:
      // TODO(nicksantos): Come up with a way to remove this.
      // If we remove object lit keys, then we will need to also
      // create dependency scopes for them.
      break;
  }
}
 
Example 4
Source File: Closure_60_NodeUtil_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Determines whether a node represents an object literal key
 * (e.g. key1 in {key1: value1, key2: value2}).
 *
 * @param node A node
 * @param parent The node's parent
 */
static boolean isObjectLitKey(Node node, Node parent) {
  switch (node.getType()) {
    case Token.STRING:
      return parent.getType() == Token.OBJECTLIT;
    case Token.GET:
    case Token.SET:
      return true;
  }
  return false;
}
 
Example 5
Source File: StripCode.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.VAR:
      removeVarDeclarationsByNameOrRvalue(t, n, parent);
      break;

    case Token.NAME:
      maybeRemoveReferenceToRemovedVariable(t, n, parent);
      break;

    case Token.ASSIGN:
    case Token.ASSIGN_BITOR:
    case Token.ASSIGN_BITXOR:
    case Token.ASSIGN_BITAND:
    case Token.ASSIGN_LSH:
    case Token.ASSIGN_RSH:
    case Token.ASSIGN_URSH:
    case Token.ASSIGN_ADD:
    case Token.ASSIGN_SUB:
    case Token.ASSIGN_MUL:
    case Token.ASSIGN_DIV:
    case Token.ASSIGN_MOD:
      maybeEliminateAssignmentByLvalueName(t, n, parent);
      break;

    case Token.CALL:
    case Token.NEW:
      maybeRemoveCall(t, n, parent);
      break;

    case Token.OBJECTLIT:
      eliminateKeysWithStripNamesFromObjLit(t, n);
      break;

    case Token.EXPR_RESULT:
      maybeEliminateExpressionByName(t, n, parent);
      break;
  }
}
 
Example 6
Source File: Closure_60_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 7
Source File: Closure_89_CollapseProperties_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Updates the first initialization (a.k.a "declaration") of a global name
 * that occurs at an ASSIGN node. See comment for
 * {@link #updateObjLitOrFunctionDeclaration}.
 *
 * @param n An object representing a global name (e.g. "a", "a.b.c")
 * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
 */
private void updateObjLitOrFunctionDeclarationAtAssignNode(
    Name n, String alias) {
  // NOTE: It's important that we don't add additional nodes
  // (e.g. a var node before the exprstmt) because the exprstmt might be
  // the child of an if statement that's not inside a block).

  Ref ref = n.declaration;
  Node rvalue = ref.node.getNext();
  Node varNode = new Node(Token.VAR);
  Node varParent = ref.node.getAncestor(3);
  Node gramps = ref.node.getAncestor(2);
  boolean isObjLit = rvalue.getType() == Token.OBJECTLIT;

  if (isObjLit && n.canEliminate()) {
    // Eliminate the object literal altogether.
    varParent.replaceChild(gramps, varNode);
    ref.node = null;

  } else {
    if (rvalue.getType() == Token.FUNCTION) {
      checkForHosedThisReferences(rvalue, n.docInfo, n);
    }

    ref.node.getParent().removeChild(rvalue);

    Node nameNode = NodeUtil.newName(
        compiler.getCodingConvention(),
        alias, ref.node.getAncestor(2), n.fullName());

    if (ref.node.getLastChild().getBooleanProp(Node.IS_CONSTANT_NAME)) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }

    varNode.addChildToBack(nameNode);
    nameNode.addChildToFront(rvalue);
    varParent.replaceChild(gramps, varNode);

    // Update the node ancestry stored in the reference.
    ref.node = nameNode;
  }

  if (isObjLit) {
    declareVarsForObjLitValues(
        n, alias, rvalue,
        varNode, varParent.getChildBefore(varNode), varParent);
  }

  addStubsForUndeclaredProperties(n, alias, varParent, varNode);

  if (!varNode.hasChildren()) {
    varParent.removeChild(varNode);
  }

  compiler.reportCodeChange();
}
 
Example 8
Source File: Cardumen_00149_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the boolean value of a node that represents a literal. This method
 * effectively emulates the <code>Boolean()</code> JavaScript cast function
 * except it return UNKNOWN for known values with side-effects, use
 * getExpressionBooleanValue if you don't care about side-effects.
 */
static TernaryValue getPureBooleanValue(Node n) {
  switch (n.getType()) {
    case Token.STRING:
      return TernaryValue.forBoolean(n.getString().length() > 0);

    case Token.NUMBER:
      return TernaryValue.forBoolean(n.getDouble() != 0);

    case Token.NOT:
      return getPureBooleanValue(n.getLastChild()).not();

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

    case Token.VOID:
      if (!mayHaveSideEffects(n.getFirstChild())) {
        return TernaryValue.FALSE;
      }
      break;

    case Token.NAME:
      String name = n.getString();
      if ("undefined".equals(name)
          || "NaN".equals(name)) {
        // We assume here that programs don't change the value of the keyword
        // undefined to something other than the value undefined.
        return TernaryValue.FALSE;
      } else if ("Infinity".equals(name)) {
        return TernaryValue.TRUE;
      }
      break;

    case Token.TRUE:
    case Token.REGEXP:
      return TernaryValue.TRUE;

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      if (!mayHaveSideEffects(n)) {
        return TernaryValue.TRUE;
      }
      break;
  }

  return TernaryValue.UNKNOWN;
}
 
Example 9
Source File: Cardumen_0014_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 10
Source File: Closure_70_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
private void attachLiteralTypes(NodeTraversal t, Node n) {
  switch (n.getType()) {
    case Token.NULL:
      n.setJSType(getNativeType(NULL_TYPE));
      break;

    case Token.VOID:
      n.setJSType(getNativeType(VOID_TYPE));
      break;

    case Token.STRING:
      // Defer keys to the Token.OBJECTLIT case
      if (!NodeUtil.isObjectLitKey(n, n.getParent())) {
        n.setJSType(getNativeType(STRING_TYPE));
      }
      break;

    case Token.NUMBER:
      n.setJSType(getNativeType(NUMBER_TYPE));
      break;

    case Token.TRUE:
    case Token.FALSE:
      n.setJSType(getNativeType(BOOLEAN_TYPE));
      break;

    case Token.REGEXP:
      n.setJSType(getNativeType(REGEXP_TYPE));
      break;

    case Token.REF_SPECIAL:
      n.setJSType(getNativeType(UNKNOWN_TYPE));
      break;

    case Token.OBJECTLIT:
      defineObjectLiteral(t, n);
      break;

      // NOTE(nicksantos): If we ever support Array tuples,
      // we will need to put ARRAYLIT here as well.
  }
}
 
Example 11
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 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:
    case Token.STRING_KEY:
      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:
      return getStringValue(n.getDouble());

    case Token.FALSE:
      return "false";

    case Token.TRUE:
      return "true";

    case Token.NULL:
      return "null";

    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 12
Source File: Nopol2017_0027_t.java    From coming with MIT License 4 votes vote down vote up
private void attachLiteralTypes(NodeTraversal t, Node n) {
  switch (n.getType()) {
    case Token.NULL:
      n.setJSType(getNativeType(NULL_TYPE));
      break;

    case Token.VOID:
      n.setJSType(getNativeType(VOID_TYPE));
      break;

    case Token.STRING:
      n.setJSType(getNativeType(STRING_TYPE));
      break;

    case Token.NUMBER:
      n.setJSType(getNativeType(NUMBER_TYPE));
      break;

    case Token.TRUE:
    case Token.FALSE:
      n.setJSType(getNativeType(BOOLEAN_TYPE));
      break;

    case Token.REGEXP:
      n.setJSType(getNativeType(REGEXP_TYPE));
      break;

    case Token.OBJECTLIT:
      JSDocInfo info = n.getJSDocInfo();
      if (info != null &&
          info.getLendsName() != null) {
        if (lentObjectLiterals == null) {
          lentObjectLiterals = Lists.newArrayList();
        }
        lentObjectLiterals.add(n);
      } else {
        defineObjectLiteral(n);
      }
      break;

      // NOTE(nicksantos): If we ever support Array tuples,
      // we will need to put ARRAYLIT here as well.
  }
}
 
Example 13
Source File: Closure_61_NodeUtil_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Gets the boolean value of a node that represents a literal. This method
 * effectively emulates the <code>Boolean()</code> JavaScript cast function
 * except it return UNKNOWN for known values with side-effects, use
 * getExpressionBooleanValue if you don't care about side-effects.
 */
static TernaryValue getPureBooleanValue(Node n) {
  switch (n.getType()) {
    case Token.STRING:
      return TernaryValue.forBoolean(n.getString().length() > 0);

    case Token.NUMBER:
      return TernaryValue.forBoolean(n.getDouble() != 0);

    case Token.NOT:
      return getPureBooleanValue(n.getLastChild()).not();

    case Token.NULL:
    case Token.FALSE:
    case Token.VOID:
      return TernaryValue.FALSE;

    case Token.NAME:
      String name = n.getString();
      if ("undefined".equals(name)
          || "NaN".equals(name)) {
        // We assume here that programs don't change the value of the keyword
        // undefined to something other than the value undefined.
        return TernaryValue.FALSE;
      } else if ("Infinity".equals(name)) {
        return TernaryValue.TRUE;
      }
      break;

    case Token.TRUE:
    case Token.REGEXP:
      return TernaryValue.TRUE;

    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      if (!mayHaveSideEffects(n)) {
        return TernaryValue.TRUE;
      }
  }

  return TernaryValue.UNKNOWN;
}
 
Example 14
Source File: Cardumen_0087_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @param locals A predicate to apply to unknown local values.
 * @return Whether the node is known to be a value that is not a reference
 *     outside the expression scope.
 */
static boolean evaluatesToLocalValue(Node value, Predicate<Node> locals) {
  switch (value.getType()) {
    case Token.ASSIGN:
      // A result that is aliased by a non-local name, is the effectively the
      // same as returning a non-local name, but this doesn't matter if the
      // value is immutable.
      return NodeUtil.isImmutableValue(value.getLastChild())
          || (locals.apply(value)
              && evaluatesToLocalValue(value.getLastChild(), locals));
    case Token.COMMA:
      return evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.AND:
    case Token.OR:
      return evaluatesToLocalValue(value.getFirstChild(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.HOOK:
      return evaluatesToLocalValue(value.getFirstChild().getNext(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.INC:
    case Token.DEC:
      if (value.getBooleanProp(Node.INCRDECR_PROP)) {
        return evaluatesToLocalValue(value.getFirstChild(), locals);
      } else {
        return true;
      }
    case Token.THIS:
      return locals.apply(value);
    case Token.NAME:
      return isImmutableValue(value) || locals.apply(value);
    case Token.GETELEM:
    case Token.GETPROP:
      // There is no information about the locality of object properties.
      return locals.apply(value);
    case Token.CALL:
      return callHasLocalResult(value)
          || isToStringMethodCall(value)
          || locals.apply(value);
    case Token.NEW:
      return newHasLocalResult(value)
             || locals.apply(value);
    case Token.FUNCTION:
    case Token.REGEXP:
    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      // Literals objects with non-literal children are allowed.
      return true;
    case Token.DELPROP:
    case Token.IN:
      // TODO(johnlenz): should IN operator be included in #isSimpleOperator?
      return true;
    default:
      // Other op force a local value:
      //  x = '' + g (x is now an local string)
      //  x -= g (x is now an local number)
      if (isAssignmentOp(value)
          || isSimpleOperator(value)
          || isImmutableValue(value)) {
        return true;
      }

      throw new IllegalStateException(
          "Unexpected expression node" + value +
          "\n parent:" + value.getParent());
  }
}
 
Example 15
Source File: Closure_89_GlobalNamespace_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (nodeFilter != null && !nodeFilter.apply(n)) {
    return;
  }

  // If we are traversing the externs, then we save a pointer to the scope
  // generated by them, so that we can do lookups in it later.
  if (externsRoot != null && n == externsRoot) {
    externsScope = t.getScope();
  }

  String name;
  boolean isSet = false;
  Name.Type type = Name.Type.OTHER;
  boolean isPropAssign = false;

  switch (n.getType()) {
    case Token.STRING:
      // This may be a key in an object literal declaration.
      name = null;
      if (parent != null && parent.getType() == Token.OBJECTLIT) {
        name = getNameForObjLitKey(n);
      }
      if (name == null) return;
      isSet = true;
      type = getValueType(n.getFirstChild());
      break;
    case Token.NAME:
      // This may be a variable get or set.
      if (parent != null) {
        switch (parent.getType()) {
          case Token.VAR:
            isSet = true;
            Node rvalue = n.getFirstChild();
            type = rvalue == null ? Name.Type.OTHER : getValueType(rvalue);
            break;
          case Token.ASSIGN:
            if (parent.getFirstChild() == n) {
              isSet = true;
              type = getValueType(n.getNext());
            }
            break;
          case Token.GETPROP:
            return;
          case Token.FUNCTION:
            Node gramps = parent.getParent();
            if (gramps == null ||
                NodeUtil.isFunctionExpression(parent)) return;
            isSet = true;
            type = Name.Type.FUNCTION;
            break;
        }
      }
      name = n.getString();
      break;
    case Token.GETPROP:
      // This may be a namespaced name get or set.
      if (parent != null) {
        switch (parent.getType()) {
          case Token.ASSIGN:
            if (parent.getFirstChild() == n) {
              isSet = true;
              type = getValueType(n.getNext());
              isPropAssign = true;
            }
            break;
          case Token.GETPROP:
            return;
        }
      }
      name = n.getQualifiedName();
      if (name == null) return;
      break;
    default:
      return;
  }

  // We are only interested in global names.
  Scope scope = t.getScope();
  if (!isGlobalNameReference(name, scope)) {
    return;
  }

  if (isSet) {
    if (isGlobalScope(scope)) {
      handleSetFromGlobal(t, n, parent, name, isPropAssign, type);
    } else {
      handleSetFromLocal(t, n, parent, name);
    }
  } else {
    handleGet(t, n, parent, name);
  }
}
 
Example 16
Source File: MethodCompilerPass.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.GETPROP:
    case Token.GETELEM:
      Node dest = n.getFirstChild().getNext();

      if (dest.isString()) {
        if (dest.getString().equals("prototype")) {
          processPrototypeParent(t, parent);
        } else {
          // Static methods of the form Foo.bar = function() {} or
          // Static methods of the form Foo.bar = baz (where baz is a
          // function name). Parse tree looks like:
          // assign                 <- parent
          //      getprop           <- n
          //          name Foo
          //          string bar
          //      function or name  <- n.getNext()
          if (parent.isAssign() &&
              parent.getFirstChild() == n) {
            addPossibleSignature(dest.getString(), n.getNext(), t);
          }
        }
      }
      break;

    case Token.OBJECTLIT:
      for (Node key = n.getFirstChild(); key != null; key = key.getNext()) {
        switch(key.getType()) {
          case Token.STRING_KEY:
            addPossibleSignature(key.getString(), key.getFirstChild(), t);
            break;
          case Token.SETTER_DEF:
          case Token.GETTER_DEF:
            nonMethodProperties.add(key.getString());
            break;
          default:
            throw new IllegalStateException(
                "unexpect OBJECTLIT key: " + key);
        }
      }
      break;
  }
}
 
Example 17
Source File: Closure_74_PeepholeFoldConstants_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold array-element. e.g [1, 2, 3][10];
 */
private Node tryFoldGetElem(Node n, Node left, Node right) {
  Preconditions.checkArgument(n.getType() == Token.GETELEM);

  if (left.getType() == Token.OBJECTLIT) {
    return tryFoldObjectPropAccess(n, left, right);
  }

  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 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 elem = left.getFirstChild();
    for (int i = 0; elem != null && i < intIndex; i++) {
      elem = elem.getNext();
    }

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

    if (elem.getType() == Token.EMPTY) {
      elem = NodeUtil.newUndefinedNode(elem);
    } else {
      left.removeChild(elem);
    }

    // Replace the entire GETELEM with the value
    n.getParent().replaceChild(n, elem);
    reportCodeChange();
    return elem;
  }
  return n;
}
 
Example 18
Source File: Closure_10_NodeUtil_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @param locals A predicate to apply to unknown local values.
 * @return Whether the node is known to be a value that is not a reference
 *     outside the expression scope.
 */
static boolean evaluatesToLocalValue(Node value, Predicate<Node> locals) {
  switch (value.getType()) {
    case Token.ASSIGN:
      // A result that is aliased by a non-local name, is the effectively the
      // same as returning a non-local name, but this doesn't matter if the
      // value is immutable.
      return NodeUtil.isImmutableValue(value.getLastChild())
          || (locals.apply(value)
              && evaluatesToLocalValue(value.getLastChild(), locals));
    case Token.COMMA:
      return evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.AND:
    case Token.OR:
      return evaluatesToLocalValue(value.getFirstChild(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.HOOK:
      return evaluatesToLocalValue(value.getFirstChild().getNext(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.INC:
    case Token.DEC:
      if (value.getBooleanProp(Node.INCRDECR_PROP)) {
        return evaluatesToLocalValue(value.getFirstChild(), locals);
      } else {
        return true;
      }
    case Token.THIS:
      return locals.apply(value);
    case Token.NAME:
      return isImmutableValue(value) || locals.apply(value);
    case Token.GETELEM:
    case Token.GETPROP:
      // There is no information about the locality of object properties.
      return locals.apply(value);
    case Token.CALL:
      return callHasLocalResult(value)
          || isToStringMethodCall(value)
          || locals.apply(value);
    case Token.NEW:
      return newHasLocalResult(value)
             || locals.apply(value);
    case Token.FUNCTION:
    case Token.REGEXP:
    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      // Literals objects with non-literal children are allowed.
      return true;
    case Token.DELPROP:
    case Token.IN:
      // TODO(johnlenz): should IN operator be included in #isSimpleOperator?
      return true;
    default:
      // Other op force a local value:
      //  x = '' + g (x is now an local string)
      //  x -= g (x is now an local number)
      if (isAssignmentOp(value)
          || isSimpleOperator(value)
          || isImmutableValue(value)) {
        return true;
      }

      throw new IllegalStateException(
          "Unexpected expression node" + value +
          "\n parent:" + value.getParent());
  }
}
 
Example 19
Source File: Closure_61_NodeUtil_s.java    From coming with MIT License 4 votes vote down vote up
static int precedence(int type) {
  switch (type) {
    case Token.COMMA:  return 0;
    case Token.ASSIGN_BITOR:
    case Token.ASSIGN_BITXOR:
    case Token.ASSIGN_BITAND:
    case Token.ASSIGN_LSH:
    case Token.ASSIGN_RSH:
    case Token.ASSIGN_URSH:
    case Token.ASSIGN_ADD:
    case Token.ASSIGN_SUB:
    case Token.ASSIGN_MUL:
    case Token.ASSIGN_DIV:
    case Token.ASSIGN_MOD:
    case Token.ASSIGN: return 1;
    case Token.HOOK:   return 2;  // ?: operator
    case Token.OR:     return 3;
    case Token.AND:    return 4;
    case Token.BITOR:  return 5;
    case Token.BITXOR: return 6;
    case Token.BITAND: return 7;
    case Token.EQ:
    case Token.NE:
    case Token.SHEQ:
    case Token.SHNE:   return 8;
    case Token.LT:
    case Token.GT:
    case Token.LE:
    case Token.GE:
    case Token.INSTANCEOF:
    case Token.IN:     return 9;
    case Token.LSH:
    case Token.RSH:
    case Token.URSH:   return 10;
    case Token.SUB:
    case Token.ADD:    return 11;
    case Token.MUL:
    case Token.MOD:
    case Token.DIV:    return 12;
    case Token.INC:
    case Token.DEC:
    case Token.NEW:
    case Token.DELPROP:
    case Token.TYPEOF:
    case Token.VOID:
    case Token.NOT:
    case Token.BITNOT:
    case Token.POS:
    case Token.NEG:    return 13;

    case Token.CALL:
    case Token.GETELEM:
    case Token.GETPROP:
    // Data values
    case Token.ARRAYLIT:
    case Token.EMPTY:  // TODO(johnlenz): remove this.
    case Token.FALSE:
    case Token.FUNCTION:
    case Token.NAME:
    case Token.NULL:
    case Token.NUMBER:
    case Token.OBJECTLIT:
    case Token.REGEXP:
    case Token.STRING:
    case Token.THIS:
    case Token.TRUE:
      return 15;

    default: throw new Error("Unknown precedence for " +
                             Node.tokenToName(type) +
                             " (type " + type + ")");
  }
}
 
Example 20
Source File: jKali_003_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @param locals A predicate to apply to unknown local values.
 * @return Whether the node is known to be a value that is not a reference
 *     outside the expression scope.
 */
static boolean evaluatesToLocalValue(Node value, Predicate<Node> locals) {
  switch (value.getType()) {
    case Token.ASSIGN:
      // A result that is aliased by a non-local name, is the effectively the
      // same as returning a non-local name, but this doesn't matter if the
      // value is immutable.
      return NodeUtil.isImmutableValue(value.getLastChild())
          || (locals.apply(value)
              && evaluatesToLocalValue(value.getLastChild(), locals));
    case Token.COMMA:
      return evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.AND:
    case Token.OR:
      return evaluatesToLocalValue(value.getFirstChild(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.HOOK:
      return evaluatesToLocalValue(value.getFirstChild().getNext(), locals)
         && evaluatesToLocalValue(value.getLastChild(), locals);
    case Token.INC:
    case Token.DEC:
      if (value.getBooleanProp(Node.INCRDECR_PROP)) {
        return evaluatesToLocalValue(value.getFirstChild(), locals);
      } else {
        return true;
      }
    case Token.THIS:
      return locals.apply(value);
    case Token.NAME:
      return isImmutableValue(value) || locals.apply(value);
    case Token.GETELEM:
    case Token.GETPROP:
      // There is no information about the locality of object properties.
      return locals.apply(value);
    case Token.CALL:
      return callHasLocalResult(value)
          || isToStringMethodCall(value)
          || locals.apply(value);
    case Token.NEW:
      return newHasLocalResult(value)
             || locals.apply(value);
    case Token.FUNCTION:
    case Token.REGEXP:
    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      // Literals objects with non-literal children are allowed.
      return true;
    case Token.DELPROP:
    case Token.IN:
      // TODO(johnlenz): should IN operator be included in #isSimpleOperator?
      return true;
    default:
      // Other op force a local value:
      //  x = '' + g (x is now an local string)
      //  x -= g (x is now an local number)
      if (isAssignmentOp(value)
          || isSimpleOperator(value)
          || isImmutableValue(value)) {
        return true;
      }

      throw new IllegalStateException(
          "Unexpected expression node" + value +
          "\n parent:" + value.getParent());
  }
}