diff --git a/tsc/internal/astnav/tokens.go b/tsc/internal/astnav/tokens.go index b921912ad6884..99b58eb11fc6d 100644 --- a/tsc/internal/astnav/tokens.go +++ b/tsc/internal/astnav/tokens.go @@ -197,8 +197,9 @@ func getTokenAtPosition( return nodeList } + visitor := getNodeVisitor(visitNode, visitNodeList) for { - VisitEachChildAndJSDoc(current, sourceFile, visitNode, visitNodeList) + visitEachChildAndJSDoc(current, sourceFile, visitor) // If prevSubtree was set on the last iteration, it ends at the target position. // Check if the rightmost token of prevSubtree should be returned based on the // `includePrecedingTokenAtEndPosition` callback. @@ -315,7 +316,10 @@ func VisitEachChildAndJSDoc( visitNode func(*ast.Node, *ast.NodeVisitor) *ast.Node, visitNodes func(*ast.NodeList, *ast.NodeVisitor) *ast.NodeList, ) { - visitor := getNodeVisitor(visitNode, visitNodes) + visitEachChildAndJSDoc(node, sourceFile, getNodeVisitor(visitNode, visitNodes)) +} + +func visitEachChildAndJSDoc(node *ast.Node, sourceFile *ast.SourceFile, visitor *ast.NodeVisitor) { for _, jsdoc := range node.JSDoc(sourceFile) { if visitor.Hooks.VisitNode != nil { visitor.Hooks.VisitNode(jsdoc, visitor) diff --git a/tsc/internal/astnav/tokens_test.go b/tsc/internal/astnav/tokens_test.go index 1a8a05f7cc72e..91596cb2e8e00 100644 --- a/tsc/internal/astnav/tokens_test.go +++ b/tsc/internal/astnav/tokens_test.go @@ -620,3 +620,15 @@ func tsFindPrecedingTokens(t *testing.T, fileText string, positions []int) []*to assert.NilError(t, err) return info } + +func BenchmarkGetTokenAtPositionNested(b *testing.B) { + text := "const value = " + strings.Repeat("call(", 24) + "target" + strings.Repeat(")", 24) + ";" + file := parser.ParseSourceFile(ast.SourceFileParseOptions{FileName: "/test.ts", PathKey: "/test.ts"}, text, core.ScriptKindTS) + position := strings.Index(text, "target") + b.ReportAllocs() + for b.Loop() { + if token := astnav.GetTokenAtPosition(file, position); token == nil || token.Kind != ast.KindIdentifier { + b.Fatal("target token not found") + } + } +}