CheckerDispatcher implements CheckerContext { public void executeCheckPostStatement(Tree syntaxNode) { this.syntaxNode = syntaxNode; addTransition(explodedGraphWalker.programState); } CheckerDispatcher(ExplodedGraphWalker explodedGraphWalker, List<SECheck> checks); boolean executeCheckPreStatement(Tree syntaxNode); void executeCheckPostStatement(Tree syntaxNode); @Override ProgramState getState(); @Override ExplodedGraph.Node getNode(); @Override void reportIssue(Tree tree, SECheck check, String message); @Override void reportIssue(Tree tree, SECheck check, String message, Set<Flow> flows); @Override void addTransition(ProgramState state); @Override void addExceptionalYield(SymbolicValue target, ProgramState exceptionalState, String exceptionFullyQualifiedName, SECheck check); @Override Object createSink(); void executeCheckEndOfExecution(); void executeCheckEndOfExecutionPath(ConstraintManager constraintManager); void init(MethodTree methodTree, CFG cfg); @Override ConstraintManager getConstraintManager(); void interruptedExecution(Exception interruptionCause); @CheckForNull Exception interruptionCause(); @Override AlwaysTrueOrFalseExpressionCollector alwaysTrueOrFalseExpressions(); @CheckForNull MethodBehavior methodBehavior(); @CheckForNull MethodBehavior peekMethodBehavior(Symbol.MethodSymbol symbol);  }
@Test void test_only_one_execution_of_post_statement_by_check() { List<SECheck> checks = Lists.newArrayList(new NullDereferenceCheck(), new CheckTest(), new CheckTest(), new CheckTest()); CheckerDispatcher checkerDispatcher = new CheckerDispatcher(mockExplodedGraphWalker(), checks); checkerDispatcher.executeCheckPostStatement(mock(Tree.class)); for (SECheck check : checks) { if(check instanceof CheckTest) { assertThat(((CheckTest) check).postStatementExecution).isEqualTo(1); } } }