@@ -154,25 +154,29 @@ namespace ts {
154154 * @param transforms An array of Transformers.
155155 */
156156 export function transformFiles ( resolver : EmitResolver , host : EmitHost , sourceFiles : SourceFile [ ] , transformers : Transformer [ ] ) : TransformationResult {
157- const lexicalEnvironmentVariableDeclarationsStack : VariableDeclaration [ ] [ ] = [ ] ;
158- const lexicalEnvironmentFunctionDeclarationsStack : FunctionDeclaration [ ] [ ] = [ ] ;
159157 const enabledSyntaxKindFeatures = new Array < SyntaxKindFeatureFlags > ( SyntaxKind . Count ) ;
160158
159+ let scopeModificationDisabled = false ;
160+
161161 let lexicalEnvironmentStackOffset = 0 ;
162- let hoistedVariableDeclarations : VariableDeclaration [ ] ;
163- let hoistedFunctionDeclarations : FunctionDeclaration [ ] ;
164- let lexicalEnvironmentDisabled : boolean ;
162+ let lexicalEnvironmentVariableDeclarations : VariableDeclaration [ ] ;
163+ let lexicalEnvironmentFunctionDeclarations : FunctionDeclaration [ ] ;
164+ let lexicalEnvironmentVariableDeclarationsStack : VariableDeclaration [ ] [ ] = [ ] ;
165+ let lexicalEnvironmentFunctionDeclarationsStack : FunctionDeclaration [ ] [ ] = [ ] ;
166+ let lexicalEnvironmentSuspended = false ;
165167
166168 // The transformation context is provided to each transformer as part of transformer
167169 // initialization.
168170 const context : TransformationContext = {
169171 getCompilerOptions : ( ) => host . getCompilerOptions ( ) ,
170172 getEmitResolver : ( ) => resolver ,
171173 getEmitHost : ( ) => host ,
172- hoistVariableDeclaration,
173- hoistFunctionDeclaration,
174174 startLexicalEnvironment,
175+ suspendLexicalEnvironment,
176+ resumeLexicalEnvironment,
175177 endLexicalEnvironment,
178+ hoistVariableDeclaration,
179+ hoistFunctionDeclaration,
176180 onSubstituteNode : ( _emitContext , node ) => node ,
177181 enableSubstitution,
178182 isSubstitutionEnabled,
@@ -188,7 +192,7 @@ namespace ts {
188192 const transformed = map ( sourceFiles , transformSourceFile ) ;
189193
190194 // Disable modification of the lexical environment.
191- lexicalEnvironmentDisabled = true ;
195+ scopeModificationDisabled = true ;
192196
193197 return {
194198 transformed,
@@ -283,26 +287,26 @@ namespace ts {
283287 * Records a hoisted variable declaration for the provided name within a lexical environment.
284288 */
285289 function hoistVariableDeclaration ( name : Identifier ) : void {
286- Debug . assert ( ! lexicalEnvironmentDisabled , "Cannot modify the lexical environment during the print phase." ) ;
290+ Debug . assert ( ! scopeModificationDisabled , "Cannot modify the lexical environment during the print phase." ) ;
287291 const decl = createVariableDeclaration ( name ) ;
288- if ( ! hoistedVariableDeclarations ) {
289- hoistedVariableDeclarations = [ decl ] ;
292+ if ( ! lexicalEnvironmentVariableDeclarations ) {
293+ lexicalEnvironmentVariableDeclarations = [ decl ] ;
290294 }
291295 else {
292- hoistedVariableDeclarations . push ( decl ) ;
296+ lexicalEnvironmentVariableDeclarations . push ( decl ) ;
293297 }
294298 }
295299
296300 /**
297301 * Records a hoisted function declaration within a lexical environment.
298302 */
299303 function hoistFunctionDeclaration ( func : FunctionDeclaration ) : void {
300- Debug . assert ( ! lexicalEnvironmentDisabled , "Cannot modify the lexical environment during the print phase." ) ;
301- if ( ! hoistedFunctionDeclarations ) {
302- hoistedFunctionDeclarations = [ func ] ;
304+ Debug . assert ( ! scopeModificationDisabled , "Cannot modify the lexical environment during the print phase." ) ;
305+ if ( ! lexicalEnvironmentFunctionDeclarations ) {
306+ lexicalEnvironmentFunctionDeclarations = [ func ] ;
303307 }
304308 else {
305- hoistedFunctionDeclarations . push ( func ) ;
309+ lexicalEnvironmentFunctionDeclarations . push ( func ) ;
306310 }
307311 }
308312
@@ -311,36 +315,52 @@ namespace ts {
311315 * are pushed onto a stack, and the related storage variables are reset.
312316 */
313317 function startLexicalEnvironment ( ) : void {
314- Debug . assert ( ! lexicalEnvironmentDisabled , "Cannot start a lexical environment during the print phase." ) ;
318+ Debug . assert ( ! scopeModificationDisabled , "Cannot start a lexical environment during the print phase." ) ;
319+ Debug . assert ( ! lexicalEnvironmentSuspended , "Lexical environment is suspended." ) ;
315320
316321 // Save the current lexical environment. Rather than resizing the array we adjust the
317322 // stack size variable. This allows us to reuse existing array slots we've
318323 // already allocated between transformations to avoid allocation and GC overhead during
319324 // transformation.
320- lexicalEnvironmentVariableDeclarationsStack [ lexicalEnvironmentStackOffset ] = hoistedVariableDeclarations ;
321- lexicalEnvironmentFunctionDeclarationsStack [ lexicalEnvironmentStackOffset ] = hoistedFunctionDeclarations ;
325+ lexicalEnvironmentVariableDeclarationsStack [ lexicalEnvironmentStackOffset ] = lexicalEnvironmentVariableDeclarations ;
326+ lexicalEnvironmentFunctionDeclarationsStack [ lexicalEnvironmentStackOffset ] = lexicalEnvironmentFunctionDeclarations ;
322327 lexicalEnvironmentStackOffset ++ ;
323- hoistedVariableDeclarations = undefined ;
324- hoistedFunctionDeclarations = undefined ;
328+ lexicalEnvironmentVariableDeclarations = undefined ;
329+ lexicalEnvironmentFunctionDeclarations = undefined ;
330+ }
331+
332+ /** Suspends the current lexical environment, usually after visiting a parameter list. */
333+ function suspendLexicalEnvironment ( ) : void {
334+ Debug . assert ( ! scopeModificationDisabled , "Cannot suspend a lexical environment during the print phase." ) ;
335+ Debug . assert ( ! lexicalEnvironmentSuspended , "Lexical environment is already suspended." ) ;
336+ lexicalEnvironmentSuspended = true ;
337+ }
338+
339+ /** Resumes a suspended lexical environment, usually before visiting a function body. */
340+ function resumeLexicalEnvironment ( ) : void {
341+ Debug . assert ( ! scopeModificationDisabled , "Cannot resume a lexical environment during the print phase." ) ;
342+ Debug . assert ( lexicalEnvironmentSuspended , "Lexical environment is not suspended suspended." ) ;
343+ lexicalEnvironmentSuspended = false ;
325344 }
326345
327346 /**
328347 * Ends a lexical environment. The previous set of hoisted declarations are restored and
329348 * any hoisted declarations added in this environment are returned.
330349 */
331350 function endLexicalEnvironment ( ) : Statement [ ] {
332- Debug . assert ( ! lexicalEnvironmentDisabled , "Cannot end a lexical environment during the print phase." ) ;
351+ Debug . assert ( ! scopeModificationDisabled , "Cannot end a lexical environment during the print phase." ) ;
352+ Debug . assert ( ! lexicalEnvironmentSuspended , "Lexical environment is suspended." ) ;
333353
334354 let statements : Statement [ ] ;
335- if ( hoistedVariableDeclarations || hoistedFunctionDeclarations ) {
336- if ( hoistedFunctionDeclarations ) {
337- statements = [ ...hoistedFunctionDeclarations ] ;
355+ if ( lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations ) {
356+ if ( lexicalEnvironmentFunctionDeclarations ) {
357+ statements = [ ...lexicalEnvironmentFunctionDeclarations ] ;
338358 }
339359
340- if ( hoistedVariableDeclarations ) {
360+ if ( lexicalEnvironmentVariableDeclarations ) {
341361 const statement = createVariableStatement (
342362 /*modifiers*/ undefined ,
343- createVariableDeclarationList ( hoistedVariableDeclarations )
363+ createVariableDeclarationList ( lexicalEnvironmentVariableDeclarations )
344364 ) ;
345365
346366 if ( ! statements ) {
@@ -354,8 +374,12 @@ namespace ts {
354374
355375 // Restore the previous lexical environment.
356376 lexicalEnvironmentStackOffset -- ;
357- hoistedVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack [ lexicalEnvironmentStackOffset ] ;
358- hoistedFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack [ lexicalEnvironmentStackOffset ] ;
377+ lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack [ lexicalEnvironmentStackOffset ] ;
378+ lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack [ lexicalEnvironmentStackOffset ] ;
379+ if ( lexicalEnvironmentStackOffset === 0 ) {
380+ lexicalEnvironmentVariableDeclarationsStack = [ ] ;
381+ lexicalEnvironmentFunctionDeclarationsStack = [ ] ;
382+ }
359383 return statements ;
360384 }
361385 }
0 commit comments