From 00279e9eca77a6107f62ee40d2b05de6ea5f19ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0=C3=A1ndor?= Date: Sat, 9 Feb 2019 17:17:09 +0100 Subject: [PATCH] Parse unexpected comments after email in author JSDoc tag (#17244) --- src/compiler/parser.ts | 38 ++++++++++--------- src/testRunner/unittests/jsDocParsing.ts | 1 + ...DocComments.parsesCorrectly.authorTag.json | 30 +++++++++++++-- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f8ffddaa600..a3f8c950c36 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -468,6 +468,8 @@ namespace ts { visitNode(cbNode, (node).typeExpression) : visitNode(cbNode, (node).typeExpression) || visitNode(cbNode, (node).name)); + case SyntaxKind.JSDocAuthorTag: + return visitNode(cbNode, (node as JSDocTag).tagName); case SyntaxKind.JSDocAugmentsTag: return visitNode(cbNode, (node as JSDocTag).tagName) || visitNode(cbNode, (node).class); @@ -6612,7 +6614,7 @@ namespace ts { let tag: JSDocTag | undefined; switch (tagName.escapedText) { case "author": - tag = parseAuthorTag(start, tagName); + tag = parseAuthorTag(start, tagName, indent); break; case "augments": case "extends": @@ -6877,14 +6879,22 @@ namespace ts { return finishNode(result); } - function parseAuthorTag(start: number, tagName: Identifier): JSDocAuthorTag { + function parseAuthorTag(start: number, tagName: Identifier, indent: number): JSDocAuthorTag { const result = createNode(SyntaxKind.JSDocAuthorTag, start); result.tagName = tagName; - const comment = tryParse(() => tryParseAuthorNameAndEmail()); + const authorInfoWithEmail = tryParse(() => tryParseAuthorNameAndEmail()); + if (!authorInfoWithEmail) { + return finishNode(result); + } - if (comment) { - result.comment = comment; + result.comment = authorInfoWithEmail; + + if (lookAhead(() => nextToken() !== SyntaxKind.NewLineTrivia)) { + const comment = parseTagComments(indent); + if (comment) { + result.comment += comment; + } } return finishNode(result); @@ -6894,7 +6904,6 @@ namespace ts { const comments: string[] = []; let seenLessThan = false; let seenGreaterThan = false; - let seenAtToken = false; let token = scanner.getToken(); loop: while (true) { @@ -6902,31 +6911,24 @@ namespace ts { case SyntaxKind.Identifier: case SyntaxKind.WhitespaceTrivia: case SyntaxKind.DotToken: + case SyntaxKind.AtToken: comments.push(scanner.getTokenText()); break; case SyntaxKind.LessThanToken: - if (seenLessThan || seenAtToken || seenGreaterThan) { + if (seenLessThan || seenGreaterThan) { return; } seenLessThan = true; comments.push(scanner.getTokenText()); break; case SyntaxKind.GreaterThanToken: - if (!seenLessThan || !seenAtToken || seenGreaterThan) { + if (!seenLessThan || seenGreaterThan) { return; } - seenGreaterThan = true; comments.push(scanner.getTokenText()); + scanner.setTextPos(scanner.getTokenPos() + 1); break loop; - case SyntaxKind.AtToken: - if (seenAtToken || !seenLessThan || seenGreaterThan) { - return; - } - - seenAtToken = true; - comments.push(scanner.getTokenText()); - break; case SyntaxKind.NewLineTrivia: case SyntaxKind.EndOfFileToken: break loop; @@ -6935,7 +6937,7 @@ namespace ts { token = nextJSDocToken(); } - if (seenLessThan && seenAtToken && seenGreaterThan) { + if (seenLessThan && seenGreaterThan) { return comments.length === 0 ? undefined : comments.join(""); } } diff --git a/src/testRunner/unittests/jsDocParsing.ts b/src/testRunner/unittests/jsDocParsing.ts index 59775862e99..41e09f5f9fe 100644 --- a/src/testRunner/unittests/jsDocParsing.ts +++ b/src/testRunner/unittests/jsDocParsing.ts @@ -317,6 +317,7 @@ namespace ts { parsesCorrectly("authorTag", `/** * @author John Doe + * @author John Doe unexpected comment */`); }); }); diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json index 5239e57649c..54e06da0465 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json @@ -1,22 +1,44 @@ { "kind": "JSDocComment", "pos": 0, - "end": 50, + "end": 112, + "modifierFlagsCache": 0, + "transformFlags": 0, "tags": { "0": { "kind": "JSDocAuthorTag", "pos": 7, - "end": 45, + "end": 50, + "modifierFlagsCache": 0, + "transformFlags": 0, "tagName": { "kind": "Identifier", "pos": 8, "end": 14, + "modifierFlagsCache": 0, + "transformFlags": 0, "escapedText": "author" }, "comment": "John Doe " }, - "length": 1, + "1": { + "kind": "JSDocAuthorTag", + "pos": 50, + "end": 110, + "modifierFlagsCache": 0, + "transformFlags": 0, + "tagName": { + "kind": "Identifier", + "pos": 51, + "end": 57, + "modifierFlagsCache": 0, + "transformFlags": 0, + "escapedText": "author" + }, + "comment": "John Doe unexpected comment" + }, + "length": 2, "pos": 7, - "end": 45 + "end": 110 } } \ No newline at end of file