@@ -288,6 +288,7 @@ interface BreakContinueItem {
288288 identifier : Identifier ;
289289 name ?: string ;
290290 path : NodePath < Statement > ;
291+ isAsync : boolean ;
291292}
292293
293294interface ForToIdentifier {
@@ -2800,6 +2801,7 @@ export default function ({
28002801 exitIdentifier ?: Identifier ;
28012802 breakIdentifiers : BreakContinueItem [ ] ;
28022803 usedIdentifiers : BreakContinueItem [ ] ;
2804+ switchCount : number ;
28032805 } > = {
28042806 Function : skipNode ,
28052807 ReturnStatement ( path ) {
@@ -2846,32 +2848,62 @@ export default function ({
28462848 }
28472849 }
28482850 } ,
2851+ SwitchStatement : {
2852+ enter ( ) {
2853+ this . switchCount ++ ;
2854+ } ,
2855+ exit ( ) {
2856+ this . switchCount -- ;
2857+ } ,
2858+ } ,
2859+ Loop : {
2860+ enter ( path ) {
2861+ const parent = path . parentPath ;
2862+ this . breakIdentifiers . unshift ( {
2863+ identifier : types . identifier ( "break" ) ,
2864+ path,
2865+ name : parent . isLabeledStatement ( ) ? parent . node . label . name : undefined ,
2866+ isAsync : false ,
2867+ } ) ;
2868+ } ,
2869+ exit ( ) {
2870+ this . breakIdentifiers . shift ( ) ;
2871+ } ,
2872+ } ,
28492873 BreakStatement ( path ) {
2850- const replace = returnStatement ( undefined , path . node ) ;
28512874 const label = path . node . label ;
2852- const index = label
2853- ? this . breakIdentifiers . findIndex ( ( breakIdentifier ) => breakIdentifier . name === label . name )
2854- : 0 ;
2855- if ( index !== - 1 && this . breakIdentifiers . length ) {
2856- const used = this . breakIdentifiers . slice ( 0 , index + 1 ) ;
2857- if ( used . length ) {
2858- pushMissing ( this . usedIdentifiers , used ) ;
2859- path . replaceWithMultiple ( [
2860- types . expressionStatement ( setBreakIdentifiers ( used , this . pluginState ) ) ,
2861- replace ,
2862- ] ) ;
2863- return ;
2875+ if ( label || this . switchCount === 0 ) {
2876+ const index = label
2877+ ? this . breakIdentifiers . findIndex ( ( breakIdentifier ) => breakIdentifier . name === label . name )
2878+ : 0 ;
2879+ const replace = returnStatement ( undefined , path . node ) ;
2880+ if ( index !== - 1 && this . breakIdentifiers . length ) {
2881+ if ( ! this . breakIdentifiers [ index ] . isAsync ) {
2882+ return ;
2883+ }
2884+ const used = this . breakIdentifiers . slice ( 0 , index + 1 ) ;
2885+ if ( used . length ) {
2886+ pushMissing ( this . usedIdentifiers , used ) ;
2887+ path . replaceWithMultiple ( [
2888+ types . expressionStatement ( setBreakIdentifiers ( used , this . pluginState ) ) ,
2889+ replace ,
2890+ ] ) ;
2891+ return ;
2892+ }
28642893 }
2894+ path . replaceWith ( replace ) ;
28652895 }
2866- path . replaceWith ( replace ) ;
28672896 } ,
28682897 ContinueStatement ( path ) {
2869- const replace = returnStatement ( undefined , path . node ) ;
28702898 const label = path . node . label ;
28712899 const index = label
28722900 ? this . breakIdentifiers . findIndex ( ( breakIdentifier ) => breakIdentifier . name === label . name )
28732901 : 0 ;
2902+ const replace = returnStatement ( undefined , path . node ) ;
28742903 if ( index !== - 1 && this . breakIdentifiers . length ) {
2904+ if ( ! this . breakIdentifiers [ index ] . isAsync ) {
2905+ return ;
2906+ }
28752907 const used = this . breakIdentifiers . slice ( 0 , index ) ;
28762908 if ( used . length ) {
28772909 pushMissing ( this . usedIdentifiers , used ) ;
@@ -2912,6 +2944,7 @@ export default function ({
29122944 exitIdentifier,
29132945 breakIdentifiers : breakContinueStackForPath ( path ) ,
29142946 usedIdentifiers,
2947+ switchCount : 0 ,
29152948 } ;
29162949 path . traverse ( replaceReturnsAndBreaksVisitor , state ) ;
29172950 // Add declarations for any new identifiers
@@ -3014,9 +3047,9 @@ export default function ({
30143047 }
30153048
30163049 // Build the break/continue stack for a path
3017- function breakContinueStackForPath ( path : NodePath ) {
3050+ function breakContinueStackForPath ( path : NodePath ) : BreakContinueItem [ ] {
30183051 let current : NodePath | null = path ;
3019- const result = [ ] ;
3052+ const result = [ ] as BreakContinueItem [ ] ;
30203053 while ( current && ! current . isFunction ( ) ) {
30213054 if ( current . isLoop ( ) || current . isSwitchStatement ( ) ) {
30223055 const breaks = pathsBreak ( current ) ;
@@ -3029,13 +3062,15 @@ export default function ({
30293062 identifier : breakIdentifierForPath ( current ) ,
30303063 name : current . parentPath . node . label . name ,
30313064 path : current . parentPath ,
3065+ isAsync : true ,
30323066 } ) ;
30333067 }
30343068 current = current . parentPath ;
30353069 } else if ( simpleReferences . length ) {
30363070 result . push ( {
30373071 identifier : breakIdentifierForPath ( current ) ,
30383072 path : current ,
3073+ isAsync : true ,
30393074 } ) ;
30403075 }
30413076 }
@@ -3046,6 +3081,7 @@ export default function ({
30463081 identifier : breakIdentifierForPath ( current . get ( "body" ) ) ,
30473082 name : current . node . label . name ,
30483083 path : current ,
3084+ isAsync : true ,
30493085 } ) ;
30503086 }
30513087 }
0 commit comments