-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Fix completion details auto-imports crashes #52686
Conversation
@typescript-bot user test tsserver |
Heya @andrewbranch, I've started to run the diff-based user code test suite (tsserver) on this PR at a1d36cd. You can monitor the build here. Update: The results are in! |
@andrewbranch Here are the results of running the user test suite comparing Something interesting changed - please have a look. Detailscreate-react-app
|
Actually, that shortcut is the other stack trace that shows up in the user tests. I suspect they’re different root causes, but maybe I’ll try to tackle that one too in this PR. |
…mpler altogether for modern clients
@typescript-bot user test tsserver |
Heya @andrewbranch, I've started to run the perf test suite on this PR at 605b0d9. You can monitor the build here. Update: The results are in! |
Heya @andrewbranch, I've started to run the diff-based user code test suite (tsserver) on this PR at 605b0d9. You can monitor the build here. Update: The results are in! |
@andrewbranch Here are the results of running the user test suite comparing Something interesting changed - please have a look. Detailsnpm
|
@andrewbranch Here they are:
CompilerComparison Report - main..52686
System
Hosts
Scenarios
TSServerComparison Report - main..52686
System
Hosts
Scenarios
StartupComparison Report - main..52686
System
Hosts
Scenarios
Developer Information: |
@typescript-bot user test tsserver |
Heya @andrewbranch, I've started to run the diff-based user code test suite (tsserver) on this PR at 6c85f52. You can monitor the build here. Update: The results are in! |
@andrewbranch Here are the results of running the user test suite comparing Something interesting changed - please have a look. Detailsnpm
|
Hm, my last commit fixed the npm repro I was able to get locally. Not sure what’s going on there now. |
I can’t repro those last two crashes locally, so I’m giving up on them for now. This fixes the large majority of the ones reported at #52660. |
}); | ||
|
||
verify.applyCodeActionFromCompletion("", { | ||
}).andApplyCodeAction({ |
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.
This is a new fourslash API for calling completionEntryDetails
with the exact data
that was returned in the completionInfo
response, as an editor would do. I was considering making sending data
for auto-import completion details requests mandatory, breaking super old editors and about 40 old tests like this one, but ultimately decided against it.
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.
LGTM from airplane wifi :D
const getChecker = createGetChecker(program, host); | ||
return getExportInfoMap(importingFile, host, program, preferences, cancellationToken) | ||
.search(importingFile.path, preferCapitalized, name => name === symbolName, info => { | ||
if (skipAlias(info[0].symbol, getChecker(info[0].isFromPackageJson)) === symbol) { | ||
if (skipAlias(info[0].symbol, getChecker(info[0].isFromPackageJson)) === symbol && info.some(i => i.moduleSymbol === moduleSymbol || i.symbol.parent === moduleSymbol)) { |
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.
Can't recall but I think our own utility for checking if something is in an array is faster.
Fixes #52661
The ExportInfoMap is a multimap that contains information about every way that every export is re-exported from different places. Usually, a single symbol that gets re-exported multiple times has a single key pointing to an array of each place it’s exported from. When auto-imports are displayed in completions, we show one completion per key, and we simply pick the “best” re-exporting location out of that array. This lets us prefer short import paths over deep imports. (When and whether this is actually a good heuristic is beside the point.)
The exception is when a single symbol is exported by an ambient module. Ambient modules are considered a stronger signal that the name of the module is significant. For example, when
"node:fs"
re-exports everything from"fs"
, we don’t want to be forced to pick which module is the “better” place to importreadFile
from—we’d rather show a completion for both, even though the exported symbol is the same in both. So each of these get their own keys in the multimap.When
completionEntryDetails
is called and we have to re-find the export we showed in the previouscompletionInfo
request, we never used to check the module symbol when searching the ExportInfoMap—instead, we asserted on it later, issuing the message seen in the telemetry bug. The fix is simply to check that the module symbol matches as part of our search instead of returning the first export info where just the export symbol itself matches.The fix sounds obvious, so why was this not more broken before? Well, when
completionEntryDetails
is called for an import from an ambient module, we were able to take shortcut that skips this search through the ExportInfoMap containing the faulty code. So the only way for the bug to manifest is when we request details for a symbol that a non-ambient module re-exports from an ambient module, and the iteration order mattered—it could have been correct by coincidence sometimes.