mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix a crash when transforming functions in modules.
When transforming a module declaration and block, parse tree nodes contained in the module block have their parent pointers reset due to `shouldEmitModuleDeclaration` calling into `isInstantiatedModule`, which needs to set parent pointers to operate. That causes a crash when later transforming any nodes within the module, as retrieving their source file in `getSourceFileOfNode` (via `getOrCreateEmitNode`) fails, due to their new synthesized parent nodes not being in a source file. This change avoids the issue by using the parse tree node in `ts.ts` to decide whether a module declaration should be emitted (i.e. whether the module contains values). This means transformers cannot add values to modules that previously did not contain any. Fixes #34644.
This commit is contained in:
@@ -2452,7 +2452,12 @@ namespace ts {
|
||||
*
|
||||
* @param node The module declaration node.
|
||||
*/
|
||||
function shouldEmitModuleDeclaration(node: ModuleDeclaration) {
|
||||
function shouldEmitModuleDeclaration(nodeIn: ModuleDeclaration) {
|
||||
const node = getParseTreeNode(nodeIn, isModuleDeclaration);
|
||||
if (!node) {
|
||||
// If we can't find a parse tree node, assume the node is instantiated.
|
||||
return true;
|
||||
}
|
||||
return isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules);
|
||||
}
|
||||
|
||||
|
||||
@@ -447,6 +447,35 @@ namespace Foo {
|
||||
}).outputText;
|
||||
});
|
||||
|
||||
testBaseline("transformUpdateModuleMember", () => {
|
||||
return transpileModule(`
|
||||
module MyModule {
|
||||
const myVariable = 1;
|
||||
function foo(param: string) {}
|
||||
}
|
||||
`, {
|
||||
transformers: {
|
||||
before: [renameVariable],
|
||||
},
|
||||
compilerOptions: {
|
||||
target: ScriptTarget.ES2015,
|
||||
newLine: NewLineKind.CarriageReturnLineFeed,
|
||||
}
|
||||
}).outputText;
|
||||
|
||||
function renameVariable(context: TransformationContext) {
|
||||
return (sourceFile: SourceFile): SourceFile => {
|
||||
return visitNode(sourceFile, rootTransform, isSourceFile);
|
||||
};
|
||||
function rootTransform<T extends Node>(node: T): Node {
|
||||
if (isVariableDeclaration(node)) {
|
||||
return updateVariableDeclaration(node, createIdentifier("newName"), /* type */ undefined, node.initializer);
|
||||
}
|
||||
return visitEachChild(node, rootTransform, context);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/24709
|
||||
testBaseline("issue24709", () => {
|
||||
const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true);
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
var MyModule;
|
||||
(function (MyModule) {
|
||||
const newName = 1;
|
||||
function foo(param) { }
|
||||
})(MyModule || (MyModule = {}));
|
||||
Reference in New Issue
Block a user