fix(47821): Assertion failure on "convert to default export" in module augmentation#47829
Conversation
e7c7d2d to
9cdea10
Compare
9cdea10 to
ae6b6da
Compare
ae6b6da to
836c1da
Compare
|
The change looks correct to me and, in practice, there's only one caller, so whether the check is pushed upstream is mostly a hygiene thing. I think it's worth investigating, but I think the change is also acceptable as-is. |
|
It sounds like this is ready to go except (probably) unconditionally calling At least, I'm pretty sure that @weswigham is right in his concern, and also that there's no penalty for calling |
| const parent = node.parent; | ||
| if (isSourceFile(parent)) { | ||
| return parent.symbol; | ||
| } | ||
| const symbol = parent.parent.symbol; | ||
| if (symbol.valueDeclaration && isExternalModuleAugmentation(symbol.valueDeclaration)) { | ||
| return checker.getMergedSymbol(symbol); | ||
| } | ||
| return symbol; |
There was a problem hiding this comment.
I think you just always want the merged symbol. Otherwise you won't correctly catch when an existing module augmentation adds a default export (which admittedly is very weird).
// @Filename: foo.ts
/////*a*/export function bar() {}/*b*/;
// @Filename: augmenter.ts
////import "./foo";
////declare module "./foo" {
//// export default function foo(): void;
////}
// @Filename: /b.ts
////import foo from "./foo";So maybe just
| const parent = node.parent; | |
| if (isSourceFile(parent)) { | |
| return parent.symbol; | |
| } | |
| const symbol = parent.parent.symbol; | |
| if (symbol.valueDeclaration && isExternalModuleAugmentation(symbol.valueDeclaration)) { | |
| return checker.getMergedSymbol(symbol); | |
| } | |
| return symbol; | |
| const parent = node.parent; | |
| const symbol = checker.getMergedSymbol(isSourceFile(parent) ? parent.symbol : parent.parent.symbol); | |
| return symbol; |
There was a problem hiding this comment.
Import in /b.ts will not be changed. Maybe need to use two symbols, something like this
const parent = node.parent;
const symbol = isSourceFile(parent) ? parent.symbol : parent.parent.symbol;
const mergedSymbol = checker.getMergedSymbol(symbol);
return symbol === mergedSymbol ? [symbol] : [symbol, mergedSymbol];or handle merged symbols directly in importTracker
There was a problem hiding this comment.
(edited my last comment to actually use a default import)
- import { foo } from "./foo";
+ import foo from "./foo";There was a problem hiding this comment.
I think my previous comment also applies to default imports.
There was a problem hiding this comment.
I’m sorry but I can’t actually tell what issue is being discussed here but it seems to be the one that’s preventing this from being merged. Is there a concrete failing test we can discuss?
There was a problem hiding this comment.
Changes should be made to the b.ts and c.ts files - @DanielRosenwasser am I right?
// @Filename: /a.ts
/////*a*/export function a() {}/*b*/;
// @Filename: /b.ts
////import "./a";
////declare module "./a" {
//// export function a(): void;
////}
// @Filename: /c.ts
////import { a } from "./a";
goTo.select("a", "b");
edit.applyRefactor({
refactorName: "Convert export",
actionName: "Convert named export to default export",
actionDescription: "Convert named export to default export",
newContent: {
"/a.ts":
`export default function a() {};`,
"/b.ts":
`import "./a";
declare module "./a" {
export default function a(): void;
}`,
"/c.ts":
`import a from "./a";`
}
});If we use only the merged symbol, changes will only be made in the /b.ts file. I see two ways how we can fix it -
- fix(47821): Assertion failure on "convert to default export" in module augmentation #47829 (comment),
- handle merged symbols in the import tracker, I'm not sure how safe it is
There was a problem hiding this comment.
Changes should be made to the
b.tsandc.tsfiles
@a-tarasyuk that test shows no changes to b.ts 🤔
There was a problem hiding this comment.
@andrewbranch default is useless in /b.ts. I've changed that
There was a problem hiding this comment.
It’s actually not 100% clear to me what the expected behavior should be. This is a very weird edge case, and I think it could be unexpected to generate changes to a merged declaration of any export. Personally I would be fine with the refactor being unavailable here.
There was a problem hiding this comment.
What did the behavior of this hypothetical test end up being?
|
@andrewbranch @amcasey I got lost reading the PR history. I think this is ready to go, and that the last outstanding request from @andrewbranch -- that the refactor not apply in the weird case given by @DanielRosenwasser -- is already true. Did I read that right? |
|
@sandersn Fine by me |
… sharedmemory file (#49204) * feat(sharedmemory): Added file waitAsync function * fix: Adjusted promise return type * Fix(sharedmemory): Addressed PR comments * Fix: Removed unused @see at sharedmemory * Feat: Added tests to shared memory * Fix: fixed ordering in libs.json * Feat: Added shared memory to line parser * Update tests es2022SharedMemory.ts as sugested Co-authored-by: Eyal Halpern Shalev <eyalsh@gmail.com> * Update es2022SharedMemory.ts * feat: Accepted baselines * fix: Adjusted grammar changes in jsdoc * fix(47821): skip nodes with export modifiers (#47829) * Use symbolic GitHub Actions Node.js versions (#49403) * update baselines Co-authored-by: Eyal Halpern Shalev <eyalsh@gmail.com> Co-authored-by: Oleksandr T <oleksandr.tarasiuk@outlook.com> Co-authored-by: Jack Bates <jack@nottheoilrig.com> Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
Fixes #47821