diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 69bdce21b48c9..570d50f848532 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6400,7 +6400,7 @@ namespace ts { switch (token()) { case SyntaxKind.AtToken: if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { - removeTrailingNewlines(comments); + removeTrailingWhitespace(comments); addTag(parseTag(indent)); // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning @@ -6460,7 +6460,7 @@ namespace ts { nextJSDocToken(); } removeLeadingNewlines(comments); - removeTrailingNewlines(comments); + removeTrailingWhitespace(comments); return createJSDocComment(); }); @@ -6470,8 +6470,8 @@ namespace ts { } } - function removeTrailingNewlines(comments: string[]) { - while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) { + function removeTrailingWhitespace(comments: string[]) { + while (comments.length && comments[comments.length - 1].trim() === "") { comments.pop(); } } @@ -6632,7 +6632,7 @@ namespace ts { } removeLeadingNewlines(comments); - removeTrailingNewlines(comments); + removeTrailingWhitespace(comments); return comments.length === 0 ? undefined : comments.join(""); } diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.asteriskAfterPreamble.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.asteriskAfterPreamble.json index 03baac016aafa..393a0c33602b2 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.asteriskAfterPreamble.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.asteriskAfterPreamble.json @@ -2,5 +2,5 @@ "kind": "JSDocComment", "pos": 0, "end": 23, - "comment": "* @type {number} " + "comment": "* @type {number}" } \ No newline at end of file diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.threeAsterisks.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.threeAsterisks.json index a89a36050aa3d..9963937db5c7b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.threeAsterisks.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.threeAsterisks.json @@ -2,5 +2,5 @@ "kind": "JSDocComment", "pos": 0, "end": 7, - "comment": "* " + "comment": "*" } \ No newline at end of file diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index bba86fea29914..2b59b35bd146b 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -208,8 +208,8 @@ verify.quickInfoAt("1q", "function simple(): void"); verify.signatureHelp({ marker: "2", docComment: "" }); verify.quickInfoAt("2q", "function multiLine(): void"); -verify.signatureHelp({ marker: "3", docComment: "this is eg of single line jsdoc style comment " }); -verify.quickInfoAt("3q", "function jsDocSingleLine(): void", "this is eg of single line jsdoc style comment "); +verify.signatureHelp({ marker: "3", docComment: "this is eg of single line jsdoc style comment" }); +verify.quickInfoAt("3q", "function jsDocSingleLine(): void", "this is eg of single line jsdoc style comment"); verify.signatureHelp({ marker: "4", docComment: "this is multiple line jsdoc stule comment\nNew line1\nNew Line2" }); verify.quickInfoAt("4q", "function jsDocMultiLine(): void", "this is multiple line jsdoc stule comment\nNew line1\nNew Line2"); @@ -217,23 +217,23 @@ verify.quickInfoAt("4q", "function jsDocMultiLine(): void", "this is multiple li verify.signatureHelp({ marker: "5", docComment: "this is multiple line jsdoc stule comment\nNew line1\nNew Line2\nShoul mege this line as well\nand this too\nAnother this one too" }); verify.quickInfoAt("5q", "function jsDocMultiLineMerge(): void", "this is multiple line jsdoc stule comment\nNew line1\nNew Line2\nShoul mege this line as well\nand this too\nAnother this one too"); -verify.signatureHelp({ marker: "6", docComment: "jsdoc comment " }); -verify.quickInfoAt("6q", "function jsDocMixedComments1(): void", "jsdoc comment "); +verify.signatureHelp({ marker: "6", docComment: "jsdoc comment" }); +verify.quickInfoAt("6q", "function jsDocMixedComments1(): void", "jsdoc comment"); -verify.signatureHelp({ marker: "7", docComment: "jsdoc comment \nanother jsDocComment" }); -verify.quickInfoAt("7q", "function jsDocMixedComments2(): void", "jsdoc comment \nanother jsDocComment"); +verify.signatureHelp({ marker: "7", docComment: "jsdoc comment\nanother jsDocComment" }); +verify.quickInfoAt("7q", "function jsDocMixedComments2(): void", "jsdoc comment\nanother jsDocComment"); -verify.signatureHelp({ marker: "8", docComment: "jsdoc comment \n* triplestar jsDocComment" }); -verify.quickInfoAt("8q", "function jsDocMixedComments3(): void", "jsdoc comment \n* triplestar jsDocComment"); +verify.signatureHelp({ marker: "8", docComment: "jsdoc comment\n* triplestar jsDocComment" }); +verify.quickInfoAt("8q", "function jsDocMixedComments3(): void", "jsdoc comment\n* triplestar jsDocComment"); -verify.signatureHelp({ marker: "9", docComment: "jsdoc comment \nanother jsDocComment" }); -verify.quickInfoAt("9q", "function jsDocMixedComments4(): void", "jsdoc comment \nanother jsDocComment"); +verify.signatureHelp({ marker: "9", docComment: "jsdoc comment\nanother jsDocComment" }); +verify.quickInfoAt("9q", "function jsDocMixedComments4(): void", "jsdoc comment\nanother jsDocComment"); -verify.signatureHelp({ marker: "10", docComment: "jsdoc comment \nanother jsDocComment" }); -verify.quickInfoAt("10q", "function jsDocMixedComments5(): void", "jsdoc comment \nanother jsDocComment"); +verify.signatureHelp({ marker: "10", docComment: "jsdoc comment\nanother jsDocComment" }); +verify.quickInfoAt("10q", "function jsDocMixedComments5(): void", "jsdoc comment\nanother jsDocComment"); -verify.signatureHelp({ marker: "11", docComment: "another jsDocComment\njsdoc comment " }); -verify.quickInfoAt("11q", "function jsDocMixedComments6(): void", "another jsDocComment\njsdoc comment "); +verify.signatureHelp({ marker: "11", docComment: "another jsDocComment\njsdoc comment" }); +verify.quickInfoAt("11q", "function jsDocMixedComments6(): void", "another jsDocComment\njsdoc comment"); verify.signatureHelp({ marker: "12", docComment: "" }); verify.quickInfoAt("12q", "function noHelpComment1(): void"); @@ -282,7 +282,7 @@ const multiplyTags: ReadonlyArray = [ { name: "param", text: "c" }, { name: "param", text: "d" }, { name: "anotherTag", text: undefined }, - { name: "param", text: "e LastParam " }, + { name: "param", text: "e LastParam" }, { name: "anotherTag", text: undefined }, ]; verify.signatureHelp({ marker: "19", docComment: "This is multiplication function", parameterDocComment: "first number", tags: multiplyTags }); @@ -303,8 +303,8 @@ verify.quickInfoAt("21aq", "(parameter) c: number"); verify.signatureHelp({ marker: "22", docComment: "This is multiplication function", tags: multiplyTags }); verify.quickInfoAt("22aq", "(parameter) d: any"); -verify.signatureHelp({ marker: "23", docComment: "This is multiplication function", parameterDocComment: "LastParam ", tags: multiplyTags }); -verify.quickInfoAt("23aq", "(parameter) e: any", "LastParam "); +verify.signatureHelp({ marker: "23", docComment: "This is multiplication function", parameterDocComment: "LastParam", tags: multiplyTags }); +verify.quickInfoAt("23aq", "(parameter) e: any", "LastParam"); goTo.marker('24'); verify.completionListContains("aOrb", "(parameter) aOrb: any", ""); @@ -420,7 +420,7 @@ verify.signatureHelp({ marker: "38", docComment: concatDoc, parameterDocComment: verify.quickInfoAt("38aq", "(parameter) bar: string", "is second string"); goTo.marker('39'); -verify.completionListContains("a", "(parameter) a: number", "this is inline comment for a \nit is first parameter"); +verify.completionListContains("a", "(parameter) a: number", "this is inline comment for a\nit is first parameter"); verify.completionListContains("b", "(parameter) b: number", "this is inline comment for b"); verify.completionListContains("c", "(parameter) c: number", "it is third parameter"); verify.completionListContains("d", "(parameter) d: number", ""); @@ -430,7 +430,7 @@ const jsdocTestTags: ReadonlyArray = [ { name: "param", text: "a it is first parameter" }, { name: "param", text: "c it is third parameter" }, ]; -verify.signatureHelp({ marker: "40", docComment: jsdocTestDocComment, parameterDocComment: "this is inline comment for a \nit is first parameter", tags: jsdocTestTags }); +verify.signatureHelp({ marker: "40", docComment: jsdocTestDocComment, parameterDocComment: "this is inline comment for a\nit is first parameter", tags: jsdocTestTags }); verify.quickInfos({ "40q": [ "function jsDocParamTest(a: number, b: number, c: number, d: number): number", @@ -438,7 +438,7 @@ verify.quickInfos({ ], "40aq": [ "(parameter) a: number", - "this is inline comment for a \nit is first parameter" + "this is inline comment for a\nit is first parameter" ] }); @@ -453,7 +453,7 @@ verify.quickInfoAt("43aq", "(parameter) d: number"); goTo.marker('44'); verify.completionListContains("jsDocParamTest", "function jsDocParamTest(a: number, b: number, c: number, d: number): number", jsdocTestDocComment); -verify.completionListContains("x", "var x: any", "This is a comment "); +verify.completionListContains("x", "var x: any", "This is a comment"); verify.completionListContains("y", "var y: any", "This is a comment"); verify.signatureHelp({ marker: "45", docComment: "This is function comment\nAnd properly aligned comment" }); diff --git a/tests/cases/fourslash/commentsFunctionExpression.ts b/tests/cases/fourslash/commentsFunctionExpression.ts index 257b834575687..f62572a466616 100644 --- a/tests/cases/fourslash/commentsFunctionExpression.ts +++ b/tests/cases/fourslash/commentsFunctionExpression.ts @@ -61,12 +61,12 @@ verify.signatureHelp( // no documentation from nested lambda verify.quickInfos({ 7: "function anotherFunc(a: number): string", - 8: ["(local var) lambdaVar: (b: string) => string", "inner docs \ndocumentation"], - 9: ["(parameter) b: string", "inner parameter "], + 8: ["(local var) lambdaVar: (b: string) => string", "inner docs\ndocumentation"], + 9: ["(parameter) b: string", "inner parameter"], 10: "(local var) localVar: string", 11: "(local var) localVar: string", - 12: ["(parameter) b: string", "inner parameter "], - 13: ["(local var) lambdaVar: (b: string) => string", "inner docs \ndocumentation"], + 12: ["(parameter) b: string", "inner parameter"], + 13: ["(local var) lambdaVar: (b: string) => string", "inner docs\ndocumentation"], 14: [ "var assigned: (s: string) => number", "Summary on expression\nOn variable" @@ -74,14 +74,14 @@ verify.quickInfos({ }); goTo.marker('15'); -verify.completionListContains('s', '(parameter) s: string', "On parameter \nparam on expression\nthe first parameter!"); +verify.completionListContains('s', '(parameter) s: string', "On parameter\nparam on expression\nthe first parameter!"); verify.quickInfoAt("16", "var assigned: (s: string) => number", "Summary on expression\nOn variable"); goTo.marker('17'); verify.completionListContains("assigned", "var assigned: (s: string) => number", "Summary on expression\nOn variable"); verify.signatureHelp({ marker: "18", docComment: "Summary on expression\nOn variable", - parameterDocComment: "On parameter \nparam on expression\nthe first parameter!", + parameterDocComment: "On parameter\nparam on expression\nthe first parameter!", tags: [ { name: "param", text: "s param on expression" }, { name: "returns", text: "return on expression" }, diff --git a/tests/cases/fourslash/commentsLinePreservation.ts b/tests/cases/fourslash/commentsLinePreservation.ts index 3f60bdbf43b0e..3bf2165014ec9 100644 --- a/tests/cases/fourslash/commentsLinePreservation.ts +++ b/tests/cases/fourslash/commentsLinePreservation.ts @@ -141,7 +141,7 @@ verify.quickInfos({ 7: ["(parameter) param1: string", "param information first line\n\nparam information third line"], k: ["function k(param1: string): void", "This is firstLine\nThis is second Line"], - 8: ["(parameter) param1: string", "hello "], + 8: ["(parameter) param1: string", "hello"], l: ["function l(param1: string): void", "This is firstLine\nThis is second Line"], 9: ["(parameter) param1: string", "first Line text\nblank line that shouldnt be shown when starting this \nsecond time information about the param again"], diff --git a/tests/cases/fourslash/completionForStringLiteral_details.ts b/tests/cases/fourslash/completionForStringLiteral_details.ts index 059770023c9ef..547c1fc5f81d1 100644 --- a/tests/cases/fourslash/completionForStringLiteral_details.ts +++ b/tests/cases/fourslash/completionForStringLiteral_details.ts @@ -24,5 +24,5 @@ goTo.marker("type"); verify.completionListContains("a", "a", "", "string"); goTo.marker("prop"); -verify.completionListContains("x", "(property) I.x: number", "Prop doc ", "property"); -verify.completionListContains("m", "(method) I.m(): void", "Method doc ", "method"); +verify.completionListContains("x", "(property) I.x: number", "Prop doc", "property"); +verify.completionListContains("m", "(method) I.m(): void", "Method doc", "method"); diff --git a/tests/cases/fourslash/completionInJsDocQualifiedNames.ts b/tests/cases/fourslash/completionInJsDocQualifiedNames.ts index 507f6b49fe36f..0de3ad0d21c11 100644 --- a/tests/cases/fourslash/completionInJsDocQualifiedNames.ts +++ b/tests/cases/fourslash/completionInJsDocQualifiedNames.ts @@ -12,4 +12,4 @@ ////const x = 0; goTo.marker(); -verify.completionListContains("T", "type T = number", "tee ", "type"); +verify.completionListContains("T", "type T = number", "tee", "type"); diff --git a/tests/cases/fourslash/completionsInJsxTag.ts b/tests/cases/fourslash/completionsInJsxTag.ts index a38f64e8fed81..223c3875cbd43 100644 --- a/tests/cases/fourslash/completionsInJsxTag.ts +++ b/tests/cases/fourslash/completionsInJsxTag.ts @@ -11,17 +11,17 @@ //// foo: string //// } //// } -////} -////class Foo { -//// render() { -////
; -////
-//// } +////} +////class Foo { +//// render() { +////
; +////
+//// } ////} goTo.marker("1"); verify.completionListCount(1); -verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute"); +verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute"); goTo.marker("2"); verify.completionListCount(1); -verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute"); +verify.completionListContains("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute"); diff --git a/tests/cases/fourslash/completionsJsxAttribute.ts b/tests/cases/fourslash/completionsJsxAttribute.ts index 29e6122ef1859..75bf20c748890 100644 --- a/tests/cases/fourslash/completionsJsxAttribute.ts +++ b/tests/cases/fourslash/completionsJsxAttribute.ts @@ -16,7 +16,7 @@ ////
; goTo.marker(); -verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute", []); +verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute", []); edit.insert("f"); -verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc ", "JSX attribute", []); +verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute", []); diff --git a/tests/cases/fourslash/jsDocForTypeAlias.ts b/tests/cases/fourslash/jsDocForTypeAlias.ts index dbda7ccbc136b..202d97fdec81e 100644 --- a/tests/cases/fourslash/jsDocForTypeAlias.ts +++ b/tests/cases/fourslash/jsDocForTypeAlias.ts @@ -4,4 +4,4 @@ ////type /**/T = number goTo.marker(); -verify.quickInfoIs("type T = number", "DOC "); +verify.quickInfoIs("type T = number", "DOC"); diff --git a/tests/cases/fourslash/jsDocFunctionSignatures9.ts b/tests/cases/fourslash/jsDocFunctionSignatures9.ts index b93516c26deb2..6c3342c0a3fc9 100644 --- a/tests/cases/fourslash/jsDocFunctionSignatures9.ts +++ b/tests/cases/fourslash/jsDocFunctionSignatures9.ts @@ -19,5 +19,5 @@ verify.verifyQuickInfoDisplayParts('function', {"text": " ", "kind": "space"}, {"text": "void", "kind": "keyword"} ], - [{"text": "first line of the comment\n\nthird line ", "kind": "text"}], + [{"text": "first line of the comment\n\nthird line", "kind": "text"}], []); diff --git a/tests/cases/fourslash/quickInfoFromContextualType.ts b/tests/cases/fourslash/quickInfoFromContextualType.ts index 020681cd022f1..657d5059c3597 100644 --- a/tests/cases/fourslash/quickInfoFromContextualType.ts +++ b/tests/cases/fourslash/quickInfoFromContextualType.ts @@ -7,4 +7,4 @@ ////} ////const i: I = { /**/x: 0 }; -verify.quickInfoAt("", "(property) I.x: number", "Documentation "); +verify.quickInfoAt("", "(property) I.x: number", "Documentation"); diff --git a/tests/cases/fourslash/quickInfoImportedTypes.ts b/tests/cases/fourslash/quickInfoImportedTypes.ts index 52da97ada91d0..1ebad1e1221f1 100644 --- a/tests/cases/fourslash/quickInfoImportedTypes.ts +++ b/tests/cases/fourslash/quickInfoImportedTypes.ts @@ -21,14 +21,14 @@ verify.quickInfoAt("1", [ "(alias) interface Foo", "import Foo", -].join("\n"), "This is an interface "); +].join("\n"), "This is an interface"); verify.quickInfoAt("2", [ "(alias) type Bar = 1 | 2", "import Bar", -].join("\n"), "One or two "); +].join("\n"), "One or two"); verify.quickInfoAt("3", [ "(alias) class Baz", "import Baz", -].join("\n"), "This is a class "); +].join("\n"), "This is a class"); diff --git a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts index d904fb59b9bf0..f63b295aa4c6a 100644 --- a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts +++ b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts @@ -18,11 +18,11 @@ verify.quickInfoAt("1", [ "(alias) type Original = () => T", "(alias) namespace Original", "export Original", -].join("\n"), "some docs "); +].join("\n"), "some docs"); verify.quickInfoAt("2", [ "(alias) function Alias(): void", "(alias) type Alias = () => T", "(alias) namespace Alias", "import Alias", -].join("\n"), "some docs "); +].join("\n"), "some docs"); diff --git a/tests/cases/fourslash/quickInfoJsDocTags1.ts b/tests/cases/fourslash/quickInfoJsDocTags1.ts new file mode 100644 index 0000000000000..a4af938ad8a49 --- /dev/null +++ b/tests/cases/fourslash/quickInfoJsDocTags1.ts @@ -0,0 +1,7 @@ +/// + +// @Filename: quickInfoJsDocTags1.ts +/////** Doc */ +////const /**/x = 0; + +verify.quickInfoAt("", "const x: 0", "Doc"); diff --git a/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts b/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts index c1e34f49bfc96..69250a310ace2 100644 --- a/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts +++ b/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts @@ -18,13 +18,13 @@ ////f4./*f4*/bar; goTo.marker("f"); -verify.quickInfoIs("(property) Foo.bar: number", "Doc "); +verify.quickInfoIs("(property) Foo.bar: number", "Doc"); goTo.marker("f2"); -verify.quickInfoIs("(property) bar: string", "Doc "); +verify.quickInfoIs("(property) bar: string", "Doc"); goTo.marker("f3"); -verify.quickInfoIs("(property) Foo.bar: number", "Doc "); +verify.quickInfoIs("(property) Foo.bar: number", "Doc"); goTo.marker("f4"); -verify.quickInfoIs("(property) bar: string", "Doc "); +verify.quickInfoIs("(property) bar: string", "Doc"); diff --git a/tests/cases/fourslash/quickInfoSpecialPropertyAssignment.ts b/tests/cases/fourslash/quickInfoSpecialPropertyAssignment.ts index 817e68f678299..b98b745251404 100644 --- a/tests/cases/fourslash/quickInfoSpecialPropertyAssignment.ts +++ b/tests/cases/fourslash/quickInfoSpecialPropertyAssignment.ts @@ -7,4 +7,4 @@ //// } ////} -verify.quickInfoAt("", "(property) C.x: number", "Doc "); +verify.quickInfoAt("", "(property) C.x: number", "Doc"); diff --git a/tests/cases/fourslash/quickInfoUnion_discriminated.ts b/tests/cases/fourslash/quickInfoUnion_discriminated.ts index 65b7cb53a0d83..d2f942a2fe116 100644 --- a/tests/cases/fourslash/quickInfoUnion_discriminated.ts +++ b/tests/cases/fourslash/quickInfoUnion_discriminated.ts @@ -27,8 +27,8 @@ ////}; verify.quickInfos({ - uKind: ['(property) A.kind: "a"', "Kind A "], - uProp: ["(property) A.prop: number", "Prop A "], + uKind: ['(property) A.kind: "a"', "Kind A"], + uProp: ["(property) A.prop: number", "Prop A"], u2Kind: '(property) kind: "bogus"', u2Prop: "(property) prop: number", }); diff --git a/tests/cases/fourslash/regexDetection.ts b/tests/cases/fourslash/regexDetection.ts index 61c6b6e349873..d19fc64ba79d4 100644 --- a/tests/cases/fourslash/regexDetection.ts +++ b/tests/cases/fourslash/regexDetection.ts @@ -7,7 +7,7 @@ verify.not.quickInfoExists(); goTo.marker("2"); verify.quickInfoIs("const Math: Math", - "An intrinsic object that provides basic mathematics functionality and constants. "); + "An intrinsic object that provides basic mathematics functionality and constants."); goTo.marker("3"); verify.not.quickInfoExists();