@Override public void visitNode(AstNode astNode) { if (skipFile) { return; } logDebug("***** Node: " + astNode); switch ((CxxGrammarImpl) astNode.getType()) { case classSpecifier: visitClassSpecifier(astNode); break; case memberDeclaration: visitMemberDeclaration(astNode); break; case functionDefinition: visitFunctionDefinition(astNode); break; case enumSpecifier: visitEnumSpecifier(astNode); break; case initDeclaratorList: visitDeclaratorList(astNode); break; case aliasDeclaration: visitAliasDeclaration(astNode); break; default: // should not happen LOG.error("Visiting unknown node: {}", astNode.getType()); break; } }
private void visitDeclaratorList(AstNode declaratorList) { // do not handle declaration in function body AstNode functionBody = declaratorList.getFirstAncestor(CxxGrammarImpl.functionBody); if (functionBody != null) { return; } // ignore friend declarations if (isFriendDeclaration(declaratorList)) { return; } AstNode declaration = declaratorList.getFirstAncestor(CxxGrammarImpl.declaration); List<AstNode> declarators = declaratorList.getChildren(CxxGrammarImpl.initDeclarator); if (declarators.size() == 1) { // a special handling is needed in case of single declarator // because documentation may be located on different places // depending on the declaration visitSingleDeclarator(declaration, declarators.get(0)); } else { // with several declarators, documentation should be located // on each declarator for (AstNode declarator : declarators) { visitDeclarator(declarator, declarator); } } }
private AstNode firstSimpleStmt(AstNode statement) { AstNode stmtList = statement.getFirstChild(PythonGrammar.STMT_LIST); if (stmtList != null) { return stmtList.getFirstChild(PythonGrammar.SIMPLE_STMT); } return null; }
private static String getValue(AstNode astNode) { StringBuilder sb = new StringBuilder(); for (AstNode child : astNode.getChildren()) { sb.append(child.getTokenValue()); } return sb.toString(); }
@Override protected void addIssue(String type, AstNode duplicate, AstNode duplicated) { String message = "This {0}''s code block is the same as the block for the {0} on line {1}."; getContext() .createLineViolation( this, message, duplicate.getParent(), type, duplicated.getParent().getTokenLine()); }
private static AstNode getFunctionBlock(AstNode functionNode) { if (functionNode.is(PHPGrammar.METHOD_DECLARATION)) { return functionNode.getFirstChild(PHPGrammar.METHOD_BODY).getFirstChild(PHPGrammar.BLOCK); } else { return functionNode.getFirstChild(PHPGrammar.BLOCK); } }
@Override public void visitNode(AstNode astNode) { if (astNode .getNextAstNode() .is( EcmaScriptGrammar.CASE_CLAUSE, EcmaScriptGrammar.DEFAULT_CLAUSE, EcmaScriptGrammar.CASE_CLAUSES)) { AstNode statementList = astNode.getFirstChild(EcmaScriptGrammar.STATEMENT_LIST); if (statementList != null && statementList .getLastChild() .getFirstChild() .isNot( EcmaScriptGrammar.BREAK_STATEMENT, EcmaScriptGrammar.RETURN_STATEMENT, EcmaScriptGrammar.THROW_STATEMENT)) { getContext() .createLineViolation( this, "Last statement in this switch-clause should be an unconditional break.", astNode); } } }
private static boolean isOnSameLineThanLeftCurlyBrace(AstNode rcurly) { return rcurly .getParent() .getFirstChild(PHPPunctuator.LCURLYBRACE, PHPPunctuator.DOLLAR_LCURLY) .getTokenLine() == rcurly.getTokenLine(); }
private void visitAliasDeclaration(AstNode aliasDeclNode) { if (isPublicApiMember(aliasDeclNode)) { logDebug("AliasDeclaration"); AstNode aliasDeclIdNode = aliasDeclNode.getFirstDescendant(GenericTokenType.IDENTIFIER); if (aliasDeclIdNode == null) { LOG.error("No identifier found at {}", aliasDeclNode.getTokenLine()); } else { // check if this is a template specification to adjust // documentation node AstNode template = aliasDeclNode.getFirstAncestor(CxxGrammarImpl.templateDeclaration); AstNode docNode = (template != null) ? template : aliasDeclNode; // look for block documentation List<Token> comments = getBlockDocumentation(docNode); // documentation may be inlined if (comments.isEmpty()) { comments = getDeclaratorInlineComment(aliasDeclNode); } visitPublicApi(aliasDeclNode, aliasDeclIdNode.getTokenValue(), comments); } } }
private void visitSingleDeclarator(AstNode declaration, AstNode declarator) { AstNode docNode; AstNode params = declaration.getFirstDescendant(CxxGrammarImpl.parametersAndQualifiers); // in case of function declaration, // the docNode is set on the declaration node if (params != null) { docNode = declaration; } else { AstNode classSpecifier = declaration.getFirstDescendant(CxxGrammarImpl.classSpecifier); // if a class is specified on the same declaration, // e.g. 'struct {} a;' // the documentation node is set on the declarator if (classSpecifier != null) { docNode = declarator; } else { docNode = declaration; } } visitDeclarator(declarator, docNode); }
private void visitIfStatementNode(AstNode node) { if (checkedIfStatements.contains(node)) { return; } List<AstNode> branchNodes = Lists.newArrayList(); AstNode ifNode = node; while (ifNode != null) { checkedIfStatements.add(ifNode); branchNodes.add(ifNode.getFirstChild(ifBranchNodeType())); AstSelect elseIfNodes = ifNode .select() .children(PHPGrammar.ELSEIF_LIST) .children(PHPGrammar.ELSEIF_CLAUSE) .children(ifBranchNodeType()); for (AstNode condition : elseIfNodes) { branchNodes.add(condition); } AstSelect elseNodes = ifNode.select().children(PHPGrammar.ELSE_CLAUSE); for (AstNode elseNode : elseNodes.children(ifBranchNodeType())) { branchNodes.add(elseNode); } AstSelect elseIfs = elseNodes.children(PHPGrammar.STATEMENT).children(PHPGrammar.IF_STATEMENT); ifNode = elseIfs.isEmpty() ? null : elseIfs.get(0); } checkBranches(branchNodes, "branch"); }
private void checkPropertySetParameterList(AstNode astNode) { AstNode identifier = astNode.getFirstChild(getContext().getGrammar().identifier); if (isEvalOrArguments(identifier.getTokenValue())) { getContext() .createLineViolation( this, createMessageFor("parameter", identifier.getTokenValue()), identifier); } }
private void checkVariableDeclaration(AstNode astNode) { AstNode identifier = astNode.getFirstChild(getContext().getGrammar().identifier); if (isEvalOrArguments(identifier.getTokenValue())) { getContext() .createLineViolation( this, createMessageFor("variable", identifier.getTokenValue()), identifier); } }
/** * Find documentation node, associated documentation, identifier of a <em>public</em> member * declarator and visit it as a public API. * * @param node the <em>public</em> member declarator to visit */ private void visitMemberDeclarator(AstNode node) { AstNode container = node.getFirstAncestor(CxxGrammarImpl.templateDeclaration, CxxGrammarImpl.classSpecifier); if (isOverriddenMethod(node)) { // assume that ancestor method is documented // and do not count as public API return; } AstNode docNode; if (container == null || container.getType() == CxxGrammarImpl.classSpecifier) { docNode = node; } else { docNode = container; } // look for block documentation List<Token> comments = getBlockDocumentation(docNode); // documentation may be inlined if (comments.isEmpty()) { comments = getDeclaratorInlineComment(node); } // find the identifier to present to concrete visitors String id = null; AstNode idNode = null; // first look for an operator function id idNode = node.getFirstDescendant(CxxGrammarImpl.operatorFunctionId); if (idNode != null) { id = getOperatorId(idNode); } else { // look for a declarator id idNode = node.getFirstDescendant(CxxGrammarImpl.declaratorId); if (idNode != null) { id = idNode.getTokenValue(); } else { // look for an identifier (e.g in bitfield declaration) idNode = node.getFirstDescendant(GenericTokenType.IDENTIFIER); if (idNode != null) { id = idNode.getTokenValue(); } else { LOG.error("Unsupported declarator at {}", node.getTokenLine()); } } } if (idNode != null && id != null) { visitPublicApi(idNode, id, comments); } }
private void checkModification(AstNode astNode) { if (isEvalOrArguments(astNode.getTokenValue()) && !astNode.hasDirectChildren(EcmaScriptPunctuator.LBRACKET) && !astNode.getParent().is(getContext().getGrammar().callExpression)) { getContext() .createLineViolation( this, "Remove the modification of '" + astNode.getTokenValue() + "'.", astNode); } }
@Override public void leaveNode(AstNode astNode) { if (isInClass && classStack.peek().isInConstructor && astNode.is(FlexGrammar.FUNCTION_DEF)) { classStack.peek().isInConstructor = false; } else if (isInClass && astNode.is(FlexGrammar.CLASS_DEF)) { classStack.pop(); isInClass = classStack.isEmpty() ? false : true; } }
@Override public void visitNode(AstNode astNode) { if (astNode.is(FlexGrammar.CLASS_DEF)) { inClass = true; classStack.push(new ClassState(astNode)); } else if (inClass && astNode.is(FlexGrammar.QUALIFIED_IDENTIFIER)) { classStack.peek().use(astNode); } }
@Override public void visitNode(AstNode node) { if (node.is(CxxGrammarImpl.LITERAL)) { reg.reset(node.getTokenOriginalValue().replaceAll("\\s", "")); if (reg.find()) { getContext() .createLineViolation(this, "Do not hard code sensitive data in programs.", node); } } }
private static List<String> getParameters(AstNode node) { ImmutableList.Builder<String> builder = ImmutableList.builder(); for (AstNode parameter : node.getFirstChild(JavaGrammar.FORMAL_PARAMETERS) .getDescendants(JavaGrammar.VARIABLE_DECLARATOR_ID)) { builder.add(parameter.getTokenOriginalValue()); } return builder.build(); }
public static int getNumberOfLine(AstNode functionNode) { if (CheckUtils.isAbstractMethod(functionNode)) { return 0; } AstNode functionBlock = getFunctionBlock(functionNode); int firstLine = functionBlock.getFirstChild(PHPPunctuator.LCURLYBRACE).getTokenLine(); int lastLine = functionBlock.getFirstChild(PHPPunctuator.RCURLYBRACE).getTokenLine(); return lastLine - firstLine + 1; }
@Override public void visitNode(AstNode astNode) { if (astNode.is(PHPGrammar.FUNCTION_DECLARATION)) { getContext().createLineViolation(this, "Move this function into a class.", astNode); } else if (scopes.isEmpty()) { checkAssignment(astNode); } if (astNode.is(FunctionUtils.functions())) { scopes.push(astNode); } }
@Test public void getSecondDeclarationTest() { AstNodeXPathQuery<AstNode> xpath1 = AstNodeXPathQuery.create("/COMPILATION_UNIT/DEFINITION[@tokenLine=4]"); AstNodeXPathQuery<AstNode> xpath2 = AstNodeXPathQuery.create("/COMPILATION_UNIT/DEFINITION[2]"); AstNode declarationAtLineFour = fileNode.getChildren().get(1); assertThat(declarationAtLineFour.is(MiniCGrammar.DEFINITION)).isTrue(); assertThat(declarationAtLineFour.getTokenLine()).isEqualTo(4); assertThat(xpath1.selectSingleNode(fileNode)).isEqualTo(declarationAtLineFour); assertThat(xpath1.selectSingleNode(fileNode)).isEqualTo(xpath2.selectSingleNode(fileNode)); }
@Override protected AstNode matchWorker(ParsingState parsingState) { Token nextToken = parsingState.peekTokenIfExists(parsingState.lexerIndex, this); AstNode astNode = new AstNode(null, "exclusiveTillMatcher", nextToken); while (nothingMatch(parsingState)) { Token token = parsingState.popToken(this); astNode.addChild(new AstNode(token)); } return astNode; }
@Override public void visitNode(AstNode astNode) { if (astNode.is(PythonGrammar.FILE_INPUT)) { visitModule(astNode); } if (astNode.is(PythonGrammar.FUNCDEF)) { visitFuncDef(astNode); } if (astNode.is(PythonGrammar.CLASSDEF)) { visitClassDef(astNode); } }
private void checkFirstSuite(AstNode astNode, String typeName) { AstNode suite = astNode.getFirstChild(PythonGrammar.SUITE); AstNode firstStatement = suite.getFirstChild(PythonGrammar.STATEMENT); AstNode firstSimpleStmt; if (firstStatement == null) { firstSimpleStmt = suite.getFirstChild(PythonGrammar.STMT_LIST).getFirstChild(PythonGrammar.SIMPLE_STMT); } else { firstSimpleStmt = firstSimpleStmt(firstStatement); } checkSimpleStmt(astNode, firstSimpleStmt, typeName); }
@Test public void test_firstAncestor_by_type() { AstNodeType type = mock(AstNodeType.class); assertThat((Object) select.firstAncestor(type)).isSameAs(AstSelectFactory.empty()); AstNode parent = mock(AstNode.class); when(node.getParent()).thenReturn(parent); AstNode ancestor = mock(AstNode.class); when(ancestor.getType()).thenReturn(type); when(parent.getParent()).thenReturn(ancestor); assertThat((Object) select.firstAncestor(type)).isInstanceOf(SingleAstSelect.class); assertThat(select.firstAncestor(type)).containsOnly(ancestor); }
/** * Method that searches for testMethod keyword in a method given a node. * * @param astNode parent node for method. * @return a boolean value, returns true if there is a testMethod keyword or false otherwise. */ public static boolean hasTestMethodKeyword(AstNode astNode) { boolean hasAnnotation = false; List<AstNode> modifiersChildren = astNode.getChildren(MODIFIERS); for (AstNode modifier : modifiersChildren) { for (AstNode modifierChild : modifier.getChildren()) { if ((modifierChild.getTokenOriginalValue().matches(TEST_METHOD_PATTERN))) { hasAnnotation = true; break; } } } return hasAnnotation; }
private boolean isOverriddenMethod(AstNode memberDeclarator) { List<AstNode> modifiers = memberDeclarator.getDescendants(CxxGrammarImpl.cliFunctionModifier); for (AstNode modifier : modifiers) { AstNode modifierId = modifier.getFirstChild(); if (TOKEN_OVERRIDE.equals(modifierId.getTokenValue())) { return true; } } return false; }
@Override public void visitNode(AstNode astNode) { EcmaScriptGrammar g = getContext().getGrammar(); if (astNode.is(g.functionDeclaration, g.functionExpression)) { checkFunction(astNode); } else if (astNode.is(g.catch_, g.variableDeclaration, g.variableDeclarationNoIn)) { checkVariableDeclaration(astNode); } else if (astNode.is(g.propertySetParameterList)) { checkPropertySetParameterList(astNode); } else if (astNode.is(g.memberExpression)) { checkModification(astNode); } }
private static List<Token> getFieldNameTokens(AstNode astNode) { List<Token> methodNames = new LinkedList<>(); AstSelect funcDefSelect = astNode .select() .children(PythonGrammar.SUITE) .children(PythonGrammar.STATEMENT) .children(PythonGrammar.COMPOUND_STMT) .children(PythonGrammar.FUNCDEF); for (AstNode node : funcDefSelect) { methodNames.add(node.getFirstChild(PythonGrammar.FUNCNAME).getToken()); } return methodNames; }