private static void savePreciseIssue(SensorContext sensorContext, InputFile inputFile, RuleKey ruleKey, PreciseIssue issue) { NewIssue newIssue = sensorContext.newIssue(); newIssue .forRule(ruleKey) .at(newLocation(inputFile, newIssue, issue.primaryLocation())); if (issue.cost() != null) { newIssue.gap(issue.cost()); } for (IssueLocation secondary : issue.secondaryLocations()) { newIssue.addLocation(newLocation(inputFile, newIssue, secondary)); } newIssue.save(); }
private void raiseIssue(FunctionTree tree, List<Tree> complexityTrees) { int complexity = complexityTrees.size(); String message = String.format(MESSAGE, complexity, maximumFunctionComplexityThreshold); IssueLocation primaryIssueLocation = new IssueLocation(tree.firstToken(), tree.parameterClause(), message); PreciseIssue issue = addIssue(new PreciseIssue(this, primaryIssueLocation)); for (Tree complexityTree : complexityTrees) { issue.secondary(complexityTree, "+1"); } issue.cost((double) complexity - maximumFunctionComplexityThreshold); }
private void addIssue(Tree expression, List<SyntaxToken> complexityOperators) { int complexity = complexityOperators.size(); String message = String.format(MESSAGE, complexity, max); PreciseIssue issue = addIssue(expression, message); for (SyntaxToken complexityOperator : complexityOperators) { issue.secondary(complexityOperator, "+1"); } issue.cost ((double) complexity - max); }
/** * Same contract as method {@link #addIssue(Tree, String)}. */ public Optional<PreciseIssue> addUniqueIssue(Tree tree, String message, Tree... secondaryLocations) { Optional<PreciseIssue> issue = addUniqueIssue(tree, message); if (issue.isPresent()) { for (Tree location : secondaryLocations) { issue.get().secondary(location); } } return issue; }
private static int line(Issue issue) { if (issue instanceof PreciseIssue) { return ((PreciseIssue) issue).primaryLocation().startLine(); } else { return ((LineIssue) issue).line(); } }
private void checkForDuplications(ListMultimap<String, CallExpressionTree> selectors) { for (String selectorText : selectors.keySet()) { List<CallExpressionTree> references = selectors.get(selectorText); int numberOfDuplications = references.size(); if (numberOfDuplications > threshold) { String message = String.format(MESSAGE, selectorText, numberOfDuplications); PreciseIssue issue = addIssue(references.get(0), message) .cost((double) numberOfDuplications - threshold); references.subList(1, references.size()).forEach(issue::secondary); } } }
private static Collection<CheckMessage> getCheckMessages(List<Issue> issues) { List<CheckMessage> checkMessages = new ArrayList<>(); for (Issue issue : issues) { CheckMessage checkMessage; if (issue instanceof FileIssue) { FileIssue fileIssue = (FileIssue)issue; checkMessage = new CheckMessage(fileIssue.check(), fileIssue.message()); } else if (issue instanceof LineIssue) { LineIssue lineIssue = (LineIssue)issue; checkMessage = new CheckMessage(lineIssue.check(), lineIssue.message()); checkMessage.setLine(lineIssue.line()); } else { PreciseIssue preciseIssue = (PreciseIssue) issue; checkMessage = new CheckMessage(preciseIssue.check(), preciseIssue.primaryLocation().message()); checkMessage.setLine(preciseIssue.primaryLocation().startLine()); } if (issue.cost() != null) { checkMessage.setCost(issue.cost()); } checkMessages.add(checkMessage); } return checkMessages; }
private static void assertSecondary(Issue actualIssue, TestIssue expectedIssue) { List<Location> expectedLocations = expectedIssue.secondaryLocations(); List<IssueLocation> actualLocations = actualIssue instanceof PreciseIssue ? ((PreciseIssue) actualIssue).secondaryLocations() : new ArrayList<>(); String format = "Bad secondary location at line %s (issue at line %s): %s"; for (Location expected : expectedLocations) { IssueLocation actual = secondary(expected.line(), actualLocations); if (actual != null) { if (expected.message() != null) { assertThat(actual.message()).as(String.format(format, expected.line(), line(actualIssue), "bad message")).isEqualTo(expected.message()); } if (expected.startColumn() != null) { assertThat(actual.startLineOffset() + 1).as(String.format(format, expected.line(), line(actualIssue), "bad start column")).isEqualTo(expected.startColumn()); assertThat(actual.endLineOffset() + 1).as(String.format(format, expected.line(), line(actualIssue), "bad end column")).isEqualTo(expected.endColumn()); } actualLocations.remove(actual); } else { throw new AssertionError("Missing secondary location at line " + expected.line() + " for issue at line " + expectedIssue.line()); } } if (!actualLocations.isEmpty()) { IssueLocation location = actualLocations.get(0); throw new AssertionError("Unexpected secondary location at line " + location.startLine() + " for issue at line " + line(actualIssue)); } }
@Override public void leaveNode(Tree tree) { if (!tree.is(Kind.YIELD_EXPRESSION)) { boolean hasYield = hasYieldStack.removeLast(); if (!hasYield) { addIssue(new PreciseIssue(this, getPrimaryLocation(tree))); } } }
private <T1 extends Tree, T2 extends Tree> void checkExpression( T1 tree, ExpressionTree symbolTree, Map<Symbol, T2> otherTypeUsageMap, Map<Symbol, T1> thisTypeUsageMap, String tail ) { Symbol symbol = getSymbol(symbolTree); if (symbol == null || symbol.external()) { return; } T2 otherTypeUsage = otherTypeUsageMap.get(symbol); if (otherTypeUsage != null && !hasIssue.contains(symbol)) { String message = String.format(MESSAGE, otherTypeUsage.firstToken().line(), tail); String secondaryMessage = String.format(SECONDARY_MESSAGE, tail); addIssue(new PreciseIssue(this, issueLocation(tree, message))) .secondary(issueLocation(otherTypeUsage, secondaryMessage)); hasIssue.add(symbol); } else { thisTypeUsageMap.put(symbol, tree); } }
@Override protected void conditionWithDeadCode(Tree condition, boolean isTruthy, Set<Tree> deadCode) { String result = isTruthy ? "true" : "false"; PreciseIssue preciseIssue = addIssue(condition, String.format(MESSAGE, result)); deadCode.forEach(deadCodeTree -> preciseIssue.secondary(deadCodeTree, "Never reached")); }
private static String message(Issue issue) { if (issue instanceof PreciseIssue) { return ((PreciseIssue) issue).primaryLocation().message(); } else { return ((LineIssue) issue).message(); } }
private void leaveScopeAndCheckNumberOfJump(SyntaxToken loopKeyword) { List<Tree> jumps = jumpTargets.pop().jumps; int jumpStatementNumber = jumps.size(); if (jumpStatementNumber > 1) { PreciseIssue issue = addIssue(loopKeyword, MESSAGE).cost((double) jumpStatementNumber - 1); for (Tree jump : jumps) { issue.secondary(new IssueLocation(jump)); } } }
private void checkForIssues() { for (Map.Entry<String, StorageType> entry : storageTypes.entrySet()) { int cost = entry.getValue().count - 1; String message = String.format(MESSAGE, entry.getKey()); addIssue(entry.getValue().tree.object(), message).cost((double) cost); } }
private void checkCommentGroup(List<SyntaxTrivia> commentGroup) { String uncommentedText = uncomment(commentGroup); if (isRawExclusion(uncommentedText)) { return; } uncommentedText = injectMissingBraces(uncommentedText); try { ScriptTree parsedUncommentedText = (ScriptTree) PARSER.parse(uncommentedText); if (isExclusion(parsedUncommentedText)) { return; } IssueLocation primaryLocation = new IssueLocation(commentGroup.get(0), commentGroup.get(commentGroup.size() - 1), MESSAGE); addIssue(new PreciseIssue(this, primaryLocation)); } catch (RecognitionException e) { // do nothing, it's just a comment } }
@Override public void visitIfStatement(IfStatementTree tree) { if (tree.elseClause() == null) { IfStatementTree innerIfStatement = getCollapsibleIfStatement(tree.statement()); if (innerIfStatement != null) { IssueLocation primaryLocation = issueLocation(tree, MESSAGE); IssueLocation secondaryLocation = issueLocation(innerIfStatement, SECONDARY_MESSAGE); addIssue(new PreciseIssue(this, primaryLocation).secondary(secondaryLocation)); } } super.visitIfStatement(tree); }
private static void savePreciseIssue(SensorContext sensorContext, InputFile inputFile, RuleKey ruleKey, PreciseIssue issue) { NewIssue newIssue = sensorContext.newIssue(); newIssue .forRule(ruleKey) .at(newLocation(inputFile, newIssue, issue.primaryLocation())); if (issue.cost() != null) { newIssue.gap(issue.cost()); } for (IssueLocation secondary : issue.secondaryLocations()) { newIssue.addLocation(newLocation(inputFile, newIssue, secondary)); } newIssue.save(); }
/** * Same contract as method {@link #addIssue(Tree, String)}. */ public Optional<PreciseIssue> addUniqueIssue(Tree tree, String message, IssueLocation... secondaryLocations) { Optional<PreciseIssue> issue = addUniqueIssue(tree, message); if (issue.isPresent()) { for (IssueLocation location : secondaryLocations) { issue.get().secondary(location); } } return issue; }
private static void verifyIssue(TestIssue expected, Issue actual) { if (line(actual) > expected.line()) { fail("Missing issue at line " + expected.line()); } if (line(actual) < expected.line()) { fail("Unexpected issue at line " + line(actual) + ": \"" + message(actual) + "\""); } if (expected.message() != null) { assertThat(message(actual)).as("Bad message at line " + expected.line()).isEqualTo(expected.message()); } if (expected.effortToFix() != null) { assertThat(actual.cost()).as("Bad effortToFix at line " + expected.line()).isEqualTo((double) expected.effortToFix()); } if (expected.startColumn() != null) { assertThat(((PreciseIssue) actual).primaryLocation().startLineOffset() + 1).as("Bad start column at line " + expected.line()).isEqualTo(expected.startColumn()); } if (expected.endColumn() != null) { assertThat(((PreciseIssue) actual).primaryLocation().endLineOffset() + 1).as("Bad end column at line " + expected.line()).isEqualTo(expected.endColumn()); } if (expected.endLine() != null) { assertThat(((PreciseIssue) actual).primaryLocation().endLine()).as("Bad end line at line " + expected.line()).isEqualTo(expected.endLine()); } if (!expected.secondaryLocations().isEmpty()) { assertSecondary(actual, expected); } }
private void raiseIssue(CognitiveComplexity.ComplexityData complexityData, Tree function) { String message = String.format(MESSAGE, complexityData.complexity(), threshold); SyntaxToken primaryLocation = function.firstToken(); if (function.is(ARROW_FUNCTION)) { primaryLocation = ((ArrowFunctionTree) function).doubleArrowToken(); } PreciseIssue issue = addIssue(primaryLocation, message).cost(complexityData.complexity() - (double)threshold); complexityData.secondaryLocations().forEach(issue::secondary); }