/** * Gets the last child node. * @return the last child node */ public DetailAST getLastChild() { DetailAST ast = getFirstChild(); while (ast != null && ast.getNextSibling() != null) { ast = ast.getNextSibling(); } return ast; }
/** * Find the last token of type {@code TokenTypes.ANNOTATION} * under the given set of modifiers. * @param modifiers {@code DetailAST}. * @return {@code DetailAST} or null if there are no annotations. */ private static DetailAST findLastAnnotation(DetailAST modifiers) { DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION); while (annotation != null && annotation.getNextSibling() != null && annotation.getNextSibling().getType() == TokenTypes.ANNOTATION) { annotation = annotation.getNextSibling(); } return annotation; }
/** * Retrieves the right side of a conditional. * * @param cond a conditional type * {@link TokenTypes#QUESTION QUESTION} * @return either the value * or another conditional */ private static DetailAST getCondRight(final DetailAST cond) { final DetailAST colon = cond.findFirstToken(TokenTypes.COLON); return colon.getNextSibling(); }
/** * Retrieves the first modifier that is not an annotation. * @param modifiers The ast to examine. * @return The first modifier or {@code null} if none found. */ private static DetailAST getFirstModifierAst(DetailAST modifiers) { DetailAST modifier = modifiers.getFirstChild(); while (modifier != null && modifier.getType() == TokenTypes.ANNOTATION) { modifier = modifier.getNextSibling(); } return modifier; }
/** * Gets the list of annotations on method definition. * @param methodDef method definition node * @return List of annotations */ private static List<DetailAST> getMethodAnnotationsList(DetailAST methodDef) { final List<DetailAST> annotationsList = new ArrayList<>(); final DetailAST modifiers = methodDef.findFirstToken(TokenTypes.MODIFIERS); DetailAST modifier = modifiers.getFirstChild(); while (modifier != null) { if (modifier.getType() == TokenTypes.ANNOTATION) { annotationsList.add(modifier); } modifier = modifier.getNextSibling(); } return annotationsList; }
/** * Get next sibling node skipping any comment nodes. * @param node current node * @return next sibling */ private static DetailAST getNextSiblingSkipComments(DetailAST node) { DetailAST result = node.getNextSibling(); while (result.getType() == TokenTypes.SINGLE_LINE_COMMENT || result.getType() == TokenTypes.BLOCK_COMMENT_BEGIN) { result = result.getNextSibling(); } return result; }
/** * Check the indentation level of modifiers. */ protected void checkModifiers() { final DetailAST modifiers = mainAst.findFirstToken(TokenTypes.MODIFIERS); for (DetailAST modifier = modifiers.getFirstChild(); modifier != null; modifier = modifier.getNextSibling()) { if (isOnStartOfLine(modifier) && !getIndent().isAcceptable(expandedTabsColumnNo(modifier))) { logError(modifier, "modifier", expandedTabsColumnNo(modifier)); } } }
/** * Counts number of case tokens subject to a case group token. * @param ast case group token. * @return number of case tokens. */ private static int countCaseTokens(DetailAST ast) { int counter = 0; for (DetailAST iterator = ast.getFirstChild(); iterator != null; iterator = iterator.getNextSibling()) { if (iterator.getType() == TokenTypes.LITERAL_CASE) { counter++; } } return counter; }
/** * Returns the last child token that makes a specified type and contains containType in * its branch. * @param ast token to be tested * @param childType the token type to match * @param containType the token type which has to be present in the branch * @return the matching token, or null if no match */ private static DetailAST findLastChildWhichContainsSpecifiedToken(DetailAST ast, int childType, int containType) { DetailAST returnValue = null; for (DetailAST astIterator = ast.getFirstChild(); astIterator != null; astIterator = astIterator.getNextSibling()) { if (astIterator.getType() == childType && astIterator.findFirstToken(containType) != null) { returnValue = astIterator; } } return returnValue; }
/** * Returns the n'th child of an AST node. * @param ast the AST node to get the child of * @param index the index of the child to get * @return the n'th child of the given AST node, or {@code null} if none */ private static DetailAST getNthChild(DetailAST ast, int index) { DetailAST child = ast.getFirstChild(); for (int i = 0; i < index && child != null; ++i) { child = child.getNextSibling(); } return child; }
/** * Checks if the case group or its sibling contain the 'default' switch. * @param caseGroupAst first case group to check. * @return true if 'default' switch found. */ private static boolean containsDefaultSwitch(DetailAST caseGroupAst) { DetailAST nextAst = caseGroupAst; boolean found = false; while (nextAst != null) { if (nextAst.findFirstToken(TokenTypes.LITERAL_DEFAULT) != null) { found = true; break; } nextAst = nextAst.getNextSibling(); } return found; }
/** * Finds the class body of the first class in the DetailAST. * @param top AST to find the class body * @return OBJBLOCK token if found; {@code null} otherwise */ private static DetailAST getClassBody(DetailAST top) { DetailAST ast = top; while (ast != null && ast.getType() != TokenTypes.CLASS_DEF) { ast = ast.getNextSibling(); } DetailAST objBlock = null; if (ast != null) { objBlock = ast.findFirstToken(TokenTypes.OBJBLOCK); } return objBlock; }
/** * Returns semicolon for variable definition statement. * @param variableDef * ast node of type TokenTypes.VARIABLE_DEF * @return ast node of type TokenTypes.SEMI */ private static DetailAST getVarDefStatementSemicolon(DetailAST variableDef) { DetailAST lastNode = variableDef.getLastChild(); if (lastNode.getType() != TokenTypes.SEMI) { lastNode = variableDef.getNextSibling(); } return lastNode; }
@Test public void testWithArrayCreateFullIdentWithArrayDeclare() throws Exception { final FileText testFileText = new FileText( new File(getPath("InputFullIdentTestArrayType.java")).getAbsoluteFile(), System.getProperty("file.encoding", StandardCharsets.UTF_8.name())); final DetailAST packageDefinitionNode = JavaParser.parse(new FileContents(testFileText)); final DetailAST arrayDeclarator = packageDefinitionNode.getNextSibling() .findFirstToken(TokenTypes.OBJBLOCK) .findFirstToken(TokenTypes.VARIABLE_DEF) .findFirstToken(TokenTypes.TYPE) .getFirstChild(); final FullIdent ident = FullIdent.createFullIdent(arrayDeclarator); Assert.assertEquals("Invalid full indent", "int[][][5x12]", ident.toString()); }
/** * Returns the first child token that makes a specified type. * @param type the token type to match * @return the matching token, or null if no match */ public DetailAST findFirstToken(int type) { DetailAST returnValue = null; for (DetailAST ast = getFirstChild(); ast != null; ast = ast.getNextSibling()) { if (ast.getType() == type) { returnValue = ast; break; } } return returnValue; }
/** * Checks if catch block is empty or contains only comments. * @param catchAst {@link TokenTypes#LITERAL_CATCH LITERAL_CATCH} * @return true if catch block is empty. */ private static boolean isEmptyCatchBlock(DetailAST catchAst) { boolean result = true; final DetailAST slistToken = catchAst.findFirstToken(TokenTypes.SLIST); DetailAST catchBlockStmt = slistToken.getFirstChild(); while (catchBlockStmt.getType() != TokenTypes.RCURLY) { if (catchBlockStmt.getType() != TokenTypes.SINGLE_LINE_COMMENT && catchBlockStmt.getType() != TokenTypes.BLOCK_COMMENT_BEGIN) { result = false; break; } catchBlockStmt = catchBlockStmt.getNextSibling(); } return result; }
/** * Checks whether there is a use of an object reference to invoke an object's method on line. * @param root root token of the line. * @return true if there is a use of an object reference to invoke an object's method on line. */ private static boolean isUsingOfObjectReferenceToInvokeMethod(DetailAST root) { return root.getFirstChild().getFirstChild().getFirstChild() != null && root.getFirstChild().getFirstChild().getFirstChild().getNextSibling() != null; }
/** * Get the child element that is not a list of statements. * * @return the non-list child element */ protected DetailAST getNonListChild() { return getMainAst().findFirstToken(TokenTypes.RPAREN).getNextSibling(); }
/** * Checks if a given switch terminated by return, throw or, * if allowed break, continue. * @param literalSwitchAst loop to check * @param useContinue should we consider continue as terminator. * @return true if switch is terminated. */ private boolean checkSwitch(final DetailAST literalSwitchAst, boolean useContinue) { DetailAST caseGroup = literalSwitchAst.findFirstToken(TokenTypes.CASE_GROUP); boolean isTerminated = caseGroup != null; while (isTerminated && caseGroup.getType() != TokenTypes.RCURLY) { final DetailAST caseBody = caseGroup.findFirstToken(TokenTypes.SLIST); isTerminated = caseBody != null && isTerminated(caseBody, false, useContinue); caseGroup = caseGroup.getNextSibling(); } return isTerminated; }
/** * Collects references made by IDENT. * @param ast the IDENT node to process */ private void processIdent(DetailAST ast) { final DetailAST parent = ast.getParent(); final int parentType = parent.getType(); if (parentType != TokenTypes.DOT && parentType != TokenTypes.METHOD_DEF || parentType == TokenTypes.DOT && ast.getNextSibling() != null) { referenced.add(ast.getText()); } }