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

The following examples show how to use com.google.javascript.rhino.Token#HOOK . 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_114_NameAnalyzer_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Determine if the parent reads the value of a child expression
 * directly.  This is true children used in predicates, RETURN
 * statements and, RHS of variable declarations and assignments.
 *
 * In the case of:
 * if (a) b else c
 *
 * This method returns true for "a", and false for "b" and "c": the
 * IF expression does something special based on "a"'s value.  "b"
 * and "c" are effectively outputs.  Same logic applies to FOR,
 * WHILE and DO loop predicates.  AND/OR/HOOK expressions are
 * syntactic sugar for IF statements; therefore this method returns
 * true for the predicate and false otherwise.
 */
private boolean valueConsumedByParent(Node n, Node parent) {
  if (NodeUtil.isAssignmentOp(parent)) {
    return parent.getLastChild() == n;
  }

  switch (parent.getType()) {
    case Token.NAME:
    case Token.RETURN:
      return true;
    case Token.AND:
    case Token.OR:
    case Token.HOOK:
      return parent.getFirstChild() == n;
    case Token.FOR:
      return parent.getFirstChild().getNext() == n;
    case Token.IF:
    case Token.WHILE:
      return parent.getFirstChild() == n;
    case Token.DO:
      return parent.getLastChild() == n;
    default:
      return false;
  }
}
 
Example 2
Source File: GlobalNamespace.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Gets the type of a value or simple expression.
 *
 * @param n An r-value in an assignment or variable declaration (not null)
 * @return A {@link Name.Type}
 */
Name.Type getValueType(Node n) {
  switch (n.getType()) {
    case Token.OBJECTLIT:
      return Name.Type.OBJECTLIT;
    case Token.FUNCTION:
      return Name.Type.FUNCTION;
    case Token.OR:
      // Recurse on the second value. If the first value were an object
      // literal or function, then the OR would be meaningless and the
      // second value would be dead code. Assume that if the second value
      // is an object literal or function, then the first value will also
      // evaluate to one when it doesn't evaluate to false.
      return getValueType(n.getLastChild());
    case Token.HOOK:
      // The same line of reasoning used for the OR case applies here.
      Node second = n.getFirstChild().getNext();
      Name.Type t = getValueType(second);
      if (t != Name.Type.OTHER) return t;
      Node third = second.getNext();
      return getValueType(third);
  }
  return Name.Type.OTHER;
}
 
Example 3
Source File: Closure_10_NodeUtil_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Apply the supplied predicate against
 * all possible result Nodes of the expression.
 */
static boolean anyResultsMatch(Node n, Predicate<Node> p) {
  switch (n.getType()) {
    case Token.ASSIGN:
    case Token.COMMA:
      return anyResultsMatch(n.getLastChild(), p);
    case Token.AND:
    case Token.OR:
      return anyResultsMatch(n.getFirstChild(), p)
          || anyResultsMatch(n.getLastChild(), p);
    case Token.HOOK:
      return anyResultsMatch(n.getFirstChild().getNext(), p)
          || anyResultsMatch(n.getLastChild(), p);
    default:
      return p.apply(n);
  }
}
 
Example 4
Source File: Cardumen_00200_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Apply the supplied predicate against
 * all possible result Nodes of the expression.
 */
static boolean anyResultsMatch(Node n, Predicate<Node> p) {
  switch (n.getType()) {
    case Token.ASSIGN:
    case Token.COMMA:
      return anyResultsMatch(n.getLastChild(), p);
    case Token.AND:
    case Token.OR:
      return anyResultsMatch(n.getFirstChild(), p)
          || anyResultsMatch(n.getLastChild(), p);
    case Token.HOOK:
      return anyResultsMatch(n.getFirstChild().getNext(), p)
          || anyResultsMatch(n.getLastChild(), p);
    default:
      return p.apply(n);
  }
}
 
Example 5
Source File: jMutRepair_003_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Apply the supplied predicate against
 * all possible result Nodes of the expression.
 */
static boolean anyResultsMatch(Node n, Predicate<Node> p) {
  switch (n.getType()) {
    case Token.ASSIGN:
    case Token.COMMA:
      return anyResultsMatch(n.getLastChild(), p);
    case Token.AND:
    case Token.OR:
      return anyResultsMatch(n.getFirstChild(), p)
          || anyResultsMatch(n.getLastChild(), p);
    case Token.HOOK:
      return anyResultsMatch(n.getFirstChild().getNext(), p)
          || anyResultsMatch(n.getLastChild(), p);
    default:
      return p.apply(n);
  }
}
 
Example 6
Source File: Closure_80_NodeUtil_s.java    From coming with MIT License 6 votes vote down vote up
/**
 * Apply the supplied predicate against the potential
 * all possible result of the expression.
 */
static boolean valueCheck(Node n, Predicate<Node> p) {
  switch (n.getType()) {
    case Token.ASSIGN:
    case Token.COMMA:
      return valueCheck(n.getLastChild(), p);
    case Token.AND:
    case Token.OR:
      return valueCheck(n.getFirstChild(), p)
          && valueCheck(n.getLastChild(), p);
    case Token.HOOK:
      return valueCheck(n.getFirstChild().getNext(), p)
          && valueCheck(n.getLastChild(), p);
    default:
      return p.apply(n);
  }
}
 
Example 7
Source File: PeepholeFoldConstants.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private void tryConvertToNumber(Node n) {
  switch (n.getType()) {
    case Token.NUMBER:
      // Nothing to do
      return;
    case Token.AND:
    case Token.OR:
    case Token.COMMA:
      tryConvertToNumber(n.getLastChild());
      return;
    case Token.HOOK:
      tryConvertToNumber(n.getChildAtIndex(1));
      tryConvertToNumber(n.getLastChild());
      return;
    case Token.NAME:
      if (!NodeUtil.isUndefined(n)) {
        return;
      }
      break;
  }

  Double result = NodeUtil.getNumberValue(n);
  if (result == null) {
    return;
  }

  double value = result;

  Node replacement = NodeUtil.numberNode(value, n);
  if (replacement.isEquivalentTo(n)) {
    return;
  }

  n.getParent().replaceChild(n, replacement);
  reportCodeChange();
}
 
Example 8
Source File: Closure_76_DeadAssignmentsElimination_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Given a variable, node n in the tree and a sub-tree denoted by exprRoot as
 * the root, this function returns true if there exists a read of that
 * variable before a write to that variable that is on the right side of n.
 *
 * For example, suppose the node is x = 1:
 *
 * y = 1, x = 1; // false, there is no reads at all.
 * y = 1, x = 1, print(x) // true, there is a read right of n.
 * y = 1, x = 1, x = 2, print(x) // false, there is a read right of n but
 *                               // it is after a write.
 *
 * @param n The current node we should look at.
 * @param exprRoot The node
 */
private boolean isVariableStillLiveWithinExpression(
    Node n, Node exprRoot, String variable) {
  while (n != exprRoot) {
    VariableLiveness state = VariableLiveness.MAYBE_LIVE;
    switch (n.getParent().getType()) {
      case Token.OR:
      case Token.AND:
        // If the currently node is the first child of
        // AND/OR, be conservative only consider the READs
        // of the second operand.

      case Token.HOOK:
        // If current node is the condition, check each following
        // branch, otherwise it is a conditional branch and the
        // other branch can be ignored.

      default:
        for(Node sibling = n.getNext(); sibling != null;
            sibling = sibling.getNext()) {
          if (!ControlFlowGraph.isEnteringNewCfgNode(sibling)) {
          state = isVariableReadBeforeKill(sibling, variable);

    // If we see a READ or KILL there is no need to continue.
    if (state == VariableLiveness.READ) {
      return true;
    } else if (state == VariableLiveness.KILL) {
      return false;
          }
        }
    }
    }
    n = n.getParent();
  }
  return false;
}
 
Example 9
Source File: Closure_106_GlobalNamespace_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Updates our respresentation of the global namespace to reflect a read
 * of a global name.
 *
 * @param t The traversal
 * @param n The node currently being visited
 * @param parent {@code n}'s parent
 * @param name The global name (e.g. "a" or "a.b.c.d")
 */
void handleGet(NodeTraversal t, Node n, Node parent, String name) {
  if (maybeHandlePrototypePrefix(t, n, parent, name)) return;

  Ref.Type type = Ref.Type.DIRECT_GET;
  if (parent != null) {
    switch (parent.getType()) {
      case Token.IF:
      case Token.TYPEOF:
      case Token.VOID:
      case Token.NOT:
      case Token.BITNOT:
      case Token.POS:
      case Token.NEG:
        break;
      case Token.CALL:
        type = n == parent.getFirstChild()
               ? Ref.Type.CALL_GET
               : Ref.Type.ALIASING_GET;
        break;
      case Token.NEW:
        type = n == parent.getFirstChild()
               ? Ref.Type.DIRECT_GET
               : Ref.Type.ALIASING_GET;
        break;
      case Token.OR:
      case Token.AND:
        // This node is x or y in (x||y) or (x&&y). We only know that an
        // alias is not getting created for this name if the result is used
        // in a boolean context or assigned to the same name
        // (e.g. var a = a || {}).
        type = determineGetTypeForHookOrBooleanExpr(t, parent, name);
        break;
      case Token.HOOK:
        if (n != parent.getFirstChild()) {
          // This node is y or z in (x?y:z). We only know that an alias is
          // not getting created for this name if the result is assigned to
          // the same name (e.g. var a = a ? a : {}).
          type = determineGetTypeForHookOrBooleanExpr(t, parent, name);
        }
        break;
      default:
        type = Ref.Type.ALIASING_GET;
        break;
    }
  }

  handleGet(t, n, parent, name, type);
}
 
Example 10
Source File: Closure_80_NodeUtil_s.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.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 11
Source File: Closure_94_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) || locals.apply(value);
    case Token.NEW:
      return true;
    case Token.FUNCTION:
    case Token.REGEXP:
    case Token.ARRAYLIT:
    case Token.OBJECTLIT:
      // Literals objects with non-literal children are allowed.
      return true;
    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 12
Source File: jMutRepair_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());
  }
}
 
Example 13
Source File: Closure_105_FoldConstants_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Try to fold a AND/OR node.
 */
void tryFoldAndOr(NodeTraversal t, Node n, Node left, Node right,
                  Node parent) {
  Node result = null;

  int type = n.getType();
  if (NodeUtil.isLiteralValue(left)) {
    boolean lval = NodeUtil.getBooleanValue(left);

    // (TRUE || x) => TRUE (also, (3 || x) => 3)
    // (FALSE && x) => FALSE
    if (lval && type == Token.OR ||
        !lval && type == Token.AND) {
      result = left;

    } else {
      // (FALSE || x) => x
      // (TRUE && x) => x
      result = right;
    }
  } else if (NodeUtil.isLiteralValue(right)) {
    // Note: We cannot always fold when the constant is on the
    // right, because the typed value of the expression will depend
    // on the type of the constant on the right, even if the boolean
    // equivalent of the value does not. Specifically, in "a = x ||
    // 0", a will be numeric 0 if x is undefined (and hence is
    // e.g. a valid array index). However, it is safe to fold
    // e.g. "if (x || true)" because 'if' doesn't care if the
    // expression is 'true' or '3'.
    int pt = parent.getType();
    if (pt == Token.IF || pt == Token.WHILE || pt == Token.DO ||
        (pt == Token.FOR && NodeUtil.getConditionExpression(parent) == n) ||
        (pt == Token.HOOK && parent.getFirstChild() == n)) {
      boolean rval = NodeUtil.getBooleanValue(right);

      // (x || FALSE) => x
      // (x && TRUE) => x
      if (type == Token.OR && !rval ||
          type == Token.AND && rval) {
        result = left;
      } else {
        // If x has no side-effects:
        //   (x || TRUE) => TRUE
        //   (x && FALSE) => FALSE
        if (!NodeUtil.mayHaveSideEffects(left)) {
          result = right;
        }
      }
    }
  }

  // Note: The parser parses 'x && FALSE && y' as 'x && (FALSE && y)', so
  // there is not much need to worry about const values on left's
  // right child.

  if (result != null) {
    // Fold it!
    n.removeChild(result);
    parent.replaceChild(n, result);
    t.getCompiler().reportCodeChange();
  }
}
 
Example 14
Source File: Nopol2017_0014_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Updates our representation of the global namespace to reflect a read
 * of a global name.
 *
 * @param module The current module
 * @param scope The current scope
 * @param n The node currently being visited
 * @param parent {@code n}'s parent
 * @param name The global name (e.g. "a" or "a.b.c.d")
 */
void handleGet(JSModule module, Scope scope,
    Node n, Node parent, String name) {
  if (maybeHandlePrototypePrefix(module, scope, n, parent, name)) {
    return;
  }

  Ref.Type type = Ref.Type.DIRECT_GET;
  if (parent != null) {
    switch (parent.getType()) {
      case Token.IF:
      case Token.INSTANCEOF:
      case Token.TYPEOF:
      case Token.VOID:
      case Token.NOT:
      case Token.BITNOT:
      case Token.POS:
      case Token.NEG:
        break;
      case Token.CALL:
        if (n == parent.getFirstChild()) {
          // It is a call target
          type = Ref.Type.CALL_GET;
        } else if (isClassDefiningCall(parent)) {
          type = Ref.Type.DIRECT_GET;
        } else {
          type = Ref.Type.ALIASING_GET;
        }
        break;
      case Token.NEW:
        type = n == parent.getFirstChild()
               ? Ref.Type.DIRECT_GET
               : Ref.Type.ALIASING_GET;
        break;
      case Token.OR:
      case Token.AND:
        // This node is x or y in (x||y) or (x&&y). We only know that an
        // alias is not getting created for this name if the result is used
        // in a boolean context or assigned to the same name
        // (e.g. var a = a || {}).
        type = determineGetTypeForHookOrBooleanExpr(module, scope, parent, name);
        break;
      case Token.HOOK:
        if (n != parent.getFirstChild()) {
          // This node is y or z in (x?y:z). We only know that an alias is
          // not getting created for this name if the result is assigned to
          // the same name (e.g. var a = a ? a : {}).
          type = determineGetTypeForHookOrBooleanExpr(module, scope, parent, name);
        }
        break;
      case Token.DELPROP:
        type = Ref.Type.DELETE_PROP;
        break;
      default:
        type = Ref.Type.ALIASING_GET;
        break;
    }
  }

  if (((com.google.javascript.jscomp.GlobalNamespace.this.externsRoot!=null) && ((-1) != ((2) - (com.google.javascript.jscomp.GlobalNamespace.this.globalNames.size())))) || (!(com.google.javascript.jscomp.GlobalNamespace.this.externsScope!=null))) {
    handleGet(module, scope, n, parent, name, type);
  }
}
 
Example 15
Source File: Cardumen_00200_t.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.STRING_KEY:
    case Token.THIS:
    case Token.TRUE:
      return 15;

    default: throw new Error("Unknown precedence for " +
                             Token.name(type) +
                             " (type " + type + ")");
  }
}
 
Example 16
Source File: Closure_76_DeadAssignmentsElimination_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Given a variable, node n in the tree and a sub-tree denoted by exprRoot as
 * the root, this function returns true if there exists a read of that
 * variable before a write to that variable that is on the right side of n.
 *
 * For example, suppose the node is x = 1:
 *
 * y = 1, x = 1; // false, there is no reads at all.
 * y = 1, x = 1, print(x) // true, there is a read right of n.
 * y = 1, x = 1, x = 2, print(x) // false, there is a read right of n but
 *                               // it is after a write.
 *
 * @param n The current node we should look at.
 * @param exprRoot The node
 */
private boolean isVariableStillLiveWithinExpression(
    Node n, Node exprRoot, String variable) {
  while (n != exprRoot) {
    VariableLiveness state = VariableLiveness.MAYBE_LIVE;
    switch (n.getParent().getType()) {
      case Token.OR:
      case Token.AND:
        // If the currently node is the first child of
        // AND/OR, be conservative only consider the READs
        // of the second operand.
        if (n.getNext() != null) {
          state = isVariableReadBeforeKill(
              n.getNext(), variable);
          if (state == VariableLiveness.KILL) {
            state = VariableLiveness.MAYBE_LIVE;
          }
        }
        break;

      case Token.HOOK:
        // If current node is the condition, check each following
        // branch, otherwise it is a conditional branch and the
        // other branch can be ignored.
        if (n.getNext() != null && n.getNext().getNext() != null) {
          state = checkHookBranchReadBeforeKill(
              n.getNext(), n.getNext().getNext(), variable);
        }
        break;

      default:
        for(Node sibling = n.getNext(); sibling != null;
            sibling = sibling.getNext()) {
          state = isVariableReadBeforeKill(sibling, variable);
          if (state != VariableLiveness.MAYBE_LIVE) {
            break;
          }
        }
    }

    // If we see a READ or KILL there is no need to continue.
    if (state == VariableLiveness.READ) {
      return true;
    } else if (state == VariableLiveness.KILL) {
      return false;
    }
    n = n.getParent();
  }
  return false;
}
 
Example 17
Source File: Closure_87_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Tries apply our various peephole minimizations on the passed in node.
 */
@Override
@SuppressWarnings("fallthrough")
public Node optimizeSubtree(Node node) {
  switch(node.getType()) {
    case Token.RETURN:
      return tryReduceReturn(node);

    case Token.NOT:
      tryMinimizeCondition(node.getFirstChild());
      return tryMinimizeNot(node);

    case Token.IF:
      tryMinimizeCondition(node.getFirstChild());
      return tryMinimizeIf(node);

    case Token.EXPR_RESULT:
      tryMinimizeCondition(node.getFirstChild());
      return node;

    case Token.HOOK:
      tryMinimizeCondition(node.getFirstChild());
      return node;

    case Token.WHILE:
    case Token.DO:
      tryMinimizeCondition(NodeUtil.getConditionExpression(node));
      return node;

    case Token.FOR:
      if (!NodeUtil.isForIn(node)) {
        tryMinimizeCondition(NodeUtil.getConditionExpression(node));
      }
      return node;

    case Token.NEW:
      node = tryFoldStandardConstructors(node);
      if (node.getType() != Token.CALL) {
        return node;
      }
      // Fall through on purpose because tryFoldStandardConstructors() may
      // convert a NEW node into a CALL node
    case Token.CALL:
      return tryFoldLiteralConstructor(node);

    default:
      return node; //Nothing changed
  }
}
 
Example 18
Source File: jKali_003_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * @returns false iff the result of the expression is not consumed.
 */
static boolean isExpressionResultUsed(Node expr) {
  // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult.
  Node parent = expr.getParent();
  switch (parent.getType()) {
    case Token.BLOCK:
    case Token.EXPR_RESULT:
      return false;
    case Token.HOOK:
    case Token.AND:
    case Token.OR:
      return (expr == parent.getFirstChild())
          ? true : isExpressionResultUsed(parent);
    case Token.COMMA:
      Node gramps = parent.getParent();
      if (gramps.isCall() &&
          parent == gramps.getFirstChild()) {
        // Semantically, a direct call to eval is different from an indirect
        // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first
        // expression to a comma to be a no-op if it's used to indirect
        // an eval. This we pretend that this is "used".
        if (expr == parent.getFirstChild() &&
            parent.getChildCount() == 2 &&
            expr.getNext().isName() &&
            "eval".equals(expr.getNext().getString())) {
          return true;
        }
      }

      return (expr == parent.getFirstChild())
          ? false : isExpressionResultUsed(parent);
    case Token.FOR:
      if (!NodeUtil.isForIn(parent)) {
        // Only an expression whose result is in the condition part of the
        // expression is used.
        return (parent.getChildAtIndex(1) == expr);
      }
      break;
  }
  return true;
}
 
Example 19
Source File: Cardumen_0014_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.STRING_KEY:
    case Token.THIS:
    case Token.TRUE:
      return 15;

    default: throw new Error("Unknown precedence for " +
                             Token.name(type) +
                             " (type " + type + ")");
  }
}
 
Example 20
Source File: jMutRepair_003_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @returns false iff the result of the expression is not consumed.
 */
static boolean isExpressionResultUsed(Node expr) {
  // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult.
  Node parent = expr.getParent();
  switch (parent.getType()) {
    case Token.BLOCK:
    case Token.EXPR_RESULT:
      return false;
    case Token.HOOK:
    case Token.AND:
    case Token.OR:
      return (expr == parent.getFirstChild())
          ? true : isExpressionResultUsed(parent);
    case Token.COMMA:
      Node gramps = parent.getParent();
      if (gramps.isCall() &&
          parent == gramps.getFirstChild()) {
        // Semantically, a direct call to eval is different from an indirect
        // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first
        // expression to a comma to be a no-op if it's used to indirect
        // an eval. This we pretend that this is "used".
        if (expr == parent.getFirstChild() &&
            parent.getChildCount() == 2 &&
            expr.getNext().isName() &&
            "eval".equals(expr.getNext().getString())) {
          return true;
        }
      }

      return (expr == parent.getFirstChild())
          ? false : isExpressionResultUsed(parent);
    case Token.FOR:
      if (!NodeUtil.isForIn(parent)) {
        // Only an expression whose result is in the condition part of the
        // expression is used.
        return (parent.getChildAtIndex(1) == expr);
      }
      break;
  }
  return true;
}