Skip to content

Conversation

@jgsheppa
Copy link

@jgsheppa jgsheppa commented Dec 11, 2025

This is a fix for #2290.

It would seem that type elements can also be included in JSDoc comments, so a check was added in addition to ast.ISJSDocKind to allow for property signatures among other type elements.

Note: This is my first contribution to the TypeScript compiler, so if I'm totally off the mark, feel free to be blunt about it.

@jgsheppa
Copy link
Author

@jgsheppa please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree

@jgsheppa jgsheppa marked this pull request as ready for review December 11, 2025 13:53
@gabritto gabritto self-requested a review December 11, 2025 17:21
if tokenStart <= position && (position < tokenEnd) {
if token == ast.KindIdentifier || !ast.IsTokenKind(token) {
if ast.IsJSDocKind(current.Kind) {
if ast.IsJSDocKind(current.Kind) || ast.IsTypeElement(current) {
Copy link
Member

@DanielRosenwasser DanielRosenwasser Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't feel like the right fix- the code path here is meant to be extremely general, and I think you can repro this for any construct that

  1. Contains a list of nodes (e.g. a NodeList)
  2. Intersperses with a *
/**
 * @type {[
 * /*$*/ SomeType,
 * ]} 
 */
error] panic handling request textDocument/completion: did not expect KindTypeReference to have KindIdentifier in its trivia
goroutine 3162 [running]:
runtime/debug.Stack()
	runtime/debug/stack.go:26 +0x5e
github.com/microsoft/typescript-go/internal/lsp.(*Server).recover(0xc0001d6008, 0xc00e95fda0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:701 +0x4c
panic({0xbb8320?, 0xc00df28a80?})
	runtime/panic.go:783 +0x132
github.com/microsoft/typescript-go/internal/astnav.getTokenAtPosition(0xc01249e008, 0x13, 0x1, 0x0)
	github.com/microsoft/typescript-go/internal/astnav/tokens.go:196 +0x5f9
github.com/microsoft/typescript-go/internal/astnav.GetTokenAtPosition(...)
	github.com/microsoft/typescript-go/internal/astnav/tokens.go:40
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).getCompletionData(0xc00dba6240, {0x109efa8, 0xc00dba61e0}, 0xc003df8c08, 0xc01249e008, 0x13, 0xc00371f400)
	github.com/microsoft/typescript-go/internal/ls/completions.go:454 +0xce
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).getCompletionsAtPosition(0xc00dba6240, {0x109efa8, 0xc00dba61e0}, 0xc01249e008, 0x13, 0x0)
	github.com/microsoft/typescript-go/internal/ls/completions.go:383 +0x2cf
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).ProvideCompletion(0xc00dba6240, {0x109efa8, 0xc00dba61e0}, {0xc003d82390?, 0xc00dba61e0?}, {0x3d82390?, 0xc0?}, 0xc0151180f0)
	github.com/microsoft/typescript-go/internal/ls/completions.go:44 +0xc8
github.com/microsoft/typescript-go/internal/lsp.(*Server).handleCompletion(0xc00110e008?, {0x109efa8?, 0xc00dba61e0?}, 0xc003d82390?, 0x40b92c?)
	github.com/microsoft/typescript-go/internal/lsp/server.go:1011 +0x39
github.com/microsoft/typescript-go/internal/lsp.init.func1.registerLanguageServiceDocumentRequestHandler[...].16({0x109efa8, 0xc00dba61e0}, 0xc00e95fda0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:617 +0x130
github.com/microsoft/typescript-go/internal/lsp.(*Server).handleRequestOrNotification(0xc0001d6008, {0x109efe0?, 0xc00f516410?}, 0xc00e95fda0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:501 +0x14b
github.com/microsoft/typescript-go/internal/lsp.(*Server).dispatchLoop.func1()
	github.com/microsoft/typescript-go/internal/lsp/server.go:404 +0x3a
created by github.com/microsoft/typescript-go/internal/lsp.(*Server).dispatchLoop in goroutine 7
	github.com/microsoft/typescript-go/internal/lsp/server.go:424 +0x9ad

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another example:

/**
 * @type {(
 *  a: string
 * /**/ b
 * ) => string} 
 */

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in general the panic we had before was correct: if we're walking trivia for a non-JSDoc node, we shouldn't find a dangling identifier. Maybe the root problem is that if we're inside a JSDoc, but current is a non-JSDoc node, we run into problems when scanning for the in-between tokens because we're also inside JSDoc?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably should have asked some preliminary question in the ticket, but I'll ask them now 😅

The panic would cause the build to fail, as I understand the code, which seems like the desired behavior if there is an additional comment, such as /*$*/ inside of a JSDoc. So what @gabritto sounds right to me. But what is the expected behavior given an example such as the on below?

/**
 * @type {(
 *  a: string
 * /**/ b
 * ) => string} 
 */

Or is my understanding off the mark?

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.

3 participants