1package org.chromium.devtools.jsdoc.checks; 2 3import com.google.common.base.Preconditions; 4import com.google.javascript.rhino.JSTypeExpression; 5import com.google.javascript.rhino.Node; 6import com.google.javascript.rhino.Token; 7 8import java.util.ArrayList; 9import java.util.Collections; 10import java.util.List; 11 12public 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