Skip to content
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

Fixed crash in go to definition related to expando classes in JS files #57628

Merged
merged 3 commits into from
Apr 19, 2024

Conversation

Andarist
Copy link
Contributor

@Andarist Andarist commented Mar 4, 2024

fixes a crash reported here

@typescript-bot
Copy link
Collaborator

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Mar 4, 2024
@@ -583,16 +583,20 @@ function isExpandoDeclaration(node: Declaration): boolean {

function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, failedAliasResolution?: boolean, excludeDeclaration?: Node): DefinitionInfo[] | undefined {
const filteredDeclarations = filter(symbol.declarations, d => d !== excludeDeclaration);
const signatureDefinition = getConstructSignatureDefinition() || getCallSignatureDefinition();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes in this function are not needed. I just tweaked it while trying to understand what happens here. This still acts as a short-circuit for calls below it so I'd call it a micro-optimization and keep the change ;p

const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
const cls = find(filteredDeclarations, isClassLike);
return cls && getSignatureDefinition(cls.members, /*selectConstructors*/ true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

there is a question in this case - should this be treated more like a class or more like a property? I decided that it's better to ignore class-ness here as the expando property acts as a common root for other things and as such it makes sense to prefer showing it here in my opinion.

Copy link
Member

Choose a reason for hiding this comment

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

What is the difference in behaviour? The baselines for goToDefinitionExpandoClass2 show that the constructor is found when present, so what are we skipping here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Without this skip it crashes while resolving what becomes defId: 0 in goToDefinitionExpandoClass2 with the fix. The resolved constructor (defId: 1) comes from sigInfo here:

return node.kind === SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo];

Copy link
Member

Choose a reason for hiding this comment

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

OK, that makes sense. I guess I thought of Test so strongly as a class in Core.Test = class { ... that I didn't even consider that it might not appear because it's a property. In other words, I think that defId: 0 definitely makes sense to include.

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.

Results look good -- but I would like to know what effect replacing an assert with a skip actually has.

const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
const cls = find(filteredDeclarations, isClassLike);
return cls && getSignatureDefinition(cls.members, /*selectConstructors*/ true);
Copy link
Member

Choose a reason for hiding this comment

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

What is the difference in behaviour? The baselines for goToDefinitionExpandoClass2 show that the constructor is found when present, so what are we skipping here?

@armanio123 armanio123 self-assigned this Apr 15, 2024
@gabritto gabritto merged commit b1d821a into microsoft:main Apr 19, 2024
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants