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

The following examples show how to use com.google.javascript.rhino.Node#hasChildren() . 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: jKali_003_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Merge a block with its parent block.
 * @return Whether the block was removed.
 */
static boolean tryMergeBlock(Node block) {
  Preconditions.checkState(block.isBlock());
  Node parent = block.getParent();
  // Try to remove the block if its parent is a block/script or if its
  // parent is label and it has exactly one child.
  if (isStatementBlock(parent)) {
    Node previous = block;
    while (block.hasChildren()) {
      Node child = block.removeFirstChild();
      parent.addChildAfter(child, previous);
      previous = child;
    }
    parent.removeChild(block);
    return true;
  } else {
    return false;
  }
}
 
Example 2
Source File: Cardumen_0014_s.java    From coming with MIT License 6 votes vote down vote up
static boolean nodeTypeMayHaveSideEffects(Node n, AbstractCompiler compiler) {
  if (isAssignmentOp(n)) {
    return true;
  }

  switch(n.getType()) {
    case Token.DELPROP:
    case Token.DEC:
    case Token.INC:
    case Token.THROW:
      return true;
    case Token.CALL:
      return NodeUtil.functionCallHasSideEffects(n, compiler);
    case Token.NEW:
      return NodeUtil.constructorCallHasSideEffects(n, compiler);
    case Token.NAME:
      // A variable definition.
      return n.hasChildren();
    default:
      return false;
  }
}
 
Example 3
Source File: Cardumen_00149_s.java    From coming with MIT License 6 votes vote down vote up
static boolean nodeTypeMayHaveSideEffects(Node n, AbstractCompiler compiler) {
  if (isAssignmentOp(n)) {
    return true;
  }

  switch(n.getType()) {
    case Token.DELPROP:
    case Token.DEC:
    case Token.INC:
    case Token.THROW:
      return true;
    case Token.CALL:
      return NodeUtil.functionCallHasSideEffects(n, compiler);
    case Token.NEW:
      return NodeUtil.constructorCallHasSideEffects(n, compiler);
    case Token.NAME:
      // A variable definition.
      return n.hasChildren();
    default:
      return false;
  }
}
 
Example 4
Source File: Cardumen_0087_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Merge a block with its parent block.
 * @return Whether the block was removed.
 */
static boolean tryMergeBlock(Node block) {
  Preconditions.checkState(block.isBlock());
  Node parent = block.getParent();
  // Try to remove the block if its parent is a block/script or if its
  // parent is label and it has exactly one child.
  if (isStatementBlock(parent)) {
    Node previous = block;
    while (block.hasChildren()) {
      Node child = block.removeFirstChild();
      parent.addChildAfter(child, previous);
      previous = child;
    }
    parent.removeChild(block);
    return true;
  } else {
    return false;
  }
}
 
Example 5
Source File: Closure_24_ScopedAliases_s.java    From coming with MIT License 6 votes vote down vote up
private void findAliases(NodeTraversal t) {
  Scope scope = t.getScope();
  for (Var v : scope.getVarIterable()) {
    Node n = v.getNode();
    int type = n.getType();
    Node parent = n.getParent();
    if (parent.isVar()) {
      if (n.hasChildren() && n.getFirstChild().isQualifiedName()) {
      String name = n.getString();
      Var aliasVar = scope.getVar(name);
      aliases.put(name, aliasVar);

      String qualifiedName =
          aliasVar.getInitialValue().getQualifiedName();
      transformation.addAlias(name, qualifiedName);
      // Bleeding functions already get a BAD_PARAMETERS error, so just
      // do nothing.
      // Parameters of the scope function also get a BAD_PARAMETERS
      // error.
    } else {
      // TODO(robbyw): Support using locals for private variables.
      report(t, n, GOOG_SCOPE_NON_ALIAS_LOCAL, n.getString());
    }
    }
  }
}
 
Example 6
Source File: Cardumen_00149_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Merge a block with its parent block.
 * @return Whether the block was removed.
 */
static boolean tryMergeBlock(Node block) {
  Preconditions.checkState(block.isBlock());
  Node parent = block.getParent();
  // Try to remove the block if its parent is a block/script or if its
  // parent is label and it has exactly one child.
  if (isStatementBlock(parent)) {
    Node previous = block;
    while (block.hasChildren()) {
      Node child = block.removeFirstChild();
      parent.addChildAfter(child, previous);
      previous = child;
    }
    parent.removeChild(block);
    return true;
  } else {
    return false;
  }
}
 
Example 7
Source File: ProcessClosurePrimitives.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @return Whether the node is namespace placeholder.
 */
private static boolean isNamespacePlaceholder(Node n) {
  if (!n.getBooleanProp(Node.IS_NAMESPACE)) {
    return false;
  }

  Node value = null;
  if (n.isExprResult()) {
    Node assign = n.getFirstChild();
    value = assign.getLastChild();
  } else if (n.isVar()) {
    Node name = n.getFirstChild();
    value = name.getFirstChild();
  }

  return value != null
    && value.isObjectLit()
    && !value.hasChildren();
}
 
Example 8
Source File: Closure_116_FunctionInjector_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Inline a function that fulfills the requirements of
 * canInlineReferenceDirectly into the call site, replacing only the CALL
 * node.
 */
private Node inlineReturnValue(Node callNode, Node fnNode) {
  Node block = fnNode.getLastChild();
  Node callParentNode = callNode.getParent();

  // NOTE: As the normalize pass guarantees globals aren't being
  // shadowed and an expression can't introduce new names, there is
  // no need to check for conflicts.

  // Create an argName -> expression map, checking for side effects.
  Map<String, Node> argMap =
      FunctionArgumentInjector.getFunctionCallParameterMap(
          fnNode, callNode, this.safeNameIdSupplier);

  Node newExpression;
  if (!block.hasChildren()) {
    Node srcLocation = block;
    newExpression = NodeUtil.newUndefinedNode(srcLocation);
  } else {
    Node returnNode = block.getFirstChild();
    Preconditions.checkArgument(returnNode.isReturn());

    // Clone the return node first.
    Node safeReturnNode = returnNode.cloneTree();
    Node inlineResult = FunctionArgumentInjector.inject(
        null, safeReturnNode, null, argMap);
    Preconditions.checkArgument(safeReturnNode == inlineResult);
    newExpression = safeReturnNode.removeFirstChild();
  }

  callParentNode.replaceChild(callNode, newExpression);
  return newExpression;
}
 
Example 9
Source File: AstValidator.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private void validateObjectLitGetKey(Node n) {
  validateNodeType(Token.GETTER_DEF, n);
  validateChildCount(n, 1);
  validateObjectLiteralKeyName(n);
  Node function = n.getFirstChild();
  validateFunctionExpression(function);
  // objlit get functions must be nameless, and must have zero parameters.
  if (!function.getFirstChild().getString().isEmpty()) {
    violation("Expected unnamed function expression.", n);
  }
  Node functionParams = function.getChildAtIndex(1);
  if (functionParams.hasChildren()) {
    violation("get methods must not have parameters.", n);
  }
}
 
Example 10
Source File: Closure_36_InlineVariables_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Remove the given VAR declaration.
 */
private void removeDeclaration(Reference declaration) {
  Node varNode = declaration.getParent();
  Node grandparent = declaration.getGrandparent();

  varNode.removeChild(declaration.getNode());

  // Remove var node if empty
  if (!varNode.hasChildren()) {
    Preconditions.checkState(varNode.isVar());
    NodeUtil.removeChild(grandparent, varNode);
  }

  compiler.reportCodeChange();
}
 
Example 11
Source File: Closure_89_CollapseProperties_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Updates the first initialization (a.k.a "declaration") of a global name
 * that occurs at a VAR node. See comment for
 * {@link #updateObjLitOrFunctionDeclaration}.
 *
 * @param n An object representing a global name (e.g. "a")
 */
private void updateObjLitOrFunctionDeclarationAtVarNode(Name n) {
  Ref ref = n.declaration;
  String name = ref.node.getString();
  Node rvalue = ref.node.getFirstChild();
  Node varNode = ref.node.getParent();
  Node gramps = varNode.getParent();

  boolean isObjLit = rvalue.getType() == Token.OBJECTLIT;
  int numChanges = 0;

  if (isObjLit) {
    numChanges += declareVarsForObjLitValues(
        n, name, rvalue, varNode, gramps.getChildBefore(varNode),
        gramps);
  }

  numChanges += addStubsForUndeclaredProperties(n, name, gramps, varNode);

  if (isObjLit && n.canEliminate()) {
    varNode.removeChild(ref.node);
    if (!varNode.hasChildren()) {
      gramps.removeChild(varNode);
    }
    numChanges++;

    // Clear out the object reference, since we've eliminated it from the
    // parse tree.
    ref.node = null;
  }

  if (numChanges > 0) {
    compiler.reportCodeChange();
  }
}
 
Example 12
Source File: ControlFlowAnalysis.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private void handleReturn(Node node) {
  Node lastJump = null;
  for (Iterator<Node> iter = exceptionHandler.iterator(); iter.hasNext();) {
    Node curHandler = iter.next();
    if (curHandler.isFunction()) {
      break;
    }
    if (NodeUtil.hasFinally(curHandler)) {
      if (lastJump == null) {
        createEdge(node, Branch.UNCOND, curHandler.getLastChild());
      } else {
        finallyMap.put(lastJump,
            computeFallThrough(curHandler.getLastChild()));
      }
      lastJump = curHandler;
    }
  }

  if (node.hasChildren()) {
    connectToPossibleExceptionHandler(node, node.getFirstChild());
  }

  if (lastJump == null) {
    createEdge(node, Branch.UNCOND, null);
  } else {
    finallyMap.put(lastJump, null);
  }
}
 
Example 13
Source File: DefinitionsRemover.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @return an {@link Definition} object if the node contains a definition or
 *     {@code null} otherwise.
 */
static Definition getDefinition(Node n, boolean isExtern) {
  // TODO(user): Since we have parent pointers handy. A lot of constructors
  // can be simplified.

  // This logic must match #isDefinitionNode
  Node parent = n.getParent();
  if (parent == null) {
    return null;
  }

  if (NodeUtil.isVarDeclaration(n) && n.hasChildren()) {
    return new VarDefinition(n, isExtern);
  } else if (parent.isFunction() && parent.getFirstChild() == n) {
    if (!NodeUtil.isFunctionExpression(parent)) {
      return new NamedFunctionDefinition(parent, isExtern);
    } else if (!n.getString().equals("")) {
      return new FunctionExpressionDefinition(parent, isExtern);
    }
  } else if (parent.isAssign() && parent.getFirstChild() == n) {
    return new AssignmentDefinition(parent, isExtern);
  } else if (NodeUtil.isObjectLitKey(n, parent)) {
    return new ObjectLiteralPropertyDefinition(parent, n, n.getFirstChild(),
        isExtern);
  } else if (parent.isParamList()) {
    Node function = parent.getParent();
    return new FunctionArgumentDefinition(function, n, isExtern);
  }
  return null;
}
 
Example 14
Source File: Closure_85_UnreachableCodeElimination_s.java    From coming with MIT License 5 votes vote down vote up
private void removeDeadExprStatementSafely(Node n) {
  Node parent = n.getParent();
  if (n.getType() == Token.EMPTY ||
      (n.getType() == Token.BLOCK && !n.hasChildren())) {
    // Not always trivial to remove, let FoldContants work its magic later.
    return;
  }

  switch (n.getType()) {
    // Removing an unreachable DO node is messy because it means we still have
    // to execute one iteration. If the DO's body has breaks in the middle, it
    // can get even more trickier 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.getType() == Token.TRY) {
        if (NodeUtil.isTryCatchNodeContainer(n)) {
          return;
        }
      }
      break;

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

  NodeUtil.redeclareVarsInsideBranch(n);
  compiler.reportCodeChange();
  if (logger.isLoggable(Level.FINE)) {
    logger.fine("Removing " + n.toString());
  }
  NodeUtil.removeChild(n.getParent(), n);
}
 
Example 15
Source File: UnreachableCodeElimination.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private Node computeFollowing(Node n) {
  Node next = ControlFlowAnalysis.computeFollowNode(n);
  while (next != null && next.isBlock()) {
    if (next.hasChildren()) {
      next = next.getFirstChild();
    } else {
      next = computeFollowing(next);
    }
  }
  return next;
}
 
Example 16
Source File: Closure_115_FunctionInjector_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * @return The difference between the function definition cost and
 *     inline cost.
 */
private static int inlineCostDelta(
    Node fnNode, Set<String> namesToAlias, InliningMode mode) {
  // The part of the function that is never inlined:
  //    "function xx(xx,xx){}" (15 + (param count * 3) -1;
  int paramCount = NodeUtil.getFunctionParameters(fnNode).getChildCount();
  int commaCount = (paramCount > 1) ? paramCount - 1 : 0;
  int costDeltaFunctionOverhead = 15 + commaCount +
      (paramCount * InlineCostEstimator.ESTIMATED_IDENTIFIER_COST);

  Node block = fnNode.getLastChild();
  if (!block.hasChildren()) {
    // Assume the inline cost is zero for empty functions.
    return -costDeltaFunctionOverhead;
  }

  if (mode == InliningMode.DIRECT) {
    // The part of the function that is inlined using direct inlining:
    //    "return " (7)
    return -(costDeltaFunctionOverhead + 7);
  } else {
    int aliasCount = namesToAlias.size();

    // Originally, we estimated purely base on the function code size, relying
    // on later optimizations. But that did not produce good results, so here
    // we try to estimate the something closer to the actual inlined coded.

    // NOTE 1: Result overhead is only if there is an assignment, but
    // getting that information would require some refactoring.
    // NOTE 2: The aliasing overhead is currently an under-estimate,
    // as some parameters are aliased because of the parameters used.
    // Perhaps we should just assume all parameters will be aliased?
    final int inlineBlockOverhead = 4; // "X:{}"
    final int perReturnOverhead = 2;   // "return" --> "break X"
    final int perReturnResultOverhead = 3; // "XX="
    final int perAliasOverhead = 3; // "XX="

    // TODO(johnlenz): Counting the number of returns is relatively expensive
    //   this information should be determined during the traversal and
    //   cached.
    int returnCount = NodeUtil.getNodeTypeReferenceCount(
        block, Token.RETURN, new NodeUtil.MatchShallowStatement());
    int resultCount = (returnCount > 0) ? returnCount - 1 : 0;
    int baseOverhead = (returnCount > 0) ? inlineBlockOverhead : 0;

    int overhead = baseOverhead
        + returnCount * perReturnOverhead
        + resultCount * perReturnResultOverhead
        + aliasCount * perAliasOverhead;

    return (overhead - costDeltaFunctionOverhead);
  }
}
 
Example 17
Source File: Closure_60_NodeUtil_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @return Whether BLOCK (from a TRY node) contains a CATCH.
 * @see NodeUtil#getCatchBlock
 */
static boolean hasCatchHandler(Node n) {
  Preconditions.checkArgument(n.getType() == Token.BLOCK);
  return n.hasChildren() && n.getFirstChild().getType() == Token.CATCH;
}
 
Example 18
Source File: Closure_126_MinimizeExitPoints_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for exits (returns, breaks, or continues, depending on the context) at
 * the end of a block and removes them by moving the if node's siblings,
 * if any, into the opposite condition block.
 *
 * @param srcBlock The block to inspect.
 * @param destBlock The block to move sibling nodes into.
 * @param ifNode The if node to work with.
 * @param exitType The type of exit to look for.
 * @param labelName The name associated with the exit, if any.
 * @nullable labelName null for anything excepted for named-break associated
 *           with a label.
 */
private void tryMinimizeIfBlockExits(Node srcBlock, Node destBlock,
    Node ifNode, int exitType, String labelName) {
  Node exitNodeParent = null;
  Node exitNode = null;

  // Pick an exit node candidate.
  if (srcBlock.isBlock()) {
    if (!srcBlock.hasChildren()) {
      return;
    }
    exitNodeParent = srcBlock;
    exitNode = exitNodeParent.getLastChild();
  } else {
    // Just a single statement, if it isn't an exit bail.
    exitNodeParent = ifNode;
    exitNode = srcBlock;
  }

  // Verify the candidate.
  if (!matchingExitNode(exitNode, exitType, labelName)) {
    return;
  }

  // Take case of the if nodes siblings, if any.
  if (ifNode.getNext() != null) {
    // Move siblings of the if block into the opposite
    // logic block of the exit.
    Node newDestBlock = IR.block().srcref(ifNode);
    if (destBlock == null) {
      // Only possible if this is the false block.
      ifNode.addChildToBack(newDestBlock);
    } else if (destBlock.isEmpty()) {
      // Use the new block.
      ifNode.replaceChild(destBlock, newDestBlock);
    } else if (destBlock.isBlock()) {
      // Reuse the existing block.
      newDestBlock = destBlock;
    } else {
      // Add the existing statement to the new block.
      ifNode.replaceChild(destBlock, newDestBlock);
      newDestBlock.addChildToBack(destBlock);
    }

    // Move all the if node's following siblings.
    moveAllFollowing(ifNode, ifNode.getParent(), newDestBlock);
    compiler.reportCodeChange();
  }
}
 
Example 19
Source File: Closure_94_NodeUtil_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * @return Whether BLOCK (from a TRY node) contains a CATCH.
 * @see NodeUtil#getCatchBlock
 */
static boolean hasCatchHandler(Node n) {
  Preconditions.checkArgument(n.getType() == Token.BLOCK);
  return n.hasChildren() && n.getFirstChild().getType() == Token.CATCH;
}
 
Example 20
Source File: TypeInference.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Updates the scope according to the result of a type change, like
 * an assignment or a type cast.
 */
private void updateScopeForTypeChange(
    FlowScope scope, Node left, JSType leftType, JSType resultType) {
  Preconditions.checkNotNull(resultType);
  switch (left.getType()) {
    case Token.NAME:
      String varName = left.getString();
      Var var = syntacticScope.getVar(varName);

      // When looking at VAR initializers for declared VARs, we trust
      // the declared type over the type it's being initialized to.
      // This has two purposes:
      // 1) We avoid re-declaring declared variables so that built-in
      //    types defined in externs are not redeclared.
      // 2) When there's a lexical closure like
      //    /** @type {?string} */ var x = null;
      //    function f() { x = 'xyz'; }
      //    the inference will ignore the lexical closure,
      //    which is just wrong. This bug needs to be fixed eventually.
      boolean isVarDeclaration = left.hasChildren();
      if (!isVarDeclaration || var == null || var.isTypeInferred()) {
        redeclareSimpleVar(scope, left, resultType);
      }
      left.setJSType(isVarDeclaration || leftType == null ?
          resultType : null);

      if (var != null && var.isTypeInferred()) {
        JSType oldType = var.getType();
        var.setType(oldType == null ?
            resultType : oldType.getLeastSupertype(resultType));
      }
      break;
    case Token.GETPROP:
      String qualifiedName = left.getQualifiedName();
      if (qualifiedName != null) {
        scope.inferQualifiedSlot(left, qualifiedName,
            leftType == null ? unknownType : leftType,
            resultType);
      }

      left.setJSType(resultType);
      ensurePropertyDefined(left, resultType);
      break;
  }
}