Skip to content

Commit 13c9b16

Browse files
authored
When reparsing top level await dont set original node for the new source file (microsoft#56439)
1 parent 2c0c128 commit 13c9b16

File tree

6 files changed

+201
-22
lines changed

6 files changed

+201
-22
lines changed

src/compiler/factory/nodeFactory.ts

+15-21
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ import {
133133
hasSyntacticModifier,
134134
HeritageClause,
135135
Identifier,
136+
identity,
136137
idText,
137138
IfStatement,
138139
ImmediatelyInvokedArrowFunction,
@@ -509,7 +510,7 @@ export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void) {
509510
* @internal
510511
*/
511512
export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNodeFactory): NodeFactory {
512-
const update = flags & NodeFactoryFlags.NoOriginalNode ? updateWithoutOriginal : updateWithOriginal;
513+
const setOriginal = flags & NodeFactoryFlags.NoOriginalNode ? identity : setOriginalNode;
513514

514515
// Lazily load the parenthesizer, node converters, and some factory methods until they are used.
515516
const parenthesizerRules = memoize(() => flags & NodeFactoryFlags.NoParenthesizerRules ? nullParenthesizerRules : createParenthesizerRules(factory));
@@ -6135,7 +6136,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
61356136

61366137
function cloneSourceFile(source: SourceFile) {
61376138
const node = source.redirectInfo ? cloneRedirectedSourceFile(source) : cloneSourceFileWorker(source);
6138-
setOriginalNode(node, source);
6139+
setOriginal(node, source);
61396140
return node;
61406141
}
61416142

@@ -6365,7 +6366,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
63656366
const clone = createBaseIdentifier(node.escapedText) as Mutable<GeneratedIdentifier>;
63666367
clone.flags |= node.flags & ~NodeFlags.Synthesized;
63676368
clone.transformFlags = node.transformFlags;
6368-
setOriginalNode(clone, node);
6369+
setOriginal(clone, node);
63696370
setIdentifierAutoGenerate(clone, { ...node.emitNode.autoGenerate });
63706371
return clone;
63716372
}
@@ -6377,7 +6378,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
63776378
clone.flowNode = node.flowNode;
63786379
clone.symbol = node.symbol;
63796380
clone.transformFlags = node.transformFlags;
6380-
setOriginalNode(clone, node);
6381+
setOriginal(clone, node);
63816382

63826383
// clone type arguments for emitter/typeWriter
63836384
const typeArguments = getIdentifierTypeArguments(node);
@@ -6389,7 +6390,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
63896390
const clone = createBasePrivateIdentifier(node.escapedText) as Mutable<GeneratedPrivateIdentifier>;
63906391
clone.flags |= node.flags & ~NodeFlags.Synthesized;
63916392
clone.transformFlags = node.transformFlags;
6392-
setOriginalNode(clone, node);
6393+
setOriginal(clone, node);
63936394
setIdentifierAutoGenerate(clone, { ...node.emitNode.autoGenerate });
63946395
return clone;
63956396
}
@@ -6398,7 +6399,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
63986399
const clone = createBasePrivateIdentifier(node.escapedText);
63996400
clone.flags |= node.flags & ~NodeFlags.Synthesized;
64006401
clone.transformFlags = node.transformFlags;
6401-
setOriginalNode(clone, node);
6402+
setOriginal(clone, node);
64026403
return clone;
64036404
}
64046405

@@ -6432,7 +6433,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
64326433

64336434
(clone as Mutable<T>).flags |= node.flags & ~NodeFlags.Synthesized;
64346435
(clone as Mutable<T>).transformFlags = node.transformFlags;
6435-
setOriginalNode(clone, node);
6436+
setOriginal(clone, node);
64366437

64376438
for (const key in node) {
64386439
if (hasProperty(clone, key) || !hasProperty(node, key)) {
@@ -7197,7 +7198,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
71977198
function asEmbeddedStatement<T extends Node>(statement: T): T | EmptyStatement;
71987199
function asEmbeddedStatement<T extends Node>(statement: T | undefined): T | EmptyStatement | undefined;
71997200
function asEmbeddedStatement<T extends Node>(statement: T | undefined): T | EmptyStatement | undefined {
7200-
return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement;
7201+
return statement && isNotEmittedStatement(statement) ? setTextRange(setOriginal(createEmptyStatement(), statement), statement) : statement;
72017202
}
72027203

72037204
function asVariableDeclaration(variableDeclaration: string | BindingName | VariableDeclaration | undefined) {
@@ -7211,21 +7212,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
72117212
}
72127213
return variableDeclaration;
72137214
}
7214-
}
7215-
7216-
function updateWithoutOriginal<T extends Node>(updated: Mutable<T>, original: T): T {
7217-
if (updated !== original) {
7218-
setTextRange(updated, original);
7219-
}
7220-
return updated;
7221-
}
72227215

7223-
function updateWithOriginal<T extends Node>(updated: Mutable<T>, original: T): T {
7224-
if (updated !== original) {
7225-
setOriginalNode(updated, original);
7226-
setTextRange(updated, original);
7216+
function update<T extends Node>(updated: Mutable<T>, original: T): T {
7217+
if (updated !== original) {
7218+
setOriginal(updated, original);
7219+
setTextRange(updated, original);
7220+
}
7221+
return updated;
72277222
}
7228-
return updated;
72297223
}
72307224

72317225
function getDefaultTagNameForKind(kind: JSDocTag["kind"]): string {

src/compiler/parser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1971,8 +1971,9 @@ namespace Parser {
19711971

19721972
// If we parsed this as an external module, it may contain top-level await
19731973
if (!isDeclarationFile && isExternalModule(sourceFile) && sourceFile.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) {
1974+
const oldSourceFile = sourceFile;
19741975
sourceFile = reparseTopLevelAwait(sourceFile);
1975-
setFields(sourceFile);
1976+
if (oldSourceFile !== sourceFile) setFields(sourceFile);
19761977
}
19771978

19781979
return sourceFile;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//// [tests/cases/compiler/dynamicImportsDeclaration.ts] ////
2+
3+
//// [case0.ts]
4+
export default 0;
5+
6+
//// [case1.ts]
7+
export default 1;
8+
9+
//// [caseFallback.ts]
10+
export default 'fallback';
11+
12+
//// [index.ts]
13+
export const mod = await (async () => {
14+
const x: number = 0;
15+
switch (x) {
16+
case 0:
17+
return await import("./case0.js");
18+
case 1:
19+
return await import("./case1.js");
20+
default:
21+
return await import("./caseFallback.js");
22+
}
23+
})();
24+
25+
//// [case0.js]
26+
"use strict";
27+
Object.defineProperty(exports, "__esModule", { value: true });
28+
exports.default = 0;
29+
//// [case1.js]
30+
"use strict";
31+
Object.defineProperty(exports, "__esModule", { value: true });
32+
exports.default = 1;
33+
//// [caseFallback.js]
34+
"use strict";
35+
Object.defineProperty(exports, "__esModule", { value: true });
36+
exports.default = 'fallback';
37+
//// [index.js]
38+
"use strict";
39+
Object.defineProperty(exports, "__esModule", { value: true });
40+
exports.mod = void 0;
41+
exports.mod = await (async () => {
42+
const x = 0;
43+
switch (x) {
44+
case 0:
45+
return await import("./case0.js");
46+
case 1:
47+
return await import("./case1.js");
48+
default:
49+
return await import("./caseFallback.js");
50+
}
51+
})();
52+
53+
54+
//// [case0.d.ts]
55+
declare const _default: 0;
56+
export default _default;
57+
//// [case1.d.ts]
58+
declare const _default: 1;
59+
export default _default;
60+
//// [caseFallback.d.ts]
61+
declare const _default: "fallback";
62+
export default _default;
63+
//// [index.d.ts]
64+
export declare const mod: {
65+
default: typeof import("./case0.js");
66+
} | {
67+
default: typeof import("./case1.js");
68+
} | {
69+
default: typeof import("./caseFallback.js");
70+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [tests/cases/compiler/dynamicImportsDeclaration.ts] ////
2+
3+
=== /case0.ts ===
4+
5+
export default 0;
6+
7+
=== /case1.ts ===
8+
9+
export default 1;
10+
11+
=== /caseFallback.ts ===
12+
13+
export default 'fallback';
14+
15+
=== /index.ts ===
16+
export const mod = await (async () => {
17+
>mod : Symbol(mod, Decl(index.ts, 0, 12))
18+
19+
const x: number = 0;
20+
>x : Symbol(x, Decl(index.ts, 1, 7))
21+
22+
switch (x) {
23+
>x : Symbol(x, Decl(index.ts, 1, 7))
24+
25+
case 0:
26+
return await import("./case0.js");
27+
>"./case0.js" : Symbol("/case0", Decl(case0.ts, 0, 0))
28+
29+
case 1:
30+
return await import("./case1.js");
31+
>"./case1.js" : Symbol("/case1", Decl(case1.ts, 0, 0))
32+
33+
default:
34+
return await import("./caseFallback.js");
35+
>"./caseFallback.js" : Symbol("/caseFallback", Decl(caseFallback.ts, 0, 0))
36+
}
37+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [tests/cases/compiler/dynamicImportsDeclaration.ts] ////
2+
3+
=== /case0.ts ===
4+
5+
export default 0;
6+
7+
=== /case1.ts ===
8+
9+
export default 1;
10+
11+
=== /caseFallback.ts ===
12+
13+
export default 'fallback';
14+
15+
=== /index.ts ===
16+
export const mod = await (async () => {
17+
>mod : { default: typeof import("/case0"); } | { default: typeof import("/case1"); } | { default: typeof import("/caseFallback"); }
18+
>await (async () => { const x: number = 0; switch (x) { case 0: return await import("./case0.js"); case 1: return await import("./case1.js"); default: return await import("./caseFallback.js"); }})() : { default: typeof import("/case0"); } | { default: typeof import("/case1"); } | { default: typeof import("/caseFallback"); }
19+
>(async () => { const x: number = 0; switch (x) { case 0: return await import("./case0.js"); case 1: return await import("./case1.js"); default: return await import("./caseFallback.js"); }})() : Promise<{ default: typeof import("/case0"); } | { default: typeof import("/case1"); } | { default: typeof import("/caseFallback"); }>
20+
>(async () => { const x: number = 0; switch (x) { case 0: return await import("./case0.js"); case 1: return await import("./case1.js"); default: return await import("./caseFallback.js"); }}) : () => Promise<{ default: typeof import("/case0"); } | { default: typeof import("/case1"); } | { default: typeof import("/caseFallback"); }>
21+
>async () => { const x: number = 0; switch (x) { case 0: return await import("./case0.js"); case 1: return await import("./case1.js"); default: return await import("./caseFallback.js"); }} : () => Promise<{ default: typeof import("/case0"); } | { default: typeof import("/case1"); } | { default: typeof import("/caseFallback"); }>
22+
23+
const x: number = 0;
24+
>x : number
25+
>0 : 0
26+
27+
switch (x) {
28+
>x : number
29+
30+
case 0:
31+
>0 : 0
32+
33+
return await import("./case0.js");
34+
>await import("./case0.js") : { default: typeof import("/case0"); }
35+
>import("./case0.js") : Promise<{ default: typeof import("/case0"); }>
36+
>"./case0.js" : "./case0.js"
37+
38+
case 1:
39+
>1 : 1
40+
41+
return await import("./case1.js");
42+
>await import("./case1.js") : { default: typeof import("/case1"); }
43+
>import("./case1.js") : Promise<{ default: typeof import("/case1"); }>
44+
>"./case1.js" : "./case1.js"
45+
46+
default:
47+
return await import("./caseFallback.js");
48+
>await import("./caseFallback.js") : { default: typeof import("/caseFallback"); }
49+
>import("./caseFallback.js") : Promise<{ default: typeof import("/caseFallback"); }>
50+
>"./caseFallback.js" : "./caseFallback.js"
51+
}
52+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @declaration: true
2+
// @module: nodenext
3+
// @target: esnext
4+
5+
// @filename: /case0.ts
6+
export default 0;
7+
8+
// @filename: /case1.ts
9+
export default 1;
10+
11+
// @filename: /caseFallback.ts
12+
export default 'fallback';
13+
14+
// @filename: /index.ts
15+
export const mod = await (async () => {
16+
const x: number = 0;
17+
switch (x) {
18+
case 0:
19+
return await import("./case0.js");
20+
case 1:
21+
return await import("./case1.js");
22+
default:
23+
return await import("./caseFallback.js");
24+
}
25+
})();

0 commit comments

Comments
 (0)