Skip to content

fix(47821): Assertion failure on "convert to default export" in module augmentation #47829

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

Merged
merged 1 commit into from
Jun 6, 2022

Conversation

a-tarasyuk
Copy link
Contributor

Fixes #47821

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Feb 10, 2022
Copy link
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions.

@a-tarasyuk a-tarasyuk marked this pull request as draft February 23, 2022 14:05
@a-tarasyuk a-tarasyuk marked this pull request as ready for review March 3, 2022 18:26
@amcasey
Copy link
Member

amcasey commented Mar 4, 2022

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.

@sandersn
Copy link
Member

It sounds like this is ready to go except (probably) unconditionally calling getMergedSymbol as @DanielRosenwasser pointed out.

At least, I'm pretty sure that @weswigham is right in his concern, and also that there's no penalty for calling getMergedSymbol too much.

Comment on lines +263 to +271
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;
Copy link
Member

@DanielRosenwasser DanielRosenwasser Apr 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Suggested change
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;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(edited my last comment to actually use a default import)

- import { foo } from "./foo";
+ import foo from "./foo";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my previous comment also applies to default imports.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

@a-tarasyuk a-tarasyuk May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 -

  1. fix(47821): Assertion failure on "convert to default export" in module augmentation #47829 (comment),
  2. FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => {
    handle merged symbols in the import tracker, I'm not sure how safe it is

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes should be made to the b.ts and c.ts files

@a-tarasyuk that test shows no changes to b.ts 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewbranch default is useless in /b.ts. I've changed that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did the behavior of this hypothetical test end up being?

@sandersn
Copy link
Member

sandersn commented Jun 6, 2022

@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?

@amcasey
Copy link
Member

amcasey commented Jun 6, 2022

@sandersn Fine by me

@DanielRosenwasser DanielRosenwasser merged commit 2f13eba into microsoft:main Jun 6, 2022
sandersn added a commit that referenced this pull request Jun 7, 2022
… 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 <[email protected]>

* 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 <[email protected]>
Co-authored-by: Oleksandr T <[email protected]>
Co-authored-by: Jack Bates <[email protected]>
Co-authored-by: Nathan Shively-Sanders <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Assertion failure on "convert to default export" in module augmentation
7 participants