mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Handle PropertyAssignment in getCommentOwnerInfo (#25911)
This commit is contained in:
parent
fd2eb4918d
commit
e4d4b0ae4b
@ -142,6 +142,16 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function forEachAncestor<T>(node: Node, callback: (n: Node) => T | undefined | "quit"): T | undefined {
|
||||
while (true) {
|
||||
const res = callback(node);
|
||||
if (res === "quit") return undefined;
|
||||
if (res !== undefined) return res;
|
||||
if (isSourceFile(node)) return undefined;
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `callback` for each entry in the map, returning the first truthy result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
|
||||
@ -338,50 +338,54 @@ namespace ts.JsDoc {
|
||||
readonly parameters?: ReadonlyArray<ParameterDeclaration>;
|
||||
}
|
||||
function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined {
|
||||
for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) {
|
||||
switch (commentOwner.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.MethodSignature:
|
||||
const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature;
|
||||
return { commentOwner, parameters };
|
||||
return forEachAncestor(tokenAtPos, getCommentOwnerInfoWorker);
|
||||
}
|
||||
function getCommentOwnerInfoWorker(commentOwner: Node): CommentOwnerInfo | undefined | "quit" {
|
||||
switch (commentOwner.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.MethodSignature:
|
||||
const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature;
|
||||
return { commentOwner, parameters };
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return { commentOwner };
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return getCommentOwnerInfoWorker((commentOwner as PropertyAssignment).initializer);
|
||||
|
||||
case SyntaxKind.VariableStatement: {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer!)
|
||||
: undefined;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// If in walking up the tree, we hit a a nested namespace declaration,
|
||||
// then we must be somewhere within a dotted namespace name; however we don't
|
||||
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
|
||||
return commentOwner.parent.kind === SyntaxKind.ModuleDeclaration ? undefined : { commentOwner };
|
||||
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const be = commentOwner as BinaryExpression;
|
||||
if (getSpecialPropertyAssignmentKind(be) === SpecialPropertyAssignmentKind.None) {
|
||||
return undefined;
|
||||
}
|
||||
const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray;
|
||||
return { commentOwner, parameters };
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.EnumMember:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return { commentOwner };
|
||||
|
||||
case SyntaxKind.VariableStatement: {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer!)
|
||||
: undefined;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
return "quit";
|
||||
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
// If in walking up the tree, we hit a a nested namespace declaration,
|
||||
// then we must be somewhere within a dotted namespace name; however we don't
|
||||
// want to give back a JSDoc template for the 'b' or 'c' in 'namespace a.b.c { }'.
|
||||
return commentOwner.parent.kind === SyntaxKind.ModuleDeclaration ? undefined : { commentOwner };
|
||||
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const be = commentOwner as BinaryExpression;
|
||||
if (getSpecialPropertyAssignmentKind(be) === SpecialPropertyAssignmentKind.None) {
|
||||
return "quit";
|
||||
}
|
||||
const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray;
|
||||
return { commentOwner, parameters };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ const multiLineOffset = 12;
|
||||
//// }
|
||||
//// /*1*/
|
||||
//// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { }
|
||||
//// /*2*/
|
||||
//// m: function(a) {}
|
||||
////}
|
||||
|
||||
verify.docCommentTemplateAt("0", singleLineOffset, "/** */");
|
||||
@ -21,3 +23,9 @@ verify.docCommentTemplateAt("1", multiLineOffset,
|
||||
* @param y
|
||||
* @param z
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("2", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @param a
|
||||
*/`);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user