mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
feat(14248): add returns tag to JSDoc template (#42068)
This commit is contained in:
parent
0d284e6c26
commit
042bf4eb15
@ -269,34 +269,35 @@ namespace ts.JsDoc {
|
||||
if (!commentOwnerInfo) {
|
||||
return undefined;
|
||||
}
|
||||
const { commentOwner, parameters } = commentOwnerInfo;
|
||||
|
||||
const { commentOwner, parameters, hasReturn } = commentOwnerInfo;
|
||||
if (commentOwner.getStart(sourceFile) < position) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!parameters || parameters.length === 0) {
|
||||
// if there are no parameters, just complete to a single line JSDoc comment
|
||||
const singleLineResult = "/** */";
|
||||
return { newText: singleLineResult, caretOffset: 3 };
|
||||
}
|
||||
|
||||
const indentationStr = getIndentationStringAtPosition(sourceFile, position);
|
||||
const isJavaScriptFile = hasJSFileExtension(sourceFile.fileName);
|
||||
const tags =
|
||||
(parameters ? parameterDocComments(parameters || [], isJavaScriptFile, indentationStr, newLine) : "") +
|
||||
(hasReturn ? returnsDocComment(indentationStr, newLine) : "");
|
||||
|
||||
// A doc comment consists of the following
|
||||
// * The opening comment line
|
||||
// * the first line (without a param) for the object's untagged info (this is also where the caret ends up)
|
||||
// * the '@param'-tagged lines
|
||||
// * the '@returns'-tag
|
||||
// * TODO: other tags.
|
||||
// * the closing comment line
|
||||
// * if the caret was directly in front of the object, then we add an extra line and indentation.
|
||||
const preamble = "/**" + newLine + indentationStr + " * ";
|
||||
const result =
|
||||
preamble + newLine +
|
||||
parameterDocComments(parameters, hasJSFileExtension(sourceFile.fileName), indentationStr, newLine) +
|
||||
indentationStr + " */" +
|
||||
(tokenStart === position ? newLine + indentationStr : "");
|
||||
|
||||
return { newText: result, caretOffset: preamble.length };
|
||||
const openComment = "/**";
|
||||
const closeComment = " */";
|
||||
if (tags) {
|
||||
const preamble = openComment + newLine + indentationStr + " * ";
|
||||
const endLine = tokenStart === position ? newLine + indentationStr : "";
|
||||
const result = preamble + newLine + tags + indentationStr + closeComment + endLine;
|
||||
return { newText: result, caretOffset: preamble.length };
|
||||
}
|
||||
return { newText: openComment + closeComment, caretOffset: 3 };
|
||||
}
|
||||
|
||||
function getIndentationStringAtPosition(sourceFile: SourceFile, position: number): string {
|
||||
@ -315,9 +316,14 @@ namespace ts.JsDoc {
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function returnsDocComment(indentationStr: string, newLine: string) {
|
||||
return `${indentationStr} * @returns${newLine}`;
|
||||
}
|
||||
|
||||
interface CommentOwnerInfo {
|
||||
readonly commentOwner: Node;
|
||||
readonly parameters?: readonly ParameterDeclaration[];
|
||||
readonly hasReturn?: boolean;
|
||||
}
|
||||
function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined {
|
||||
return forEachAncestor(tokenAtPos, getCommentOwnerInfoWorker);
|
||||
@ -330,8 +336,8 @@ namespace ts.JsDoc {
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
const { parameters } = commentOwner as FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature;
|
||||
return { commentOwner, parameters };
|
||||
const host = commentOwner as ArrowFunction | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature;
|
||||
return { commentOwner, parameters: host.parameters, hasReturn: hasReturn(host) };
|
||||
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return getCommentOwnerInfoWorker((commentOwner as PropertyAssignment).initializer);
|
||||
@ -347,10 +353,12 @@ namespace ts.JsDoc {
|
||||
case SyntaxKind.VariableStatement: {
|
||||
const varStatement = <VariableStatement>commentOwner;
|
||||
const varDeclarations = varStatement.declarationList.declarations;
|
||||
const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer)
|
||||
const host = varDeclarations.length === 1 && varDeclarations[0].initializer
|
||||
? getRightHandSideOfAssignment(varDeclarations[0].initializer)
|
||||
: undefined;
|
||||
return { commentOwner, parameters };
|
||||
return host
|
||||
? { commentOwner, parameters: host.parameters, hasReturn: hasReturn(host) }
|
||||
: { commentOwner };
|
||||
}
|
||||
|
||||
case SyntaxKind.SourceFile:
|
||||
@ -369,26 +377,24 @@ namespace ts.JsDoc {
|
||||
if (getAssignmentDeclarationKind(be) === AssignmentDeclarationKind.None) {
|
||||
return "quit";
|
||||
}
|
||||
const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray;
|
||||
return { commentOwner, parameters };
|
||||
return isFunctionLike(be.right)
|
||||
? { commentOwner, parameters: be.right.parameters, hasReturn: hasReturn(be.right) }
|
||||
: { commentOwner };
|
||||
}
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
const init = (commentOwner as PropertyDeclaration).initializer;
|
||||
if (init && (isFunctionExpression(init) || isArrowFunction(init))) {
|
||||
return { commentOwner, parameters: init.parameters };
|
||||
return { commentOwner, parameters: init.parameters, hasReturn: hasReturn(init) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Digs into an an initializer or RHS operand of an assignment operation
|
||||
* to get the parameters of an apt signature corresponding to a
|
||||
* function expression or a class expression.
|
||||
*
|
||||
* @param rightHandSide the expression which may contain an appropriate set of parameters
|
||||
* @returns the parameters of a signature found on the RHS if one exists; otherwise 'emptyArray'.
|
||||
*/
|
||||
function getParametersFromRightHandSideOfAssignment(rightHandSide: Expression): readonly ParameterDeclaration[] {
|
||||
function hasReturn(node: Node) {
|
||||
return isArrowFunction(node) && isExpression(node.body)
|
||||
|| isFunctionLikeDeclaration(node) && node.body && isBlock(node.body) && !!forEachReturnStatement(node.body, n => n);
|
||||
}
|
||||
|
||||
function getRightHandSideOfAssignment(rightHandSide: Expression): FunctionExpression | ArrowFunction | ConstructorDeclaration | undefined {
|
||||
while (rightHandSide.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
rightHandSide = (<ParenthesizedExpression>rightHandSide).expression;
|
||||
}
|
||||
@ -396,13 +402,9 @@ namespace ts.JsDoc {
|
||||
switch (rightHandSide.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return (<FunctionExpression>rightHandSide).parameters;
|
||||
case SyntaxKind.ClassExpression: {
|
||||
const ctr = find((rightHandSide as ClassExpression).members, isConstructorDeclaration);
|
||||
return ctr ? ctr.parameters : emptyArray;
|
||||
}
|
||||
return (<FunctionExpression>rightHandSide);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return find((rightHandSide as ClassExpression).members, isConstructorDeclaration);
|
||||
}
|
||||
|
||||
return emptyArray;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const singleLineOffset = 3;
|
||||
const multiLineOffset = 12;
|
||||
|
||||
////class C {
|
||||
@ -12,8 +11,11 @@ const multiLineOffset = 12;
|
||||
//// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { }
|
||||
////}
|
||||
|
||||
verify.docCommentTemplateAt("0", singleLineOffset,
|
||||
"/** */");
|
||||
verify.docCommentTemplateAt("0", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("1", multiLineOffset,
|
||||
`/**
|
||||
|
||||
@ -23,17 +23,18 @@ verify.docCommentTemplateAt("0", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @param p0
|
||||
* @returns
|
||||
*/`);
|
||||
verify.docCommentTemplateAt("1", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @param p1
|
||||
* @returns
|
||||
*/`);
|
||||
verify.docCommentTemplateAt("2", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @param p2
|
||||
* @param p3
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
const singleLineOffset = 3;
|
||||
const multiLineOffset = 12;
|
||||
|
||||
////var x = {
|
||||
@ -19,7 +18,11 @@ const multiLineOffset = 12;
|
||||
//// m2: (a: string, b: string) => {}
|
||||
////}
|
||||
|
||||
verify.docCommentTemplateAt("0", singleLineOffset, "/** */");
|
||||
verify.docCommentTemplateAt("0", multiLineOffset,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("1", multiLineOffset,
|
||||
`/**
|
||||
|
||||
56
tests/cases/fourslash/docCommentTemplateReturnsTag.ts
Normal file
56
tests/cases/fourslash/docCommentTemplateReturnsTag.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*0*/
|
||||
////function f1() {}
|
||||
|
||||
/////*1*/
|
||||
////function f2() {
|
||||
//// return 1;
|
||||
////}
|
||||
|
||||
/////*2*/
|
||||
////const f3 = () => 1;
|
||||
|
||||
/////*3*/
|
||||
////const f3 = () => {
|
||||
//// return 1;
|
||||
////}
|
||||
|
||||
////class Foo {
|
||||
//// /*4*/
|
||||
//// m1() {}
|
||||
////
|
||||
//// /*5*/
|
||||
//// m2() {
|
||||
//// return 1;
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.docCommentTemplateAt("0", 3, "/** */");
|
||||
|
||||
verify.docCommentTemplateAt("1", 8,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("2", 8,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("3", 8,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("4", 3, "/** */");
|
||||
|
||||
|
||||
verify.docCommentTemplateAt("5", 12,
|
||||
`/**
|
||||
*
|
||||
* @returns
|
||||
*/`);
|
||||
@ -39,6 +39,7 @@ verify.docCommentTemplateAt("e", /*newTextOffset*/ 8,
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("f", /*newTextOffset*/ 8,
|
||||
|
||||
@ -33,6 +33,7 @@ verify.docCommentTemplateAt("a", /*newTextOffset*/ 8,
|
||||
`/**
|
||||
*
|
||||
* @param x
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("b", /*newTextOffset*/ 8,
|
||||
@ -41,12 +42,14 @@ verify.docCommentTemplateAt("b", /*newTextOffset*/ 8,
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("c", /*newTextOffset*/ 8,
|
||||
`/**
|
||||
*
|
||||
* @param x
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("d", /*newTextOffset*/ 3,
|
||||
@ -56,6 +59,7 @@ verify.docCommentTemplateAt("e", /*newTextOffset*/ 8,
|
||||
`/**
|
||||
*
|
||||
* @param param0
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.docCommentTemplateAt("f", /*newTextOffset*/ 3,
|
||||
|
||||
@ -10,6 +10,7 @@ verify.docCommentTemplateAt("", /*newTextOffset*/ 8,
|
||||
`/**
|
||||
*
|
||||
* @param p
|
||||
* @returns
|
||||
*/`);
|
||||
|
||||
verify.noDocCommentTemplateAt("1");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user