From 1e48cbe2c92d4e0338179f1ac512ae3bbb6f5c40 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 7 Feb 2020 08:35:40 -0800 Subject: [PATCH] Fix jsdoc comment parsing initial state (#36661) * Fix jsdoc comment parsing initial state Jsdoc comment parsing can be invoked in two modes: 1. top-level parsing, for comments not inside a tag. 2. tag parsing, for comment that occur after the semantic parts of a tag. Top-level parsing skips an initial * because it assumes that it is starting at the very beginning of a JSDoc comment. Tag parsing does not. The two modes are distinguished by an optional second parameter named `margin`. When `margin` is provided, it provides an initial indent used for comment alignment. Previously, the check for `margin` was a truthy check `if (margin)`. This check incorrectly treats `margin=""` the same as `margin=undefined`. This PR changes the check to `if (margin !== undefined)`, which correctly treats `margin=""` the same as `margin=" "`. * Fixes for broken tests 1. Use SawAsterisk start state. 2. @template needs to skip asterisk in addition to whitespace while parsing type parameter names. * undo code move --- src/compiler/parser.ts | 10 +++-- .../quickInfoDisplayPartsParameters.baseline | 44 +++++++++++-------- .../quickInfoDisplayPartsParameters.ts | 15 ++++--- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 62172582758..78938bd6a2a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7017,10 +7017,12 @@ namespace ts { comments.push(text); indent += text.length; } - if (initialMargin) { + if (initialMargin !== undefined) { // jump straight to saving comments if there is some initial indentation - pushComment(initialMargin); - state = JSDocState.SavingComments; + if (initialMargin !== "") { + pushComment(initialMargin); + } + state = JSDocState.SawAsterisk; } let tok = token() as JSDocSyntaxKind; loop: while (true) { @@ -7558,7 +7560,7 @@ namespace ts { const typeParameter = createNode(SyntaxKind.TypeParameter); typeParameter.name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); finishNode(typeParameter); - skipWhitespace(); + skipWhitespaceOrAsterisk(); typeParameters.push(typeParameter); } while (parseOptionalJsdoc(SyntaxKind.CommaToken)); diff --git a/tests/baselines/reference/quickInfoDisplayPartsParameters.baseline b/tests/baselines/reference/quickInfoDisplayPartsParameters.baseline index 45f6128c2b1..c9bb71314de 100644 --- a/tests/baselines/reference/quickInfoDisplayPartsParameters.baseline +++ b/tests/baselines/reference/quickInfoDisplayPartsParameters.baseline @@ -2,13 +2,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 9 + "position": 33 }, "quickInfo": { "kind": "function", "kindModifiers": "", "textSpan": { - "start": 9, + "start": 33, "length": 3 }, "displayParts": [ @@ -153,19 +153,25 @@ "kind": "keyword" } ], - "documentation": [] + "documentation": [], + "tags": [ + { + "name": "return", + "text": "*crunch*" + } + ] } }, { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 13 + "position": 37 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 13, + "start": 37, "length": 5 }, "displayParts": [ @@ -208,13 +214,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 28 + "position": 52 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 28, + "start": 52, "length": 13 }, "displayParts": [ @@ -257,13 +263,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 52 + "position": 76 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 52, + "start": 76, "length": 20 }, "displayParts": [ @@ -306,13 +312,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 87 + "position": 111 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 87, + "start": 111, "length": 9 }, "displayParts": [ @@ -363,13 +369,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 114 + "position": 138 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 114, + "start": 138, "length": 5 }, "displayParts": [ @@ -412,13 +418,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 135 + "position": 159 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 135, + "start": 159, "length": 13 }, "displayParts": [ @@ -461,13 +467,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 164 + "position": 188 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 164, + "start": 188, "length": 20 }, "displayParts": [ @@ -510,13 +516,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts", - "position": 200 + "position": 224 }, "quickInfo": { "kind": "parameter", "kindModifiers": "", "textSpan": { - "start": 200, + "start": 224, "length": 9 }, "displayParts": [ diff --git a/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts b/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts index 58cc8159b92..b330d87b223 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsParameters.ts @@ -1,10 +1,11 @@ /// -////function /*1*/foo(/*2*/param: string, /*3*/optionalParam?: string, /*4*/paramWithInitializer = "hello", .../*5*/restParam: string[]) { -//// /*6*/param = "Hello"; -//// /*7*/optionalParam = "World"; -//// /*8*/paramWithInitializer = "Hello"; -//// /*9*/restParam[0] = "World"; -////} +//// /** @return *crunch* */ +//// function /*1*/foo(/*2*/param: string, /*3*/optionalParam?: string, /*4*/paramWithInitializer = "hello", .../*5*/restParam: string[]) { +//// /*6*/param = "Hello"; +//// /*7*/optionalParam = "World"; +//// /*8*/paramWithInitializer = "Hello"; +//// /*9*/restParam[0] = "World"; +//// } -verify.baselineQuickInfo(); \ No newline at end of file +verify.baselineQuickInfo();