Skip to content

Commit a0da47f

Browse files
committed
Added missing places for visitParameterList
1 parent ba4f52c commit a0da47f

File tree

8 files changed

+192
-190
lines changed

8 files changed

+192
-190
lines changed

src/compiler/transformer.ts

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/compiler/transformers/es2015.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ namespace ts {
166166
export function transformES2015(context: TransformationContext) {
167167
const {
168168
startLexicalEnvironment,
169+
resumeLexicalEnvironment,
169170
endLexicalEnvironment,
170171
hoistVariableDeclaration,
171172
} = context;
@@ -822,17 +823,14 @@ namespace ts {
822823
* @param hasSynthesizedSuper A value indicating whether the constructor starts with a
823824
* synthesized `super` call.
824825
*/
825-
function transformConstructorParameters(constructor: ConstructorDeclaration, hasSynthesizedSuper: boolean): ParameterDeclaration[] {
826+
function transformConstructorParameters(constructor: ConstructorDeclaration, hasSynthesizedSuper: boolean) {
826827
// If the TypeScript transformer needed to synthesize a constructor for property
827828
// initializers, it would have also added a synthetic `...args` parameter and
828829
// `super` call.
829830
// If this is the case, we do not include the synthetic `...args` parameter and
830831
// will instead use the `arguments` object in ES5/3.
831-
if (constructor && !hasSynthesizedSuper) {
832-
return visitNodes(constructor.parameters, visitor, isParameter);
833-
}
834-
835-
return [];
832+
return visitParameterList(constructor && !hasSynthesizedSuper && constructor.parameters, visitor, context)
833+
|| <ParameterDeclaration[]>[];
836834
}
837835

838836
/**
@@ -846,7 +844,7 @@ namespace ts {
846844
*/
847845
function transformConstructorBody(constructor: ConstructorDeclaration | undefined, node: ClassDeclaration | ClassExpression, extendsClauseElement: ExpressionWithTypeArguments, hasSynthesizedSuper: boolean) {
848846
const statements: Statement[] = [];
849-
startLexicalEnvironment();
847+
resumeLexicalEnvironment();
850848

851849
let statementOffset = -1;
852850
if (hasSynthesizedSuper) {
@@ -1504,8 +1502,17 @@ namespace ts {
15041502
if (node.transformFlags & TransformFlags.ContainsLexicalThis) {
15051503
enableSubstitutionsForCapturedThis();
15061504
}
1507-
1508-
const func = transformFunctionLikeToExpression(node, /*location*/ node, /*name*/ undefined);
1505+
const func = createFunctionExpression(
1506+
/*modifiers*/ undefined,
1507+
/*asteriskToken*/ undefined,
1508+
/*name*/ undefined,
1509+
/*typeParameters*/ undefined,
1510+
visitParameterList(node.parameters, visitor, context),
1511+
/*type*/ undefined,
1512+
transformFunctionBody(node),
1513+
node
1514+
);
1515+
setOriginalNode(func, node);
15091516
setEmitFlags(func, EmitFlags.CapturesThis);
15101517
return func;
15111518
}
@@ -1516,7 +1523,17 @@ namespace ts {
15161523
* @param node a FunctionExpression node.
15171524
*/
15181525
function visitFunctionExpression(node: FunctionExpression): Expression {
1519-
return transformFunctionLikeToExpression(node, /*location*/ node, node.name);
1526+
return updateFunctionExpression(
1527+
node,
1528+
/*modifiers*/ undefined,
1529+
node.name,
1530+
/*typeParameters*/ undefined,
1531+
visitParameterList(node.parameters, visitor, context),
1532+
/*type*/ undefined,
1533+
node.transformFlags & TransformFlags.ES2015
1534+
? transformFunctionBody(node)
1535+
: visitFunctionBody(node.body, visitor, context)
1536+
);
15201537
}
15211538

15221539
/**
@@ -1525,19 +1542,18 @@ namespace ts {
15251542
* @param node a FunctionDeclaration node.
15261543
*/
15271544
function visitFunctionDeclaration(node: FunctionDeclaration): FunctionDeclaration {
1528-
return setOriginalNode(
1529-
createFunctionDeclaration(
1530-
/*decorators*/ undefined,
1531-
node.modifiers,
1532-
node.asteriskToken,
1533-
node.name,
1534-
/*typeParameters*/ undefined,
1535-
visitNodes(node.parameters, visitor, isParameter),
1536-
/*type*/ undefined,
1537-
transformFunctionBody(node),
1538-
/*location*/ node
1539-
),
1540-
/*original*/ node);
1545+
return updateFunctionDeclaration(
1546+
node,
1547+
/*decorators*/ undefined,
1548+
node.modifiers,
1549+
node.name,
1550+
/*typeParameters*/ undefined,
1551+
visitParameterList(node.parameters, visitor, context),
1552+
/*type*/ undefined,
1553+
node.transformFlags & TransformFlags.ES2015
1554+
? transformFunctionBody(node)
1555+
: visitFunctionBody(node.body, visitor, context)
1556+
);
15411557
}
15421558

15431559
/**
@@ -1559,7 +1575,7 @@ namespace ts {
15591575
node.asteriskToken,
15601576
name,
15611577
/*typeParameters*/ undefined,
1562-
visitNodes(node.parameters, visitor, isParameter),
1578+
visitParameterList(node.parameters, visitor, context),
15631579
/*type*/ undefined,
15641580
saveStateAndInvoke(node, transformFunctionBody),
15651581
location
@@ -1586,7 +1602,7 @@ namespace ts {
15861602
const body = node.body;
15871603
let statementOffset: number;
15881604

1589-
context.startLexicalEnvironment();
1605+
resumeLexicalEnvironment();
15901606
if (isBlock(body)) {
15911607
// ensureUseStrict is false because no new prologue-directive should be added.
15921608
// addPrologueDirectives will simply put already-existing directives at the beginning of the target statement-array

src/compiler/transformers/es2017.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace ts {
1414

1515
const {
1616
startLexicalEnvironment,
17+
resumeLexicalEnvironment,
1718
endLexicalEnvironment,
1819
} = context;
1920

@@ -51,18 +52,14 @@ namespace ts {
5152
}
5253

5354
currentSourceFileExternalHelpersModuleName = node.externalHelpersModuleName;
54-
5555
return visitEachChild(node, visitor, context);
5656
}
5757

5858
function visitor(node: Node): VisitResult<Node> {
59-
if (node.transformFlags & TransformFlags.ContainsES2017) {
60-
return visitorWorker(node);
59+
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
60+
return node;
6161
}
62-
return node;
63-
}
6462

65-
function visitorWorker(node: Node): VisitResult<Node> {
6663
switch (node.kind) {
6764
case SyntaxKind.AsyncKeyword:
6865
// ES2017 async modifier should be elided for targets < ES2017
@@ -149,7 +146,7 @@ namespace ts {
149146
visitNodes(node.modifiers, visitor, isModifier),
150147
node.name,
151148
/*typeParameters*/ undefined,
152-
visitNodes(node.parameters, visitor, isParameter),
149+
visitParameterList(node.parameters, visitor, context),
153150
/*type*/ undefined,
154151
isAsyncFunctionLike(node)
155152
? transformAsyncFunctionBody(node)
@@ -174,7 +171,7 @@ namespace ts {
174171
/*modifiers*/ undefined,
175172
node.name,
176173
/*typeParameters*/ undefined,
177-
visitNodes(node.parameters, visitor, isParameter),
174+
visitParameterList(node.parameters, visitor, context),
178175
/*type*/ undefined,
179176
isAsyncFunctionLike(node)
180177
? transformAsyncFunctionBody(node)
@@ -192,7 +189,7 @@ namespace ts {
192189
node,
193190
visitNodes(node.modifiers, visitor, isModifier),
194191
/*typeParameters*/ undefined,
195-
visitNodes(node.parameters, visitor, isParameter),
192+
visitParameterList(node.parameters, visitor, context),
196193
/*type*/ undefined,
197194
isAsyncFunctionLike(node)
198195
? transformAsyncFunctionBody(node)
@@ -203,6 +200,8 @@ namespace ts {
203200
function transformAsyncFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody;
204201
function transformAsyncFunctionBody(node: ArrowFunction): ConciseBody;
205202
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
203+
resumeLexicalEnvironment();
204+
206205
const original = getOriginalNode(node, isFunctionLike);
207206
const nodeType = original.type;
208207
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;

src/compiler/transformers/esnext.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
namespace ts {
66
export function transformESNext(context: TransformationContext) {
77
const {
8+
resumeLexicalEnvironment,
89
endLexicalEnvironment
910
} = context;
1011
return transformSourceFile;
1112

1213
function transformSourceFile(node: SourceFile) {
14+
if (isDeclarationFile(node)) {
15+
return node;
16+
}
17+
1318
return visitEachChild(node, visitor, context);
1419
}
1520

@@ -343,6 +348,7 @@ namespace ts {
343348
function transformFunctionBody(node: FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | AccessorDeclaration): FunctionBody;
344349
function transformFunctionBody(node: ArrowFunction): ConciseBody;
345350
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
351+
resumeLexicalEnvironment();
346352
let leadingStatements: Statement[];
347353
for (const parameter of node.parameters) {
348354
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {

0 commit comments

Comments
 (0)