Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 4, 2025

Panic when type-checking JavaScript files with JSDoc @overload annotations, caused by invalid AST structures created by the reparser.

Root Cause

The reparser was creating synthetic MethodDeclaration nodes for ALL @overload JSDoc tags, including those on object literal methods. This created invalid AST structures where a MethodDeclaration was a direct child of SourceFile (e.g., for methods in object literals), resulting in the panic:

KindStringKeyword -> KindParameter -> KindMethodDeclaration -> KindSourceFile

Changes

  • Modified reparseUnhosted() to only create synthetic overload declarations for legal contexts:
    • Function declarations (KindFunctionDeclaration)
    • Class methods (KindMethodDeclaration when not in PCObjectLiteralMembers parsing context)
    • Interface methods (KindMethodSignature)
  • Reports parsing error TS8110 for @overload tags on object literal methods
  • Added nil check in getConditionalFlowTypeOfType to prevent panic when nodes have nil parents
  • Added new diagnostic message TS8110: "A JSDoc '@overload' tag is not allowed in this context."
  • Added regression test case with JSDoc overloads that previously panicked

Example

The following JavaScript now reports a parsing error instead of panicking:

const foo = {
	/**
	 * @overload
	 * @param {string} termCode
	 * @param {string[]} crnList
	 * @returns {Record<string, string>}
	 */
	/**
	 * @param {string} termCode
	 * @param {string | string[]} crnList
	 * @returns {string | Record<string, string>}
	 */
	getStatus(termCode, crnList) {},
};

Error: error TS8110: A JSDoc '@overload' tag is not allowed in this context.

Function declarations and class methods with @overload continue to work correctly with proper overload declarations generated in .d.ts files.

Impact

This fix properly addresses the panic while maintaining full support for legal @overload use cases in function and class/interface method declarations. Object literal methods with @overload tags now receive appropriate parsing errors.

Original prompt

This section details on the original issue you should resolve

<issue_title>Panic on initial attempt of existing JavaScript + JSDoc project</issue_title>
<issue_description>## Stack trace

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x102a8783c]

goroutine 1 [running]:
github.com/microsoft/typescript-go/internal/ast.IsParameter(...)
	github.com/microsoft/typescript-go/internal/ast/ast.go:3976
github.com/microsoft/typescript-go/internal/checker.(*Checker).getConditionalFlowTypeOfType(0x14003eb4c08, 0x140043b8410, 0x14006a85658?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:24330 +0xac
github.com/microsoft/typescript-go/internal/checker.(*Checker).getTypeFromTypeNode(0x14003eb4c08, 0x14002531fc8)
	github.com/microsoft/typescript-go/internal/checker/checker.go:22257 +0x34
github.com/microsoft/typescript-go/internal/checker.(*Checker).tryGetTypeFromTypeNode(0x14003eb4c08, 0x102a634bc?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:22251 +0x34
github.com/microsoft/typescript-go/internal/checker.(*Checker).getTypeForVariableLikeDeclaration(0x14003eb4c08, 0x14002563468, 0x0?, 0x0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:16187 +0x17c
github.com/microsoft/typescript-go/internal/checker.(*Checker).getWidenedTypeForVariableLikeDeclaration(0x14003eb4c08, 0x14002563468, 0x1)
	github.com/microsoft/typescript-go/internal/checker/checker.go:16158 +0x30
github.com/microsoft/typescript-go/internal/checker.(*Checker).getTypeOfVariableOrParameterOrPropertyWorker(0x14003eb4c08, 0x14003d68a18)
	github.com/microsoft/typescript-go/internal/checker/checker.go:16118 +0x24c
github.com/microsoft/typescript-go/internal/checker.(*Checker).getTypeOfVariableOrParameterOrProperty(0x14003eb4c08, 0x14003d68a18)
	github.com/microsoft/typescript-go/internal/checker/checker.go:16055 +0x50
github.com/microsoft/typescript-go/internal/checker.(*Checker).getTypeOfSymbol(0x14003eb4c08?, 0x14002563468?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:16015 +0xa8
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkVariableLikeDeclaration(0x14003eb4c08, 0x14002563468)
	github.com/microsoft/typescript-go/internal/checker/checker.go:5703 +0x258
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkParameter(0x14003eb4c08, 0x14002563468)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2559 +0x30
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElementWorker(0x14003eb4c08, 0x14002563468)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2179 +0xa0
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElement(0x14003eb4c08, 0x102a1f250?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2150 +0x58
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElements(0x14003eb4c08, {0x1400211ce40, 0x3, 0x0?})
	github.com/microsoft/typescript-go/internal/checker/checker.go:2140 +0x34
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSignatureDeclaration(0x14003eb4c08, 0x140025126e0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2631 +0x100
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkFunctionOrMethodDeclaration(0x14003eb4c08, 0x140025126e0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:3297 +0x30
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkMethodDeclaration(0x14003eb4c08, 0x140025126e0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2694 +0x14c
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElementWorker(0x14003eb4c08, 0x140025126e0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2187 +0xb8
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElement(0x14003eb4c08, 0x140046fb5f0?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2150 +0x58
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElements(0x14003eb4c08, {0x140017bcc58, 0x1c, 0x140019fedc0?})
	github.com/microsoft/typescript-go/internal/checker/checker.go:2140 +0x34
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceFile(0x14003eb4c08, {0x1032a1600, 0x10391c860}, 0x14002521508)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2112 +0xf4
github.com/microsoft/typescript-go/internal/checker.(*Checker).CheckSourceFile(0x14003eb4c08, {0x1032a1600, 0x10391c860}, 0x14002521508)
	github.com/microsoft/typescript-go/internal/checker/checker.go:2101 +0x64
github.com/microsoft/typescript-go/internal/checker.(*Checker).getDiagnostics(0x14003eb4c08, {0x1032a1600, 0x10391c860}, 0x14002521508, 0x14003eb4df0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:13516 +0xac
github.com/microsoft/typescript-go/internal/checker.(*Checker).GetDiagno...

</details>

- Fixes microsoft/typescript-go#2218

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

Copilot AI and others added 2 commits December 4, 2025 18:13
Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Add nil check for parent node to prevent panic when processing
JavaScript files with JSDoc overload annotations. The panic occurred
when parent was nil during type checking of parameters.

Includes regression test with JSDoc @overload annotations.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix panic error on initial attempt in JavaScript project Fix nil pointer panic in getConditionalFlowTypeOfType for JSDoc overloads Dec 4, 2025
Copilot AI requested a review from jakebailey December 4, 2025 18:28
Copilot finished work on behalf of jakebailey December 4, 2025 18:28
@jakebailey
Copy link
Member

@copilot

This is just a band-aid fix. The real problem is that we have this chain of AST nodes:

KindStringKeyword KindParameter KindMethodDeclaration KindSourceFile

We should not have a method declaration that is a child of a source file! That does not make any sense.

There must be an issue in the reparser's handling of overloads or something.

The reparser was creating synthetic MethodDeclaration nodes for @overload
tags and adding them to the top-level source file statements. This created
invalid AST structures where a MethodDeclaration was a direct child of
SourceFile (e.g., for methods in object literals).

TypeScript's implementation keeps overload information in the JSDoc structure
and retrieves it when needed by the checker/declaration emitter, rather than
creating synthetic AST nodes that get added to reparseList.

This fix removes the code that was creating these invalid synthetic nodes.
The overload information remains in the JSDoc and can be accessed by
future checker improvements.

Addresses feedback from @jakebailey about invalid AST structure:
KindStringKeyword -> KindParameter -> KindMethodDeclaration -> KindSourceFile

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 4, 2025

@copilot

This is just a band-aid fix. The real problem is that we have this chain of AST nodes:
...

Fixed in 7d45569. The reparser was incorrectly creating synthetic MethodDeclaration nodes for @overload tags and adding them to reparseList, which caused them to be appended as top-level SourceFile statements. This has been removed - overload information now stays in the JSDoc structure as in TypeScript's implementation.

@jakebailey
Copy link
Member

Well, that is certainly wrong.

Do we even allow overloads on object literal methods in TypeScript? Is this just something we must ban in JS? @sandersn

Address code review feedback: moved the comment explaining why
JSDocOverloadTag is not handled to the top of the function for clarity.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title Fix nil pointer panic in getConditionalFlowTypeOfType for JSDoc overloads Fix panic caused by invalid AST structure in JSDoc overload handling Dec 4, 2025
Copilot finished work on behalf of jakebailey December 4, 2025 19:10
@jakebailey
Copy link
Member

@copilot This fix is too broad.

We need to instead change the reparser to ban @overload in any context where an overload would not be legal in TS, which should just be function and class/interface method declarations. This means that these object method overloads would be illegal.

There are existing errors to this effect in the parser/reparser that ban things that can be looked at for an example. You'll know if you did it right if jsFileFunctionOverloads's baseline changes get reverted.

Instead of removing all overload handling, now restrict @overload to only
legal contexts: function declarations and class/interface method declarations.
Object literal methods are silently ignored to maintain compatibility with
alternative @overload syntax.

Also added nil check in checker.getConditionalFlowTypeOfType to prevent panic
when synthetic overload nodes have nil parents.

This restores function and class method overload support while preventing
invalid AST structures from object literal methods.

Addresses @jakebailey's feedback to make the fix more targeted.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

@copilot This fix is too broad.

We need to instead change the reparser to ban @overload in any context where an overload would not be legal in TS, which should just be function and class/interfac...

Fixed in cf45e9c. Now only allows @overload on function declarations and class/interface methods. Object literal methods are silently ignored. Function overload baselines are restored as expected.

Clarified the logic for determining valid @overload contexts by
eliminating duplication and making the intent more explicit.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
@jakebailey
Copy link
Member

@copilot This should not be a silent error. We have a mechanism to issue JSDoc errors in parsing; use that.

Clarified the nil parent handling with explicit if/else to avoid
any potential confusion about short-circuit evaluation.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title Fix panic caused by invalid AST structure in JSDoc overload handling Fix panic by restricting @overload to legal contexts in JSDoc Dec 5, 2025
Copilot finished work on behalf of jakebailey December 5, 2025 18:06
Instead of silently ignoring @overload tags on object literal methods,
now reports error TS8110 using the parsing context to distinguish
between class methods (allowed) and object literal methods (disallowed).

Uses the PCObjectLiteralMembers parsing context flag to detect when
we're parsing an object literal, allowing proper error reporting during
the reparsing phase.

Addresses @jakebailey's feedback to use the JSDoc error reporting mechanism.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

@copilot This should not be a silent error. We have a mechanism to issue JSDoc errors in parsing; use that.

Fixed in bef66f5. Now reports error TS8110 for @overload on object literal methods using the PCObjectLiteralMembers parsing context to distinguish them from class methods.

Copilot finished work on behalf of jakebailey December 5, 2025 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants