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

The following examples show how to use com.google.javascript.rhino.Node#isEmpty() . 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: ExternExportsPass.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private void appendPathDefinition(String path, Node initializer) {
  Node pathDefinition;

  if (!path.contains(".")) {
    if (initializer.isEmpty()) {
      pathDefinition = IR.var(IR.name(path));
    } else {
      pathDefinition = NodeUtil.newVarNode(path, initializer);
    }
  } else {
    Node qualifiedPath = NodeUtil.newQualifiedNameNode(
        compiler.getCodingConvention(), path);
    if (initializer.isEmpty()) {
      pathDefinition = NodeUtil.newExpr(qualifiedPath);
    } else {
      pathDefinition = NodeUtil.newExpr(
          IR.assign(qualifiedPath, initializer));
    }
  }

  externsRoot.addChildToBack(pathDefinition);

  alreadyExportedPaths.add(path);
}
 
Example 2
Source File: Closure_123_CodeGenerator_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * @param maxCount The maximum number of children to look for.
 * @return The number of children of this node that are non empty up to
 * maxCount.
 */
private static int getNonEmptyChildCount(Node n, int maxCount) {
  int i = 0;
  Node c = n.getFirstChild();
  for (; c != null && i < maxCount; c = c.getNext()) {
    if (c.isBlock()) {
      i += getNonEmptyChildCount(c, maxCount - i);
    } else if (!c.isEmpty()) {
      i++;
    }
  }
  return i;
}
 
Example 3
Source File: AstValidator.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private void validateOptionalExpression(Node n) {
  if (n.isEmpty()) {
    validateChildless(n);
  } else {
    validateExpression(n);
  }
}
 
Example 4
Source File: PeepholeRemoveDeadCode.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Removes FORs that always evaluate to false.
 */
Node tryFoldFor(Node n) {
  Preconditions.checkArgument(n.isFor());
  // If this is a FOR-IN loop skip it.
  if (NodeUtil.isForIn(n)) {
    return n;
  }

  Node init = n.getFirstChild();
  Node cond = init.getNext();
  Node increment = cond.getNext();

  if (!init.isEmpty() && !init.isVar()) {
    init = trySimplifyUnusedResult(init, false);
  }

  if (!increment.isEmpty()) {
    increment = trySimplifyUnusedResult(increment, false);
  }

  // There is an initializer skip it
  if (!n.getFirstChild().isEmpty()) {
    return n;
  }

  if (NodeUtil.getImpureBooleanValue(cond) != TernaryValue.FALSE) {
    return n;
  }

  NodeUtil.redeclareVarsInsideBranch(n);
  if (!mayHaveSideEffects(cond)) {
    NodeUtil.removeChild(n.getParent(), n);
  } else {
    Node statement = IR.exprResult(cond.detachFromParent())
        .copyInformationFrom(cond);
    n.getParent().replaceChild(n, statement);
  }
  reportCodeChange();
  return null;
}
 
Example 5
Source File: Cardumen_0018_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if ((((((((com.google.javascript.jscomp.NodeUtil.isAssignmentOp(n)) && ((n.getFirstChild()) == n)) || ((com.google.javascript.jscomp.NodeUtil.isForIn(n)) && ((n.getFirstChild()) == n))) || (n.isVar())) || ((n.isFunction()) && ((n.getFirstChild()) == n))) || (n.isDec())) || (n.isInc())) || (n.isParamList())) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 6
Source File: jMutRepair_0023_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (parent.getType() == Token.COMMA) {
    Node gramps = parent.getParent();
    if (gramps.isCall() && parent == gramps.getFirstChild()) {
      if (n == parent.getFirstChild() && parent.getChildCount() == 2 && n.getNext().isName() && "eval".equals(n.getNext().getString())) {
    return;
      }
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA)
          continue;
        if (ancestorType > Token.EXPR_RESULT && ancestorType != Token.BLOCK)
          return;
        else
          break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() ||
         n == parent.getFirstChild().getNext().getNext())) {
    } else {
    return;
    }
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (!isResultUsed &&
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    if (n.isQualifiedName() && n.getJSDocInfo() != null) {
      return;
    } else if (n.isExprResult()) {
      return;
    }
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 7
Source File: jMutRepair_0022_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if (ancestorType > Token.EXPR_RESULT && ancestorType != Token.BLOCK) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 8
Source File: JGenProg2017_0010_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 9
Source File: Closure_127_UnreachableCodeElimination_s.java    From coming with MIT License 4 votes vote down vote up
private void removeDeadExprStatementSafely(Node n) {
  Node parent = n.getParent();
  if (n.isEmpty() || (n.isBlock() && !n.hasChildren())) {
    // Not always trivial to remove, let FoldConstants work its magic later.
    return;
  }

  // TODO(user): This is a problem with removeNoOpStatements.
  // Every expression in a FOR-IN header looks side effect free on its own.
  if (NodeUtil.isForIn(parent)) {
    return;
  }

  switch (n.getType()) {
    // Removing an unreachable DO node is messy b/c it means we still have
    // to execute one iteration. If the DO's body has breaks in the middle,
    // it can get even more tricky and code size might actually increase.
    case Token.DO:
      return;

    case Token.BLOCK:
      // BLOCKs are used in several ways including wrapping CATCH
      // blocks in TRYs
      if (parent.isTry() && NodeUtil.isTryCatchNodeContainer(n)) {
        return;
      }
      break;

    case Token.CATCH:
      Node tryNode = parent.getParent();
      NodeUtil.maybeAddFinally(tryNode);
      break;
  }

  if (n.isVar() && !n.getFirstChild().hasChildren()) {
    // Very unlikely case, Consider this:
    // File 1: {throw 1}
    // File 2: {var x}
    // The node var x is unreachable in the global scope.
    // Before we remove the node, redeclareVarsInsideBranch
    // would basically move var x to the beginning of File 2,
    // which resulted in zero changes to the AST but triggered
    // reportCodeChange().
    // Instead, we should just ignore dead variable declarations.
    return;
  }

  removeNode(n);
}
 
Example 10
Source File: PeepholeCollectPropertyAssignments.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
private boolean collectArrayProperty(
    Node arrayLiteral, Node propertyCandidate) {
  Node assignment = propertyCandidate.getFirstChild();
  final int sizeOfArrayAtStart = arrayLiteral.getChildCount();
  int maxIndexAssigned = sizeOfArrayAtStart - 1;

  Node lhs = assignment.getFirstChild();
  Node rhs = lhs.getNext();
  if (!lhs.isGetElem()) {
    return false;
  }
  Node obj = lhs.getFirstChild();
  Node property = obj.getNext();
  // The left hand side must have a numeric index
  if (!property.isNumber()) {
    return false;
  }
  // that is a valid array index
  double dindex = property.getDouble();
  if (!(dindex >= 0)  // Handles NaN and negatives.
      || Double.isInfinite(dindex) || dindex > 0x7fffffffL) {
    return false;
  }
  int index = (int) dindex;
  if (dindex != index) {
    return false;
  }
  // that would not make the array so sparse that they take more space
  // when rendered than x[9]=1.
  if (maxIndexAssigned + 4 < index) {
    return false;
  }
  if (index > maxIndexAssigned) {
    while (maxIndexAssigned < index - 1) {
      // Pad the array if it is sparse.
      // So if array is [0] and integer 3 is assigned at index is 2, then
      // we want to produce [0,,2].
      Node emptyNode = IR.empty().srcref(arrayLiteral);
      arrayLiteral.addChildToBack(emptyNode);
      ++maxIndexAssigned;
    }
    arrayLiteral.addChildToBack(rhs.detachFromParent());
  } else {
    // An out of order assignment.  Allow it if it's a hole.
    Node currentValue = arrayLiteral.getChildAtIndex(index);
    if (!currentValue.isEmpty()) {
      // We've already collected a value for this index.
      return false;
    }
    arrayLiteral.replaceChild(currentValue, rhs.detachFromParent());
  }

  propertyCandidate.detachFromParent();
  return true;
}
 
Example 11
Source File: jKali_005_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 12
Source File: jMutRepair_0047_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType > Token.BLOCK) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 13
Source File: jKali_0048_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType != Token.BLOCK) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 14
Source File: JGenProg2017_0053_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (parent.getType() == Token.COMMA) {
    Node gramps = parent.getParent();
    if (gramps.isCall() && parent == gramps.getFirstChild()) {
      if (n == parent.getFirstChild() && parent.getChildCount() == 2 && n.getNext().isName() && "eval".equals(n.getNext().getString())) {
    return;
      }
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA)
          continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType != Token.BLOCK)
          return;
        else
          break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() ||
         n == parent.getFirstChild().getNext().getNext())) {
    } else {
    return;
    }
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (!isResultUsed &&
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    if (n.isQualifiedName() && n.getJSDocInfo() != null) {
      return;
    } else if (n.isExprResult()) {
      return;
    }
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 15
Source File: jMutRepair_0031_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType != Token.BLOCK) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 16
Source File: jMutRepair_0023_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (parent.getType() == Token.COMMA) {
    Node gramps = parent.getParent();
    if (gramps.isCall() && parent == gramps.getFirstChild()) {
      if (n == parent.getFirstChild() && parent.getChildCount() == 2 && n.getNext().isName() && "eval".equals(n.getNext().getString())) {
    return;
      }
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA)
          continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType != Token.BLOCK)
          return;
        else
          break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() ||
         n == parent.getFirstChild().getNext().getNext())) {
    } else {
    return;
    }
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (!isResultUsed &&
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    if (n.isQualifiedName() && n.getJSDocInfo() != null) {
      return;
    } else if (n.isExprResult()) {
      return;
    }
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 17
Source File: Cardumen_00248_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // VOID nodes appear when there are extra semicolons at the BLOCK level.
  // I've been unable to think of any cases where this indicates a bug,
  // and apparently some people like keeping these semicolons around,
  // so we'll allow it.
  if (n.isEmpty() ||
      n.isComma()) {
    return;
  }

  if (parent == null) {
    return;
  }

  // Do not try to remove a block or an expr result. We already handle
  // these cases when we visit the child, and the peephole passes will
  // fix up the tree in more clever ways when these are removed.
  if (n.isExprResult()) {
    return;
  }

  // This no-op statement was there so that JSDoc information could
  // be attached to the name. This check should not complain about it.
  if (n.isQualifiedName() && n.getJSDocInfo() != null) {
    return;
  }

  boolean isResultUsed = NodeUtil.isExpressionResultUsed(n);
  boolean isSimpleOp = NodeUtil.isSimpleOperatorType(n.getType());
  if (parent.getType() == Token.COMMA) {
    if (isResultUsed) {
      return;
    }
    if (n == parent.getLastChild()) {
      for (Node an : parent.getAncestors()) {
        int ancestorType = an.getType();
        if (ancestorType == Token.COMMA) continue;
        if (ancestorType != Token.EXPR_RESULT && ancestorType != Token.BLOCK) return;
        else break;
      }
    }
  } else if (parent.getType() != Token.EXPR_RESULT && parent.getType() != Token.BLOCK) {
    if (! (parent.getType() == Token.FOR && parent.getChildCount() == 4 && (n == parent.getFirstChild() || n == parent.getFirstChild().getNext().getNext()))) {
      return;
    }
  }
  if (
      (isSimpleOp || !NodeUtil.mayHaveSideEffects(n, t.getCompiler()))) {
    String msg = "This code lacks side-effects. Is there a bug?";
    if (n.isString()) {
      msg = "Is there a missing '+' on the previous line?";
    } else if (isSimpleOp) {
      msg = "The result of the '" + Token.name(n.getType()).toLowerCase() +
          "' operator is not being used.";
    }

    t.getCompiler().report(
        t.makeError(n, level, USELESS_CODE_ERROR, msg));
    // TODO(johnlenz): determine if it is necessary to
    // try to protect side-effect free statements as well.
    if (!NodeUtil.isStatement(n)) {
      problemNodes.add(n);
    }
  }
}
 
Example 18
Source File: Closure_127_UnreachableCodeElimination_t.java    From coming with MIT License 4 votes vote down vote up
private void removeDeadExprStatementSafely(Node n) {
  Node parent = n.getParent();
  if (n.isEmpty() || (n.isBlock() && !n.hasChildren())) {
    // Not always trivial to remove, let FoldConstants work its magic later.
    return;
  }

  // TODO(user): This is a problem with removeNoOpStatements.
  // Every expression in a FOR-IN header looks side effect free on its own.
  if (NodeUtil.isForIn(parent)) {
    return;
  }

  switch (n.getType()) {
    // Removing an unreachable DO node is messy b/c it means we still have
    // to execute one iteration. If the DO's body has breaks in the middle,
    // it can get even more tricky and code size might actually increase.
    case Token.DO:
      return;

    case Token.BLOCK:
      // BLOCKs are used in several ways including wrapping CATCH
      // blocks in TRYs
      if (parent.isTry() && NodeUtil.isTryCatchNodeContainer(n)) {
        return;
      }
      break;

    case Token.CATCH:
      Node tryNode = parent.getParent();
      NodeUtil.maybeAddFinally(tryNode);
      break;
  }

  if (n.isVar() && !n.getFirstChild().hasChildren()) {
    // Very unlikely case, Consider this:
    // File 1: {throw 1}
    // File 2: {var x}
    // The node var x is unreachable in the global scope.
    // Before we remove the node, redeclareVarsInsideBranch
    // would basically move var x to the beginning of File 2,
    // which resulted in zero changes to the AST but triggered
    // reportCodeChange().
    // Instead, we should just ignore dead variable declarations.
    return;
  }

  removeNode(n);
}
 
Example 19
Source File: Cardumen_0014_s.java    From coming with MIT License 2 votes vote down vote up
/**
 * When converting arrays to string using Array.prototype.toString or
 * Array.prototype.join, the rules for conversion to String are different
 * than converting each element individually.  Specifically, "null" and
 * "undefined" are converted to an empty string.
 * @param n A node that is a member of an Array.
 * @return The string representation.
 */
static String getArrayElementStringValue(Node n) {
  return (NodeUtil.isNullOrUndefined(n) || n.isEmpty())
      ? "" : getStringValue(n);
}
 
Example 20
Source File: Cardumen_00200_s.java    From coming with MIT License 2 votes vote down vote up
/**
 * When converting arrays to string using Array.prototype.toString or
 * Array.prototype.join, the rules for conversion to String are different
 * than converting each element individually.  Specifically, "null" and
 * "undefined" are converted to an empty string.
 * @param n A node that is a member of an Array.
 * @return The string representation.
 */
static String getArrayElementStringValue(Node n) {
  return (NodeUtil.isNullOrUndefined(n) || n.isEmpty())
      ? "" : getStringValue(n);
}