-
Notifications
You must be signed in to change notification settings - Fork 13k
Fix auto import crash on weird JS aliasing #46490
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
@typescript-bot perf test this |
Heya @andrewbranch, I've started to run the perf test suite on this PR at fbf8470. You can monitor the build here. Update: The results are in! |
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 looks like a good fix, although I have a couple of questions.
} | ||
|
||
function isNamedMember(member: Symbol, escapedName: __String) { | ||
return !isReservedMemberName(escapedName) && symbolIsValue(member); |
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.
what does symbolIsValue
do, and how is it useful here?
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.
It just checks symbol.flags & SymbolFlags.Value
, and it’s used to filter out type and uninstantiated namespace members out of instantiated namespaces. (I just moved this existing logic into a function so I could reuse it.)
} | ||
}); | ||
const exportEquals = resolveExternalModuleSymbol(moduleSymbol); | ||
if (exportEquals !== 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.
is forEachExportAndPropertyOfModule
only used in the services layer?
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.
Yep.
// 3. Otherwise, we have a default/namespace import that can be imported by any name, and | ||
// `symbolTableKey` will be something undesirable like `export=` or `default`, so we try to | ||
// get a better name. | ||
const importedName = exportKind === ExportKind.Named || isExternalModuleSymbol(namedSymbol) |
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 fine, but it feels a little backward compared to the usual approach of checking for special names first
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.
I probably agree—this is a refactor of a refactor of a refactor of... it has probably accumulated some unnecessary roundabout logic that could be simplified if rewritten fresh.
@andrewbranch Here they are:Comparison Report - main..46490
System
Hosts
Scenarios
Developer Information: |
* Fix auto import crash on weird JS aliasing * Comment up the weird test * Fix setting members on union/intersection type, happens later
Fixes #46024
Also probably fixes #38071 with the missing
checker.getMergedSymbol
Side note: the distinction between a type’s
members
andproperties
(orresolvedProperties
in the case of a union/intersection type) is frustrating—members
contains crucial information thatproperties
lacks, which is the key in the symbol table where that symbol is stored. It’s usually justsymbol.escapedName
, but not always, as in this test case: the type of theexport=
symbol has a key nameddefaults
, but the symbol at that location has the namenewDefaults
. (This weirdness may only happen in JS code where we jump through weird hoops to bind everything we can, not sure.) But theproperties
array also has filtered out the non-value symbols and symbols with reserved names (specifyingunique symbol
and#private
members), somembers
is not a drop-in replacement. That said, this filtering appears to be very cheap, so I really wonder if storingproperties
alongsidemembers
is even worth the weight of the array allocations. Might be an interesting experiment.