ruby_mod_kit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +99 -0
- data/examples/user.rb +83 -0
- data/examples/user.rbm +47 -0
- data/exe/ruby_mod_kit +5 -0
- data/lib/ruby_mod_kit/cli.rb +27 -0
- data/lib/ruby_mod_kit/generation.rb +170 -0
- data/lib/ruby_mod_kit/memo/class.rb +27 -0
- data/lib/ruby_mod_kit/memo/ivar.rb +42 -0
- data/lib/ruby_mod_kit/memo/method.rb +49 -0
- data/lib/ruby_mod_kit/memo/offset_memo.rb +26 -0
- data/lib/ruby_mod_kit/memo/parameter.rb +39 -0
- data/lib/ruby_mod_kit/memo.rb +73 -0
- data/lib/ruby_mod_kit/mission/fix_parse_error.rb +213 -0
- data/lib/ruby_mod_kit/mission/ivar_arg.rb +42 -0
- data/lib/ruby_mod_kit/mission/overload.rb +73 -0
- data/lib/ruby_mod_kit/mission/type_attr.rb +75 -0
- data/lib/ruby_mod_kit/mission/type_parameter.rb +39 -0
- data/lib/ruby_mod_kit/mission/type_return.rb +33 -0
- data/lib/ruby_mod_kit/mission.rb +40 -0
- data/lib/ruby_mod_kit/node/call_node.rb +30 -0
- data/lib/ruby_mod_kit/node/class_node.rb +37 -0
- data/lib/ruby_mod_kit/node/def_node.rb +57 -0
- data/lib/ruby_mod_kit/node/parameter_node.rb +42 -0
- data/lib/ruby_mod_kit/node/program_node.rb +23 -0
- data/lib/ruby_mod_kit/node/statements_node.rb +27 -0
- data/lib/ruby_mod_kit/node/symbol_node.rb +34 -0
- data/lib/ruby_mod_kit/node/untyped_node.rb +25 -0
- data/lib/ruby_mod_kit/node.rb +164 -0
- data/lib/ruby_mod_kit/offset_diff.rb +37 -0
- data/lib/ruby_mod_kit/transpiler.rb +20 -0
- data/lib/ruby_mod_kit/version.rb +7 -0
- data/lib/ruby_mod_kit.rb +59 -0
- data/ruby_mod_kit.gemspec +51 -0
- data/sig/generated/examples/user.rbs +60 -0
- data/sig/generated/ruby_mod_kit/cli.rbs +14 -0
- data/sig/generated/ruby_mod_kit/generation.rbs +101 -0
- data/sig/generated/ruby_mod_kit/memo/class.rbs +20 -0
- data/sig/generated/ruby_mod_kit/memo/ivar.rbs +30 -0
- data/sig/generated/ruby_mod_kit/memo/located.rbs +14 -0
- data/sig/generated/ruby_mod_kit/memo/method.rbs +37 -0
- data/sig/generated/ruby_mod_kit/memo/offset_memo.rbs +20 -0
- data/sig/generated/ruby_mod_kit/memo/parameter.rbs +33 -0
- data/sig/generated/ruby_mod_kit/memo/parameter_type.rbs +14 -0
- data/sig/generated/ruby_mod_kit/memo.rbs +41 -0
- data/sig/generated/ruby_mod_kit/mission/fix_parse_error.rbs +73 -0
- data/sig/generated/ruby_mod_kit/mission/ivar_arg.rbs +19 -0
- data/sig/generated/ruby_mod_kit/mission/overload.rbs +20 -0
- data/sig/generated/ruby_mod_kit/mission/type_attr.rbs +18 -0
- data/sig/generated/ruby_mod_kit/mission/type_parameter.rbs +18 -0
- data/sig/generated/ruby_mod_kit/mission/type_return.rbs +18 -0
- data/sig/generated/ruby_mod_kit/mission.rbs +25 -0
- data/sig/generated/ruby_mod_kit/node/call_node.rbs +25 -0
- data/sig/generated/ruby_mod_kit/node/class_node.rbs +29 -0
- data/sig/generated/ruby_mod_kit/node/def_node.rbs +39 -0
- data/sig/generated/ruby_mod_kit/node/parameter_node.rbs +26 -0
- data/sig/generated/ruby_mod_kit/node/program_node.rbs +16 -0
- data/sig/generated/ruby_mod_kit/node/statements_node.rbs +21 -0
- data/sig/generated/ruby_mod_kit/node/symbol_node.rbs +24 -0
- data/sig/generated/ruby_mod_kit/node/untyped_node.rbs +21 -0
- data/sig/generated/ruby_mod_kit/node.rbs +63 -0
- data/sig/generated/ruby_mod_kit/offset_diff.rbs +20 -0
- data/sig/generated/ruby_mod_kit/transpiler.rbs +11 -0
- data/sig/generated/ruby_mod_kit/version.rbs +5 -0
- data/sig/generated/ruby_mod_kit.rbs +33 -0
- data/sig/sorted_set.rbs +8 -0
- data/sig/thor.rbs +3 -0
- metadata +157 -0
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              # The class of transpiler generation.
         | 
| 7 | 
            +
              class Memo
         | 
| 8 | 
            +
                # @rbs @classes_memo: Hash[Integer, Memo::Class]
         | 
| 9 | 
            +
                # @rbs @methods_memo: Hash[Integer, Memo::Method]
         | 
| 10 | 
            +
                # @rbs @parameters_memo: Hash[Integer, Memo::Parameter]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                attr_reader :classes_memo #: Hash[Integer, Memo::Class]
         | 
| 13 | 
            +
                attr_reader :methods_memo #: Hash[Integer, Memo::Method]
         | 
| 14 | 
            +
                attr_reader :parameters_memo #: Hash[Integer, Memo::Parameter]
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                # @rbs return: void
         | 
| 17 | 
            +
                def initialize
         | 
| 18 | 
            +
                  @classes_memo = {}
         | 
| 19 | 
            +
                  @methods_memo = {}
         | 
| 20 | 
            +
                  @parameters_memo = {}
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # @rbs offset_diff: OffsetDiff
         | 
| 24 | 
            +
                # @rbs return: void
         | 
| 25 | 
            +
                def succ(offset_diff)
         | 
| 26 | 
            +
                  [@methods_memo, @parameters_memo, @classes_memo].each do |offset_node_memo|
         | 
| 27 | 
            +
                    new_offset_node_memo = {}
         | 
| 28 | 
            +
                    offset_node_memo.each_value do |node_memo|
         | 
| 29 | 
            +
                      node_memo.succ(offset_diff)
         | 
| 30 | 
            +
                      new_offset_node_memo[node_memo.offset] = node_memo
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                    offset_node_memo.replace(new_offset_node_memo)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                  self
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # @rbs class_node: Node::ClassNode
         | 
| 38 | 
            +
                # @rbs return: Memo::Class
         | 
| 39 | 
            +
                def class_memo(class_node)
         | 
| 40 | 
            +
                  @classes_memo[class_node.offset] ||= Memo::Class.new(class_node)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                # @rbs def_node: Node::DefNode
         | 
| 44 | 
            +
                # @rbs return: Memo::Method
         | 
| 45 | 
            +
                def method_memo(def_node)
         | 
| 46 | 
            +
                  @methods_memo[def_node.offset] ||= Memo::Method.new(def_node)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                # @rbs node: Node
         | 
| 50 | 
            +
                # @rbs return: Memo::Parameter
         | 
| 51 | 
            +
                def parameter_memo(node)
         | 
| 52 | 
            +
                  memo = @parameters_memo[node.offset] ||= Memo::Parameter.new(node.offset)
         | 
| 53 | 
            +
                  def_node = node.def_node_at(node.offset)
         | 
| 54 | 
            +
                  raise RubyModKit::Error unless def_node.is_a?(Node::DefNode)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  method_memo(def_node).add_parameter(memo)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                class << self
         | 
| 60 | 
            +
                  # @rbs type: String
         | 
| 61 | 
            +
                  # @rbs return: String
         | 
| 62 | 
            +
                  def unify_type(type)
         | 
| 63 | 
            +
                    type[/\A\(([^()]*)\)\z/, 1] || type
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
            end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            require_relative "memo/offset_memo"
         | 
| 70 | 
            +
            require_relative "memo/class"
         | 
| 71 | 
            +
            require_relative "memo/ivar"
         | 
| 72 | 
            +
            require_relative "memo/method"
         | 
| 73 | 
            +
            require_relative "memo/parameter"
         | 
| @@ -0,0 +1,213 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for parameter types
         | 
| 8 | 
            +
                class FixParseError < Mission
         | 
| 9 | 
            +
                  # @rbs @previous_error_messages: Array[String]
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  # @rbs return: void
         | 
| 12 | 
            +
                  def initialize
         | 
| 13 | 
            +
                    super(0)
         | 
| 14 | 
            +
                    @previous_error_messages = []
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # @rbs generation: Generation
         | 
| 18 | 
            +
                  # @rbs root_node: Node
         | 
| 19 | 
            +
                  # @rbs parse_result: Prism::ParseResult
         | 
| 20 | 
            +
                  # @rbs memo: Memo
         | 
| 21 | 
            +
                  # @rbs return: bool
         | 
| 22 | 
            +
                  def perform(generation, root_node, parse_result, memo)
         | 
| 23 | 
            +
                    return true if parse_result.errors.empty?
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    check_prev_errors(generation, parse_result)
         | 
| 26 | 
            +
                    @previous_error_messages = parse_result.errors.map(&:message)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    parse_result.errors.each do |parse_error|
         | 
| 29 | 
            +
                      case parse_error.type
         | 
| 30 | 
            +
                      when :argument_formal_ivar
         | 
| 31 | 
            +
                        fix_argument_formal_ivar(parse_error, generation, root_node, memo)
         | 
| 32 | 
            +
                      when :argument_formal_constant
         | 
| 33 | 
            +
                        fix_argument_formal_constant(parse_error, generation)
         | 
| 34 | 
            +
                      when :unexpected_token_ignore
         | 
| 35 | 
            +
                        case parse_error.location.slice
         | 
| 36 | 
            +
                        when "=>"
         | 
| 37 | 
            +
                          fix_unexpected_assoc(parse_error, generation, root_node, memo)
         | 
| 38 | 
            +
                        when ":"
         | 
| 39 | 
            +
                          fix_unexpected_colon(parse_error, generation, root_node, memo)
         | 
| 40 | 
            +
                        end
         | 
| 41 | 
            +
                      when :def_params_term_paren
         | 
| 42 | 
            +
                        fix_def_params_term_paren(parse_error, generation, root_node, memo)
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    false
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  # @rbs generation: Generation
         | 
| 50 | 
            +
                  # @rbs parse_result: Prism::ParseResult
         | 
| 51 | 
            +
                  # @rbs return: void
         | 
| 52 | 
            +
                  def check_prev_errors(generation, parse_result)
         | 
| 53 | 
            +
                    return if @previous_error_messages.empty?
         | 
| 54 | 
            +
                    return if parse_result.errors.empty?
         | 
| 55 | 
            +
                    return if @previous_error_messages != parse_result.errors.map(&:message)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    message = +""
         | 
| 58 | 
            +
                    parse_result.errors.each do |parse_error|
         | 
| 59 | 
            +
                      message << "\n" unless message.empty?
         | 
| 60 | 
            +
                      message << "#{generation.name}:#{parse_error.location.start_line}:#{parse_error.message} "
         | 
| 61 | 
            +
                      message << "(#{parse_error.type})\n"
         | 
| 62 | 
            +
                      message << parse_result.source.lines[parse_error.location.start_line - 1].chomp << "\n"
         | 
| 63 | 
            +
                      message << "#{" " * parse_error.location.start_column}^#{"~" * [parse_error.location.length - 1, 0].max}"
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                    raise RubyModKit::SyntaxError, message
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 69 | 
            +
                  # @rbs generation: Generation
         | 
| 70 | 
            +
                  # @rbs root_node: Node
         | 
| 71 | 
            +
                  # @rbs memo: Memo
         | 
| 72 | 
            +
                  # @rbs return: void
         | 
| 73 | 
            +
                  def fix_def_params_term_paren(parse_error, generation, root_node, memo)
         | 
| 74 | 
            +
                    column = parse_error.location.start_column - 1
         | 
| 75 | 
            +
                    return if column < 0
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    line = generation.line(parse_error)[column..] || return
         | 
| 78 | 
            +
                    line =~ /\A\*(.*?)\s*=>\s*/
         | 
| 79 | 
            +
                    length = ::Regexp.last_match(0)&.length || return
         | 
| 80 | 
            +
                    type = ::Regexp.last_match(1) || return
         | 
| 81 | 
            +
                    offset = parse_error.location.start_offset - 1
         | 
| 82 | 
            +
                    parameter_position_node = root_node.node_at(offset + length) || return
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    generation[parse_error.location.start_offset, length - 1] = ""
         | 
| 85 | 
            +
                    parameter_memo = memo.parameter_memo(parameter_position_node)
         | 
| 86 | 
            +
                    parameter_memo.type = type
         | 
| 87 | 
            +
                    parameter_memo.qualifier = "*"
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 91 | 
            +
                  # @rbs generation: Generation
         | 
| 92 | 
            +
                  # @rbs root_node: Node
         | 
| 93 | 
            +
                  # @rbs memo: Memo
         | 
| 94 | 
            +
                  # @rbs return: void
         | 
| 95 | 
            +
                  def fix_argument_formal_ivar(parse_error, generation, root_node, memo)
         | 
| 96 | 
            +
                    src_offset = parse_error.location.start_offset
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    name = parse_error.location.slice[1..]
         | 
| 99 | 
            +
                    raise RubyModKit::Error unless name
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                    parameter_position_node = root_node.node_at(src_offset)
         | 
| 102 | 
            +
                    raise RubyModKit::Error unless parameter_position_node
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                    generation[src_offset, parse_error.location.length] = name
         | 
| 105 | 
            +
                    parameter_memo = memo.parameter_memo(parameter_position_node)
         | 
| 106 | 
            +
                    parameter_memo.ivar_parameter = true
         | 
| 107 | 
            +
                    generation.add_mission(Mission::IvarArg.new(src_offset))
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    return unless parameter_memo.untyped?
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                    class_node = root_node.class_node_at(parse_error.location.start_offset) || return
         | 
| 112 | 
            +
                    ivar_memo_type = memo.class_memo(class_node).ivar_memo(name.to_sym).type || return
         | 
| 113 | 
            +
                    parameter_memo.type = ivar_memo_type
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 117 | 
            +
                  # @rbs generation: Generation
         | 
| 118 | 
            +
                  # @rbs return: void
         | 
| 119 | 
            +
                  def fix_argument_formal_constant(parse_error, generation)
         | 
| 120 | 
            +
                    line = generation.line(parse_error)
         | 
| 121 | 
            +
                    line = line[parse_error.location.start_column..] || return
         | 
| 122 | 
            +
                    parameter_type = line[/(\A[A-Z]\w*(?:::[A-Z]\w*)+)(?:\s*=>\s*)/, 1] || return
         | 
| 123 | 
            +
                    src_offset = parse_error.location.start_offset
         | 
| 124 | 
            +
                    generation[src_offset, parameter_type.length] = "(#{parameter_type})"
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 128 | 
            +
                  # @rbs generation: Generation
         | 
| 129 | 
            +
                  # @rbs root_node: Node
         | 
| 130 | 
            +
                  # @rbs memo: Memo
         | 
| 131 | 
            +
                  # @rbs return: void
         | 
| 132 | 
            +
                  def fix_unexpected_assoc(parse_error, generation, root_node, memo)
         | 
| 133 | 
            +
                    def_node = root_node.def_node_at(parse_error.location.start_offset) || return
         | 
| 134 | 
            +
                    def_parent_node = def_node.parent
         | 
| 135 | 
            +
                    parameters_node, body_node, = def_node.children
         | 
| 136 | 
            +
                    return if !def_parent_node || !parameters_node || !body_node
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                    last_parameter_node = parameters_node.children.max_by(&:offset) || return
         | 
| 139 | 
            +
                    last_parameter_offset = last_parameter_node.offset
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                    right_node = body_node.children.find { _1.offset >= parse_error.location.end_offset } || return
         | 
| 142 | 
            +
                    right_offset = right_node.offset
         | 
| 143 | 
            +
                    parameter_type = generation[last_parameter_offset...right_offset] || raise(RubyModKit::Error)
         | 
| 144 | 
            +
                    parameter_type = parameter_type.sub(/\s*=>\s*\z/, "")
         | 
| 145 | 
            +
                    generation[last_parameter_offset, right_offset - last_parameter_offset] = ""
         | 
| 146 | 
            +
                    memo.parameter_memo(last_parameter_node).type = parameter_type
         | 
| 147 | 
            +
                  end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 150 | 
            +
                  # @rbs generation: Generation
         | 
| 151 | 
            +
                  # @rbs root_node: Node
         | 
| 152 | 
            +
                  # @rbs memo: Memo
         | 
| 153 | 
            +
                  # @rbs return: void
         | 
| 154 | 
            +
                  def fix_unexpected_colon(parse_error, generation, root_node, memo)
         | 
| 155 | 
            +
                    parent_node = root_node.statements_node_at(parse_error.location.start_offset)&.parent
         | 
| 156 | 
            +
                    case parent_node
         | 
| 157 | 
            +
                    when Node::DefNode
         | 
| 158 | 
            +
                      fix_unexpected_colon_in_def(parse_error, generation, root_node, parent_node, memo)
         | 
| 159 | 
            +
                    when Node::ClassNode
         | 
| 160 | 
            +
                      fix_unexpected_colon_in_module(parse_error, generation, parent_node, memo)
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                  end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 165 | 
            +
                  # @rbs generation: Generation
         | 
| 166 | 
            +
                  # @rbs root_node: Node
         | 
| 167 | 
            +
                  # @rbs def_node: Node::DefNode
         | 
| 168 | 
            +
                  # @rbs memo: Memo
         | 
| 169 | 
            +
                  # @rbs return: void
         | 
| 170 | 
            +
                  def fix_unexpected_colon_in_def(parse_error, generation, root_node, def_node, memo)
         | 
| 171 | 
            +
                    lparen_loc = def_node.lparen_loc
         | 
| 172 | 
            +
                    rparen_loc = def_node.rparen_loc
         | 
| 173 | 
            +
                    if !lparen_loc && !rparen_loc
         | 
| 174 | 
            +
                      src_offset = def_node.name_loc.end_offset
         | 
| 175 | 
            +
                    elsif lparen_loc && rparen_loc && lparen_loc.slice == "(" && rparen_loc.slice == ")"
         | 
| 176 | 
            +
                      src_offset = rparen_loc.end_offset
         | 
| 177 | 
            +
                    else
         | 
| 178 | 
            +
                      return
         | 
| 179 | 
            +
                    end
         | 
| 180 | 
            +
                    return if generation[src_offset...parse_error.location.start_offset] !~ /\A\s*\z/
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                    return_type_location = root_node.node_at(parse_error.location.end_offset + 1)&.location || return_type_location
         | 
| 183 | 
            +
                    generation[src_offset, return_type_location.end_offset - src_offset] = ""
         | 
| 184 | 
            +
                    memo.method_memo(def_node).type = return_type_location.slice
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  # @rbs parse_error: Prism::ParseError
         | 
| 188 | 
            +
                  # @rbs generation: Generation
         | 
| 189 | 
            +
                  # @rbs class_node: Node::ClassNode
         | 
| 190 | 
            +
                  # @rbs memo: Memo
         | 
| 191 | 
            +
                  # @rbs return: void
         | 
| 192 | 
            +
                  def fix_unexpected_colon_in_module(parse_error, generation, class_node, memo)
         | 
| 193 | 
            +
                    line = generation.line(parse_error)
         | 
| 194 | 
            +
                    line_offset = generation.src_offset(parse_error) || return
         | 
| 195 | 
            +
                    attr_patterns = %i[attr_reader reader getter attr_writer writer setter attr_accessor accessor property]
         | 
| 196 | 
            +
                    return if line !~ /(\A\s*)(?:(#{attr_patterns.join("|")}) )?@(\w*)\s*:\s*(.*)/
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                    length = ::Regexp.last_match(0)&.length
         | 
| 199 | 
            +
                    indent = ::Regexp.last_match(1)
         | 
| 200 | 
            +
                    attr_kind = ::Regexp.last_match(2)
         | 
| 201 | 
            +
                    ivar_name = ::Regexp.last_match(3)
         | 
| 202 | 
            +
                    type = ::Regexp.last_match(4)
         | 
| 203 | 
            +
                    return if !length || !indent || !ivar_name || !type
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    ivar_memo = memo.class_memo(class_node).ivar_memo(ivar_name.to_sym)
         | 
| 206 | 
            +
                    ivar_memo.type = type
         | 
| 207 | 
            +
                    ivar_memo.attr_kind = attr_kind if attr_kind
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                    generation[line_offset, length] = "#{indent}# @rbs @#{ivar_name}: #{Memo.unify_type(type)}"
         | 
| 210 | 
            +
                  end
         | 
| 211 | 
            +
                end
         | 
| 212 | 
            +
              end
         | 
| 213 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for instance variable arguments
         | 
| 8 | 
            +
                class IvarArg < Mission
         | 
| 9 | 
            +
                  # @rbs @assignment: String
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  attr_reader :assignment #: String
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  # @rbs generation: Generation
         | 
| 14 | 
            +
                  # @rbs root_node: Node
         | 
| 15 | 
            +
                  # @rbs _parse_result: Prism::ParseResult
         | 
| 16 | 
            +
                  # @rbs _memo: Memo
         | 
| 17 | 
            +
                  # @rbs return: bool
         | 
| 18 | 
            +
                  def perform(generation, root_node, _parse_result, _memo)
         | 
| 19 | 
            +
                    parameter_node = root_node.parameter_node_at(@offset)
         | 
| 20 | 
            +
                    raise RubyModKit::Error unless parameter_node
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def_node = root_node.def_node_at(@offset)
         | 
| 23 | 
            +
                    raise RubyModKit::Error, "DefNode not found" unless def_node
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    def_body_location = def_node.body_location
         | 
| 26 | 
            +
                    end_loc = def_node.end_keyword_loc
         | 
| 27 | 
            +
                    if def_body_location
         | 
| 28 | 
            +
                      indent = def_body_location.start_column
         | 
| 29 | 
            +
                      src_offset = def_body_location.start_offset - indent
         | 
| 30 | 
            +
                    elsif end_loc
         | 
| 31 | 
            +
                      indent = end_loc.start_column + 2
         | 
| 32 | 
            +
                      src_offset = end_loc.start_offset - indent + 2
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                    raise RubyModKit::Error if !src_offset || !indent
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    name = parameter_node.name
         | 
| 37 | 
            +
                    generation[src_offset, 0] = "#{" " * indent}@#{name} = #{name}\n"
         | 
| 38 | 
            +
                    true
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for overload
         | 
| 8 | 
            +
                class Overload < Mission
         | 
| 9 | 
            +
                  OVERLOAD_METHOD_MAP = {
         | 
| 10 | 
            +
                    "*": "_mul",
         | 
| 11 | 
            +
                  }.freeze #: Hash[Symbol, String]
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  # @rbs return: void
         | 
| 14 | 
            +
                  def initialize
         | 
| 15 | 
            +
                    super(0)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # @rbs generation: Generation
         | 
| 19 | 
            +
                  # @rbs root_node: Node
         | 
| 20 | 
            +
                  # @rbs parse_result: Prism::ParseResult
         | 
| 21 | 
            +
                  # @rbs memo: Memo
         | 
| 22 | 
            +
                  # @rbs return: bool
         | 
| 23 | 
            +
                  def perform(generation, root_node, parse_result, memo)
         | 
| 24 | 
            +
                    method_memo_groups = memo.methods_memo.each_value.group_by do |method_memo|
         | 
| 25 | 
            +
                      [root_node.class_node_at(method_memo.offset), method_memo.name]
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    method_memo_groups.each_value do |method_memos|
         | 
| 28 | 
            +
                      next if method_memos.length <= 1
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                      first_method_memo = method_memos.first
         | 
| 31 | 
            +
                      name = first_method_memo.name
         | 
| 32 | 
            +
                      first_def_node = root_node.def_node_at(first_method_memo.offset)
         | 
| 33 | 
            +
                      raise RubyModKit::Error unless first_def_node.is_a?(Node::DefNode)
         | 
| 34 | 
            +
                      raise RubyModKit::Error unless name.is_a?(Symbol)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      start_line = first_def_node.location.start_line - 1
         | 
| 37 | 
            +
                      indent = parse_result.source.lines[start_line][/\A */] || ""
         | 
| 38 | 
            +
                      start_line -= 1 while parse_result.source.lines[start_line - 1] =~ /^ *# *@rbs /
         | 
| 39 | 
            +
                      src_offset = parse_result.source.offsets[start_line]
         | 
| 40 | 
            +
                      script = +""
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      method_memos.each do |method_memo|
         | 
| 43 | 
            +
                        script << if script.empty?
         | 
| 44 | 
            +
                          "# @rbs"
         | 
| 45 | 
            +
                        else
         | 
| 46 | 
            +
                          "#    |"
         | 
| 47 | 
            +
                        end
         | 
| 48 | 
            +
                        type = method_memo.type
         | 
| 49 | 
            +
                        type = "(#{type})" if type.include?(" ")
         | 
| 50 | 
            +
                        script << " (#{method_memo.parameters.map(&:type).join(", ")}) -> #{type}\n"
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
                      script << "def #{name}(*args)\n  case args\n"
         | 
| 53 | 
            +
                      overload_prefix = +"#{OVERLOAD_METHOD_MAP[name] || name}_"
         | 
| 54 | 
            +
                      method_memos.each_with_index do |method_memo, i|
         | 
| 55 | 
            +
                        overload_name = "#{overload_prefix}_overload#{i}"
         | 
| 56 | 
            +
                        def_node = root_node.def_node_at(method_memo.offset)
         | 
| 57 | 
            +
                        raise RubyModKit::Error if !def_node || !def_node.is_a?(Node::DefNode)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                        name_loc = def_node.name_loc
         | 
| 60 | 
            +
                        generation[name_loc.start_offset, name_loc.length] = overload_name
         | 
| 61 | 
            +
                        script << "  in [#{method_memo.parameters.map(&:type).join(", ")}]\n"
         | 
| 62 | 
            +
                        script << "    #{overload_name}(*args)\n"
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
                      script << "  end\nend\n\n"
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      script.gsub!(/^(?=.)/, indent)
         | 
| 67 | 
            +
                      generation[src_offset, 0] = script
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
                    true
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for parameter types
         | 
| 8 | 
            +
                class TypeAttr < Mission
         | 
| 9 | 
            +
                  # @rbs return: void
         | 
| 10 | 
            +
                  def initialize
         | 
| 11 | 
            +
                    super(0)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # @rbs generation: Generation
         | 
| 15 | 
            +
                  # @rbs root_node: Node
         | 
| 16 | 
            +
                  # @rbs _parse_result: Prism::ParseResult
         | 
| 17 | 
            +
                  # @rbs memo: Memo
         | 
| 18 | 
            +
                  # @rbs return: bool
         | 
| 19 | 
            +
                  def perform(generation, root_node, _parse_result, memo)
         | 
| 20 | 
            +
                    memo.classes_memo.each_value do |class_memo|
         | 
| 21 | 
            +
                      ivars_memo = class_memo.ivars_memo.dup
         | 
| 22 | 
            +
                      class_node = root_node.class_node_at(class_memo.offset) || raise(RubyModKit::Error)
         | 
| 23 | 
            +
                      attr_adding_line = 0
         | 
| 24 | 
            +
                      class_node.body_node&.children&.each do |call_node|
         | 
| 25 | 
            +
                        break if ivars_memo.empty?
         | 
| 26 | 
            +
                        next unless call_node.is_a?(Node::CallNode)
         | 
| 27 | 
            +
                        next unless %i[attr_reader attr_writer attr_accessor].include?(call_node.name)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                        attr_adding_line = call_node.location.end_line
         | 
| 30 | 
            +
                        argument_nodes = call_node.children[0].children
         | 
| 31 | 
            +
                        next if argument_nodes.size != 1 || !argument_nodes[0].is_a?(Node::SymbolNode)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        name = argument_nodes[0].value || next
         | 
| 34 | 
            +
                        ivar_memo = ivars_memo.delete(name) || next
         | 
| 35 | 
            +
                        line = generation.line(call_node)
         | 
| 36 | 
            +
                        length = line[/\A\s*(#{call_node.name}\s+:#{name})(?=\n\z)/, 1]&.length || next
         | 
| 37 | 
            +
                        generation[call_node.location.start_offset + length, 0] = " #: #{ivar_memo.type}"
         | 
| 38 | 
            +
                      end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                      ivars_memo.keep_if { |_, ivar_memo| ivar_memo.attr_kind }
         | 
| 41 | 
            +
                      next if ivars_memo.empty?
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      add_first_separator_line = false
         | 
| 44 | 
            +
                      if attr_adding_line == 0
         | 
| 45 | 
            +
                        attr_adding_line = class_node.location.start_line
         | 
| 46 | 
            +
                        prev_line = nil
         | 
| 47 | 
            +
                        while generation.line(attr_adding_line) =~ /\A\s*#.*|\A$/
         | 
| 48 | 
            +
                          prev_line = ::Regexp.last_match(0)
         | 
| 49 | 
            +
                          attr_adding_line += 1
         | 
| 50 | 
            +
                        end
         | 
| 51 | 
            +
                        add_first_separator_line = prev_line != ""
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                      line = generation.line(attr_adding_line) || next
         | 
| 54 | 
            +
                      add_separator_line = line != "\n" && line !~ /\A\s*end$/
         | 
| 55 | 
            +
                      offset = generation.src_offset(attr_adding_line) || next
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                      if class_node.body_node
         | 
| 58 | 
            +
                        first_line = generation.line(class_node.body_node)
         | 
| 59 | 
            +
                        indent = first_line[/\A\s*/] || raise(RubyModKit::Error)
         | 
| 60 | 
            +
                      else
         | 
| 61 | 
            +
                        class_line = generation.line(class_node)
         | 
| 62 | 
            +
                        indent = "  #{class_line[/\A\s*/]}"
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                      generation[offset, 0] = "\n" if add_first_separator_line
         | 
| 66 | 
            +
                      ivars_memo.each do |name, ivar_memo|
         | 
| 67 | 
            +
                        generation[offset, 0] = "#{indent}#{ivar_memo.attr_kind} :#{name} #: #{ivar_memo.type}\n"
         | 
| 68 | 
            +
                      end
         | 
| 69 | 
            +
                      generation[offset, 0] = "\n" if add_separator_line
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                    true
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for parameter types
         | 
| 8 | 
            +
                class TypeParameter < Mission
         | 
| 9 | 
            +
                  # @rbs return: void
         | 
| 10 | 
            +
                  def initialize
         | 
| 11 | 
            +
                    super(0)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # @rbs generation: Generation
         | 
| 15 | 
            +
                  # @rbs root_node: Node
         | 
| 16 | 
            +
                  # @rbs parse_result: Prism::ParseResult
         | 
| 17 | 
            +
                  # @rbs memo: Memo
         | 
| 18 | 
            +
                  # @rbs return: bool
         | 
| 19 | 
            +
                  def perform(generation, root_node, parse_result, memo)
         | 
| 20 | 
            +
                    memo.parameters_memo.each do |offset, parameter_memo|
         | 
| 21 | 
            +
                      next if parameter_memo.untyped?
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                      def_node = root_node.def_node_at(offset)
         | 
| 24 | 
            +
                      raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                      parameter_node = root_node.parameter_node_at(offset)
         | 
| 27 | 
            +
                      raise RubyModKit::Error, "ParameterNode not found" unless parameter_node
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      type = parameter_memo.type
         | 
| 30 | 
            +
                      src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
         | 
| 31 | 
            +
                      indent = def_node.offset - src_offset
         | 
| 32 | 
            +
                      qualified_name = "#{parameter_memo.qualifier}#{parameter_node.name}"
         | 
| 33 | 
            +
                      generation[src_offset, 0] = "#{" " * indent}# @rbs #{qualified_name}: #{type}\n"
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    true
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Mission
         | 
| 7 | 
            +
                # The mission for parameter types
         | 
| 8 | 
            +
                class TypeReturn < Mission
         | 
| 9 | 
            +
                  # @rbs return: void
         | 
| 10 | 
            +
                  def initialize
         | 
| 11 | 
            +
                    super(0)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # @rbs generation: Generation
         | 
| 15 | 
            +
                  # @rbs root_node: Node
         | 
| 16 | 
            +
                  # @rbs parse_result: Prism::ParseResult
         | 
| 17 | 
            +
                  # @rbs memo: Memo
         | 
| 18 | 
            +
                  # @rbs return: bool
         | 
| 19 | 
            +
                  def perform(generation, root_node, parse_result, memo)
         | 
| 20 | 
            +
                    memo.methods_memo.each do |offset, method_memo|
         | 
| 21 | 
            +
                      def_node = root_node.def_node_at(offset)
         | 
| 22 | 
            +
                      raise RubyModKit::Error, "DefNode not found" if !def_node || !def_node.is_a?(Node::DefNode)
         | 
| 23 | 
            +
                      next if method_memo.untyped?
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      src_offset = parse_result.source.offsets[def_node.location.start_line - 1]
         | 
| 26 | 
            +
                      indent = offset - src_offset
         | 
| 27 | 
            +
                      generation[src_offset, 0] = "#{" " * indent}# @rbs return: #{method_memo.type}\n"
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                    true
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              # The class of transpiler mission.
         | 
| 7 | 
            +
              class Mission
         | 
| 8 | 
            +
                # @rbs @offset: Integer
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                attr_accessor :offset #: Integer
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # @rbs offset: Integer
         | 
| 13 | 
            +
                # @rbs return: void
         | 
| 14 | 
            +
                def initialize(offset)
         | 
| 15 | 
            +
                  @offset = offset
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # @rbs _generation: Generation
         | 
| 19 | 
            +
                # @rbs _root_node: Node
         | 
| 20 | 
            +
                # @rbs _parse_result: Prism::ParseResult
         | 
| 21 | 
            +
                # @rbs _memo: Memo
         | 
| 22 | 
            +
                # @rbs return: void
         | 
| 23 | 
            +
                def perform(_generation, _root_node, _parse_result, _memo)
         | 
| 24 | 
            +
                  raise RubyModKit::Error, "Unexpected type #{self.class}"
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                # @rbs offset_diff: OffsetDiff
         | 
| 28 | 
            +
                # @rbs return: void
         | 
| 29 | 
            +
                def succ(offset_diff)
         | 
| 30 | 
            +
                  @offset = offset_diff[@offset]
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            require_relative "mission/ivar_arg"
         | 
| 36 | 
            +
            require_relative "mission/type_attr"
         | 
| 37 | 
            +
            require_relative "mission/type_parameter"
         | 
| 38 | 
            +
            require_relative "mission/type_return"
         | 
| 39 | 
            +
            require_relative "mission/fix_parse_error"
         | 
| 40 | 
            +
            require_relative "mission/overload"
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Node
         | 
| 7 | 
            +
                # Transpiler method call node
         | 
| 8 | 
            +
                class CallNode < Node
         | 
| 9 | 
            +
                  # @rbs @prism_node: Prism::CallNode
         | 
| 10 | 
            +
                  # @rbs @name: Symbol
         | 
| 11 | 
            +
                  # @rbs @parent: Node
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  attr_reader :prism_node #: Prism::CallNode
         | 
| 14 | 
            +
                  attr_reader :name #: Symbol
         | 
| 15 | 
            +
                  attr_reader :parent #: Node
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # @rbs prism_node: Prism::CallNode
         | 
| 18 | 
            +
                  # @rbs parent: Node
         | 
| 19 | 
            +
                  # @rbs return: void
         | 
| 20 | 
            +
                  def initialize(prism_node, parent:)
         | 
| 21 | 
            +
                    @prism_node = prism_node
         | 
| 22 | 
            +
                    @parent = parent
         | 
| 23 | 
            +
                    raise RubyModKit::Error unless prism_node.is_a?(Prism::CallNode)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    @name = prism_node.name.to_sym
         | 
| 26 | 
            +
                    super()
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # rbs_inline: enabled
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module RubyModKit
         | 
| 6 | 
            +
              class Node
         | 
| 7 | 
            +
                # Transpiler program node
         | 
| 8 | 
            +
                class ClassNode < Node
         | 
| 9 | 
            +
                  # @rbs @prism_node: Prism::ClassNode
         | 
| 10 | 
            +
                  # @rbs @body_node: nil | Node::StatementsNode
         | 
| 11 | 
            +
                  # @rbs @parent: Node
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  attr_reader :prism_node #: Prism::ClassNode
         | 
| 14 | 
            +
                  attr_reader :body_node #: nil | Node::StatementsNode
         | 
| 15 | 
            +
                  attr_reader :parent #: Node
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # @rbs prism_node: Prism::ClassNode
         | 
| 18 | 
            +
                  # @rbs parent: Node
         | 
| 19 | 
            +
                  # @rbs return: void
         | 
| 20 | 
            +
                  def initialize(prism_node, parent:)
         | 
| 21 | 
            +
                    @prism_node = prism_node
         | 
| 22 | 
            +
                    @parent = parent
         | 
| 23 | 
            +
                    raise RubyModKit::Error unless prism_node.is_a?(Prism::ClassNode)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    super()
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # @rbs child_prism_node: Prism::Node
         | 
| 29 | 
            +
                  # @rbs return: Node
         | 
| 30 | 
            +
                  def wrap(child_prism_node)
         | 
| 31 | 
            +
                    node = super
         | 
| 32 | 
            +
                    @body_node = node if child_prism_node == prism_node.body && node.is_a?(Node::StatementsNode)
         | 
| 33 | 
            +
                    node
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         |