From 6cd27a32177dea4fbba78a09e8a9e9b7709170a2 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 25 Jun 2018 11:40:45 -0700 Subject: [PATCH] Support doc comment template at function expression (#25050) --- src/services/jsDoc.ts | 18 +++++++++++------- .../docCommentTemplateClassDeclMethods01.ts | 5 +++-- .../docCommentTemplateFunctionExpression.ts | 12 ++++++++++++ ...docCommentTemplateObjectLiteralMethods01.ts | 5 ++--- .../cases/fourslash/docCommentTemplateRegex.ts | 1 - 5 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 tests/cases/fourslash/docCommentTemplateFunctionExpression.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index bfd371d1154..136ac7b09eb 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -263,11 +263,7 @@ namespace ts.JsDoc { return { newText: singleLineResult, caretOffset: 3 }; } - const posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); - const lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; - - // replace non-whitespace characters in prefix with spaces. - const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, () => " "); + const indentationStr = getIndentationStringAtPosition(sourceFile, position); // A doc comment consists of the following // * The opening comment line @@ -276,8 +272,7 @@ namespace ts.JsDoc { // * 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 preamble = "/**" + newLine + indentationStr + " * "; const result = preamble + newLine + parameterDocComments(parameters, hasJavaScriptFileExtension(sourceFile.fileName), indentationStr, newLine) + @@ -287,6 +282,14 @@ namespace ts.JsDoc { return { newText: result, caretOffset: preamble.length }; } + function getIndentationStringAtPosition(sourceFile: SourceFile, position: number): string { + const { text } = sourceFile; + const lineStart = getLineStartPositionForPosition(position, sourceFile); + let pos = lineStart; + for (; pos <= position && isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++); + return text.slice(lineStart, pos); + } + function parameterDocComments(parameters: ReadonlyArray, isJavaScriptFile: boolean, indentationStr: string, newLine: string): string { return parameters.map(({ name, dotDotDotToken }, i) => { const paramName = name.kind === SyntaxKind.Identifier ? name.text : "param" + i; @@ -303,6 +306,7 @@ namespace ts.JsDoc { 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: diff --git a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts index 2e729243497..6acd0ad314e 100644 --- a/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateClassDeclMethods01.ts @@ -9,7 +9,7 @@ const multiLineOffset = 12; //// foo(); //// /*2*/foo(a); //// /*3*/foo(a, b); -//// /*4*/ foo(a, {x: string}, [c]); +//// /*4*/foo(a, {x: string}, [c]); //// /*5*/foo(a?, b?, ...args) { //// } ////} @@ -43,7 +43,8 @@ verify.docCommentTemplateAt("4", multiLineOffset, * @param a * @param param1 * @param param2 - */`); + */ + `); verify.docCommentTemplateAt("5", multiLineOffset, `/** diff --git a/tests/cases/fourslash/docCommentTemplateFunctionExpression.ts b/tests/cases/fourslash/docCommentTemplateFunctionExpression.ts new file mode 100644 index 00000000000..eaf75d064fc --- /dev/null +++ b/tests/cases/fourslash/docCommentTemplateFunctionExpression.ts @@ -0,0 +1,12 @@ +/// + +/////*above*/ +////const x = /*next*/ function f(p) {} + +for (const marker of test.markerNames()) { + verify.docCommentTemplateAt(marker, 8, +`/** + * + * @param p + */`); +} diff --git a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts index 5121957a718..029d685e3a0 100644 --- a/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts +++ b/tests/cases/fourslash/docCommentTemplateObjectLiteralMethods01.ts @@ -12,8 +12,7 @@ const multiLineOffset = 12; //// [1 + 2 + 3 + Math.rand()](x: number, y: string, z = true) { } ////} -verify.docCommentTemplateAt("0", singleLineOffset, - "/** */"); +verify.docCommentTemplateAt("0", singleLineOffset, "/** */"); verify.docCommentTemplateAt("1", multiLineOffset, `/** @@ -21,4 +20,4 @@ verify.docCommentTemplateAt("1", multiLineOffset, * @param x * @param y * @param z - */`); \ No newline at end of file + */`); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index 685c1ca5aef..108ecc25430 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -1,6 +1,5 @@ /// -// @Filename: regex.ts ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; for (const marker of test.markers()) {