-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Fix a crash when transforming functions in modules. #34513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I am unsure what the intended invariant of the AST structure is here.
I presume @rbuckton might know? |
Transformed nodes (i.e. nodes with the Generally this means that
Yes, this is a bug. There are only a few places where we explicitly set the In the case of
It is not a bug to have an I do not believe this is the correct fix for this issue. I would be more interested in finding the specific case where the |
@rbuckton thanks for the thorough explanation! That's really helpful. I've traced this a bit longer, and (by using
This looks as if |
I filed #34644 to track this. |
The issue is that I’ve just fixed this locally by cloning the tree in |
@mprobst I talked to @rbuckton and he suggested that the caller of ts.ts: function shouldEmitModuleDeclaration(nodeIn: ModuleDeclaration) {
const node = getParseTreeNode(nodeIn, isModuleDeclaration);
// if we can't find a parse tree node, assume the node is instantiated.
return node ? isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules) : true;
} We need to get this in in the next couple days for 3.7, so let me know if you want to update it here. Otherwise, or if I don’t hear from you by Wednesday-ish, I’ll open a new PR. Thanks for the investigation! |
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 microsoft#34644.
03e1604
to
62aad54
Compare
@andrewbranch thanks for the help. Done, and rebased onto current master. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mprobst! 🙌
@typescript-bot cherry-pick this to release-3.7 |
Hey @andrewbranch, I've opened #34800 for you. |
Component commits: 62aad54 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 microsoft#34644.
Component commits: 62aad54 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.
When transforming a module declaration and block, a containing function
declarations parent pointer ends up pointing and the synthetic module
block and module declaration nodes.
If a function is contained in such a module declaration, and any of its
preceding statements are transformed, the
getOrCreateEmitNode
triggered by
visitParameter
fails becausegetSourceFileOfNode
failsto find a SourceFile for the synthetic module declaration nodes.
This change avoids the crash by finding original nodes in
getSourceFileOfNode
.