@Override public void scanFile(JavaFileScannerContext context) { this.context = context; if (context.getSemanticModel() != null) { scan(context.getTree()); } }
@Override public void scanFile(JavaFileScannerContext context) { CompilationUnitTree tree = context.getTree(); if (tree.packageDeclaration() == null && tree.types().isEmpty()) { context.addIssue(context.getTree(), this, "This Java file is empty."); } }
@Override public void scanFile(JavaFileScannerContext context) { if (pattern == null) { pattern = Pattern.compile(format, Pattern.DOTALL); } this.context = context; // For debugging purpose, you can print out the entire AST of the analyzed file System.out.println(PrinterVisitor.print(context.getTree())); scan(context.getTree()); }
@Override public void scanFile(JavaFileScannerContext context) { JavaTree.CompilationUnitTreeImpl tree = (JavaTree.CompilationUnitTreeImpl) context.getTree(); currentPackage = PackageDeclarationTreeImpl.packageNameAsString(tree.packageDeclaration()).replace('.', '/'); currentFile = context.getFile(); currentClassKey.clear(); parent.clear(); anonymousInnerClassCounter.clear(); suppressWarningLines.clear(); scan(tree); }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; validUsagesStack = new ArrayDeque<>(); exceptions = Splitter.on(",").trimResults().split(exceptionsCommaSeparated); exceptionIdentifiers = Lists.newArrayList(); for (String exception : exceptions) { exceptionIdentifiers.add(exception.substring(exception.lastIndexOf(".") + 1)); } semanticModel = (SemanticModel) context.getSemanticModel(); if (semanticModel != null) { scan(context.getTree()); } }
@Override public void visitMethod(MethodTree tree) { int max; String partialMessage; if (tree.is(Tree.Kind.CONSTRUCTOR)) { max = constructorMax; partialMessage = "Constructor"; } else { max = maximum; partialMessage = "Method"; } int size = tree.parameters().size(); if (size > max) { context.addIssue( tree, this, partialMessage + " has " + size + " parameters, which is greater than " + max + " authorized."); } super.visitMethod(tree); }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; scan(context.getTree()); shifts.clear(); byteContainments.clear(); }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; reportedLines.clear(); excludePackages = exclude.split(","); scan(context.getTree()); }
@Override public void visitUnaryExpression(UnaryExpressionTree tree) { super.visitUnaryExpression(tree); if (isIncrementOrDecrement(tree)) { context.addIssue( tree, this, "Extract this increment or decrement operator into a dedicated statement."); } }
@Override public void scanFile(JavaFileScannerContext context) { Multimap<Tree, String> issues = ((DefaultJavaFileScannerContext) context).getSEIssues(UnclosedResourcesCheck.class); for (Map.Entry<Tree, String> issue : issues.entries()) { context.reportIssue(this, issue.getKey(), issue.getValue()); } }
private void checkShiftWithoutByteSecuring(ExpressionTree shiftExpr, ExpressionTree byteExpr) { if (shifts.contains(shiftExpr) && !byteContainments.contains(byteExpr) && byteExpr.symbolType().isPrimitive(Primitives.BYTE)) { context.reportIssue( this, byteExpr, "Prevent \"int\" promotion by adding \"& 0xff\" to this expression."); } }
private void checkIdentifier(IdentifierTree identifierTree) { if (loopCounters.contains(identifierTree.name())) { context.addIssue( identifierTree, ruleKey, "Refactor the code in order to not assign to this loop counter from within the loop body."); } }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; if (pattern == null) { pattern = Pattern.compile(format, Pattern.DOTALL); } this.context = context; scan(context.getTree()); }
@Override public void visitLiteral(LiteralTree tree) { if (tree.value().length() > 3) { String temp = tree.value().substring(1, tree.value().length() - 1); if (pattern.matcher(temp).matches()) { context.addIssue(tree, this, String.format("Avoid using non-secure urls %s", temp)); } } super.visitLiteral(tree); }
private void checkStatements(List<StatementTree> statements) { for (StatementTree statement : statements) { if (statement.is(Tree.Kind.BLOCK)) { context.reportIssue( this, ((BlockTree) statement).openBraceToken(), "Extract this nested code block into a method."); } } }
@Override public void visitCatch(CatchTree tree) { if (!isExcludedType(tree.parameter().type())) { Symbol exception = tree.parameter().symbol(); validUsagesStack.addFirst(exception.usages()); super.visitCatch(tree); Collection<IdentifierTree> usages = validUsagesStack.pop(); if (usages.isEmpty()) { context.reportIssue(this, tree.parameter(), "Either log or rethrow this exception."); } } }
@Override public void scanFile(JavaFileScannerContext context) { sonarFile = fs.inputFile(fs.predicates().is(context.getFile())); classTrees.clear(); methods = 0; complexityInMethods = 0; accessors = 0; classes = 0; PublicApiChecker publicApiChecker = PublicApiChecker.newInstanceWithAccessorsHandledAsMethods(); if (separateAccessorsFromMethods) { publicApiChecker = PublicApiChecker.newInstanceWithAccessorsSeparatedFromMethods(); } publicApiChecker.scan(context.getTree()); methodComplexityDistribution = new RangeDistributionBuilder( CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION, LIMITS_COMPLEXITY_METHODS); CommentLinesVisitor commentLinesVisitor = new CommentLinesVisitor(); commentLinesVisitor.analyzeCommentLines(context.getTree()); noSonarFilter.addComponent( sensorContext.getResource(sonarFile).getEffectiveKey(), commentLinesVisitor.noSonarLines()); super.scanFile(context); // leave file. int fileComplexity = context.getComplexityNodes(context.getTree()).size(); saveMetricOnFile(CoreMetrics.CLASSES, classes); saveMetricOnFile(CoreMetrics.FUNCTIONS, methods); saveMetricOnFile(CoreMetrics.ACCESSORS, accessors); saveMetricOnFile(CoreMetrics.COMPLEXITY_IN_FUNCTIONS, complexityInMethods); saveMetricOnFile(CoreMetrics.COMPLEXITY_IN_CLASSES, fileComplexity); saveMetricOnFile(CoreMetrics.COMPLEXITY, fileComplexity); saveMetricOnFile(CoreMetrics.PUBLIC_API, publicApiChecker.getPublicApi()); saveMetricOnFile( CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, publicApiChecker.getDocumentedPublicApiDensity()); saveMetricOnFile( CoreMetrics.PUBLIC_UNDOCUMENTED_API, publicApiChecker.getUndocumentedPublicApi()); saveMetricOnFile(CoreMetrics.COMMENT_LINES, commentLinesVisitor.commentLinesMetric()); saveMetricOnFile( CoreMetrics.STATEMENTS, new StatementVisitor().numberOfStatements(context.getTree())); saveMetricOnFile(CoreMetrics.NCLOC, new LinesOfCodeVisitor().linesOfCode(context.getTree())); sensorContext.saveMeasure( sonarFile, methodComplexityDistribution.build(true).setPersistenceMode(PersistenceMode.MEMORY)); RangeDistributionBuilder fileComplexityDistribution = new RangeDistributionBuilder( CoreMetrics.FILE_COMPLEXITY_DISTRIBUTION, LIMITS_COMPLEXITY_FILES); sensorContext.saveMeasure( sonarFile, fileComplexityDistribution .add(fileComplexity) .build(true) .setPersistenceMode(PersistenceMode.MEMORY)); saveLinesMetric(); }
@Override public void visitMemberSelectExpression(MemberSelectExpressionTree tree) { String reference = ExpressionsHelper.concatenate(tree); if (!isExcluded(reference)) { int line = FirstSyntaxTokenFinder.firstSyntaxToken(tree).line(); if (!reportedLines.contains(line) && isSunClass(reference)) { context.addIssue( line, this, "Replace this usage of Sun classes by ones from the Java API."); reportedLines.add(line); } super.visitMemberSelectExpression(tree); } }
@Override public void visitVariable(VariableTree tree) { // System.out.println("HAB: Bool? " + tree.type().symbolType() + // tree.type().symbolType().is("java.lang.Boolean") ); if ((tree.type().symbolType().is("boolean") || tree.type().symbolType().is("java.lang.Boolean")) && !pattern.matcher(tree.simpleName().name()).matches()) { context.addIssue( tree, this, "El nombre de las variables boleana debe iniciar con is seguido de Upper Pascal Case"); } super.visitVariable(tree); }
@Override public void visitMethodInvocation(MethodInvocationTree mit) { super.visitMethodInvocation(mit); if (FILE_DELETE.matches(mit)) { checkAndAdvanceState(mit, State.CREATE_TMP_FILE, State.DELETE); } else if (FILE_MKDIR.matches(mit) && State.MKDIR.equals(checkAndAdvanceState(mit, State.DELETE, State.MKDIR))) { context.addIssue( mit, this, "Use \"Files.createTempDirectory\" or a library function to create this directory instead."); } }
@Override public void visitSwitchStatement(SwitchStatementTree tree) { int count = 0; for (CaseGroupTree caseGroup : tree.cases()) { count += caseGroup.labels().size(); } if (count < 3) { context.addIssue( tree, ruleKey, "Replace this \"switch\" statement by \"if\" statements to increase readability."); } super.visitSwitchStatement(tree); }
@Override public void visitBinaryExpression(BinaryExpressionTree tree) { super.visitBinaryExpression(tree); if (tree.is(Tree.Kind.EQUAL_TO)) { Type leftOperandType = ((JavaTree.AbstractExpressionTree) tree.leftOperand()).getType(); Type rightOperandType = ((JavaTree.AbstractExpressionTree) tree.rightOperand()).getType(); if (leftOperandType == null || rightOperandType == null) { // FIXME null type should not happen. return; } if (!isNullComparison(leftOperandType, rightOperandType) && (isClass(leftOperandType) || isClass(rightOperandType))) { context.addIssue(tree, ruleKey, "Change this comparison to use the equals method."); } } }
@Override public void visitClass(ClassTree tree) { if (tree.is(Tree.Kind.CLASS) || tree.is(Tree.Kind.ENUM)) { for (Tree member : tree.members()) { if (member.is(Tree.Kind.VARIABLE) && isPublicStaticNotFinal((VariableTree) member)) { context.addIssue( member, this, "Make this \"public static " + ((VariableTree) member).simpleName() + "\" field final"); } } } super.visitClass(tree); }
@Override public void visitNewClass(NewClassTree tree) { if (TARGETED_CLASS.contains(getclassName(tree)) && tree.arguments().size() == 1) { ExpressionTree argument = tree.arguments().get(0); if (argument.is(Tree.Kind.CHAR_LITERAL)) { String character = ((LiteralTree) argument).value(); context.reportIssue( this, argument, "Replace the constructor character parameter " + character + " with string parameter " + character.replace("'", "\"") + "."); } } }
@Override public void visitClass(ClassTree tree) { Symbol.TypeSymbol symbol = tree.symbol(); if (!tree.is(Tree.Kind.CLASS)) { return; } outerClasses.push(symbol); atLeastOneReference.push(Boolean.FALSE); scan(tree.members()); Boolean oneReference = atLeastOneReference.pop(); outerClasses.pop(); if (!symbol.isStatic() && !oneReference && !outerClasses.isEmpty() && isFirstParentStatic(outerClasses)) { String named = symbol.name().isEmpty() ? "named " : ""; context.addIssue(tree, this, "Make this a " + named + "\"static\" inner class."); } }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; loopCounters.clear(); scan(context.getTree()); }
@Override public void scanFile(JavaFileScannerContext context) { this.context = context; scan(context.getTree()); }
private void createIssue(Tree reportingTree, String wrapperName) { context.reportIssue(this, reportingTree, "Use \"" + wrapperName + ".toString\" instead."); }
@Override public void scanFile(JavaFileScannerContext context) { if (context.getTree().packageDeclaration() == null) { context.addIssueOnFile(this, "Move this file to a named package."); } }