mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Constructor function methods:Add two missing tag lookups (#47742)
1. During name resolution, `@param` and `@return` tags should walk up through the jsdoc comment and then jump to the host function. Previously they did not, which would cause them to not resolve type parameters bound in the scope of a host that was not a sibling of the comment. The example from #46618 is a prototype method: ```js /** * @template {T} * @param {T} t */ C.prototype.m = function (t) { } ``` 2. During name resolution, prototype methods are supposed to resolve types both from the host function's location and from the containing class' location. The containing class lookup happens in a separate call to `resolveName`. Previously, the code that finds the containing class only worked for the above style of comment, which is on the outer ExpressionStatement, but not for the below style, which is on the function expression itself: ```js C.prototype.m = /** * @template {T} * @param {T} t */ function (t) { } ```
This commit is contained in:
committed by
GitHub
parent
2cf5afd49e
commit
d5c3015516
@@ -1833,6 +1833,8 @@ namespace ts {
|
||||
// type parameters are visible in parameter list, return type and type parameter list
|
||||
? lastLocation === (location as FunctionLikeDeclaration).type ||
|
||||
lastLocation.kind === SyntaxKind.Parameter ||
|
||||
lastLocation.kind === SyntaxKind.JSDocParameterTag ||
|
||||
lastLocation.kind === SyntaxKind.JSDocReturnTag ||
|
||||
lastLocation.kind === SyntaxKind.TypeParameter
|
||||
// local types not visible outside the function body
|
||||
: false;
|
||||
@@ -2101,8 +2103,8 @@ namespace ts {
|
||||
lastSelfReferenceLocation = location;
|
||||
}
|
||||
lastLocation = location;
|
||||
location = isJSDocTemplateTag(location) ?
|
||||
getEffectiveContainerForJSDocTemplateTag(location) || location.parent :
|
||||
location = isJSDocTemplateTag(location) ? getEffectiveContainerForJSDocTemplateTag(location) || location.parent :
|
||||
isJSDocParameterTag(location) || isJSDocReturnTag(location) ? getHostSignatureFromJSDoc(location) || location.parent :
|
||||
location.parent;
|
||||
}
|
||||
|
||||
@@ -3374,16 +3376,20 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
const host = getJSDocHost(node);
|
||||
if (host &&
|
||||
isExpressionStatement(host) &&
|
||||
isBinaryExpression(host.expression) &&
|
||||
getAssignmentDeclarationKind(host.expression) === AssignmentDeclarationKind.PrototypeProperty) {
|
||||
// X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
|
||||
if (host && isExpressionStatement(host) && isPrototypePropertyAssignment(host.expression)) {
|
||||
// /** @param {K} p */ X.prototype.m = function () { } <-- look for K on X's declaration
|
||||
const symbol = getSymbolOfNode(host.expression.left);
|
||||
if (symbol) {
|
||||
return getDeclarationOfJSPrototypeContainer(symbol);
|
||||
}
|
||||
}
|
||||
if (host && isFunctionExpression(host) && isPrototypePropertyAssignment(host.parent) && isExpressionStatement(host.parent.parent)) {
|
||||
// X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
|
||||
const symbol = getSymbolOfNode(host.parent.left);
|
||||
if (symbol) {
|
||||
return getDeclarationOfJSPrototypeContainer(symbol);
|
||||
}
|
||||
}
|
||||
if (host && (isObjectLiteralMethod(host) || isPropertyAssignment(host)) &&
|
||||
isBinaryExpression(host.parent.parent) &&
|
||||
getAssignmentDeclarationKind(host.parent.parent) === AssignmentDeclarationKind.Prototype) {
|
||||
|
||||
@@ -2510,7 +2510,7 @@ namespace ts {
|
||||
return expr.right;
|
||||
}
|
||||
|
||||
export function isPrototypePropertyAssignment(node: Node): boolean {
|
||||
export function isPrototypePropertyAssignment(node: Node): node is BinaryExpression {
|
||||
return isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.PrototypeProperty;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user