Module: YARDSorbet::NodeUtils

Extended by:
T::Sig
Defined in:
lib/yard-sorbet/node_utils.rb

Overview

Helper methods for working with YARD AST Nodes

Constant Summary collapse

ATTRIBUTE_METHODS =

Command node types that can have type signatures

T.let(%i[attr attr_accessor attr_reader attr_writer].freeze, T::Array[Symbol])
SKIP_METHOD_CONTENTS =

Skip these method contents during BFS node traversal, they can have their own nested types via T.Proc

T.let(%i[params returns].freeze, T::Array[Symbol])
SigableNode =

Node types that can have type signatures

T.type_alias { T.any(YARD::Parser::Ruby::MethodDefinitionNode, YARD::Parser::Ruby::MethodCallNode) }

Class Method Summary collapse

Class Method Details

.bfs_traverse(node, &_blk) {|YARD::Parser::Ruby::AstNode| ... } ⇒ void

Note:

This will skip over some node types.

This method returns an undefined value.

Traverse AST nodes in breadth-first order

Parameters:

  • node (YARD::Parser::Ruby::AstNode)
  • _blk (T.proc.params(n: YARD::Parser::Ruby::AstNode).void)

Yields:

  • (YARD::Parser::Ruby::AstNode)


22
23
24
25
26
27
28
29
30
# File 'lib/yard-sorbet/node_utils.rb', line 22

def self.bfs_traverse(node, &_blk)
  queue = [node]
  until queue.empty?
    n = T.must(queue.shift)
    yield n
    n.children.each { |c| queue.push(c) }
    queue.pop if n.is_a?(YARD::Parser::Ruby::MethodCallNode) && SKIP_METHOD_CONTENTS.include?(n.method_name(true))
  end
end

.get_method_node(node) ⇒ SigableNode

Gets the node that a sorbet sig can be attached do, bypassing visisbility modifiers and the like

Parameters:

  • node (YARD::Parser::Ruby::AstNode)

Returns:



34
35
36
37
38
39
40
41
42
43
# File 'lib/yard-sorbet/node_utils.rb', line 34

def self.get_method_node(node)
  case node
  when YARD::Parser::Ruby::MethodDefinitionNode
    return node
  when YARD::Parser::Ruby::MethodCallNode
    return node if ATTRIBUTE_METHODS.include?(node.method_name(true))
  end

  node.jump(:def, :defs)
end

.sibling_node(node) ⇒ YARD::Parser::Ruby::AstNode

Find and return the adjacent node (ascending)

Parameters:

  • node (YARD::Parser::Ruby::AstNode)

Returns:

  • (YARD::Parser::Ruby::AstNode)

Raises:

  • (IndexError)

    if the node does not have an adjacent sibling (ascending)



48
49
50
51
52
# File 'lib/yard-sorbet/node_utils.rb', line 48

def self.sibling_node(node)
  siblings = node.parent.children
  node_index = siblings.find_index { |sibling| sibling.equal?(node) }
  siblings.fetch(node_index + 1)
end