@Override public void visitCompilationUnit(CompilationUnitTree tree) { passwordHashSaltTrees.clear(); this.assignmentExpressionVisitor = new AssignmentExpressionVisitor(context().symbolTable()); tree.accept(assignmentExpressionVisitor); super.visitCompilationUnit(tree); if (containsPasswordHashFunction && !passwordHashSaltTrees.isEmpty()) { passwordHashSaltTrees.forEach(salt -> context().newIssue(this, salt, USE_DEFAULT_SALT_MESSAGE)); } }
@Test public void without_statement() throws Exception { CompilationUnitTree tree = parse("<?php", PHPLexicalGrammar.COMPILATION_UNIT); assertThat(tree.is(Kind.COMPILATION_UNIT)).isTrue(); assertThat(tree.script().fileOpeningTagToken().text()).isEqualTo("<?php"); assertThat(tree.script().statements()).isEmpty(); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { SyntaxToken eofToken = tree.eofToken(); if (eofToken.column() != 0 || eofToken.line() == 1) { context().newFileIssue(this, MESSAGE); } } }
@Test public void test_lines_of_code_number_on_tree() throws Exception { CompilationUnitTree cut = parse("metrics/lines_of_code.php"); Optional<ClassDeclarationTree> firstClassTree = cut.script().statements().stream() .filter(statement -> statement.is(Tree.Kind.CLASS_DECLARATION)) .map(ClassDeclarationTree.class::cast) .findFirst(); assertThat(firstClassTree).isPresent(); assertThat(LineVisitor.linesOfCode(firstClassTree.get())).isEqualTo(4); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { SyntaxToken eofToken = tree.eofToken(); if (eofToken.column() != 0 || eofToken.line() == 1) { context().newFileIssue(this, MESSAGE); } } }
@Test public void test_isDescendant() { Tree tree = PHPParserBuilder.createParser().parse("<?= for(;;) {} ?>"); StatementTree statementTree = ((CompilationUnitTree) tree).script().statements().get(0); assertThat(isDescendant(statementTree, tree)).isTrue(); assertThat(isDescendant(tree, statementTree)).isFalse(); assertThat(isDescendant(tree, tree)).isTrue(); assertThat(isDescendant(statementTree, statementTree)).isTrue(); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { passwordHashSaltTrees.clear(); this.assignmentExpressionVisitor = new AssignmentExpressionVisitor(context().symbolTable()); tree.accept(assignmentExpressionVisitor); super.visitCompilationUnit(tree); if (containsPasswordHashFunction && !passwordHashSaltTrees.isEmpty()) { passwordHashSaltTrees.forEach(salt -> context().newIssue(this, salt, USE_DEFAULT_SALT_MESSAGE)); } }
@Test public void without_php() throws Exception { CompilationUnitTree tree = parse("hello world\n", PHPLexicalGrammar.COMPILATION_UNIT); assertThat(tree.is(Kind.COMPILATION_UNIT)).isTrue(); assertThat(tree.script().fileOpeningTagToken().text()).isEqualTo("hello world\n"); assertThat(tree.eofToken().line()).isEqualTo(2); }
@Test public void retrieve_symbol_by_tree() { ExpressionTree dollarAUsage = ((AssignmentExpressionTree) ((ExpressionStatementTree) ((FunctionDeclarationTree) cut.script().statements().get(5)).body().statements().get(3)).expression()).variable(); Symbol symbol = SYMBOL_MODEL.getSymbol(dollarAUsage); assertThat(symbol).isNotNull(); assertThat(symbol.name()).isEqualTo("$a"); }
public static int complexity(CompilationUnitTree cut) { // Only explicitly visit functions, methods and function expressions. // Rest of the compilation unit is based on CognitiveComplexityVisitor computation class CompilationUnitVisitor extends CognitiveComplexityVisitor { private int functionsComplexity = 0; @Override public void visitMethodDeclaration(MethodDeclarationTree tree) { sumComplexity(tree); } @Override public void visitFunctionDeclaration(FunctionDeclarationTree tree) { sumComplexity(tree); } @Override public void visitFunctionExpression(FunctionExpressionTree tree) { sumComplexity(tree); } private void sumComplexity(FunctionTree tree) { functionsComplexity += complexity(tree).getValue(); } private int complexityWithFunctionsAndRestOfSript() { int scriptComplexity = super.complexity.value; return functionsComplexity + scriptComplexity; } } CompilationUnitVisitor compilationUnitVisitor = new CompilationUnitVisitor(); cut.accept(compilationUnitVisitor); return compilationUnitVisitor.complexityWithFunctionsAndRestOfSript(); }
@Test public void test() throws Exception { CompilationUnitTree tree = parse("<?php $a;", PHPLexicalGrammar.COMPILATION_UNIT); assertThat(tree.is(Kind.COMPILATION_UNIT)).isTrue(); assertThat(tree.script().fileOpeningTagToken().text()).isEqualTo("<?php"); assertThat(tree.script().statements()).hasSize(1); assertThat(tree.eofToken().line()).isEqualTo(1); }
@Test public void test_buildCFG() { CompilationUnitTree tree = parse("<?php " + "function foo() {" + " $expr = function() {echo 'Hello';};" + "}" + "echo 'Hello';", PHPLexicalGrammar.COMPILATION_UNIT); FunctionDeclarationTree func = (FunctionDeclarationTree) tree.script().statements().get(0); ExpressionStatementTree expr = (ExpressionStatementTree) func.body().statements().get(0); ControlFlowGraph cfg = ControlFlowGraph.build(func, checkContext); assertThat(cfg.start().elements().get(0)).isEqualTo(expr); FunctionExpressionTree funcExpr = ((FunctionExpressionTree) ((AssignmentExpressionTree) expr.expression()).value()); StatementTree echo = funcExpr.body().statements().get(0); cfg = ControlFlowGraph.build(funcExpr, checkContext); assertThat(cfg.start().elements().get(0)).isEqualTo(echo); StatementTree scriptEcho = tree.script().statements().get(1); cfg = ControlFlowGraph.build(tree.script(), checkContext); assertThat(cfg.start().elements().get(0)).isEqualTo(func); assertThat(cfg.start().elements().get(1)).isEqualTo(scriptEcho); }
public static int complexity(CompilationUnitTree cut) { // Only explicitly visit functions, methods and function expressions. // Rest of the compilation unit is based on CognitiveComplexityVisitor computation class CompilationUnitVisitor extends CognitiveComplexityVisitor { private int functionsComplexity = 0; @Override public void visitMethodDeclaration(MethodDeclarationTree tree) { sumComplexity(tree); } @Override public void visitFunctionDeclaration(FunctionDeclarationTree tree) { sumComplexity(tree); } @Override public void visitFunctionExpression(FunctionExpressionTree tree) { sumComplexity(tree); } private void sumComplexity(FunctionTree tree) { functionsComplexity += complexity(tree).getValue(); } private int complexityWithFunctionsAndRestOfSript() { int scriptComplexity = super.complexity.value; return functionsComplexity + scriptComplexity; } } CompilationUnitVisitor compilationUnitVisitor = new CompilationUnitVisitor(); cut.accept(compilationUnitVisitor); return compilationUnitVisitor.complexityWithFunctionsAndRestOfSript(); }
@Test public void test_buildCFG_with_method() { CompilationUnitTree tree = parse("<?php " + "class A {" + " function foo() {" + " echo 'Hello';" + " }" + " abstract function bar();" + "}", PHPLexicalGrammar.COMPILATION_UNIT); ClassDeclarationTree cls = (ClassDeclarationTree) tree.script().statements().get(0); MethodDeclarationTree method = (MethodDeclarationTree) cls.members().get(0); StatementTree echo = ((BlockTree) method.body()).statements().get(0); ControlFlowGraph cfg = ControlFlowGraph.build(method, checkContext); assertThat(cfg.start().elements().get(0)).isEqualTo(echo); MethodDeclarationTree abstractMethod = (MethodDeclarationTree) cls.members().get(1); cfg = ControlFlowGraph.build(abstractMethod, checkContext); assertThat(cfg).isNull(); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { assignmentExpressionVisitor = new AssignmentExpressionVisitor(context().symbolTable()); tree.accept(assignmentExpressionVisitor); super.visitCompilationUnit(tree); }
private void verifyLiveVariableAnalysis(String argsList, String body) { CompilationUnitTree cut = parse("<?php function f(" + argsList + ") { " + body + " }", PHPLexicalGrammar.COMPILATION_UNIT); SymbolTableImpl symbolTable = SymbolTableImpl.create(cut); FunctionDeclarationTree functionTree = (FunctionDeclarationTree) cut.script().statements().get(0); ControlFlowGraph cfg = ControlFlowGraph.build(functionTree.body()); LiveVariablesAnalysis analysis = LiveVariablesAnalysis.analyze(cfg, symbolTable); Validator.assertLiveVariables(cfg, analysis); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { assignmentExpressionVisitor = new AssignmentExpressionVisitor(context().symbolTable()); tree.accept(assignmentExpressionVisitor); super.visitCompilationUnit(tree); }
@Test public void test_cfg_failure_logs() { CompilationUnitTree tree = parse("<?php\n" + "function foo() {\n" + " break;\n" + "}\n", PHPLexicalGrammar.COMPILATION_UNIT); FunctionDeclarationTree func = (FunctionDeclarationTree) tree.script().statements().get(0); ControlFlowGraph cfg = ControlFlowGraph.build(func, checkContext); assertThat(cfg).isNull(); assertThat(logTester.logs(LoggerLevel.WARN)).contains("Failed to build control flow graph for file [mock.php] at line 2"); assertThat(logTester.logs(LoggerLevel.WARN)).contains("Failed to build CFG"); logTester.clear(); // testing mechanism avoiding reporting failure multiple times for the same tree cfg = ControlFlowGraph.build(func, checkContext); assertThat(cfg).isNull(); assertThat(logTester.logs()).isEmpty(); }
@Override public void visitCompilationUnit(CompilationUnitTree tree) { assignmentExpressionVisitor = new AssignmentExpressionVisitor(context().symbolTable()); tree.accept(assignmentExpressionVisitor); super.visitCompilationUnit(tree); }