@@ -125,10 +125,8 @@ func getTokenAtPosition(
125125 return nodeList
126126 }
127127
128- nodeVisitor := getNodeVisitor (visitNode , visitNodeList )
129-
130128 for {
131- VisitEachChildAndJSDoc (current , sourceFile , nodeVisitor )
129+ VisitEachChildAndJSDoc (current , sourceFile , visitNode , visitNodeList )
132130 // If prevSubtree was set on the last iteration, it ends at the target position.
133131 // Check if the rightmost token of prevSubtree should be returned based on the
134132 // `includePrecedingTokenAtEndPosition` callback.
@@ -146,7 +144,7 @@ func getTokenAtPosition(
146144 // we can in the AST. We've either found a token, or we need to run the scanner
147145 // to construct one that isn't stored in the AST.
148146 if next == nil {
149- if ast .IsTokenKind (current .Kind ) || ast . IsJSDocCommentContainingNode (current ) {
147+ if ast .IsTokenKind (current .Kind ) || shouldSkipChild (current ) {
150148 return current
151149 }
152150 scanner := scanner .GetScannerForSourceFile (sourceFile , left )
@@ -217,7 +215,13 @@ func findRightmostNode(node *ast.Node) *ast.Node {
217215 }
218216}
219217
220- func VisitEachChildAndJSDoc (node * ast.Node , sourceFile * ast.SourceFile , visitor * ast.NodeVisitor ) {
218+ func VisitEachChildAndJSDoc (
219+ node * ast.Node ,
220+ sourceFile * ast.SourceFile ,
221+ visitNode func (* ast.Node , * ast.NodeVisitor ) * ast.Node ,
222+ visitNodes func (* ast.NodeList , * ast.NodeVisitor ) * ast.NodeList ,
223+ ) {
224+ visitor := getNodeVisitor (visitNode , visitNodes )
221225 if node .Flags & ast .NodeFlagsHasJSDoc != 0 {
222226 for _ , jsdoc := range node .JSDoc (sourceFile ) {
223227 if visitor .Hooks .VisitNode != nil {
@@ -275,9 +279,6 @@ func FindPrecedingTokenEx(sourceFile *ast.SourceFile, position int, startNode *a
275279 }
276280 if nodeList != nil && len (nodeList .Nodes ) > 0 {
277281 nodes := nodeList .Nodes
278- if ast .IsJSDocSingleCommentNodeList (n , nodeList ) {
279- return nodeList
280- }
281282 index , match := core .BinarySearchUniqueFunc (nodes , func (middle int , _ * ast.Node ) int {
282283 // synthetic jsdoc nodes should have jsdocNode.End() <= n.Pos()
283284 if nodes [middle ].Flags & ast .NodeFlagsReparsed != 0 {
@@ -308,8 +309,7 @@ func FindPrecedingTokenEx(sourceFile *ast.SourceFile, position int, startNode *a
308309 }
309310 return nodeList
310311 }
311- nodeVisitor := getNodeVisitor (visitNode , visitNodes )
312- VisitEachChildAndJSDoc (n , sourceFile , nodeVisitor )
312+ VisitEachChildAndJSDoc (n , sourceFile , visitNode , visitNodes )
313313
314314 if foundChild != nil {
315315 // Note that the span of a node's tokens is [getStartOfNode(node, ...), node.end).
@@ -420,9 +420,6 @@ func findRightmostValidToken(endPos int, sourceFile *ast.SourceFile, containingN
420420 }
421421 visitNodes := func (nodeList * ast.NodeList , _ * ast.NodeVisitor ) * ast.NodeList {
422422 if nodeList != nil && len (nodeList .Nodes ) > 0 {
423- if ast .IsJSDocSingleCommentNodeList (n , nodeList ) {
424- return nodeList
425- }
426423 hasChildren = true
427424 index , _ := core .BinarySearchUniqueFunc (nodeList .Nodes , func (middle int , node * ast.Node ) int {
428425 if node .End () > endPos {
@@ -450,16 +447,15 @@ func findRightmostValidToken(endPos int, sourceFile *ast.SourceFile, containingN
450447 }
451448 return nodeList
452449 }
453- nodeVisitor := getNodeVisitor (visitNode , visitNodes )
454- VisitEachChildAndJSDoc (n , sourceFile , nodeVisitor )
450+ VisitEachChildAndJSDoc (n , sourceFile , visitNode , visitNodes )
455451
456452 // Three cases:
457453 // 1. The answer is a token of `rightmostValidNode`.
458454 // 2. The answer is one of the unvisited tokens that occur after the rightmost valid node.
459455 // 3. The current node is a childless, token-less node. The answer is the current node.
460456
461457 // Case 2: Look at unvisited trailing tokens that occur in between the rightmost visited nodes.
462- if ! ast . IsJSDocCommentContainingNode (n ) { // JSDoc nodes don't include trivia tokens as children.
458+ if ! shouldSkipChild (n ) { // JSDoc nodes don't include trivia tokens as children.
463459 var startPos int
464460 if rightmostValidNode != nil {
465461 startPos = rightmostValidNode .End ()
@@ -563,8 +559,7 @@ func FindNextToken(previousToken *ast.Node, parent *ast.Node, file *ast.SourceFi
563559 }
564560 return nodeList
565561 }
566- nodeVisitor := getNodeVisitor (visitNode , visitNodes )
567- VisitEachChildAndJSDoc (n , file , nodeVisitor )
562+ VisitEachChildAndJSDoc (n , file , visitNode , visitNodes )
568563 // Cases:
569564 // 1. no answer exists
570565 // 2. answer is an unvisited token
@@ -597,15 +592,44 @@ func getNodeVisitor(
597592 visitNode func (* ast.Node , * ast.NodeVisitor ) * ast.Node ,
598593 visitNodes func (* ast.NodeList , * ast.NodeVisitor ) * ast.NodeList ,
599594) * ast.NodeVisitor {
595+ var wrappedVisitNode func (* ast.Node , * ast.NodeVisitor ) * ast.Node
596+ var wrappedVisitNodes func (* ast.NodeList , * ast.NodeVisitor ) * ast.NodeList
597+ if visitNode != nil {
598+ wrappedVisitNode = func (n * ast.Node , v * ast.NodeVisitor ) * ast.Node {
599+ if ast .IsJSDocSingleCommentNodeComment (n ) {
600+ return n
601+ }
602+ return visitNode (n , v )
603+ }
604+ }
605+
606+ if visitNodes != nil {
607+ wrappedVisitNodes = func (n * ast.NodeList , v * ast.NodeVisitor ) * ast.NodeList {
608+ if ast .IsJSDocSingleCommentNodeList (n ) {
609+ return n
610+ }
611+ return visitNodes (n , v )
612+ }
613+ }
614+
600615 return ast .NewNodeVisitor (core .Identity , nil , ast.NodeVisitorHooks {
601- VisitNode : visitNode ,
602- VisitToken : visitNode ,
603- VisitNodes : visitNodes ,
616+ VisitNode : wrappedVisitNode ,
617+ VisitToken : wrappedVisitNode ,
618+ VisitNodes : wrappedVisitNodes ,
604619 VisitModifiers : func (modifiers * ast.ModifierList , visitor * ast.NodeVisitor ) * ast.ModifierList {
605620 if modifiers != nil {
606- visitNodes (& modifiers .NodeList , visitor )
621+ wrappedVisitNodes (& modifiers .NodeList , visitor )
607622 }
608623 return modifiers
609624 },
610625 })
611626}
627+
628+ func shouldSkipChild (node * ast.Node ) bool {
629+ return node .Kind == ast .KindJSDoc ||
630+ node .Kind == ast .KindJSDocText ||
631+ node .Kind == ast .KindJSDocTypeLiteral ||
632+ node .Kind == ast .KindJSDocSignature ||
633+ ast .IsJSDocLinkLike (node ) ||
634+ ast .IsJSDocTag (node )
635+ }
0 commit comments