109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)package org.chromium.devtools.jsdoc.checks; 209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 3197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport com.google.common.base.Preconditions; 4197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport com.google.javascript.rhino.JSTypeExpression; 5197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport com.google.javascript.rhino.Node; 6197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport com.google.javascript.rhino.Token; 7197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 8197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport java.util.ArrayList; 9197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport java.util.Collections; 10197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport java.util.List; 1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public class AstUtil { 1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) private static final String PROTOTYPE_SUFFIX = ".prototype"; 1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 16197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static Node parentOfType(Node node, int tokenType) { 17197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Node parent = node.getParent(); 18aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch return (parent == null || parent.getType() != tokenType) ? null : parent; 1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 21197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch /** 22197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Based on NodeUtil#getFunctionNameNode(Node). 23197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch */ 24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static Node getFunctionNameNode(Node node) { 25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Preconditions.checkState(node.isFunction()); 2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Node parent = node.getParent(); 28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (parent != null) { 29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch switch (parent.getType()) { 30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch case Token.NAME: 31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // var name = function() ... 32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // var name2 = function name1() ... 33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return parent; 34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // FIXME: Enable the setter and getter checks. 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // case Token.SETTER_DEF: 36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // case Token.GETTER_DEF: 37197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch case Token.STRING_KEY: 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return parent; 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch case Token.NUMBER: 40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return parent; 41f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) case Token.ASSIGN: 42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) int nameType = parent.getFirstChild().getType(); 43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // We only consider these types of name nodes as acceptable. 44c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return nameType == Token.NAME || nameType == Token.GETPROP 45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ? parent.getFirstChild() 46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) : null; 47f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) case Token.VAR: 48197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return parent.getFirstChild(); 49f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) default: 50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) Node funNameNode = node.getFirstChild(); 51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // Don't return the name node for anonymous functions 52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return funNameNode.getString().isEmpty() ? null : funNameNode; 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 55aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch 5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return null; 5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) static String getTypeNameFromPrototype(String value) { 6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return value.substring(0, value.length() - PROTOTYPE_SUFFIX.length()); 6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) static boolean isPrototypeName(String typeName) { 6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return typeName.endsWith(PROTOTYPE_SUFFIX); 6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static Node getAssignedTypeNameNode(Node assignment) { 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Preconditions.checkState(assignment.isAssign() || assignment.isVar()); 69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Node typeNameNode = assignment.getFirstChild(); 7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (typeNameNode.getType() != Token.GETPROP && typeNameNode.getType() != Token.NAME) { 7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return null; 7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return typeNameNode; 7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static List<Node> getArguments(Node functionCall) { 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int childCount = functionCall.getChildCount(); 78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (childCount == 1) { 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return Collections.emptyList(); 8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch List<Node> arguments = new ArrayList<>(childCount - 1); 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch for (int i = 1; i < childCount; ++i) { 83197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch arguments.add(functionCall.getChildAtIndex(i)); 8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return arguments; 86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 87aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch 88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static String getAnnotationTypeString(JSTypeExpression expression) { 89197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return expression.getRoot().getFirstChild().getString(); 9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) private AstUtil() {} 9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 94