Skip to content

Conversation

@andrewbranch
Copy link
Member

@andrewbranch andrewbranch commented Aug 2, 2021

Fixes #45101, fixes #45200.

@andrewbranch andrewbranch requested a review from sandersn August 2, 2021 19:27
? checker.resolveExternalModuleSymbol(moduleSymbol)
: checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol));
: checker.tryGetMemberInModuleExportsAndProperties(unescapeLeadingUnderscores(info.symbolTableKey), moduleSymbol),
`Could not find symbol '${info.symbolName}' by key '${info.symbolTableKey}' in module ${moduleSymbol.name}`);
Copy link
Member Author

Choose a reason for hiding this comment

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

Double checking with @amcasey that this is ok to put in an error message. info.symbolName may be a variable name written by a user and moduleSymbol.name may be most of a file path. This info will help discover a repro if a user sees it in their TS Server log and can share it.

Copy link
Member

Choose a reason for hiding this comment

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

Obviously, the less customer content, the better but, as we've discussed, we have reason to believe this will be broadly useful and the telemetry for the resulting exception will be sanitized appropriately.

const type = getTypeOfSymbol(exportEquals);
if (shouldTreatPropertiesOfExternalModuleAsExports(type)) {
getPropertiesOfType(type).forEach(symbol => {
cb(symbol, symbol.escapedName);
Copy link
Member Author

Choose a reason for hiding this comment

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

I would have had to refactor or duplicate a lot of checker code to get the actual map key of symbol.members here, so I’m hoping that the map key for a property is always symbol.escapedName, which is not always true for an export. I added a debug assertion here while running tests and it never triggered, but I don’t want to leave it in production code because this is an extremely hot path (can easily hit tens of thousands of times while building a large export info map).

Copy link
Member

Choose a reason for hiding this comment

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

What's the penalty for providing the wrong key in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

It will crash in rehydrateCachedInfo, for the same reason it does before this PR—no change. The cases I’ve identified where symbol.escapedName was not the key were all in exports, not members, which definitely gets the real map key.

@andrewbranch
Copy link
Member Author

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 2, 2021

Heya @andrewbranch, I've started to run the tarball bundle task on this PR at e640207. You can monitor the build here.

@andrewbranch
Copy link
Member Author

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 2, 2021

Heya @andrewbranch, I've started to run the tarball bundle task on this PR at 55974d6. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 2, 2021

Hey @andrewbranch, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/107805/artifacts?artifactName=tgz&fileId=B352F149EEC638AD81BA5D7EDBAEE389AD0A6FE2DAB5A014EB67981DD6FF77D102&fileName=/typescript-4.4.0-insiders.20210802.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@4.4.0-pr-45289-4".;

@andrewbranch
Copy link
Member Author

Confirmed this fixes #45200

@andrewbranch andrewbranch self-assigned this Aug 3, 2021
@andrewbranch andrewbranch added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Aug 3, 2021
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

As far as I understand auto imports/module exports, this seems like an improvement. I have a question about what happens if the key isn't symbol.escapedName.

return startsWith(symbol.escapedName as string, "__@");
}

export function isPrivateIdentifierSymbol(symbol: Symbol): boolean {
Copy link
Member

Choose a reason for hiding this comment

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

hmm. I had to figure this out recently and I thought the Right Way was symbol.valueDeclaration?.kind === SyntaxKind.PrivateIdentifier or something similar. But I guess this way works too.

Copy link
Member Author

@andrewbranch andrewbranch Aug 4, 2021

Choose a reason for hiding this comment

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

I would readily believe, or at least hope, that those are equivalent, but this implementation gets to the core of what went wrong in the linked crash. You cannot ask for a name starting with __# in checker.tryGetInModuleExportsAndProperties and expect to get the private identifier symbol it came from back out, because the checker will underscore-escape that string and try to find a property whose actual name starts with __#. So it’s very important that we don’t store any symbols with escapedNames like this, somewhat regardless of what it represents.

const type = getTypeOfSymbol(exportEquals);
if (shouldTreatPropertiesOfExternalModuleAsExports(type)) {
getPropertiesOfType(type).forEach(symbol => {
cb(symbol, symbol.escapedName);
Copy link
Member

Choose a reason for hiding this comment

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

What's the penalty for providing the wrong key in this PR?

@andrewbranch andrewbranch merged commit f80bc3f into microsoft:main Aug 4, 2021
@andrewbranch andrewbranch deleted the bug/45101 branch August 4, 2021 23:31
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Author: Team For Milestone Bug PRs that fix a bug with a specific milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TS Server: Debug Failure. (VSCode completions don't work) Auto import doesn't work when re-export alias merges with augmentation

4 participants