From 5ac079f08e14d944ce77e1835e83d96dab70d4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 16 Sep 2024 13:45:43 +0200 Subject: [PATCH 1/2] Fixed `@template` tags used with `@overload`s --- src/compiler/types.ts | 3 +- src/compiler/utilities.ts | 6 +-- src/compiler/utilitiesPublic.ts | 1 + .../reference/jsdocTemplateTagOverload1.js | 54 +++++++++++++++++++ .../jsdocTemplateTagOverload1.symbols | 33 ++++++++++++ .../reference/jsdocTemplateTagOverload1.types | 36 +++++++++++++ .../jsdoc/jsdocTemplateTagOverload1.ts | 35 ++++++++++++ 7 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/jsdocTemplateTagOverload1.js create mode 100644 tests/baselines/reference/jsdocTemplateTagOverload1.symbols create mode 100644 tests/baselines/reference/jsdocTemplateTagOverload1.types create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 590911b3f6e99..55d41c03ef565 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1536,6 +1536,7 @@ export type HasLocals = | JSDocFunctionType | JSDocSignature | JSDocTypedefTag + | JSDocOverloadTag | MappedTypeNode | MethodDeclaration | MethodSignature @@ -4063,7 +4064,7 @@ export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration, LocalsCont readonly typeExpression: JSDocSignature; } -export interface JSDocOverloadTag extends JSDocTag { +export interface JSDocOverloadTag extends JSDocTag, LocalsContainer { readonly kind: SyntaxKind.JSDocOverloadTag; readonly parent: JSDoc; readonly typeExpression: JSDocSignature; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c7ade289737ca..4a07b83424922 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4595,10 +4595,10 @@ export function getParameterSymbolFromJSDoc(node: JSDocParameterTag): Symbol | u } /** @internal */ -export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag): SignatureDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | undefined { +export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag): SignatureDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocOverloadTag | JSDocEnumTag | undefined { if (isJSDoc(node.parent) && node.parent.tags) { - // A @template tag belongs to any @typedef, @callback, or @enum tags in the same comment block, if they exist. - const typeAlias = find(node.parent.tags, isJSDocTypeAlias); + // A @template tag belongs to any @overload, @typedef, @callback, or @enum tags in the same comment block, if they exist. + const typeAlias = find(node.parent.tags, tag => isJSDocOverloadTag(tag) || isJSDocTypeAlias(tag)); if (typeAlias) { return typeAlias; } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 462ebc6da06d4..69fc9ef4647f4 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -2288,6 +2288,7 @@ export function canHaveLocals(node: Node): node is HasLocals { case SyntaxKind.JSDocFunctionType: case SyntaxKind.JSDocSignature: case SyntaxKind.JSDocTypedefTag: + case SyntaxKind.JSDocOverloadTag: case SyntaxKind.MappedType: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: diff --git a/tests/baselines/reference/jsdocTemplateTagOverload1.js b/tests/baselines/reference/jsdocTemplateTagOverload1.js new file mode 100644 index 0000000000000..5f0ae3bd83aed --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTagOverload1.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts] //// + +//// [index.js] +/** + * @template {string} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @template {boolean} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @overload + * @param {number} element + * @returns {() => void} + */ + +/** + * @param {any} element + */ +export function on(element) { + return () => {} +} + + + + +//// [index.d.ts] +/** + * @template {string} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ +export function on(element: Element): () => void; +/** + * @template {boolean} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ +export function on(element: Element): () => void; +/** + * @overload + * @param {number} element + * @returns {() => void} + */ +export function on(element: number): () => void; diff --git a/tests/baselines/reference/jsdocTemplateTagOverload1.symbols b/tests/baselines/reference/jsdocTemplateTagOverload1.symbols new file mode 100644 index 0000000000000..213ef574eeae9 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTagOverload1.symbols @@ -0,0 +1,33 @@ +//// [tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts] //// + +=== index.js === +/** + * @template {string} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @template {boolean} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @overload + * @param {number} element + * @returns {() => void} + */ + +/** + * @param {any} element + */ +export function on(element) { +>on : Symbol(on, Decl(index.js, 0, 0)) +>element : Symbol(element, Decl(index.js, 23, 19)) + + return () => {} +} + diff --git a/tests/baselines/reference/jsdocTemplateTagOverload1.types b/tests/baselines/reference/jsdocTemplateTagOverload1.types new file mode 100644 index 0000000000000..c3ad4eda3391c --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTagOverload1.types @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts] //// + +=== index.js === +/** + * @template {string} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @template {boolean} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @overload + * @param {number} element + * @returns {() => void} + */ + +/** + * @param {any} element + */ +export function on(element) { +>on : { (element: Element): () => void; (element: Element): () => void; (element: number): () => void; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^ +>element : any + + return () => {} +>() => {} : () => void +> : ^^^^^^^^^^ +} + diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts new file mode 100644 index 0000000000000..961cb2b5791b2 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTagOverload1.ts @@ -0,0 +1,35 @@ +// @strict: true +// @allowJs: true +// @checkJs: true +// @declaration: true +// @emitDeclarationOnly: true +// @outDir: dist + +// @filename: index.js + +/** + * @template {string} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @template {boolean} Element + * @overload + * @param {Element} element + * @returns {() => void} + */ + +/** + * @overload + * @param {number} element + * @returns {() => void} + */ + +/** + * @param {any} element + */ +export function on(element) { + return () => {} +} From 3dd3783b93a039cf3e187d8590960edf862625ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 16 Sep 2024 14:16:01 +0200 Subject: [PATCH 2/2] update baselines --- tests/baselines/reference/api/typescript.d.ts | 2 +- tests/baselines/reference/jsFileFunctionOverloads.types | 4 ++-- tests/baselines/reference/jsFileFunctionOverloads2.types | 4 ++-- .../reference/templateInsideCallback.errors.txt | 9 ++++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 304462086e8a8..ee1306d1e9111 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5782,7 +5782,7 @@ declare namespace ts { readonly name?: Identifier; readonly typeExpression: JSDocSignature; } - interface JSDocOverloadTag extends JSDocTag { + interface JSDocOverloadTag extends JSDocTag, LocalsContainer { readonly kind: SyntaxKind.JSDocOverloadTag; readonly parent: JSDoc; readonly typeExpression: JSDocSignature; diff --git a/tests/baselines/reference/jsFileFunctionOverloads.types b/tests/baselines/reference/jsFileFunctionOverloads.types index 13f9ed2c199f2..ebedd7112c538 100644 --- a/tests/baselines/reference/jsFileFunctionOverloads.types +++ b/tests/baselines/reference/jsFileFunctionOverloads.types @@ -74,8 +74,8 @@ function flatMap(array, iterable = identity) { > : ^^^^^^^^^ >iterable : (x: unknown) => unknown > : ^ ^^ ^^^^^ ->identity : (x: T_1) => T_1 -> : ^^^^^^ ^^ ^^^^^ +>identity : (x: T) => T +> : ^ ^^ ^^ ^^^^^ /** @type {unknown[]} */ const result = []; diff --git a/tests/baselines/reference/jsFileFunctionOverloads2.types b/tests/baselines/reference/jsFileFunctionOverloads2.types index d6cd0fb445762..c57b8db78d79f 100644 --- a/tests/baselines/reference/jsFileFunctionOverloads2.types +++ b/tests/baselines/reference/jsFileFunctionOverloads2.types @@ -69,8 +69,8 @@ function flatMap(array, iterable = identity) { > : ^^^^^^^^^ >iterable : (x: unknown) => unknown > : ^ ^^ ^^^^^ ->identity : (x: T_1) => T_1 -> : ^^^^^^ ^^ ^^^^^ +>identity : (x: T) => T +> : ^ ^^ ^^ ^^^^^ /** @type {unknown[]} */ const result = []; diff --git a/tests/baselines/reference/templateInsideCallback.errors.txt b/tests/baselines/reference/templateInsideCallback.errors.txt index 2d37efe52f547..e44aa60290f62 100644 --- a/tests/baselines/reference/templateInsideCallback.errors.txt +++ b/tests/baselines/reference/templateInsideCallback.errors.txt @@ -1,4 +1,4 @@ -error TS-1: Pre-emit (11) and post-emit (13) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here! +error TS-1: Pre-emit (12) and post-emit (14) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here! templateInsideCallback.js(2,13): error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags. templateInsideCallback.js(9,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag templateInsideCallback.js(10,12): error TS2304: Cannot find name 'T'. @@ -8,15 +8,16 @@ templateInsideCallback.js(23,5): error TS8039: A JSDoc '@template' tag may not f templateInsideCallback.js(30,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag templateInsideCallback.js(32,12): error TS2304: Cannot find name 'T'. templateInsideCallback.js(33,16): error TS2304: Cannot find name 'T'. +templateInsideCallback.js(33,22): error TS2304: Cannot find name 'U'. templateInsideCallback.js(38,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag templateInsideCallback.js(39,12): error TS2304: Cannot find name 'T'. -!!! error TS-1: Pre-emit (11) and post-emit (13) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here! +!!! error TS-1: Pre-emit (12) and post-emit (14) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here! !!! related TS-1: The excess diagnostics are: !!! related TS7012 templateInsideCallback.js:29:5: This overload implicitly returns the type 'any' because it lacks a return type annotation. !!! related TS7012 templateInsideCallback.js:37:5: This overload implicitly returns the type 'any' because it lacks a return type annotation. -==== templateInsideCallback.js (11 errors) ==== +==== templateInsideCallback.js (12 errors) ==== /** * @typedef Oops ~~~~ @@ -68,6 +69,8 @@ templateInsideCallback.js(39,12): error TS2304: Cannot find name 'T'. * @param {(x: T) => U[]} iterable ~ !!! error TS2304: Cannot find name 'T'. + ~ +!!! error TS2304: Cannot find name 'U'. * @returns {U[]} */ /**