Skip to content

Commit 2d0d655

Browse files
authored
Merge pull request #25561 from ajafff/multiple-prologue-directives
handle multiple prologue directives
2 parents 42a2d9e + 2a96001 commit 2d0d655

13 files changed

+34
-30
lines changed

src/compiler/transformers/es2015.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ namespace ts {
529529
createVariableStatement(/*modifiers*/ undefined,
530530
createVariableDeclarationList(taggedTemplateStringDeclarations)));
531531
}
532-
prependStatements(statements, endLexicalEnvironment());
532+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
533533
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
534534
return updateSourceFileNode(
535535
node,
@@ -837,7 +837,7 @@ namespace ts {
837837
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
838838
statements.push(statement);
839839

840-
prependStatements(statements, endLexicalEnvironment());
840+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
841841

842842
const block = createBlock(setTextRange(createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
843843
setEmitFlags(block, EmitFlags.NoComments);
@@ -980,7 +980,7 @@ namespace ts {
980980
);
981981
}
982982

983-
prependStatements(statements, endLexicalEnvironment());
983+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
984984

985985
if (constructor) {
986986
prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false);
@@ -1892,7 +1892,7 @@ namespace ts {
18921892
}
18931893

18941894
const lexicalEnvironment = context.endLexicalEnvironment();
1895-
prependStatements(statements, lexicalEnvironment);
1895+
addStatementsAfterPrologue(statements, lexicalEnvironment);
18961896
prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false);
18971897

18981898
// If we added any final generated statements, this must be a multi-line block
@@ -2707,7 +2707,7 @@ namespace ts {
27072707
if (loopOutParameters.length) {
27082708
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
27092709
}
2710-
prependStatements(statements, lexicalEnvironment);
2710+
addStatementsAfterPrologue(statements, lexicalEnvironment);
27112711
loopBody = createBlock(statements, /*multiline*/ true);
27122712
}
27132713

src/compiler/transformers/es2017.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ namespace ts {
413413
)
414414
);
415415

416-
prependStatements(statements, endLexicalEnvironment());
416+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
417417

418418
const block = createBlock(statements, /*multiLine*/ true);
419419
setTextRange(block, node.body);

src/compiler/transformers/esnext.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ namespace ts {
675675
)
676676
);
677677

678-
prependStatements(statements, endLexicalEnvironment());
678+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
679679
const block = updateBlock(node.body!, statements);
680680

681681
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
@@ -707,7 +707,7 @@ namespace ts {
707707
const leadingStatements = endLexicalEnvironment();
708708
if (statementOffset > 0 || some(statements) || some(leadingStatements)) {
709709
const block = convertToFunctionBody(body, /*multiLine*/ true);
710-
prependStatements(statements, leadingStatements);
710+
addStatementsAfterPrologue(statements, leadingStatements);
711711
addRange(statements, block.statements.slice(statementOffset));
712712
return updateBlock(block, setTextRange(createNodeArray(statements), block.statements));
713713
}

src/compiler/transformers/generators.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ namespace ts {
587587
transformAndEmitStatements(body.statements, statementOffset);
588588

589589
const buildResult = build();
590-
prependStatements(statements, endLexicalEnvironment());
590+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
591591
statements.push(createReturn(buildResult));
592592

593593
// Restore previous generator state

src/compiler/transformers/module/module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ namespace ts {
9797
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
9898
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
9999
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
100-
prependStatements(statements, endLexicalEnvironment());
100+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
101101

102102
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
103103
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
@@ -426,7 +426,7 @@ namespace ts {
426426

427427
// End the lexical environment for the module body
428428
// and merge any new lexical declarations.
429-
prependStatements(statements, endLexicalEnvironment());
429+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
430430

431431
const body = createBlock(statements, /*multiLine*/ true);
432432
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {

src/compiler/transformers/module/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ namespace ts {
257257
// We emit hoisted variables early to align roughly with our previous emit output.
258258
// Two key differences in this approach are:
259259
// - Temporary variables will appear at the top rather than at the bottom of the file
260-
prependStatements(statements, endLexicalEnvironment());
260+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
261261

262262
const exportStarFunction = addExportStarIfNeeded(statements)!; // TODO: GH#18217
263263
const moduleObject = createObjectLiteral([

src/compiler/transformers/ts.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ namespace ts {
682682
setEmitFlags(statement, EmitFlags.NoComments | EmitFlags.NoTokenSourceMaps);
683683
statements.push(statement);
684684

685-
prependStatements(statements, context.endLexicalEnvironment());
685+
addStatementsAfterPrologue(statements, context.endLexicalEnvironment());
686686

687687
const iife = createImmediatelyInvokedArrowFunction(statements);
688688
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
@@ -2711,7 +2711,7 @@ namespace ts {
27112711
const statements: Statement[] = [];
27122712
startLexicalEnvironment();
27132713
const members = map(node.members, transformEnumMember);
2714-
prependStatements(statements, endLexicalEnvironment());
2714+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
27152715
addRange(statements, members);
27162716

27172717
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
@@ -3026,7 +3026,7 @@ namespace ts {
30263026
statementsLocation = moveRangePos(moduleBlock.statements, -1);
30273027
}
30283028

3029-
prependStatements(statements, endLexicalEnvironment());
3029+
addStatementsAfterPrologue(statements, endLexicalEnvironment());
30303030
currentNamespaceContainerName = savedCurrentNamespaceContainerName;
30313031
currentNamespace = savedCurrentNamespace;
30323032
currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;

src/compiler/utilities.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -401,21 +401,18 @@ namespace ts {
401401
}
402402

403403
/**
404-
* Appends a range of value to begin of an array, returning the array.
405-
*
406-
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
407-
* is created if `value` was appended.
408-
* @param from The values to append to the array. If `from` is `undefined`, nothing is
409-
* appended. If an element of `from` is `undefined`, that element is not appended.
404+
* Prepends statements to an array while taking care of prologue directives.
410405
*/
411-
export function prependStatements<T extends Statement>(to: T[], from: ReadonlyArray<T> | undefined): T[] | undefined {
406+
export function addStatementsAfterPrologue<T extends Statement>(to: T[], from: ReadonlyArray<T> | undefined): T[] {
412407
if (from === undefined || from.length === 0) return to;
413-
if (to === undefined) return from.slice();
414-
const prologue = to.length && isPrologueDirective(to[0]) && to.shift();
415-
to.unshift(...from);
416-
if (prologue) {
417-
to.unshift(prologue);
408+
let statementIndex = 0;
409+
// skip all prologue directives to insert at the correct position
410+
for (; statementIndex < to.length; ++statementIndex) {
411+
if (!isPrologueDirective(to[statementIndex])) {
412+
break;
413+
}
418414
}
415+
to.splice(statementIndex, 0, ...from);
419416
return to;
420417
}
421418

src/compiler/visitor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,8 @@ namespace ts {
14761476
}
14771477

14781478
return isNodeArray(statements)
1479-
? setTextRange(createNodeArray(prependStatements(statements.slice(), declarations)), statements)
1480-
: prependStatements(statements, declarations);
1479+
? setTextRange(createNodeArray(addStatementsAfterPrologue(statements.slice(), declarations)), statements)
1480+
: addStatementsAfterPrologue(statements, declarations);
14811481
}
14821482

14831483
/**
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
//// [destructuringTempOccursAfterPrologue.ts]
22
function test(p: any) {
33
'use strict';
4+
'use strong';
45
p = { prop: p } = p;
56
}
67

78
//// [destructuringTempOccursAfterPrologue.js]
89
function test(p) {
910
'use strict';
11+
'use strong';
1012
var _a;
1113
p = (_a = p, p = _a.prop, _a);
1214
}

tests/baselines/reference/destructuringTempOccursAfterPrologue.symbols

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ function test(p: any) {
44
>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14))
55

66
'use strict';
7+
'use strong';
78
p = { prop: p } = p;
89
>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14))
9-
>prop : Symbol(prop, Decl(destructuringTempOccursAfterPrologue.ts, 2, 9))
10+
>prop : Symbol(prop, Decl(destructuringTempOccursAfterPrologue.ts, 3, 9))
1011
>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14))
1112
>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14))
1213
}

tests/baselines/reference/destructuringTempOccursAfterPrologue.types

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ function test(p: any) {
66
'use strict';
77
>'use strict' : "use strict"
88

9+
'use strong';
10+
>'use strong' : "use strong"
11+
912
p = { prop: p } = p;
1013
>p = { prop: p } = p : any
1114
>p : any
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
function test(p: any) {
22
'use strict';
3+
'use strong';
34
p = { prop: p } = p;
45
}

0 commit comments

Comments
 (0)