MCPcopy Create free account
hub / github.com/microsoft/typescript-go / FindPrecedingTokenEx

Function FindPrecedingTokenEx

internal/astnav/tokens.go:332–452  ·  view source on GitHub ↗
(sourceFile *ast.SourceFile, position int, startNode *ast.Node, excludeJSDoc bool)

Source from the content-addressed store, hash-verified

330}
331
332func FindPrecedingTokenEx(sourceFile *ast.SourceFile, position int, startNode *ast.Node, excludeJSDoc bool) *ast.Node {
333 var find func(node *ast.Node) *ast.Node
334 find = func(n *ast.Node) *ast.Node {
335 if ast.IsNonWhitespaceToken(n) && n.Kind != ast.KindEndOfFile {
336 return n
337 }
338
339 // `foundChild` is the leftmost node that contains the target position.
340 // `prevChild` is the last visited child of the current node.
341 var foundChild, prevChild *ast.Node
342 visitNode := func(node *ast.Node, _ *ast.NodeVisitor) *ast.Node {
343 // skip synthesized nodes (that will exist now because of jsdoc handling)
344 if node == nil || node.Flags&ast.NodeFlagsReparsed != 0 {
345 return node
346 }
347 if foundChild != nil { // We cannot abort visiting children, so once the desired child is found, we do nothing.
348 return node
349 }
350 if position < node.End() && (prevChild == nil || prevChild.End() <= position) {
351 foundChild = node
352 } else {
353 prevChild = node
354 }
355 return node
356 }
357 visitNodes := func(nodeList *ast.NodeList, _ *ast.NodeVisitor) *ast.NodeList {
358 if foundChild != nil {
359 return nodeList
360 }
361 if nodeList != nil && len(nodeList.Nodes) > 0 {
362 nodes := nodeList.Nodes
363 index, match := core.BinarySearchUniqueFunc(nodes, func(middle int, _ *ast.Node) int {
364 // synthetic jsdoc nodes should have jsdocNode.End() <= n.Pos()
365 if nodes[middle].Flags&ast.NodeFlagsReparsed != 0 {
366 return comparisonLessThan
367 }
368 if position < nodes[middle].End() {
369 if middle == 0 || position >= nodes[middle-1].End() {
370 return comparisonEqualTo
371 }
372 return comparisonGreaterThan
373 }
374 return comparisonLessThan
375 })
376
377 if match {
378 foundChild = nodes[index]
379 }
380
381 validLookupIndex := core.IfElse(match, index-1, len(nodes)-1)
382 for i := validLookupIndex; i >= 0; i-- {
383 if nodes[i].Flags&ast.NodeFlagsReparsed != 0 {
384 continue
385 }
386 if prevChild == nil {
387 prevChild = nodes[i]
388 }
389 }

Callers 5

createCompletionItemMethod · 0.92
containsPrecedingTokenFunction · 0.92
GetIndentationFunction · 0.92
getTokenAtPositionFunction · 0.85
FindPrecedingTokenFunction · 0.85

Calls 15

EndMethod · 0.95
PosMethod · 0.95
IsNonWhitespaceTokenFunction · 0.92
BinarySearchUniqueFuncFunction · 0.92
IfElseFunction · 0.92
IsWhitespaceOnlyJsxTextFunction · 0.92
lenFunction · 0.85
VisitEachChildAndJSDocFunction · 0.85
GetStartOfNodeFunction · 0.85
panicFunction · 0.85
JSDocMethod · 0.80
isValidPrecedingNodeFunction · 0.70

Tested by

no test coverage detected