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

The following examples show how to use com.google.javascript.rhino.Node#isFunction() . 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: Cardumen_0087_t.java    From coming with MIT License 6 votes vote down vote up
/**
 * Determines whether this node is used as an L-value. Notice that sometimes
 * names are used as both L-values and R-values.
 *
 * We treat "var x;" as a pseudo-L-value, which kind of makes sense if you
 * treat it as "assignment to 'undefined' at the top of the scope". But if
 * we're honest with ourselves, it doesn't make sense, and we only do this
 * because it makes sense to treat this as syntactically similar to
 * "var x = 0;".
 *
 * @param n The node
 * @return True if n is an L-value.
 */
public static boolean isLValue(Node n) {
  Preconditions.checkArgument(n.isName() || n.isGetProp() ||
      n.isGetElem());
  Node parent = n.getParent();
  if (parent == null) {
    return false;
  }
  return (NodeUtil.isAssignmentOp(parent) && parent.getFirstChild() == n)
      || (NodeUtil.isForIn(parent) && parent.getFirstChild() == n)
      || parent.isVar()
      || (parent.isFunction() && parent.getFirstChild() == n)
      || parent.isDec()
      || parent.isInc()
      || parent.isParamList()
      || parent.isCatch();
}
 
Example 2
Source File: FunctionToBlockMutatorTest.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private static Node findFunction(Node n, String name) {
  if (n.isFunction()) {
    if (n.getFirstChild().getString().equals(name)) {
      return n;
    }
  }

  for (Node c : n.children()) {
    Node result = findFunction(c, name);
    if (result != null) {
      return result;
    }
  }

  return null;
}
 
Example 3
Source File: PeepholeOptimizationsPass.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private boolean shouldRetraverse(Node node) {
  if (retraverseOnChange
      && node.getParent() != null 
      && (node.isFunction() || node.isScript())) {
    ScopeState state = traversalState.peek();
    if (state.changed) {
      // prepare to re-visit the scope:
      // when revisiting, only visit the immediate scope
      // this reduces the cost of getting to a fixed
      // point in global scope.
      state.changed = false;
      state.traverseChildScopes = false;
      return true;
    }
  }
  return false;
}
 
Example 4
Source File: FunctionArgumentInjector.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Check for uses of the named value that imply a pass-by-value
 * parameter is expected.  This is used to prevent cases like:
 *
 *   function (x) {
 *     x=2;
 *     return x;
 *   }
 *
 * We don't want "undefined" to be substituted for "x", and get
 *   undefined=2
 *
 * @param n The node in question.
 * @param parent The parent of the node.
 * @param names The set of names to check.
 * @param unsafe The set of names that require aliases.
 * @param inInnerFunction Whether the inspection is occurring on a inner
 *     function.
 */
private static Set<String> findModifiedParameters(
    Node n, Node parent, Set<String> names, Set<String> unsafe,
    boolean inInnerFunction) {
  Preconditions.checkArgument(unsafe != null);
  if (n.isName()) {
    if (names.contains(n.getString())) {
      if (inInnerFunction || canNameValueChange(n, parent)) {
        unsafe.add(n.getString());
      }
    }
  } else if (n.isFunction()) {
    // A function parameter can not be replaced with a direct inlined value
    // if it is referred to by an inner function. The inner function
    // can out live the call we are replacing, so inner function must
    // capture a unique name.  This approach does not work within loop
    // bodies so those are forbidden elsewhere.
    inInnerFunction = true;
  }

  for (Node c : n.children()) {
    findModifiedParameters(c, n, names, unsafe, inInnerFunction);
  }

  return unsafe;
}
 
Example 5
Source File: jKali_003_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * @return Whether the specified node has a loop parent that
 * is within the current scope.
 */
static boolean isWithinLoop(Node n) {
  for (Node parent : n.getAncestors()) {
    if (NodeUtil.isLoopStructure(parent)) {
      return true;
    }

    if (parent.isFunction()) {
      break;
    }
  }
  return false;
}
 
Example 6
Source File: Closure_37_NodeTraversal_s.java    From coming with MIT License 5 votes vote down vote up
@Override
public final boolean shouldTraverse(NodeTraversal nodeTraversal, Node n,
    Node parent) {
  // We do want to traverse the name of a named function, but we don't
  // want to traverse the arguments or body.
  return parent == null || !parent.isFunction() ||
      n == parent.getFirstChild();
}
 
Example 7
Source File: jMutRepair_003_s.java    From coming with MIT License 5 votes vote down vote up
@Override
public boolean apply(Node n) {
  Node parent = n.getParent();
  return n.isBlock()
      || (!n.isFunction() && (parent == null
          || isControlStructure(parent)
          || isStatementBlock(parent)));
}
 
Example 8
Source File: Cardumen_0016_s.java    From coming with MIT License 5 votes vote down vote up
private boolean shouldVisit(Node node) {
  if (node.isFunction() || node.isScript()) {
    ScopeState previous = traversalState.peek();
    if (!previous.traverseChildScopes) {
      return false;
    }
    traversalState.push();
  }
  return true;
}
 
Example 9
Source File: jMutRepair_003_t.java    From coming with MIT License 5 votes vote down vote up
@Override
public boolean apply(Node n) {
  Node parent = n.getParent();
  return n.isBlock()
      || (!n.isFunction() && (parent == null
          || isControlStructure(parent)
          || isStatementBlock(parent)));
}
 
Example 10
Source File: RescopeGlobalSymbols.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) {
  if (!n.isName()) {
    return;
  }
  String name = n.getString();
  // Ignore anonymous functions
  if (parent.isFunction() && name.length() == 0) {
    return;
  }
  Scope.Var var = t.getScope().getVar(name);
  if (var == null) {
    return;
  }
  // Don't touch externs.
  if (var.isExtern()) {
    return;
  }
  // When the globalSymbolNamespace is used as a local variable name
  // add suffix to avoid shadowing the namespace. Also add a suffix
  // if a name starts with the name of the globalSymbolNamespace and
  // the suffix.
  if (!var.isExtern() && (name.equals(globalSymbolNamespace) ||
      name.indexOf(globalSymbolNamespace + DISAMBIGUATION_SUFFIX) == 0)) {
    n.setString(name + DISAMBIGUATION_SUFFIX);
    compiler.reportCodeChange();
  }
  // We only care about global vars.
  if (!var.isGlobal()) {
    return;
  }
  Node nameNode = var.getNameNode();
  // The exception variable (e in try{}catch(e){}) should not be rewritten.
  if (nameNode != null && nameNode.getParent() != null &&
      nameNode.getParent().isCatch()) {
    return;
  }
  replaceSymbol(n, name);
}
 
Example 11
Source File: Cardumen_0016_t.java    From coming with MIT License 5 votes vote down vote up
private boolean shouldVisit(Node node) {
  if (node.isFunction() || node.isScript()) {
    ScopeState previous = traversalState.peek();
    if (!previous.traverseChildScopes) {
      return !(node.isString());
    }
    traversalState.push();
  }
  return true;
}
 
Example 12
Source File: Closure_130_CollapseProperties_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Updates the initial assignment to a collapsible property at global scope
 * by changing it to a variable declaration (e.g. a.b = 1 -> var a$b = 1).
 * The property's value may either be a primitive or an object literal or
 * function whose properties aren't collapsible.
 *
 * @param alias The flattened property name (e.g. "a$b")
 * @param refName The name for the reference being updated.
 * @param ref An object containing information about the assignment getting
 *     updated
 */
private void updateSimpleDeclaration(String alias, Name refName, Ref ref) {
  Node rvalue = ref.node.getNext();
  Node parent = ref.node.getParent();
  Node gramps = parent.getParent();
  Node greatGramps = gramps.getParent();

  if (rvalue != null && rvalue.isFunction()) {
    checkForHosedThisReferences(rvalue, refName.docInfo, refName);
  }

  // Create the new alias node.
  Node nameNode = NodeUtil.newName(
      compiler.getCodingConvention(), alias, gramps.getFirstChild(),
      refName.getFullName());
  NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode);

  if (gramps.isExprResult()) {
    // BEFORE: a.b.c = ...;
    //   exprstmt
    //     assign
    //       getprop
    //         getprop
    //           name a
    //           string b
    //         string c
    //       NODE
    // AFTER: var a$b$c = ...;
    //   var
    //     name a$b$c
    //       NODE

    // Remove the r-value (NODE).
    parent.removeChild(rvalue);
    nameNode.addChildToFront(rvalue);

    Node varNode = IR.var(nameNode);
    greatGramps.replaceChild(gramps, varNode);
  } else {
    // This must be a complex assignment.
    Preconditions.checkNotNull(ref.getTwin());

    // BEFORE:
    // ... (x.y = 3);
    //
    // AFTER:
    // var x$y;
    // ... (x$y = 3);

    Node current = gramps;
    Node currentParent = gramps.getParent();
    for (; !currentParent.isScript() &&
           !currentParent.isBlock();
         current = currentParent,
         currentParent = currentParent.getParent()) {}

    // Create a stub variable declaration right
    // before the current statement.
    Node stubVar = IR.var(nameNode.cloneTree())
        .copyInformationFrom(nameNode);
    currentParent.addChildBefore(stubVar, current);

    parent.replaceChild(ref.node, nameNode);
  }

  compiler.reportCodeChange();
}
 
Example 13
Source File: Closure_120_ReferenceCollectingCallback_s.java    From coming with MIT License 4 votes vote down vote up
/**
* @return For an assignment, variable declaration, or function declaration
* return the assigned value, otherwise null.
*/
Node getAssignedValue() {
  Node parent = getParent();
  return (parent.isFunction())
      ? parent : NodeUtil.getAssignedValue(nameNode);
}
 
Example 14
Source File: Cardumen_0087_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public boolean apply(Node n) {
  return !n.isFunction();
}
 
Example 15
Source File: Closure_45_RemoveUnusedVars_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Removes any vars in the scope that were not referenced. Removes any
 * assignments to those variables as well.
 */
private void removeUnreferencedVars() {
  CodingConvention convention = codingConvention;

  for (Iterator<Var> it = maybeUnreferenced.iterator(); it.hasNext(); ) {
    Var var = it.next();

    // Remove calls to inheritance-defining functions where the unreferenced
    // class is the subclass.
    for (Node exprCallNode : inheritsCalls.get(var)) {
      NodeUtil.removeChild(exprCallNode.getParent(), exprCallNode);
      compiler.reportCodeChange();
    }

    // Regardless of what happens to the original declaration,
    // we need to remove all assigns, because they may contain references
    // to other unreferenced variables.
    removeAllAssigns(var);

    compiler.addToDebugLog("Unreferenced var: " + var.name);
    Node nameNode = var.nameNode;
    Node toRemove = nameNode.getParent();
    Node parent = toRemove.getParent();

    Preconditions.checkState(
        toRemove.isVar() ||
        toRemove.isFunction() ||
        toRemove.isParamList() &&
        parent.isFunction(),
        "We should only declare vars and functions and function args");

    if (toRemove.isParamList() &&
        parent.isFunction()) {
      // Don't remove function arguments here. That's a special case
      // that's taken care of in removeUnreferencedFunctionArgs.
    } else if (NodeUtil.isFunctionExpression(toRemove)) {
      if (!preserveFunctionExpressionNames) {
        toRemove.getFirstChild().setString("");
        compiler.reportCodeChange();
      }
      // Don't remove bleeding functions.
    } else if (parent != null &&
        parent.isFor() &&
        parent.getChildCount() < 4) {
      // foreach iterations have 3 children. Leave them alone.
    } else if (toRemove.isVar() &&
        nameNode.hasChildren() &&
        NodeUtil.mayHaveSideEffects(nameNode.getFirstChild())) {
      // If this is a single var declaration, we can at least remove the
      // declaration itself and just leave the value, e.g.,
      // var a = foo(); => foo();
      if (toRemove.getChildCount() == 1) {
        parent.replaceChild(toRemove,
            IR.exprResult(nameNode.removeFirstChild()));
        compiler.reportCodeChange();
      }
    } else if (toRemove.isVar() &&
        toRemove.getChildCount() > 1) {
      // For var declarations with multiple names (i.e. var a, b, c),
      // only remove the unreferenced name
      toRemove.removeChild(nameNode);
      compiler.reportCodeChange();
    } else if (parent != null) {
      NodeUtil.removeChild(parent, toRemove);
      compiler.reportCodeChange();
    }
  }
}
 
Example 16
Source File: NameReferenceGraphConstruction.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@SuppressWarnings("fallthrough")
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.NAME:
    case Token.GETPROP:
      if (parent.isGetProp()) {
        // We will resolve this when we visit parent later in the traversal.
        return;
      } else if (parent.isFunction()) {
        // Function declarations have been taken care of in enterScope();
        return;
      } else if (parent.isAssign()) {
        // Handled below.
        return;
      }

      if (isLocalNameReference(t, n)) {
        // Ignore all local variable references unless is creates a closure.
        return;
      }

      if (isPrototypeNameReference(n)) {
        recordPrototypePropUse(t, n, parent);
      } else if (isStaticNameReference(n, t.getScope())) {
        recordStaticNameUse(t, n, parent);
      } else {
        recordUnknownUse(t, n, parent);
      }
      break;

    case Token.ASSIGN:
      Node lhs = n.getFirstChild();
      Node rhs = n.getLastChild();
      if (rhs.isFunction()) {
        // These are recorded when entering the scope.
        return;
      }
      if (lhs.isName() ||
          lhs.isGetProp() ||
          rhs.isGetProp()) {
        if (NodeUtil.isPrototypeProperty(lhs)) {
          Name name = recordPrototypePropDefinition(
              t, lhs, getType(rhs), n, parent, parent.getParent());
          name.setAliased(true);
        }
      }
      maybeAliasNamesOnAssign(lhs, rhs);
      break;

    case Token.VAR:
      // var foo = bar;
      Node varName = n.getFirstChild();
      Node assignedValue = varName.getFirstChild();
      if (assignedValue == null) {
        return;
      }
      maybeAliasNamesOnAssign(varName, assignedValue);
      break;

    case Token.CALL:
      Node param = n.getFirstChild();
      // We need to alias every name that is passed as a parameter because
      // they have different names inside the function's scope.
      while ((param = param.getNext()) != null) {
        if (param.isName() || param.isGetProp()) {
          safeAlias(param);
        }
      }

      maybeRecordExport(n);
      break;
  }
}
 
Example 17
Source File: Closure_121_InlineVariables_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * @return true if the provided reference and declaration can be safely
 *         inlined according to our criteria
 */
private boolean canInline(
    Reference declaration,
    Reference initialization,
    Reference reference) {
  if (!isValidDeclaration(declaration)
      || !isValidInitialization(initialization)
      || !isValidReference(reference)) {
    return false;
  }

  // If the value is read more than once, skip it.
  // VAR declarations and EXPR_RESULT don't need the value, but other
  // ASSIGN expressions parents do.
  if (declaration != initialization &&
      !initialization.getGrandparent().isExprResult()) {
    return false;
  }

  // Be very conservative and do no cross control structures or
  // scope boundaries
  if (declaration.getBasicBlock() != initialization.getBasicBlock()
      || declaration.getBasicBlock() != reference.getBasicBlock()) {
    return false;
  }

  // Do not inline into a call node. This would change
  // the context in which it was being called. For example,
  //   var a = b.c;
  //   a();
  // should not be inlined, because it calls a in the context of b
  // rather than the context of the window.
  //   var a = b.c;
  //   f(a)
  // is OK.
  Node value = initialization.getAssignedValue();
  Preconditions.checkState(value != null);
  if (value.isGetProp()
      && reference.getParent().isCall()
      && reference.getParent().getFirstChild() == reference.getNode()) {
    return false;
  }

  if (value.isFunction()) {
    Node callNode = reference.getParent();
    if (reference.getParent().isCall()) {
      CodingConvention convention = compiler.getCodingConvention();
      // Bug 2388531: Don't inline subclass definitions into class defining
      // calls as this confused class removing logic.
      SubclassRelationship relationship =
          convention.getClassesDefinedByCall(callNode);
      if (relationship != null) {
        return false;
      }

      // issue 668: Don't inline singleton getter methods
      // calls as this confused class removing logic.
      if (convention.getSingletonGetterClassName(callNode) != null) {
        return false;
      }
    }
  }

  return canMoveAggressively(value) ||
      canMoveModerately(initialization, reference);
}
 
Example 18
Source File: Closure_48_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 19
Source File: Cardumen_0089_s.java    From coming with MIT License 4 votes vote down vote up
private void exitNode(Node node) {
  if (node.isFunction() || node.isScript()) {
    traversalState.pop();
  }
}
 
Example 20
Source File: Nopol2017_0014_t.java    From coming with MIT License 3 votes vote down vote up
/**
 * Determines whether a set operation is a constructor or enumeration
 * or interface declaration. The set operation may either be an assignment
 * to a name, a variable declaration, or an object literal key mapping.
 *
 * @param n The node that represents the name being set
 * @param parent Parent node of {@code n} (an ASSIGN, VAR, or OBJLIT node)
 * @return Whether the set operation is either a constructor or enum
 *     declaration
 */
private boolean isTypeDeclaration(Node n, Node parent) {
  Node valueNode = NodeUtil.getRValueOfLValue(n);
  JSDocInfo info = NodeUtil.getBestJSDocInfo(n);
  // Heed the annotations only if they're sensibly used.
  return info != null && valueNode != null &&
         (info.isConstructor() && valueNode.isFunction() ||
          info.isInterface() && valueNode.isFunction() ||
          info.hasEnumParameterType() && valueNode.isObjectLit());
}