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
-
.bfs_traverse(node, &_blk) {|YARD::Parser::Ruby::AstNode| ... } ⇒ void
Traverse AST nodes in breadth-first order.
- .delete_node(node) ⇒ void
-
.enqueue_children(queue, node) ⇒ void
Enqueue the eligible children of a node in the BFS queue.
-
.get_method_node(node) ⇒ SigableNode
Gets the node that a sorbet
sig
can be attached do, bypassing visisbility modifiers and the like. -
.sibling_node(node) ⇒ YARD::Parser::Ruby::AstNode
Find and return the adjacent node (ascending).
- .sigable_node?(node) ⇒ Boolean
- .validated_attribute_names(attr_node) ⇒ Array<String>
Class Method Details
.bfs_traverse(node, &_blk) {|YARD::Parser::Ruby::AstNode| ... } ⇒ void
This will skip over some node types.
This method returns an undefined value.
Traverse AST nodes in breadth-first order
21 22 23 24 25 26 27 28 |
# File 'lib/yard-sorbet/node_utils.rb', line 21 def self.bfs_traverse(node, &_blk) queue = Queue.new << node until queue.empty? n = queue.deq(true) yield n enqueue_children(queue, n) end end |
.delete_node(node) ⇒ void
This method returns an undefined value.
31 |
# File 'lib/yard-sorbet/node_utils.rb', line 31 def self.delete_node(node) = node.parent.children.delete(node) |
.enqueue_children(queue, node) ⇒ void
This method returns an undefined value.
Enqueue the eligible children of a node in the BFS queue
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/yard-sorbet/node_utils.rb', line 35 def self.enqueue_children(queue, node) last_child = node.children.last node.children.each do |child| next if child == last_child && node.is_a?(YARD::Parser::Ruby::MethodCallNode) && SKIP_METHOD_CONTENTS.include?(node.method_name(true)) queue.enq(child) end end |
.get_method_node(node) ⇒ SigableNode
Gets the node that a sorbet sig
can be attached do, bypassing visisbility modifiers and the like
48 |
# File 'lib/yard-sorbet/node_utils.rb', line 48 def self.get_method_node(node) = sigable_node?(node) ? node : node.jump(:def, :defs) |
.sibling_node(node) ⇒ YARD::Parser::Ruby::AstNode
Find and return the adjacent node (ascending)
53 54 55 56 57 |
# File 'lib/yard-sorbet/node_utils.rb', line 53 def self.sibling_node(node) siblings = node.parent.children node_index = siblings.find_index { _1.equal?(node) } siblings.fetch(node_index + 1) end |
.sigable_node?(node) ⇒ Boolean
60 61 62 63 64 65 66 |
# File 'lib/yard-sorbet/node_utils.rb', line 60 def self.sigable_node?(node) case node when YARD::Parser::Ruby::MethodDefinitionNode then true when YARD::Parser::Ruby::MethodCallNode then ATTRIBUTE_METHODS.include?(node.method_name(true)) else false end end |
.validated_attribute_names(attr_node) ⇒ Array<String>
71 72 73 74 75 76 77 78 |
# File 'lib/yard-sorbet/node_utils.rb', line 71 def self.validated_attribute_names(attr_node) attr_node.parameters(false).map do |obj| case obj when YARD::Parser::Ruby::LiteralNode then obj[0][0].source else raise YARD::Parser::UndocumentableError, obj.source end end end |