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
120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rbs/prototype/helpers.rb', line 120 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
144 145 146 |
# File 'lib/rbs/prototype/helpers.rb', line 144 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?
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 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 |
# File 'lib/rbs/prototype/helpers.rb', line 32 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.
108 109 110 |
# File 'lib/rbs/prototype/helpers.rb', line 108 def each_child(node, &block) each_node node.children, &block end |
#each_node(nodes) {|arg0| ... } ⇒ void
This method returns an undefined value.
112 113 114 115 116 117 118 |
# File 'lib/rbs/prototype/helpers.rb', line 112 def each_node(nodes) nodes.each do |child| if child.is_a?(RubyVM::AbstractSyntaxTree::Node) yield child end end end |
#keyword_hash?(node) ⇒ Boolean
132 133 134 135 136 137 138 139 140 |
# File 'lib/rbs/prototype/helpers.rb', line 132 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]
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/rbs/prototype/helpers.rb', line 8 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
159 160 161 |
# File 'lib/rbs/prototype/helpers.rb', line 159 def untyped @untyped ||= Types::Bases::Any.new(location: nil) end |