Home | History | Annotate | Download | only in checks
      1 package org.chromium.devtools.jsdoc.checks;
      2 
      3 import com.google.common.base.Preconditions;
      4 import com.google.javascript.rhino.JSTypeExpression;
      5 import com.google.javascript.rhino.Node;
      6 import com.google.javascript.rhino.Token;
      7 
      8 import java.util.ArrayList;
      9 import java.util.Collections;
     10 import java.util.List;
     11 
     12 public class AstUtil {
     13 
     14     private static final String PROTOTYPE_SUFFIX = ".prototype";
     15 
     16     static Node parentOfType(Node node, int tokenType) {
     17         Node parent = node.getParent();
     18         return (parent == null || parent.getType() != tokenType) ? null : parent;
     19     }
     20 
     21     /**
     22      * Based on NodeUtil#getFunctionNameNode(Node).
     23      */
     24     static Node getFunctionNameNode(Node node) {
     25         Preconditions.checkState(node.isFunction());
     26 
     27         Node parent = node.getParent();
     28         if (parent != null) {
     29             switch (parent.getType()) {
     30             case Token.NAME:
     31                 // var name = function() ...
     32                 // var name2 = function name1() ...
     33                 return parent;
     34             // FIXME: Enable the setter and getter checks.
     35             // case Token.SETTER_DEF:
     36             // case Token.GETTER_DEF:
     37             case Token.STRING_KEY:
     38                 return parent;
     39             case Token.NUMBER:
     40                 return parent;
     41             case Token.ASSIGN:
     42                 int nameType = parent.getFirstChild().getType();
     43                 // We only consider these types of name nodes as acceptable.
     44                 return nameType == Token.NAME || nameType == Token.GETPROP
     45                     ? parent.getFirstChild()
     46                     : null;
     47             case Token.VAR:
     48                 return parent.getFirstChild();
     49             default:
     50                 Node funNameNode = node.getFirstChild();
     51                 // Don't return the name node for anonymous functions
     52                 return funNameNode.getString().isEmpty() ? null : funNameNode;
     53             }
     54         }
     55 
     56         return null;
     57     }
     58 
     59     static String getTypeNameFromPrototype(String value) {
     60         return value.substring(0, value.length() - PROTOTYPE_SUFFIX.length());
     61     }
     62 
     63     static boolean isPrototypeName(String typeName) {
     64         return typeName.endsWith(PROTOTYPE_SUFFIX);
     65     }
     66 
     67     static Node getAssignedTypeNameNode(Node assignment) {
     68         Preconditions.checkState(assignment.isAssign() || assignment.isVar());
     69         Node typeNameNode = assignment.getFirstChild();
     70         if (typeNameNode.getType() != Token.GETPROP && typeNameNode.getType() != Token.NAME) {
     71             return null;
     72         }
     73         return typeNameNode;
     74     }
     75 
     76     static List<Node> getArguments(Node functionCall) {
     77         int childCount = functionCall.getChildCount();
     78         if (childCount == 1) {
     79             return Collections.emptyList();
     80         }
     81         List<Node> arguments = new ArrayList<>(childCount - 1);
     82         for (int i = 1; i < childCount; ++i) {
     83             arguments.add(functionCall.getChildAtIndex(i));
     84         }
     85         return arguments;
     86     }
     87 
     88     static String getAnnotationTypeString(JSTypeExpression expression) {
     89         return expression.getRoot().getFirstChild().getString();
     90     }
     91 
     92     private AstUtil() {}
     93 }
     94