@@ -39156,16 +39156,6 @@ namespace ts {
39156
39156
return node.parent.kind === SyntaxKind.ExpressionWithTypeArguments;
39157
39157
}
39158
39158
39159
- function getJSDocEntryNameReference(node: Identifier | PrivateIdentifier | PropertyAccessExpression | QualifiedName): JSDocNameReference | undefined {
39160
- while (node.parent.kind === SyntaxKind.QualifiedName) {
39161
- node = node.parent as QualifiedName;
39162
- }
39163
- while (node.parent.kind === SyntaxKind.PropertyAccessExpression) {
39164
- node = node.parent as PropertyAccessExpression;
39165
- }
39166
- return isJSDocNameReference(node.parent) ? node.parent : undefined;
39167
- }
39168
-
39169
39159
function forEachEnclosingClass<T>(node: Node, callback: (node: Node) => T | undefined): T | undefined {
39170
39160
let result: T | undefined;
39171
39161
@@ -39240,7 +39230,7 @@ namespace ts {
39240
39230
return undefined;
39241
39231
}
39242
39232
39243
- function getSymbolOfNameOrPropertyAccessExpression(name: EntityName | PrivateIdentifier | PropertyAccessExpression): Symbol | undefined {
39233
+ function getSymbolOfNameOrPropertyAccessExpression(name: EntityName | PrivateIdentifier | PropertyAccessExpression | JSDocMemberName ): Symbol | undefined {
39244
39234
if (isDeclarationName(name)) {
39245
39235
return getSymbolOfNode(name.parent);
39246
39236
}
@@ -39249,7 +39239,7 @@ namespace ts {
39249
39239
name.parent.kind === SyntaxKind.PropertyAccessExpression &&
39250
39240
name.parent === (name.parent.parent as BinaryExpression).left) {
39251
39241
// Check if this is a special property assignment
39252
- if (!isPrivateIdentifier(name)) {
39242
+ if (!isPrivateIdentifier(name) && !isJSDocMemberName(name) ) {
39253
39243
const specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(name);
39254
39244
if (specialPropertyAssignmentSymbol) {
39255
39245
return specialPropertyAssignmentSymbol;
@@ -39265,14 +39255,14 @@ namespace ts {
39265
39255
return success;
39266
39256
}
39267
39257
}
39268
- else if (!isPropertyAccessExpression(name) && !isPrivateIdentifier (name) && isInRightSideOfImportOrExportAssignment(name)) {
39258
+ else if (isEntityName (name) && isInRightSideOfImportOrExportAssignment(name)) {
39269
39259
// Since we already checked for ExportAssignment, this really could only be an Import
39270
39260
const importEqualsDeclaration = getAncestor(name, SyntaxKind.ImportEqualsDeclaration);
39271
39261
Debug.assert(importEqualsDeclaration !== undefined);
39272
39262
return getSymbolOfPartOfRightHandSideOfImportEquals(name, /*dontResolveAlias*/ true);
39273
39263
}
39274
39264
39275
- if (!isPropertyAccessExpression(name) && !isPrivateIdentifier (name)) {
39265
+ if (isEntityName (name)) {
39276
39266
const possibleImportNode = isImportTypeQualifierPart(name);
39277
39267
if (possibleImportNode) {
39278
39268
getTypeFromTypeNode(possibleImportNode);
@@ -39281,8 +39271,8 @@ namespace ts {
39281
39271
}
39282
39272
}
39283
39273
39284
- while (isRightSideOfQualifiedNameOrPropertyAccess (name)) {
39285
- name = name.parent as QualifiedName | PropertyAccessEntityNameExpression;
39274
+ while (isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName (name)) {
39275
+ name = name.parent as QualifiedName | PropertyAccessEntityNameExpression | JSDocMemberName ;
39286
39276
}
39287
39277
39288
39278
if (isHeritageClauseElementIdentifier(name)) {
@@ -39323,12 +39313,14 @@ namespace ts {
39323
39313
return undefined;
39324
39314
}
39325
39315
39316
+ const isJSDoc = findAncestor(name, or(isJSDocLink, isJSDocNameReference, isJSDocMemberName));
39317
+ const meaning = isJSDoc ? SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value : SymbolFlags.Value;
39326
39318
if (name.kind === SyntaxKind.Identifier) {
39327
39319
if (isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) {
39328
39320
const symbol = getIntrinsicTagSymbol(name.parent as JsxOpeningLikeElement);
39329
39321
return symbol === unknownSymbol ? undefined : symbol;
39330
39322
}
39331
- return resolveEntityName(name, SymbolFlags.Value , /*ignoreErrors*/ false, /*dontResolveAlias*/ true );
39323
+ return resolveEntityName(name, meaning , /*ignoreErrors*/ false, /*dontResolveAlias*/ !isJSDoc, getHostSignatureFromJSDoc(name) );
39332
39324
}
39333
39325
else if (name.kind === SyntaxKind.PropertyAccessExpression || name.kind === SyntaxKind.QualifiedName) {
39334
39326
const links = getNodeLinks(name);
@@ -39342,47 +39334,53 @@ namespace ts {
39342
39334
else {
39343
39335
checkQualifiedName(name, CheckMode.Normal);
39344
39336
}
39337
+ if (!links.resolvedSymbol && isJSDoc && isQualifiedName(name)) {
39338
+ return resolveJSDocMemberName(name);
39339
+ }
39345
39340
return links.resolvedSymbol;
39346
39341
}
39342
+ else if (isJSDocMemberName(name)) {
39343
+ return resolveJSDocMemberName(name);
39344
+ }
39347
39345
}
39348
39346
else if (isTypeReferenceIdentifier(name as EntityName)) {
39349
39347
const meaning = name.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace;
39350
39348
return resolveEntityName(name as EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
39351
39349
}
39352
-
39353
- const jsdocReference = getJSDocEntryNameReference(name);
39354
- if (jsdocReference || isJSDocLink(name.parent)) {
39355
- const meaning = SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value;
39356
- const symbol = resolveEntityName(name as EntityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ false, getHostSignatureFromJSDoc(name));
39357
- if (symbol) {
39358
- return symbol;
39359
- }
39360
- else if (isQualifiedName(name) && isIdentifier(name.left)) {
39361
- // resolve C.m as a static member first
39362
- const links = getNodeLinks(name);
39363
- if (links.resolvedSymbol) {
39364
- return links.resolvedSymbol;
39365
- }
39366
- checkQualifiedName(name, CheckMode.Normal);
39367
- if (links.resolvedSymbol) {
39368
- return links.resolvedSymbol;
39369
- }
39370
-
39371
- // then resolve it as an instance member
39372
- const s = resolveEntityName(name.left, meaning, /*ignoreErrors*/ false);
39373
- if (s) {
39374
- const t = getDeclaredTypeOfSymbol(s);
39375
- return getPropertyOfType(t, name.right.escapedText);
39376
- }
39377
- }
39378
- }
39379
39350
if (name.parent.kind === SyntaxKind.TypePredicate) {
39380
39351
return resolveEntityName(name as Identifier, /*meaning*/ SymbolFlags.FunctionScopedVariable);
39381
39352
}
39382
39353
39383
39354
return undefined;
39384
39355
}
39385
39356
39357
+ /**
39358
+ * Recursively resolve entity names and jsdoc instance references:
39359
+ * 1. K#m as K.prototype.m for a class (or other value) K
39360
+ * 2. K.m as K.prototype.m
39361
+ * 3. I.m as I.m for a type I, or any other I.m that fails to resolve in (1) or (2)
39362
+ */
39363
+ function resolveJSDocMemberName(name: EntityName | JSDocMemberName): Symbol | undefined {
39364
+ if (isEntityName(name)) {
39365
+ const symbol = resolveEntityName(
39366
+ name,
39367
+ SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value,
39368
+ /*ignoreErrors*/ false,
39369
+ /*dontResolveAlias*/ true,
39370
+ getHostSignatureFromJSDoc(name));
39371
+ if (symbol || isIdentifier(name)) {
39372
+ // can't recur on identifier, so just return when it's undefined
39373
+ return symbol;
39374
+ }
39375
+ }
39376
+ const left = resolveJSDocMemberName(name.left);
39377
+ if (left) {
39378
+ const proto = left.flags & SymbolFlags.Value && getPropertyOfType(getTypeOfSymbol(left), "prototype" as __String);
39379
+ const t = proto ? getTypeOfSymbol(proto) : getDeclaredTypeOfSymbol(left);
39380
+ return getPropertyOfType(t, name.right.escapedText);
39381
+ }
39382
+ }
39383
+
39386
39384
function getSymbolAtLocation(node: Node, ignoreErrors?: boolean): Symbol | undefined {
39387
39385
if (node.kind === SyntaxKind.SourceFile) {
39388
39386
return isExternalModule(node as SourceFile) ? getMergedSymbol(node.symbol) : undefined;
0 commit comments