Skip to content

Conversation

gabritto
Copy link
Member

Fixes #1298.

The issue had two different call stacks, but it turned out to be the same bug that was showing up in two different places.

I had to add a very minimal version of fourslash.VerifySignatureHelp to be able to write a fourslash test for this.

Context:
node.getChildren() has been replaced in Corsa by code that visits child nodes and uses the scanner to obtain child tokens. In this new setup, we use sourceFile.GetOrCreateToken to get a token object if one has been created before, or creating a new token object and caching it. That's done like that because we want the invariant that if you call sourceFile.GetOrCreateToken with the same token information (i.e. same kind, position, etc), you get the same Go object and comparing tokens by pointer equality will work out. A consequence of this is that you have to provide the same parent when getting or creating a token, i.e. the parent the token would have in Strada.

getTokensFromNode in signature help was not respecting this: it was using the scanner to scan all tokens in the range of a given node, and assuming the given node would be the token's parent. That's wrong because a token in the given node's range could have e.g. a child of that node as its parent. For instance, if you have the call expression node foo(()), then the first ( token has the call expression as parent, but the second ( has as parent the parenthesized expression ().

@Copilot Copilot AI review requested due to automatic review settings August 14, 2025 19:07
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug in signature help functionality where tokens were being assigned incorrect parent nodes, causing crashes during signature help requests. The issue occurred because the original getTokensFromNode function was incorrectly assuming that all tokens within a node's range had that node as their parent.

Key changes:

  • Replaced getTokensFromNode with getChildrenFromNode that properly uses ForEachChild to traverse actual child nodes
  • Updated the token creation logic to scan between child nodes and assign correct parent relationships
  • Added fourslash test infrastructure for signature help verification to prevent regressions

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
internal/ls/signaturehelp.go Core fix: replaced token scanning logic with proper child node traversal and correct parent assignment
internal/fourslash/tests/signatureHelpTokenCrash_test.go New test case reproducing the crash scenario with nested parentheses in function calls
internal/fourslash/fourslash.go Added VerifySignatureHelp infrastructure and refactored position prefix generation for better test support

Comment on lines +1655 to +1661
token := scanner.Token()
tokenFullStart := scanner.TokenFullStart()
tokenEnd := scanner.TokenEnd()
children = append(children, sourceFile.GetOrCreateToken(token, tokenFullStart, tokenEnd, node))
pos = tokenEnd
scanner.Scan()
}
Copy link
Member

Choose a reason for hiding this comment

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

This code seems to never be run; do we just not have an examples of trailing tokens at the moment? (The code seems correct, I think anyway)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I think it's just not tested right now, especially since it's only signature help using it and I don't know how good the signature help tests are in terms of coverage (even in Strada).

@gabritto gabritto added this pull request to the merge queue Aug 14, 2025
Merged via the queue into main with commit 0711420 Aug 14, 2025
22 checks passed
@gabritto gabritto deleted the gabritto/issue1298 branch August 14, 2025 21:19
andrewbranch pushed a commit to andrewbranch/typescript-go that referenced this pull request Aug 18, 2025
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.

panic handling request textDocument/signatureHelp Token cache mismatch: parent. Expected parent of kind KindAsExpression, got KindCallExpression

2 participants