From 838db2766a8b3da2d524abbddfd590b7d871e2c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 19:41:46 +0000 Subject: [PATCH 1/4] Initial plan From cd0eb30aeb2d25acd6ea90a4c2e0c7ea292d3392 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 19:56:19 +0000 Subject: [PATCH 2/4] Fix panic when @callback/@overload @param has a qualified name Guard needCollisionCheckForIdentifier against non-Identifier nodes (e.g., QualifiedName from @param x.y) to match TypeScript's behavior where the function only accepts Identifier | undefined. Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/435989fa-39a8-4d7a-aeca-6166b6e55db8 Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- internal/checker/checker.go | 2 +- .../jsdocCallbackParamQualifiedName.errors.txt | 12 ++++++++++++ .../compiler/jsdocCallbackParamQualifiedName.symbols | 9 +++++++++ .../compiler/jsdocCallbackParamQualifiedName.types | 9 +++++++++ .../compiler/jsdocCallbackParamQualifiedName.ts | 9 +++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt create mode 100644 testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols create mode 100644 testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types create mode 100644 testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 020fe61193..382676a70a 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -10453,7 +10453,7 @@ func (c *Checker) checkCollisionWithGlobalObjectInGeneratedCode(node *ast.Node, } func (c *Checker) needCollisionCheckForIdentifier(node *ast.Node, identifier *ast.Node, name string) bool { - if identifier != nil && identifier.Text() != name { + if identifier == nil || !ast.IsIdentifier(identifier) || identifier.Text() != name { return false } switch node.Kind { diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt new file mode 100644 index 0000000000..8b6bda81bc --- /dev/null +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt @@ -0,0 +1,12 @@ +bug.js(3,4): error TS7006: Parameter 'x.y' implicitly has an 'any' type. + + +==== bug.js (1 errors) ==== + /** + * @callback cb + * @param x.y + ~~~~~~~~~~ + */ + ~ +!!! error TS7006: Parameter 'x.y' implicitly has an 'any' type. + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols new file mode 100644 index 0000000000..ef1a647f4b --- /dev/null +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/jsdocCallbackParamQualifiedName.ts] //// + +=== bug.js === + +/** + * @callback cb + * @param x.y + */ + diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types new file mode 100644 index 0000000000..ef1a647f4b --- /dev/null +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types @@ -0,0 +1,9 @@ +//// [tests/cases/compiler/jsdocCallbackParamQualifiedName.ts] //// + +=== bug.js === + +/** + * @callback cb + * @param x.y + */ + diff --git a/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts new file mode 100644 index 0000000000..8fca686235 --- /dev/null +++ b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts @@ -0,0 +1,9 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @filename: bug.js +/** + * @callback cb + * @param x.y + */ From dd9999591983cdf132920790a5b55347fb40b9ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 20:42:59 +0000 Subject: [PATCH 3/4] Fix in reparser: skip qualified-name params when creating ParameterDeclarations Sub-property JSDoc params like @param x.y have QualifiedNames and describe properties of a parent parameter, not standalone parameters. The reparser should skip these instead of creating ParameterDeclarations with QualifiedNames, which is the root cause of the panic. Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/6da36b57-11b5-459e-a9e2-b5a1b47f5943 Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- internal/checker/checker.go | 2 +- internal/parser/reparser.go | 5 +++++ .../jsdocCallbackParamQualifiedName.errors.txt | 12 ------------ .../compiler/jsdocCallbackParamQualifiedName.symbols | 6 ++++++ .../compiler/jsdocCallbackParamQualifiedName.types | 6 ++++++ .../compiler/jsdocCallbackParamQualifiedName.ts | 6 ++++++ 6 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 382676a70a..020fe61193 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -10453,7 +10453,7 @@ func (c *Checker) checkCollisionWithGlobalObjectInGeneratedCode(node *ast.Node, } func (c *Checker) needCollisionCheckForIdentifier(node *ast.Node, identifier *ast.Node, name string) bool { - if identifier == nil || !ast.IsIdentifier(identifier) || identifier.Text() != name { + if identifier != nil && identifier.Text() != name { return false } switch node.Kind { diff --git a/internal/parser/reparser.go b/internal/parser/reparser.go index d482e8ad72..cbb48352ab 100644 --- a/internal/parser/reparser.go +++ b/internal/parser/reparser.go @@ -135,6 +135,11 @@ func (p *Parser) reparseJSDocSignature(jsSignature *ast.Node, fun *ast.Node, jsD } } else if param.Kind == ast.KindJSDocParameterTag || param.Kind == ast.KindJSDocPropertyTag { jsparam := param.AsJSDocParameterOrPropertyTag() + // Skip sub-property parameters (e.g., @param x.y) - these have QualifiedNames + // and describe properties of a parent parameter, not standalone parameters. + if ast.IsQualifiedName(jsparam.Name()) { + continue + } var dotDotDotToken *ast.Node var paramType *ast.TypeNode diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt deleted file mode 100644 index 8b6bda81bc..0000000000 --- a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -bug.js(3,4): error TS7006: Parameter 'x.y' implicitly has an 'any' type. - - -==== bug.js (1 errors) ==== - /** - * @callback cb - * @param x.y - ~~~~~~~~~~ - */ - ~ -!!! error TS7006: Parameter 'x.y' implicitly has an 'any' type. - \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols index ef1a647f4b..7badd6e10a 100644 --- a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols @@ -7,3 +7,9 @@ * @param x.y */ +/** + * @callback cb2 + * @param {object} x + * @param {string} x.y + */ + diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types index ef1a647f4b..7badd6e10a 100644 --- a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types @@ -7,3 +7,9 @@ * @param x.y */ +/** + * @callback cb2 + * @param {object} x + * @param {string} x.y + */ + diff --git a/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts index 8fca686235..9f630b60ed 100644 --- a/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts +++ b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts @@ -7,3 +7,9 @@ * @callback cb * @param x.y */ + +/** + * @callback cb2 + * @param {object} x + * @param {string} x.y + */ From dac332838bd920e331e67bb6e290e437dd12d7ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 21:18:52 +0000 Subject: [PATCH 4/4] Add @overload test case with qualified @param Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/9169ebac-be22-4565-a138-50bf451ec3bd Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- ...jsdocCallbackParamQualifiedName.errors.txt | 31 +++++++++++++++++++ .../jsdocCallbackParamQualifiedName.symbols | 19 +++++++++++- .../jsdocCallbackParamQualifiedName.types | 21 ++++++++++++- .../jsdocCallbackParamQualifiedName.ts | 14 +++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt new file mode 100644 index 0000000000..487c98d509 --- /dev/null +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.errors.txt @@ -0,0 +1,31 @@ +bug.js(23,14): error TS2339: Property 'y' does not exist on type 'object'. + + +==== bug.js (1 errors) ==== + /** + * @callback cb + * @param x.y + */ + + /** + * @callback cb2 + * @param {object} x + * @param {string} x.y + */ + + /** + * @overload + * @param {object} x + * @param {string} x.y + * @returns {string} + */ + /** + * @param {object} x + * @returns {string} + */ + function foo(x) { + return x.y; + ~ +!!! error TS2339: Property 'y' does not exist on type 'object'. + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols index 7badd6e10a..af3105570c 100644 --- a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.symbols @@ -1,7 +1,6 @@ //// [tests/cases/compiler/jsdocCallbackParamQualifiedName.ts] //// === bug.js === - /** * @callback cb * @param x.y @@ -13,3 +12,21 @@ * @param {string} x.y */ +/** + * @overload + * @param {object} x + * @param {string} x.y + * @returns {string} + */ +/** + * @param {object} x + * @returns {string} + */ +function foo(x) { +>foo : Symbol(foo, Decl(bug.js, 12, 4), Decl(bug.js, 0, 0)) +>x : Symbol(x, Decl(bug.js, 21, 13)) + + return x.y; +>x : Symbol(x, Decl(bug.js, 21, 13)) +} + diff --git a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types index 7badd6e10a..5c2595bf02 100644 --- a/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types +++ b/testdata/baselines/reference/compiler/jsdocCallbackParamQualifiedName.types @@ -1,7 +1,6 @@ //// [tests/cases/compiler/jsdocCallbackParamQualifiedName.ts] //// === bug.js === - /** * @callback cb * @param x.y @@ -13,3 +12,23 @@ * @param {string} x.y */ +/** + * @overload + * @param {object} x + * @param {string} x.y + * @returns {string} + */ +/** + * @param {object} x + * @returns {string} + */ +function foo(x) { +>foo : (x: { y: string; }) => string +>x : object + + return x.y; +>x.y : any +>x : object +>y : any +} + diff --git a/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts index 9f630b60ed..98f5575ffc 100644 --- a/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts +++ b/testdata/tests/cases/compiler/jsdocCallbackParamQualifiedName.ts @@ -13,3 +13,17 @@ * @param {object} x * @param {string} x.y */ + +/** + * @overload + * @param {object} x + * @param {string} x.y + * @returns {string} + */ +/** + * @param {object} x + * @returns {string} + */ +function foo(x) { + return x.y; +}