@@ -12,6 +12,10 @@ import {
1212 type NodeType ,
1313} from "./cfg-defs" ;
1414
15+ interface SwitchOptions {
16+ noImplicitDefault : boolean ;
17+ }
18+
1519export class CFGBuilder {
1620 private graph : MultiDirectedGraph < GraphNode , GraphEdge > ;
1721 private entry : string ;
@@ -120,8 +124,9 @@ export class CFGBuilder {
120124 return this . processForStatement ( node ) ;
121125 case "expression_switch_statement" :
122126 case "type_switch_statement" :
123- case "select_statement" :
124127 return this . processSwitchlike ( node ) ;
128+ case "select_statement" :
129+ return this . processSwitchlike ( node , { noImplicitDefault : true } ) ;
125130 case "return_statement" : {
126131 const returnNode = this . addNode ( "RETURN" , node . text ) ;
127132 return { entry : returnNode , exit : null } ;
@@ -157,9 +162,15 @@ export class CFGBuilder {
157162 cases : Case [ ] ,
158163 mergeNode : string ,
159164 switchHeadNode : string ,
165+ options ?: SwitchOptions ,
160166 ) {
161167 let fallthrough : string | null = null ;
162168 let previous : string | null = switchHeadNode ;
169+ if ( options ?. noImplicitDefault ) {
170+ // This prevents the linking of the switch head to the merge node.
171+ // It is required for select statements, as they block until satisfied.
172+ previous = null ;
173+ }
163174 cases . forEach ( ( thisCase ) => {
164175 if ( this . flatSwitch ) {
165176 if ( thisCase . consequenceEntry ) {
@@ -251,7 +262,10 @@ export class CFGBuilder {
251262 return cases ;
252263 }
253264
254- private processSwitchlike ( switchSyntax : Parser . SyntaxNode ) : BasicBlock {
265+ private processSwitchlike (
266+ switchSyntax : Parser . SyntaxNode ,
267+ options ?: SwitchOptions ,
268+ ) : BasicBlock {
255269 const blockHandler = new BlockHandler ( ) ;
256270
257271 const cases = this . collectCases ( switchSyntax , blockHandler ) ;
@@ -260,7 +274,7 @@ export class CFGBuilder {
260274 this . getChildFieldText ( switchSyntax , "value" ) ,
261275 ) ;
262276 const mergeNode : string = this . addNode ( "SWITCH_MERGE" , "" ) ;
263- this . buildSwitch ( cases , mergeNode , headNode ) ;
277+ this . buildSwitch ( cases , mergeNode , headNode , options ) ;
264278
265279 blockHandler . forEachBreak ( ( breakNode ) => {
266280 this . addEdge ( breakNode , mergeNode ) ;
0 commit comments