From 03b036b63096a4aad5a7f82408c1a4f00a38c2a0 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 11 Dec 2017 15:56:31 -0800 Subject: [PATCH 1/2] Revert "Loosen restrictions on jsdoc completion locations" This reverts commit 612616a1058d7aa9fc181126f83041549bfbe295. --- src/services/jsDoc.ts | 68 ++++++++++++------- .../fourslash/docCommentTemplateEmptyFile.ts | 2 +- ...ommentTemplateInsideFunctionDeclaration.ts | 10 +-- .../fourslash/docCommentTemplateJSXText.ts | 12 ---- ...ocCommentTemplateNamespacesAndModules02.ts | 4 +- .../fourslash/docCommentTemplateRegex.ts | 8 +-- 6 files changed, 53 insertions(+), 51 deletions(-) delete mode 100644 tests/cases/fourslash/docCommentTemplateJSXText.ts diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 79b08780226f1..1e312caaf5da1 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -1,6 +1,5 @@ /* @internal */ namespace ts.JsDoc { - const singleLineTemplate = { newText: "/** */", caretOffset: 3 }; const jsDocTagNames = [ "augments", "author", @@ -197,9 +196,15 @@ namespace ts.JsDoc { /** * Checks if position points to a valid position to add JSDoc comments, and if so, * returns the appropriate template. Otherwise returns an empty string. - * Invalid positions are - * - within comments, strings (including template literals and regex), and JSXText - * - within a token + * Valid positions are + * - outside of comments, statements, and expressions, and + * - preceding a: + * - function/constructor/method declaration + * - class declarations + * - variable statements + * - namespace declarations + * - interface declarations + * - method signatures * * Hosts should ideally check that: * - The line is all whitespace up to 'position' before performing the insertion. @@ -225,19 +230,17 @@ namespace ts.JsDoc { const commentOwnerInfo = getCommentOwnerInfo(tokenAtPos); if (!commentOwnerInfo) { - // if climbing the tree did not find a declaration with parameters, complete to a single line comment - return singleLineTemplate; + return undefined; } const { commentOwner, parameters } = commentOwnerInfo; - - if (commentOwner.kind === SyntaxKind.JsxText) { + if (commentOwner.getStart() < position) { return undefined; } - if (commentOwner.getStart() < position || parameters.length === 0) { - // if climbing the tree found a declaration with parameters but the request was made inside it - // or if there are no parameters, complete to a single line comment - return singleLineTemplate; + 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 posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); @@ -247,11 +250,19 @@ namespace ts.JsDoc { const indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, () => " "); const isJavaScriptFile = hasJavaScriptFileExtension(sourceFile.fileName); - const docParams = parameters.map(({name}, i) => { - const nameText = isIdentifier(name) ? name.text : `param${i}`; - const type = isJavaScriptFile ? "{any} " : ""; - return `${indentationStr} * @param ${type}${nameText}${newLine}`; - }).join(""); + let docParams = ""; + for (let i = 0; i < parameters.length; i++) { + const currentName = parameters[i].name; + const paramName = currentName.kind === SyntaxKind.Identifier ? + (currentName).escapedText : + "param" + i; + if (isJavaScriptFile) { + docParams += `${indentationStr} * @param {any} ${paramName}${newLine}`; + } + else { + docParams += `${indentationStr} * @param ${paramName}${newLine}`; + } + } // A doc comment consists of the following // * The opening comment line @@ -273,7 +284,7 @@ namespace ts.JsDoc { interface CommentOwnerInfo { readonly commentOwner: Node; - readonly parameters: ReadonlyArray; + readonly parameters?: ReadonlyArray; } function getCommentOwnerInfo(tokenAtPos: Node): CommentOwnerInfo | undefined { for (let commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { @@ -285,18 +296,32 @@ namespace ts.JsDoc { 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.VariableStatement: { const varStatement = commentOwner; const varDeclarations = varStatement.declarationList.declarations; const parameters = varDeclarations.length === 1 && varDeclarations[0].initializer ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer) : undefined; - return parameters ? { commentOwner, parameters } : 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) === ts.SpecialPropertyAssignmentKind.None) { @@ -305,11 +330,6 @@ namespace ts.JsDoc { const parameters = isFunctionLike(be.right) ? be.right.parameters : emptyArray; return { commentOwner, parameters }; } - - case SyntaxKind.JsxText: { - const parameters: ReadonlyArray = emptyArray; - return { commentOwner, parameters }; - } } } } diff --git a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts index 064306e3fbd92..f04653dc32838 100644 --- a/tests/cases/fourslash/docCommentTemplateEmptyFile.ts +++ b/tests/cases/fourslash/docCommentTemplateEmptyFile.ts @@ -3,4 +3,4 @@ // @Filename: emptyFile.ts /////*0*/ -verify.docCommentTemplateAt("0", 3, "/** */"); +verify.noDocCommentTemplateAt("0"); diff --git a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts index 67a11a27133e9..e0ebc00dc392a 100644 --- a/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts +++ b/tests/cases/fourslash/docCommentTemplateInsideFunctionDeclaration.ts @@ -3,10 +3,6 @@ // @Filename: functionDecl.ts ////f/*0*/unction /*1*/foo/*2*/(/*3*/) /*4*/{ /*5*/} -verify.noDocCommentTemplateAt("0"); - -verify.docCommentTemplateAt("1", 3, "/** */"); -verify.docCommentTemplateAt("2", 3, "/** */"); -verify.docCommentTemplateAt("3", 3, "/** */"); -verify.docCommentTemplateAt("4", 3, "/** */"); -verify.docCommentTemplateAt("5", 3, "/** */"); +for (const marker of test.markers()) { + verify.noDocCommentTemplateAt(marker); +} diff --git a/tests/cases/fourslash/docCommentTemplateJSXText.ts b/tests/cases/fourslash/docCommentTemplateJSXText.ts deleted file mode 100644 index 845f969f4e3bf..0000000000000 --- a/tests/cases/fourslash/docCommentTemplateJSXText.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -//@Filename: file.tsx -//// -//// var x =
-//// /*0*/hello/*1*/ -//// /*2*/goodbye/*3*/ -////
; - -for (const marker in test.markers()) { - verify.noDocCommentTemplateAt(marker); -} \ No newline at end of file diff --git a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts index 3beb9368661aa..787e9f04481d1 100644 --- a/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts +++ b/tests/cases/fourslash/docCommentTemplateNamespacesAndModules02.ts @@ -9,6 +9,6 @@ verify.docCommentTemplateAt("top", /*indentation*/ 3, "/** */"); -verify.docCommentTemplateAt("n2", 3, "/** */"); +verify.noDocCommentTemplateAt("n2"); -verify.docCommentTemplateAt("n3", 3, "/** */"); +verify.noDocCommentTemplateAt("n3"); diff --git a/tests/cases/fourslash/docCommentTemplateRegex.ts b/tests/cases/fourslash/docCommentTemplateRegex.ts index c1368190ca248..685c1ca5aef79 100644 --- a/tests/cases/fourslash/docCommentTemplateRegex.ts +++ b/tests/cases/fourslash/docCommentTemplateRegex.ts @@ -3,8 +3,6 @@ // @Filename: regex.ts ////var regex = /*0*///*1*/asdf/*2*/ /*3*///*4*/; -verify.docCommentTemplateAt("0", 3, "/** */"); -verify.noDocCommentTemplateAt("1"); -verify.noDocCommentTemplateAt("2"); -verify.noDocCommentTemplateAt("3"); -verify.docCommentTemplateAt("4", 3, "/** */"); \ No newline at end of file +for (const marker of test.markers()) { + verify.noDocCommentTemplateAt(marker); +} From 97a573984f808a89deb7cc20910f77c7398bce90 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 11 Dec 2017 16:15:32 -0800 Subject: [PATCH 2/2] Add type alias declarations to inclusion list docs --- src/services/jsDoc.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 1e312caaf5da1..33d84763d440e 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -205,6 +205,7 @@ namespace ts.JsDoc { * - namespace declarations * - interface declarations * - method signatures + * - type alias declarations * * Hosts should ideally check that: * - The line is all whitespace up to 'position' before performing the insertion.