@VisibleForTesting protected ExplodedGraphWalker(List<SECheck> seChecks, BehaviorCache behaviorCache, SemanticModel semanticModel) { this.alwaysTrueOrFalseExpressionCollector = new AlwaysTrueOrFalseExpressionCollector(); this.checkerDispatcher = new CheckerDispatcher(this, seChecks); this.behaviorCache = behaviorCache; this.semanticModel = semanticModel; }
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 checkEndOfExecution(CheckerContext context) { AlwaysTrueOrFalseExpressionCollector atof = context.alwaysTrueOrFalseExpressions(); for (Tree condition : atof.alwaysFalse()) { reportBooleanExpression(context, atof, condition, false); } for (Tree condition : atof.alwaysTrue()) { reportBooleanExpression(context, atof, condition, true); } }
public Set<Flow> flowForExpression(Tree expression) { Collection<ExplodedGraph.Node> nodes = getNodes(expression); return collectFlow(nodes); }
alwaysTrueOrFalseExpressionCollector.evaluatedToFalse(cleanupCondition((ExpressionTree) condition), node); alwaysTrueOrFalseExpressionCollector.evaluatedToTrue(cleanupCondition((ExpressionTree) condition), node);
public static boolean hasUnreachableCode(Tree booleanExpr, boolean isTrue) { Tree parent = biggestTreeWithSameEvaluation(booleanExpr, isTrue); if (parent.is(Tree.Kind.IF_STATEMENT)) { IfStatementTree ifStatementTree = (IfStatementTree) parent; return !isTrue || ifStatementTree.elseStatement() != null; } // Tree.Kind.DO_STATEMENT not considered, because it is always executed at least once if (parent.is(Tree.Kind.WHILE_STATEMENT) && !isTrue) { return true; } return parent.is(Tree.Kind.CONDITIONAL_EXPRESSION); }
@Override public void checkEndOfExecution(CheckerContext context) { context.alwaysTrueOrFalseExpressions().alwaysTrue().forEach(tree -> { Tree statementParent = firstStatementParent(tree); if (statementParent != null && statementParent.is(Tree.Kind.WHILE_STATEMENT)) { checkLoopWithAlwaysTrueCondition(context, statementParent); } }); contexts.pop(); }
public Set<Flow> flowForExpression(Tree expression) { Collection<ExplodedGraph.Node> nodes = getNodes(expression); return collectFlow(nodes); }
alwaysTrueOrFalseExpressionCollector.evaluatedToFalse(cleanupCondition((ExpressionTree) condition), node); alwaysTrueOrFalseExpressionCollector.evaluatedToTrue(cleanupCondition((ExpressionTree) condition), node);
public static boolean hasUnreachableCode(Tree booleanExpr, boolean isTrue) { Tree parent = biggestTreeWithSameEvaluation(booleanExpr, isTrue); if (parent.is(Tree.Kind.IF_STATEMENT)) { IfStatementTree ifStatementTree = (IfStatementTree) parent; return !isTrue || ifStatementTree.elseStatement() != null; } // Tree.Kind.DO_STATEMENT not considered, because it is always executed at least once if (parent.is(Tree.Kind.WHILE_STATEMENT) && !isTrue) { return true; } return parent.is(Tree.Kind.CONDITIONAL_EXPRESSION); }
@Override public void checkEndOfExecution(CheckerContext context) { context.alwaysTrueOrFalseExpressions().alwaysTrue().forEach(tree -> { Tree statementParent = firstStatementParent(tree); if (statementParent != null && statementParent.is(Tree.Kind.WHILE_STATEMENT)) { checkLoopWithAlwaysTrueCondition(context, statementParent); } }); contexts.pop(); }
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); } }
@Override public void checkEndOfExecution(CheckerContext context) { AlwaysTrueOrFalseExpressionCollector atof = context.alwaysTrueOrFalseExpressions(); for (Tree condition : atof.alwaysFalse()) { reportBooleanExpression(context, atof, condition, false); } for (Tree condition : atof.alwaysTrue()) { reportBooleanExpression(context, atof, condition, true); } }
@VisibleForTesting protected ExplodedGraphWalker(List<SECheck> seChecks, BehaviorCache behaviorCache, SemanticModel semanticModel) { this.alwaysTrueOrFalseExpressionCollector = new AlwaysTrueOrFalseExpressionCollector(); this.checkerDispatcher = new CheckerDispatcher(this, seChecks); this.behaviorCache = behaviorCache; this.semanticModel = semanticModel; }
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 checkEndOfExecution(CheckerContext context) { AlwaysTrueOrFalseExpressionCollector atof = context.alwaysTrueOrFalseExpressions(); for (Tree condition : atof.alwaysFalse()) { reportBooleanExpression(context, atof, condition, false); } for (Tree condition : atof.alwaysTrue()) { reportBooleanExpression(context, atof, condition, true); } }
@VisibleForTesting public ExplodedGraphWalker(BehaviorCache behaviorCache, SemanticModel semanticModel) { List<SECheck> checks = Lists.newArrayList(new NullDereferenceCheck(), new DivisionByZeroCheck(), new UnclosedResourcesCheck(), new LocksNotUnlockedCheck(), new NonNullSetToNullCheck(), new NoWayOutLoopCheck()); this.alwaysTrueOrFalseExpressionCollector = new AlwaysTrueOrFalseExpressionCollector(); this.checkerDispatcher = new CheckerDispatcher(this, checks); this.behaviorCache = behaviorCache; this.semanticModel = semanticModel; }
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); } }
@Override public void checkEndOfExecution(CheckerContext context) { AlwaysTrueOrFalseExpressionCollector atof = context.alwaysTrueOrFalseExpressions(); for (Tree condition : atof.alwaysFalse()) { reportBooleanExpression(context, atof, condition, false); } for (Tree condition : atof.alwaysTrue()) { reportBooleanExpression(context, atof, condition, true); } }
@VisibleForTesting public ExplodedGraphWalker(BehaviorCache behaviorCache, SemanticModel semanticModel) { List<SECheck> checks = Lists.newArrayList(new NullDereferenceCheck(), new DivisionByZeroCheck(), new UnclosedResourcesCheck(), new LocksNotUnlockedCheck(), new NonNullSetToNullCheck(), new NoWayOutLoopCheck()); this.alwaysTrueOrFalseExpressionCollector = new AlwaysTrueOrFalseExpressionCollector(); this.checkerDispatcher = new CheckerDispatcher(this, checks); this.behaviorCache = behaviorCache; this.semanticModel = semanticModel; }