Fixed a symbol display crash on expando members write locations (#55478)

This commit is contained in:
Mateusz Burzyński 2025-04-01 22:40:59 +02:00 committed by GitHub
parent 7b26d2eba5
commit 89c572ca0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import {
AccessorDeclaration,
addRange,
arrayFrom,
BinaryExpression,
@ -16,7 +17,6 @@ import {
first,
firstDefined,
forEach,
GetAccessorDeclaration,
getCombinedLocalAndExportSymbolFlags,
getDeclarationOfKind,
getExternalModuleImportEqualsDeclarationExpression,
@ -83,7 +83,6 @@ import {
ScriptElementKind,
ScriptElementKindModifier,
SemanticMeaning,
SetAccessorDeclaration,
Signature,
SignatureDeclaration,
SignatureFlags,
@ -276,7 +275,14 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker: Type
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) {
// If symbol is accessor, they are allowed only if location is at declaration identifier of the accessor
if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
const declaration = find(symbol.declarations as ((GetAccessorDeclaration | SetAccessorDeclaration | PropertyDeclaration)[]), declaration => declaration.name === location);
const declaration = find(
symbol.declarations as (AccessorDeclaration | PropertyDeclaration | PropertyAccessExpression)[],
(declaration): declaration is AccessorDeclaration | PropertyDeclaration =>
declaration.name === location
// an expando member could have been added to an object with a set accessor
// we need to ignore such write location as it shouldn't be displayed as `(setter)` anyway
&& declaration.kind !== SyntaxKind.PropertyAccessExpression,
);
if (declaration) {
switch (declaration.kind) {
case SyntaxKind.GetAccessor:

View File

@ -0,0 +1,16 @@
/// <reference path="fourslash.ts" />
// @strict: true
// @checkJs: true
// @filename: index.js
//// const x = {};
////
//// Object.defineProperty(x, "foo", {
//// /** @param {number} v */
//// set(v) {},
//// });
////
//// x.foo/**/ = 1;
verify.quickInfoAt("", "(property) x.foo: number");

View File

@ -0,0 +1,19 @@
/// <reference path="fourslash.ts" />
// @strict: true
// @checkJs: true
// @filename: index.js
//// const obj = {};
//// let val = 10;
//// Object.defineProperty(obj, "a", {
//// configurable: true,
//// enumerable: true,
//// set(v) {
//// val = v;
//// },
//// });
////
//// obj.a/**/ = 100;
verify.quickInfoAt("", "(property) obj.a: any");