Module: RBS::Prototype::Helpers
- Defined in:
- lib/rbs/prototype/helpers.rb,
sig/prototype/helpers.rbs
Instance Method Summary collapse
- #any_node?(node, nodes: []) {|arg0| ... } ⇒ Boolean
-
#args_from_node(args_node) ⇒ Array[untyped]
NOTE: args_node may be a nil by a bug https://bugs.ruby-lang.org/issues/17495.
- #block_from_body(node) ⇒ Types::Block?
- #each_child(node) {|child| ... } ⇒ void
- #each_node(nodes) {|arg0| ... } ⇒ void
- #keyword_hash?(node) ⇒ Boolean
- #parse_comments(string, include_trailing:) ⇒ Hash[Integer, AST::Comment]
-
#symbol_literal_node?(node) ⇒ Symbol?
Returns a symbol if the node is a symbol literal node.
- #untyped ⇒ Types::Bases::Any
Instance Method Details
#any_node?(node, nodes: []) {|arg0| ... } ⇒ Boolean
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/rbs/prototype/helpers.rb', line 153 def any_node?(node, nodes: [], &block) if yield(node) nodes << node end each_child node do |child| any_node? child, nodes: nodes, &block end nodes.empty? ? nil : nodes end |
#args_from_node(args_node) ⇒ Array[untyped]
NOTE: args_node may be a nil by a bug https://bugs.ruby-lang.org/issues/17495
177 178 179 |
# File 'lib/rbs/prototype/helpers.rb', line 177 def args_from_node(args_node) args_node&.children || [0, nil, nil, nil, 0, nil, nil, nil, nil, nil] end |
#block_from_body(node) ⇒ Types::Block?
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/rbs/prototype/helpers.rb', line 65 def block_from_body(node) _, args_node, body_node = node.children _pre_num, _pre_init, _opt, _first_post, _post_num, _post_init, _rest, _kw, _kwrest, block_var = args_from_node(args_node) # @type var body_node: node? if body_node yields = any_node?(body_node) {|n| n.type == :YIELD } end if yields || block_var required = true if body_node if any_node?(body_node) {|n| n.type == :FCALL && n.children[0] == :block_given? && !n.children[1] } required = false end end if _rest == :* && block_var == :& # ... is given required = false end if block_var if body_node usage = NodeUsage.new(body_node) if usage.each_conditional_node.any? {|n| n.type == :LVAR && n.children[0] == block_var } required = false end end end if yields function = Types::Function.empty(untyped) yields.each do |yield_node| array_content = yield_node.children[0]&.children&.compact || [] # @type var keywords: node? positionals, keywords = if keyword_hash?(array_content.last) [array_content.take(array_content.size - 1), array_content.last] else [array_content, nil] end if (diff = positionals.size - function.required_positionals.size) > 0 diff.times do function.required_positionals << Types::Function::Param.new( type: untyped, name: nil ) end end if keywords keywords.children[0].children.each_slice(2) do |key_node, value_node| if key_node key = key_node.children[0] function.required_keywords[key] ||= Types::Function::Param.new( type: untyped, name: nil ) end end end end else function = Types::UntypedFunction.new(return_type: untyped) end Types::Block.new(required: required, type: function, self_type: nil) end end |
#each_child(node) {|child| ... } ⇒ void
This method returns an undefined value.
141 142 143 |
# File 'lib/rbs/prototype/helpers.rb', line 141 def each_child(node, &block) each_node node.children, &block end |
#each_node(nodes) {|arg0| ... } ⇒ void
This method returns an undefined value.
145 146 147 148 149 150 151 |
# File 'lib/rbs/prototype/helpers.rb', line 145 def each_node(nodes) nodes.each do |child| if child.is_a?(RubyVM::AbstractSyntaxTree::Node) yield child end end end |
#keyword_hash?(node) ⇒ Boolean
165 166 167 168 169 170 171 172 173 |
# File 'lib/rbs/prototype/helpers.rb', line 165 def keyword_hash?(node) if node && node.type == :HASH node.children[0].children.compact.each_slice(2).all? {|key, _| symbol_literal_node?(key) } else false end end |
#parse_comments(string, include_trailing:) ⇒ Hash[Integer, AST::Comment]
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/rbs/prototype/helpers.rb', line 10 def parse_comments(string, include_trailing:) Prism.parse_comments(string, version: "current").yield_self do |prism_comments| # steep:ignore UnexpectedKeywordArgument prism_comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment] # Skip EmbDoc comments next unless comment.is_a?(Prism::InlineComment) # skip like `module Foo # :nodoc:` next if comment.trailing? && !include_trailing line = comment.location.start_line body = "#{comment.location.slice}\n" body = body[2..-1] or raise body = "\n" if body.empty? comment = AST::Comment.new(string: body, location: nil) if prev_comment = hash.delete(line - 1) hash[line] = AST::Comment.new(string: prev_comment.string + comment.string, location: nil) else hash[line] = comment end end end end |
#symbol_literal_node?(node) ⇒ Symbol?
Returns a symbol if the node is a symbol literal node
20 21 22 23 24 25 26 27 28 29 |
# File 'sig/prototype/helpers.rbs', line 20 def symbol_literal_node?(node) case node.type when :LIT if node.children[0].is_a?(Symbol) node.children[0] end when :SYM node.children[0] end end |
#untyped ⇒ Types::Bases::Any
192 193 194 |
# File 'lib/rbs/prototype/helpers.rb', line 192 def untyped @untyped ||= Types::Bases::Any.new(location: nil) end |