114114import spoon .reflect .visitor .CtAbstractVisitor ;
115115
116116import java .lang .annotation .Annotation ;
117+ import java .util .ArrayList ;
117118import java .util .HashMap ;
118119import java .util .List ;
119120import java .util .Stack ;
@@ -390,7 +391,12 @@ public <T> void visitCtBinaryOperator(CtBinaryOperator<T> operator) {
390391
391392 }
392393
393- private <R > void travelStatementList (List <CtStatement > statements ) {
394+ /**
395+ * Add a list of statements as a block to the current CFG.
396+ * @param statements The list of statements
397+ * @return The start node of the block
398+ */
399+ private ControlFlowNode travelStatementList (List <CtStatement > statements ) {
394400 ControlFlowNode begin = new ControlFlowNode (null , result , BranchKind .BLOCK_BEGIN );
395401 tryAddEdge (lastNode , begin );
396402 lastNode = begin ;
@@ -402,6 +408,7 @@ private <R> void travelStatementList(List<CtStatement> statements) {
402408 ControlFlowNode end = new ControlFlowNode (null , result , BranchKind .BLOCK_END );
403409 tryAddEdge (lastNode , end );
404410 lastNode = end ;
411+ return begin ;
405412 }
406413
407414 @ Override
@@ -774,14 +781,34 @@ public <S> void visitCtSwitch(CtSwitch<S> switchStatement) {
774781
775782 //Visit Case
776783 registerStatementLabel (caseStatement );
777- ControlFlowNode cn = new ControlFlowNode (caseStatement .getCaseExpression (), result , BranchKind .STATEMENT );
778- hasDefaultCase |= caseStatement .getCaseExpressions ().isEmpty ();
779- tryAddEdge (lastNode , cn );
780- if (lastNode != switchNode ) {
781- tryAddEdge (switchNode , cn );
784+ var caseExpressions = caseStatement .getCaseExpressions ();
785+ ArrayList <ControlFlowNode > caseExpressionNodes = new ArrayList <>();
786+ for (CtExpression <?> expression : caseExpressions ) {
787+ ControlFlowNode caseNode = new ControlFlowNode (expression , result , BranchKind .STATEMENT );
788+ caseExpressionNodes .add (caseNode );
789+ tryAddEdge (switchNode , caseNode );
790+ }
791+
792+ if (caseExpressionNodes .isEmpty ()) {
793+ hasDefaultCase = true ;
794+ ControlFlowNode defaultNode = new ControlFlowNode (null , result , BranchKind .STATEMENT );
795+ caseExpressionNodes .add (defaultNode );
796+ tryAddEdge (switchNode , defaultNode );
797+ }
798+
799+ ControlFlowNode fallThroughEnd = null ;
800+ if (lastNode != switchNode ) {
801+ fallThroughEnd = lastNode ;
782802 }
783- lastNode = cn ;
784- travelStatementList (caseStatement .getStatements ());
803+ lastNode = null ;
804+
805+ ControlFlowNode blockStart = travelStatementList (caseStatement .getStatements ());
806+ tryAddEdge (fallThroughEnd , blockStart );
807+
808+ for (ControlFlowNode expressionNode : caseExpressionNodes ) {
809+ tryAddEdge (expressionNode , blockStart );
810+ }
811+
785812 if (lastNode .getStatement () instanceof CtBreak ) {
786813 lastNode = switchNode ;
787814 }
0 commit comments