= nil @results = [] end def visit_class_node(node) previous_class_name = @class_name @class_name = node.name visit(node.body) if node.body @class_name = previous_class_name end def visit_call_node(node) return if @class_name.nil? || node.name != :def_nil_bang node.arguments.child_nodes.each do |child_node| @results << { class_name: @class_name, method_name: child_node.value } end end end def generate_def_nil_bangs_rbs(rbs_env, ruby_path, io) result = Prism.parse(File.read(ruby_path)) return unless result.success? visitor = DefNilBangVisitor.new visitor.visit(result.value) return if visitor.results.empty? sigs = visitor.results.filter_map do |result| type_name = RBS::TypeName.new( namespace: RBS::Namespace.parse('::'), name: result[:class_name] ) rbs_env.class_decls[type_name].primary.decl.members.filter_map do |member| if member.is_a?(RBS::AST::Members::AttrReader) && member.type.is_a?(RBS::Types::Optional) && member.name == result[:method_name].to_sym <<~"RBS" class #{type_name} def #{result[:method_name]}!: () -> #{member.type.type} end RBS end end end io.puts sigs.join("\n") end def_nil_bangマクロ 型の生成処理