From ea9d519424a249933547d3765e2f8228f5c5ce90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0=C3=A1ndor?= Date: Sun, 3 Feb 2019 20:44:07 +0100 Subject: [PATCH 1/5] Support email in author JSDoc tag - fixes #17244 --- src/compiler/parser.ts | 66 +++++++++++++++++++ src/compiler/scanner.ts | 2 + src/compiler/types.ts | 6 ++ src/compiler/utilities.ts | 4 ++ src/testRunner/unittests/jsDocParsing.ts | 4 ++ ...DocComments.parsesCorrectly.authorTag.json | 22 +++++++ .../reference/api/tsserverlibrary.d.ts | 6 +- tests/baselines/reference/api/typescript.d.ts | 6 +- .../reference/quickInfoJsDocTags.baseline | 6 +- tests/cases/fourslash/quickInfoJsDocTags.ts | 2 +- 10 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ada42889032..f8ffddaa600 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6611,6 +6611,9 @@ namespace ts { let tag: JSDocTag | undefined; switch (tagName.escapedText) { + case "author": + tag = parseAuthorTag(start, tagName); + break; case "augments": case "extends": tag = parseAugmentsTag(start, tagName); @@ -6874,6 +6877,69 @@ namespace ts { return finishNode(result); } + function parseAuthorTag(start: number, tagName: Identifier): JSDocAuthorTag { + const result = createNode(SyntaxKind.JSDocAuthorTag, start); + result.tagName = tagName; + + const comment = tryParse(() => tryParseAuthorNameAndEmail()); + + if (comment) { + result.comment = comment; + } + + return finishNode(result); + } + + function tryParseAuthorNameAndEmail(): string | undefined { + const comments: string[] = []; + let seenLessThan = false; + let seenGreaterThan = false; + let seenAtToken = false; + let token = scanner.getToken(); + + loop: while (true) { + switch (token) { + case SyntaxKind.Identifier: + case SyntaxKind.WhitespaceTrivia: + case SyntaxKind.DotToken: + comments.push(scanner.getTokenText()); + break; + case SyntaxKind.LessThanToken: + if (seenLessThan || seenAtToken || seenGreaterThan) { + return; + } + seenLessThan = true; + comments.push(scanner.getTokenText()); + break; + case SyntaxKind.GreaterThanToken: + if (!seenLessThan || !seenAtToken || seenGreaterThan) { + return; + } + + seenGreaterThan = true; + comments.push(scanner.getTokenText()); + 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; + } + + token = nextJSDocToken(); + } + + if (seenLessThan && seenAtToken && seenGreaterThan) { + return comments.length === 0 ? undefined : comments.join(""); + } + } + function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag { const result = createNode(SyntaxKind.JSDocAugmentsTag, start); result.tagName = tagName; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 36ac8adfa90..256e41629a1 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -2086,6 +2086,8 @@ namespace ts { return token = SyntaxKind.CloseBracketToken; case CharacterCodes.lessThan: return token = SyntaxKind.LessThanToken; + case CharacterCodes.greaterThan: + return token = SyntaxKind.GreaterThanToken; case CharacterCodes.equals: return token = SyntaxKind.EqualsToken; case CharacterCodes.comma: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0b952a4d009..432d1dccba7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -17,6 +17,7 @@ namespace ts { | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken + | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken @@ -459,6 +460,7 @@ namespace ts { JSDocSignature, JSDocTag, JSDocAugmentsTag, + JSDocAuthorTag, JSDocClassTag, JSDocCallbackTag, JSDocEnumTag, @@ -2455,6 +2457,10 @@ namespace ts { class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; } + export interface JSDocAuthorTag extends JSDocTag { + kind: SyntaxKind.JSDocAuthorTag; + } + export interface JSDocClassTag extends JSDocTag { kind: SyntaxKind.JSDocClassTag; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2e6c3ae4f86..b72a30ffba4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6116,6 +6116,10 @@ namespace ts { return node.kind === SyntaxKind.JSDocComment; } + export function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag { + return node.kind === SyntaxKind.JSDocAuthorTag; + } + export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag { return node.kind === SyntaxKind.JSDocAugmentsTag; } diff --git a/src/testRunner/unittests/jsDocParsing.ts b/src/testRunner/unittests/jsDocParsing.ts index 4171a330f32..59775862e99 100644 --- a/src/testRunner/unittests/jsDocParsing.ts +++ b/src/testRunner/unittests/jsDocParsing.ts @@ -313,6 +313,10 @@ namespace ts { * {@link first link} * Inside {@link link text} thing * @see {@link second link text} and {@link Foo|a foo} as well. + */`); + parsesCorrectly("authorTag", +`/** + * @author John Doe */`); }); }); diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json new file mode 100644 index 00000000000..5239e57649c --- /dev/null +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.authorTag.json @@ -0,0 +1,22 @@ +{ + "kind": "JSDocComment", + "pos": 0, + "end": 50, + "tags": { + "0": { + "kind": "JSDocAuthorTag", + "pos": 7, + "end": 45, + "tagName": { + "kind": "Identifier", + "pos": 8, + "end": 14, + "escapedText": "author" + }, + "comment": "John Doe " + }, + "length": 1, + "pos": 7, + "end": 45 + } +} \ No newline at end of file diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3f31d83d4f3..0d55487a4a7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -72,7 +72,7 @@ declare namespace ts { pos: number; end: number; } - type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; + type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; enum SyntaxKind { @@ -1581,6 +1581,9 @@ declare namespace ts { expression: Identifier | PropertyAccessEntityNameExpression; }; } + interface JSDocAuthorTag extends JSDocTag { + kind: SyntaxKind.JSDocAuthorTag; + } interface JSDocClassTag extends JSDocTag { kind: SyntaxKind.JSDocClassTag; } @@ -3521,6 +3524,7 @@ declare namespace ts { function isJSDocFunctionType(node: Node): node is JSDocFunctionType; function isJSDocVariadicType(node: Node): node is JSDocVariadicType; function isJSDoc(node: Node): node is JSDoc; + function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag; function isJSDocClassTag(node: Node): node is JSDocClassTag; function isJSDocEnumTag(node: Node): node is JSDocEnumTag; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ab4faf036b1..579b3276185 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -72,7 +72,7 @@ declare namespace ts { pos: number; end: number; } - type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; + type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; enum SyntaxKind { @@ -1581,6 +1581,9 @@ declare namespace ts { expression: Identifier | PropertyAccessEntityNameExpression; }; } + interface JSDocAuthorTag extends JSDocTag { + kind: SyntaxKind.JSDocAuthorTag; + } interface JSDocClassTag extends JSDocTag { kind: SyntaxKind.JSDocClassTag; } @@ -3521,6 +3524,7 @@ declare namespace ts { function isJSDocFunctionType(node: Node): node is JSDocFunctionType; function isJSDocVariadicType(node: Node): node is JSDocVariadicType; function isJSDoc(node: Node): node is JSDoc; + function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag; function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag; function isJSDocClassTag(node: Node): node is JSDocClassTag; function isJSDocEnumTag(node: Node): node is JSDocEnumTag; diff --git a/tests/baselines/reference/quickInfoJsDocTags.baseline b/tests/baselines/reference/quickInfoJsDocTags.baseline index d3ed4ad5ef1..a146e8e1876 100644 --- a/tests/baselines/reference/quickInfoJsDocTags.baseline +++ b/tests/baselines/reference/quickInfoJsDocTags.baseline @@ -2,13 +2,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoJsDocTags.ts", - "position": 256 + "position": 272 }, "quickInfo": { "kind": "function", "kindModifiers": "", "textSpan": { - "start": 256, + "start": 272, "length": 3 }, "displayParts": [ @@ -70,7 +70,7 @@ "tags": [ { "name": "author", - "text": "Me" + "text": "Me " }, { "name": "augments", diff --git a/tests/cases/fourslash/quickInfoJsDocTags.ts b/tests/cases/fourslash/quickInfoJsDocTags.ts index 798a850a310..2d81cb23679 100644 --- a/tests/cases/fourslash/quickInfoJsDocTags.ts +++ b/tests/cases/fourslash/quickInfoJsDocTags.ts @@ -3,7 +3,7 @@ // @Filename: quickInfoJsDocTags.ts /////** //// * Doc -//// * @author Me +//// * @author Me //// * @augments {C} Augments it //// * @template T A template //// * @type {number | string} A type 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 2/5] 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 From 08bd017db97445709cc249d3c0c9661ff962c009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0=C3=A1ndor?= Date: Fri, 19 Apr 2019 12:03:33 +0200 Subject: [PATCH 3/5] JSDoc author tag parsing updates (#17244) --- src/compiler/parser.ts | 4 +- .../reference/api/tsserverlibrary.d.ts | 39 ++++++++++--------- tests/baselines/reference/api/typescript.d.ts | 39 ++++++++++--------- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a3f8c950c36..ce50eeac19d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6614,7 +6614,7 @@ namespace ts { let tag: JSDocTag | undefined; switch (tagName.escapedText) { case "author": - tag = parseAuthorTag(start, tagName, indent); + tag = parseAuthorTag(start, tagName, margin); break; case "augments": case "extends": @@ -6934,7 +6934,7 @@ namespace ts { break loop; } - token = nextJSDocToken(); + token = nextTokenJSDoc(); } if (seenLessThan && seenGreaterThan) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0d55487a4a7..b557509f8ce 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -379,23 +379,24 @@ declare namespace ts { JSDocSignature = 299, JSDocTag = 300, JSDocAugmentsTag = 301, - JSDocClassTag = 302, - JSDocCallbackTag = 303, - JSDocEnumTag = 304, - JSDocParameterTag = 305, - JSDocReturnTag = 306, - JSDocThisTag = 307, - JSDocTypeTag = 308, - JSDocTemplateTag = 309, - JSDocTypedefTag = 310, - JSDocPropertyTag = 311, - SyntaxList = 312, - NotEmittedStatement = 313, - PartiallyEmittedExpression = 314, - CommaListExpression = 315, - MergeDeclarationMarker = 316, - EndOfDeclarationMarker = 317, - Count = 318, + JSDocAuthorTag = 302, + JSDocClassTag = 303, + JSDocCallbackTag = 304, + JSDocEnumTag = 305, + JSDocParameterTag = 306, + JSDocReturnTag = 307, + JSDocThisTag = 308, + JSDocTypeTag = 309, + JSDocTemplateTag = 310, + JSDocTypedefTag = 311, + JSDocPropertyTag = 312, + SyntaxList = 313, + NotEmittedStatement = 314, + PartiallyEmittedExpression = 315, + CommaListExpression = 316, + MergeDeclarationMarker = 317, + EndOfDeclarationMarker = 318, + Count = 319, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -422,9 +423,9 @@ declare namespace ts { LastBinaryOperator = 72, FirstNode = 149, FirstJSDocNode = 289, - LastJSDocNode = 311, + LastJSDocNode = 312, FirstJSDocTagNode = 300, - LastJSDocTagNode = 311, + LastJSDocTagNode = 312, } enum NodeFlags { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 579b3276185..de6b2b187c2 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -379,23 +379,24 @@ declare namespace ts { JSDocSignature = 299, JSDocTag = 300, JSDocAugmentsTag = 301, - JSDocClassTag = 302, - JSDocCallbackTag = 303, - JSDocEnumTag = 304, - JSDocParameterTag = 305, - JSDocReturnTag = 306, - JSDocThisTag = 307, - JSDocTypeTag = 308, - JSDocTemplateTag = 309, - JSDocTypedefTag = 310, - JSDocPropertyTag = 311, - SyntaxList = 312, - NotEmittedStatement = 313, - PartiallyEmittedExpression = 314, - CommaListExpression = 315, - MergeDeclarationMarker = 316, - EndOfDeclarationMarker = 317, - Count = 318, + JSDocAuthorTag = 302, + JSDocClassTag = 303, + JSDocCallbackTag = 304, + JSDocEnumTag = 305, + JSDocParameterTag = 306, + JSDocReturnTag = 307, + JSDocThisTag = 308, + JSDocTypeTag = 309, + JSDocTemplateTag = 310, + JSDocTypedefTag = 311, + JSDocPropertyTag = 312, + SyntaxList = 313, + NotEmittedStatement = 314, + PartiallyEmittedExpression = 315, + CommaListExpression = 316, + MergeDeclarationMarker = 317, + EndOfDeclarationMarker = 318, + Count = 319, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -422,9 +423,9 @@ declare namespace ts { LastBinaryOperator = 72, FirstNode = 149, FirstJSDocNode = 289, - LastJSDocNode = 311, + LastJSDocNode = 312, FirstJSDocTagNode = 300, - LastJSDocTagNode = 311, + LastJSDocTagNode = 312, } enum NodeFlags { None = 0, From 252840ad40f33518b5efd47a9d2a9c7c8d1514ab Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 24 Jun 2019 17:37:14 -0700 Subject: [PATCH 4/5] Fix incorrect noImplicitAny error on contextual union function signature --- src/compiler/checker.ts | 4 +++- .../functionExpressionContextualTyping3.js | 8 ++++++++ .../functionExpressionContextualTyping3.symbols | 12 ++++++++++++ .../functionExpressionContextualTyping3.types | 13 +++++++++++++ .../functionExpressionContextualTyping3.ts | 5 +++++ 5 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/functionExpressionContextualTyping3.js create mode 100644 tests/baselines/reference/functionExpressionContextualTyping3.symbols create mode 100644 tests/baselines/reference/functionExpressionContextualTyping3.types create mode 100644 tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3abe1dc5b5..534e5e2f067 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19095,7 +19095,9 @@ namespace ts { } } // Result is union of signatures collected (return type is union of return types of this signature set) - return signatureList && createUnionSignature(signatureList[0], signatureList); + if (signatureList) { + return signatureList.length === 1 ? signatureList[0] : createUnionSignature(signatureList[0], signatureList); + } } function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type { diff --git a/tests/baselines/reference/functionExpressionContextualTyping3.js b/tests/baselines/reference/functionExpressionContextualTyping3.js new file mode 100644 index 00000000000..b25754b568f --- /dev/null +++ b/tests/baselines/reference/functionExpressionContextualTyping3.js @@ -0,0 +1,8 @@ +//// [functionExpressionContextualTyping3.ts] +// #31114 +declare function f(value: T | number): void; +f((a: any) => "") + + +//// [functionExpressionContextualTyping3.js] +f(function (a) { return ""; }); diff --git a/tests/baselines/reference/functionExpressionContextualTyping3.symbols b/tests/baselines/reference/functionExpressionContextualTyping3.symbols new file mode 100644 index 00000000000..8b773f08428 --- /dev/null +++ b/tests/baselines/reference/functionExpressionContextualTyping3.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts === +// #31114 +declare function f(value: T | number): void; +>f : Symbol(f, Decl(functionExpressionContextualTyping3.ts, 0, 0)) +>T : Symbol(T, Decl(functionExpressionContextualTyping3.ts, 1, 19)) +>value : Symbol(value, Decl(functionExpressionContextualTyping3.ts, 1, 22)) +>T : Symbol(T, Decl(functionExpressionContextualTyping3.ts, 1, 19)) + +f((a: any) => "") +>f : Symbol(f, Decl(functionExpressionContextualTyping3.ts, 0, 0)) +>a : Symbol(a, Decl(functionExpressionContextualTyping3.ts, 2, 3)) + diff --git a/tests/baselines/reference/functionExpressionContextualTyping3.types b/tests/baselines/reference/functionExpressionContextualTyping3.types new file mode 100644 index 00000000000..662aa72ea90 --- /dev/null +++ b/tests/baselines/reference/functionExpressionContextualTyping3.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts === +// #31114 +declare function f(value: T | number): void; +>f : (value: number | T) => void +>value : number | T + +f((a: any) => "") +>f((a: any) => "") : void +>f : (value: number | T) => void +>(a: any) => "" : (a: any) => "" +>a : any +>"" : "" + diff --git a/tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts b/tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts new file mode 100644 index 00000000000..a1dc4e5d7d7 --- /dev/null +++ b/tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping3.ts @@ -0,0 +1,5 @@ +// @noImplicitAny: true + +// #31114 +declare function f(value: T | number): void; +f((a: any) => "") From ba1a062b93c1def5b7a6329c2fe4bbba17c571ff Mon Sep 17 00:00:00 2001 From: typescript-bot Date: Wed, 3 Jul 2019 14:02:33 +0000 Subject: [PATCH 5/5] Update user baselines --- tests/baselines/reference/user/prettier.log | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index c69f88a4a78..4bebd0414b1 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -5,6 +5,8 @@ src/cli/util.js(60,44): error TS2345: Argument of type 'null' is not assignable src/cli/util.js(119,38): error TS2339: Property 'sync' does not exist on type '(...args: any[]) => any'. src/cli/util.js(372,29): error TS2532: Object is possibly 'undefined'. src/cli/util.js(372,64): error TS2339: Property 'length' does not exist on type 'Ignore'. +src/cli/util.js(413,36): error TS2345: Argument of type '{ dot: true; nodir: boolean; }' is not assignable to parameter of type 'GlobbyOptions'. + Object literal may only specify known properties, and 'nodir' does not exist in type 'GlobbyOptions'. src/cli/util.js(452,25): error TS2532: Object is possibly 'undefined'. src/cli/util.js(452,52): error TS2339: Property 'length' does not exist on type 'Ignore'. src/cli/util.js(510,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'.