protected void reportIssue(Tree tree, String message, Object... parameters) { context.reportIssue(tree, NonNullSetToNullCheck.this, MessageFormat.format(message, parameters)); } }
@Override public void checkEndOfExecution(CheckerContext context) { for (Tree condition : Sets.difference(evaluatedToFalse, evaluatedToTrue)) { context.reportIssue(condition, this, "Change this condition so that it does not always evaluate to \"false\""); } for (Tree condition : Sets.difference(evaluatedToTrue, evaluatedToFalse)) { context.reportIssue(condition, this, "Change this condition so that it does not always evaluate to \"true\""); } }
protected void reportIssue(Tree tree, String message, Object... parameters) { context.reportIssue(tree, NonNullSetToNullCheck.this, MessageFormat.format(message, parameters)); } }
private void reportBooleanExpression(CheckerContext context, AlwaysTrueOrFalseExpressionCollector atof, Tree condition, boolean isTrue) { if (!AlwaysTrueOrFalseExpressionCollector.hasUnreachableCode(condition, isTrue)) { Set<Flow> flows = atof.flowForExpression(condition).stream() .map(flow -> AlwaysTrueOrFalseExpressionCollector.addIssueLocation(flow, condition, isTrue)) .collect(Collectors.toSet()); context.reportIssue(condition, this, "Remove this expression which always evaluates to \"" + isTrue + "\"", flows); } } }
private void reportBooleanExpression(CheckerContext context, AlwaysTrueOrFalseExpressionCollector atof, Tree condition, boolean isTrue) { if (AlwaysTrueOrFalseExpressionCollector.hasUnreachableCode(condition, isTrue)) { Set<Flow> flows = atof.flowForExpression(condition).stream() .map(flow -> AlwaysTrueOrFalseExpressionCollector.addIssueLocation(flow, condition, isTrue)) .collect(Collectors.toSet()); context.reportIssue(condition, this, String.format(MESSAGE, isTrue), flows); } }
private void reportBooleanExpression(CheckerContext context, AlwaysTrueOrFalseExpressionCollector atof, Tree condition, boolean isTrue) { if (AlwaysTrueOrFalseExpressionCollector.hasUnreachableCode(condition, isTrue)) { Set<Flow> flows = atof.flowForExpression(condition).stream() .map(flow -> AlwaysTrueOrFalseExpressionCollector.addIssueLocation(flow, condition, isTrue)) .collect(Collectors.toSet()); context.reportIssue(condition, this, String.format(MESSAGE, isTrue), flows); } }
private void checkLoopWithAlwaysTrueCondition(CheckerContext context, Tree statementParent) { CFGLoop loopBlocks = contexts.peek().getLoop(statementParent); if (loopBlocks != null && loopBlocks.hasNoWayOut()) { context.reportIssue(statementParent, NoWayOutLoopCheck.this, "Add an end condition to this loop."); } }
private void checkLoopWithAlwaysTrueCondition(CheckerContext context, Tree statementParent) { CFGLoop loopBlocks = contexts.peek().getLoop(statementParent); if (loopBlocks != null && loopBlocks.hasNoWayOut()) { context.reportIssue(statementParent, NoWayOutLoopCheck.this, "Add an end condition to this loop."); } }
private void reportBooleanExpression(CheckerContext context, AlwaysTrueOrFalseExpressionCollector atof, Tree condition, boolean isTrue) { if (!AlwaysTrueOrFalseExpressionCollector.hasUnreachableCode(condition, isTrue)) { Set<Flow> flows = atof.flowForExpression(condition).stream() .map(flow -> AlwaysTrueOrFalseExpressionCollector.addIssueLocation(flow, condition, isTrue)) .collect(Collectors.toSet()); context.reportIssue(condition, this, "Remove this expression which always evaluates to \"" + isTrue + "\"", flows); } } }
@Override public void visitForStatement(ForStatementTree tree) { if (tree.condition() == null) { checkLoopWithAlwaysTrueCondition(context, tree); } else if (isConditionUnreachable(tree)) { context.reportIssue(tree, NoWayOutLoopCheck.this, "Correct this loop's end condition."); } }
@Override public void visitForStatement(ForStatementTree tree) { if (tree.condition() == null) { checkLoopWithAlwaysTrueCondition(context, tree); } else if (isConditionUnreachable(tree)) { context.reportIssue(tree, NoWayOutLoopCheck.this, "Correct this loop's end condition."); } }
private void report(CheckerContext context, SECheck check) { context.reportIssue(getInvocation, check, issueMsg(), flows()); }
private void report(CheckerContext context, SECheck check) { context.reportIssue(getInvocation, check, issueMsg(), flows()); }
@Override public void checkEndOfExecutionPath(CheckerContext context, ConstraintManager constraintManager) { final List<ObjectConstraint> constraints = context.getState().getFieldConstraints(Status.LOCKED); for (ObjectConstraint constraint : constraints) { Tree syntaxNode = constraint.syntaxNode(); context.reportIssue(syntaxNode, this, "Unlock \"" + syntaxNode.toString() + "\" along all executions paths of this method."); } } }
private void checkVariable(CheckerContext context, MethodTree tree, final Symbol symbol) { String nonNullAnnotation = nonNullAnnotation(symbol); if (nonNullAnnotation == null || symbol.isStatic()) { return; } if (isUndefinedOrNull(context, symbol)) { context.reportIssue(tree.simpleName(), this, MessageFormat.format("\"{0}\" is marked \"{1}\" but is not initialized in this constructor.", symbol.name(), nonNullAnnotation)); } }
private void checkVariable(CheckerContext context, MethodTree tree, final Symbol symbol) { String nonNullAnnotation = nonNullAnnotation(symbol); if (nonNullAnnotation == null || symbol.isStatic()) { return; } if (isUndefinedOrNull(context, symbol)) { context.reportIssue(tree.simpleName(), this, MessageFormat.format("\"{0}\" is marked \"{1}\" but is not initialized in this constructor.", symbol.name(), nonNullAnnotation)); } }
private void reportIssue(Tree tree, SymbolicValue denominator, Symbol denominatorSymbol) { ExpressionTree expression = getDenominator(tree); String operation = tree.is(Tree.Kind.REMAINDER, Tree.Kind.REMAINDER_ASSIGNMENT) ? "modulation" : "division"; String expressionName = expression.is(Tree.Kind.IDENTIFIER) ? ("\"" + ((IdentifierTree) expression).name() + "\"") : "this expression"; List<Class<? extends Constraint>> domains = Collections.singletonList(ZeroConstraint.class); Set<Flow> flows = FlowComputation.flow(context.getNode(), denominator, domains, denominatorSymbol).stream() .filter(f -> !f.isEmpty()) .map(f -> Flow.builder() .add(new JavaFileScannerContext.Location("Division by zero.", tree)) .addAll(f) .build()) .collect(Collectors.toSet()); context.reportIssue(expression, DivisionByZeroCheck.this, "Make sure " + expressionName + " can't be zero before doing this " + operation + ".", flows); }
private void reportIssue(MethodInvocationTree mit) { String identifier = getIdentifierPart(mit.methodSelect()); String issueMsg = identifier.isEmpty() ? "Optional#" : (identifier + "."); Tree reportTree = mit.methodSelect().is(Tree.Kind.MEMBER_SELECT) ? ((MemberSelectExpressionTree) mit.methodSelect()).expression() : mit; context.reportIssue(reportTree, check, "Call \""+ issueMsg + "isPresent()\" before accessing the value."); }
private void reportIssue(MethodInvocationTree mit) { String identifier = getIdentifierPart(mit.methodSelect()); String issueMsg = identifier.isEmpty() ? "Optional#" : (identifier + "."); Tree reportTree = mit.methodSelect().is(Tree.Kind.MEMBER_SELECT) ? ((MemberSelectExpressionTree) mit.methodSelect()).expression() : mit; context.reportIssue(reportTree, check, "Call \""+ issueMsg + "isPresent()\" before accessing the value."); }
@Override public ProgramState checkPostStatement(CheckerContext context, Tree syntaxNode) { if (syntaxNode.is(Tree.Kind.SWITCH_STATEMENT) && context.getConstraintManager().isNull(context.getState(), context.getState().peekValue())) { context.reportIssue(syntaxNode, this, "NullPointerException might be thrown as '" + SyntaxTreeNameFinder.getName(syntaxNode) + "' is nullable here"); context.createSink(); return context.getState(); } List<ProgramState> programStates = setNullConstraint(context, syntaxNode); for (ProgramState programState : programStates) { context.addTransition(programState); } return context.getState(); }