From 14259a5ae3d4b747d7bca87735b99735d2563881 Mon Sep 17 00:00:00 2001 From: Kaan Ozkan Date: Wed, 10 Jun 2026 14:03:35 -0400 Subject: [PATCH 1/4] Move parser comment handling to shared visitor --- lib/rbi/parser.rb | 150 ++++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/lib/rbi/parser.rb b/lib/rbi/parser.rb index ffb2cc8e..7599db88 100644 --- a/lib/rbi/parser.rb +++ b/lib/rbi/parser.rb @@ -112,12 +112,13 @@ def parse(source, file:) end class Visitor < Prism::Visitor - #: (String source, file: String) -> void - def initialize(source, file:) + #: (String source, file: String, ?comments_by_line: Hash[Integer, Prism::Comment]?) -> void + def initialize(source, file:, comments_by_line: nil) super() @source = source @file = file + @comments_by_line = comments_by_line || {} #: Hash[Integer, Prism::Comment] end private @@ -159,6 +160,75 @@ def self?(node) def t_sig_without_runtime?(node) !!(node.is_a?(Prism::ConstantPathNode) && node_string(node) =~ /(::)?T::Sig::WithoutRuntime/) end + + #: (Prism::Node node) -> Array[Comment] + def node_comments(node) + comments = [] + + start_line = node.location.start_line + start_line -= 1 unless @comments_by_line.key?(start_line) + + rbs_continuation = [] #: Array[Prism::Comment] + + start_line.downto(1) do |line| + comment = @comments_by_line[line] + break unless comment + + text = comment.location.slice + + # If we find a RBS comment continuation `#|`, we store it until we find the start with `#:` + if text.start_with?("#|") + rbs_continuation << comment + @comments_by_line.delete(line) + next + end + + loc = Loc.from_prism(@file, comment.location) + + # If we find the start of a RBS comment, we create a new RBSComment + # Note that we ignore RDoc directives such as `:nodoc:` + # See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives + if text.start_with?("#:") && !(text =~ /^#:[a-z_]+:/) + text = text.sub(/^#: ?/, "").rstrip + + # If we found continuation comments, we merge them in reverse order (since we go from bottom to top) + rbs_continuation.reverse_each do |rbs_comment| + continuation_text = rbs_comment.location.slice.sub(/^#\| ?/, "").strip + continuation_loc = Loc.from_prism(@file, rbs_comment.location) + loc = loc.join(continuation_loc) + text = "#{text}#{continuation_text}" + end + + rbs_continuation.clear + comments.unshift(RBSComment.new(text, loc: loc)) + else + # If we have unused continuation comments, we should inject them back to not lose them + rbs_continuation.each do |rbs_comment| + comments.unshift(parse_comment(rbs_comment)) + end + + rbs_continuation.clear + comments.unshift(parse_comment(comment)) + end + + @comments_by_line.delete(line) + end + + # If we have unused continuation comments, we should inject them back to not lose them + rbs_continuation.each do |rbs_comment| + comments.unshift(parse_comment(rbs_comment)) + end + rbs_continuation.clear + + comments + end + + #: (Prism::Comment node) -> Comment + def parse_comment(node) + text = node.location.slice.sub(/^# ?/, "").rstrip + loc = Loc.from_prism(@file, node.location) + Comment.new(text, loc: loc) + end end class TreeBuilder < Visitor @@ -170,9 +240,12 @@ class TreeBuilder < Visitor #: (String source, comments: Array[Prism::Comment], file: String) -> void def initialize(source, comments:, file:) - super(source, file: file) + super( + source, + comments_by_line: comments.to_h { |c| [c.location.start_line, c] }, + file: file, + ) - @comments_by_line = comments.to_h { |c| [c.location.start_line, c] } #: Hash[Integer, Prism::Comment] @tree = Tree.new #: Tree @scopes_stack = [@tree] #: Array[Tree] @@ -600,75 +673,6 @@ def detach_comments_from_sigs(sigs) comments end - #: (Prism::Node node) -> Array[Comment] - def node_comments(node) - comments = [] - - start_line = node.location.start_line - start_line -= 1 unless @comments_by_line.key?(start_line) - - rbs_continuation = [] #: Array[Prism::Comment] - - start_line.downto(1) do |line| - comment = @comments_by_line[line] - break unless comment - - text = comment.location.slice - - # If we find a RBS comment continuation `#|`, we store it until we find the start with `#:` - if text.start_with?("#|") - rbs_continuation << comment - @comments_by_line.delete(line) - next - end - - loc = Loc.from_prism(@file, comment.location) - - # If we find the start of a RBS comment, we create a new RBSComment - # Note that we ignore RDoc directives such as `:nodoc:` - # See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives - if text.start_with?("#:") && !(text =~ /^#:[a-z_]+:/) - text = text.sub(/^#: ?/, "").rstrip - - # If we found continuation comments, we merge them in reverse order (since we go from bottom to top) - rbs_continuation.reverse_each do |rbs_comment| - continuation_text = rbs_comment.location.slice.sub(/^#\| ?/, "").strip - continuation_loc = Loc.from_prism(@file, rbs_comment.location) - loc = loc.join(continuation_loc) - text = "#{text}#{continuation_text}" - end - - rbs_continuation.clear - comments.unshift(RBSComment.new(text, loc: loc)) - else - # If we have unused continuation comments, we should inject them back to not lose them - rbs_continuation.each do |rbs_comment| - comments.unshift(parse_comment(rbs_comment)) - end - - rbs_continuation.clear - comments.unshift(parse_comment(comment)) - end - - @comments_by_line.delete(line) - end - - # If we have unused continuation comments, we should inject them back to not lose them - rbs_continuation.each do |rbs_comment| - comments.unshift(parse_comment(rbs_comment)) - end - rbs_continuation.clear - - comments - end - - #: (Prism::Comment node) -> Comment - def parse_comment(node) - text = node.location.slice.sub(/^# ?/, "").rstrip - loc = Loc.from_prism(@file, node.location) - Comment.new(text, loc: loc) - end - #: (Prism::Node? node) -> Array[Arg] def parse_send_args(node) args = [] #: Array[Arg] From ded19127073cb3b00663fc6c86129bb301744c74 Mon Sep 17 00:00:00 2001 From: Kaan Ozkan Date: Wed, 10 Jun 2026 14:04:09 -0400 Subject: [PATCH 2/4] Preserve sig param comments in RBS output --- lib/rbi/parser.rb | 22 +++++++--- lib/rbi/rbs_printer.rb | 20 ++++++++- test/rbi/parser_test.rb | 27 +++++++++++++ test/rbi/rbs_printer_test.rb | 78 ++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 7 deletions(-) diff --git a/lib/rbi/parser.rb b/lib/rbi/parser.rb index 7599db88..7ac895c9 100644 --- a/lib/rbi/parser.rb +++ b/lib/rbi/parser.rb @@ -161,12 +161,13 @@ def t_sig_without_runtime?(node) !!(node.is_a?(Prism::ConstantPathNode) && node_string(node) =~ /(::)?T::Sig::WithoutRuntime/) end - #: (Prism::Node node) -> Array[Comment] - def node_comments(node) + #: (Prism::Node node, ?min_line: Integer?) -> Array[Comment] + def node_comments(node, min_line: nil) comments = [] start_line = node.location.start_line start_line -= 1 unless @comments_by_line.key?(start_line) + start_line = [start_line, min_line].max if min_line rbs_continuation = [] #: Array[Prism::Comment] @@ -767,7 +768,7 @@ def parse_params(node) #: (Prism::CallNode node) -> Sig def parse_sig(node) - builder = SigBuilder.new(@source, file: @file) + builder = SigBuilder.new(@source, comments_by_line: @comments_by_line, file: @file) builder.current.loc = node_loc(node) builder.visit_call_node(node) builder.current.comments = node_comments(node) @@ -920,11 +921,16 @@ class SigBuilder < Visitor #: Sig attr_reader :current - #: (String content, file: String) -> void - def initialize(content, file:) - super + # Bounds sig param comment lookup to comments inside the current `params(...)` call. + #: Integer? + attr_reader :params_start_line + + #: (String content, comments_by_line: Hash[Integer, Prism::Comment], file: String) -> void + def initialize(content, comments_by_line:, file:) + super(content, comments_by_line: comments_by_line, file: file) @current = Sig.new #: Sig + @params_start_line = nil #: Integer? end # @override @@ -955,7 +961,9 @@ def visit_call_node(node) when "overridable" @current.is_overridable = true when "params" + @params_start_line = node.location.start_line visit(node.arguments) + @params_start_line = nil when "returns" args = node.arguments if args.is_a?(Prism::ArgumentsNode) @@ -983,6 +991,8 @@ def visit_assoc_node(node) @current.params << SigParam.new( node_string!(node.key).delete_suffix(":"), node_string!(node.value), + loc: node_loc(node), + comments: node_comments(node, min_line: params_start_line), ) end diff --git a/lib/rbi/rbs_printer.rb b/lib/rbi/rbs_printer.rb index c4deb3bf..eacfd0d4 100644 --- a/lib/rbi/rbs_printer.rb +++ b/lib/rbi/rbs_printer.rb @@ -406,7 +406,7 @@ def print_method_sig(node, sig) @out = old_out max_line_length = @max_line_length - if max_line_length.nil? || new_out.string.size <= max_line_length + if !sig_params_have_comments?(node, sig) && (max_line_length.nil? || new_out.string.size <= max_line_length) print(new_out.string) else print_method_sig_multiline(node, sig) @@ -495,6 +495,7 @@ def print_method_sig_multiline(node, sig) printl("(") indent sig_params.each_with_index do |param, index| + print_sig_param_comments(param) printt print_sig_param(node, param) print(",") if index < sig_params.size - 1 @@ -899,6 +900,23 @@ def print_sig_param(node, param) end end + #: (Method node, Sig sig) -> bool + def sig_params_have_comments?(node, sig) + sig_params = sig.params + + block_param = node.params.find { |param| param.is_a?(BlockParam) } + if block_param + sig_params = sig_params.reject { |param| param.name == block_param.name } + end + + sig_params.any?(&:comments?) + end + + #: (SigParam param) -> void + def print_sig_param_comments(param) + visit_all(param.comments) + end + #: (Param node, last: bool) -> void def print_param_comment_leading_space(node, last:) printn diff --git a/test/rbi/parser_test.rb b/test/rbi/parser_test.rb index 0be7aa3a..4f92ed1d 100644 --- a/test/rbi/parser_test.rb +++ b/test/rbi/parser_test.rb @@ -318,6 +318,33 @@ def test_parse_sig_comments assert_equal(rbi, out.string) end + def test_parse_sig_param_comments + rbi = <<~RBI + sig do + params( + # `a` comment + a: Integer, + # `b` comment 1 + # `b` comment 2 + b: String + ).void + end + def foo(a, b); end + RBI + + out = Parser.parse_string(rbi) + assert_equal(<<~RBI, out.string) + sig do + params( + a: Integer, # `a` comment + b: String # `b` comment 1 + # `b` comment 2 + ).void + end + def foo(a, b); end + RBI + end + def test_parse_methods_with_visibility rbi = <<~RBI private def m1; end diff --git a/test/rbi/rbs_printer_test.rb b/test/rbi/rbs_printer_test.rb index 477334b8..e143299d 100644 --- a/test/rbi/rbs_printer_test.rb +++ b/test/rbi/rbs_printer_test.rb @@ -560,6 +560,84 @@ def test_print_breaks_long_signatures RBI end + def test_print_breaks_signatures_with_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << ReqParam.new("a") + node.params << ReqParam.new("b") + end + + rbi_sig = Sig.new do |sig| + sig.params << SigParam.new("a", "Integer", comments: [Comment.new("First param")]) + sig.params << SigParam.new("b", "String") + sig.return_type = "void" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal(<<~RBI.strip, out.string) + ( + # First param + Integer a, + String b + ) -> void + RBI + end + + def test_print_breaks_signatures_with_multiple_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << ReqParam.new("a") + node.params << ReqParam.new("b") + node.params << KwParam.new("c") + end + + rbi_sig = Sig.new do |sig| + sig.params << SigParam.new("a", "Integer", comments: [Comment.new("First param")]) + sig.params << SigParam.new("b", "String", comments: [Comment.new("Second param")]) + sig.params << SigParam.new("c", "Symbol", comments: [Comment.new("Keyword param")]) + sig.return_type = "void" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal(<<~RBI.strip, out.string) + ( + # First param + Integer a, + # Second param + String b, + # Keyword param + c: Symbol + ) -> void + RBI + end + + def test_print_breaks_signatures_with_mixed_sig_param_comments + rbi = parse_rbi(<<~RBI) + sig do + params( + a: Integer, + # Commented param + b: String, + c: Symbol + ).void + end + def foo(a, b, c:); end + RBI + + assert_equal(<<~RBI, rbi.rbs_string) + def foo: ( + Integer a, + # Commented param + String b, + c: Symbol + ) -> void + RBI + end + def test_print_simplified_types rbi = parse_rbi(<<~RBI) sig { returns(T.any(String, String, NilClass, T.nilable(T.nilable(Integer)), TrueClass, FalseClass)) } From 8271c75ae0efc3854a347a2a2104cf5b9f4e7b4b Mon Sep 17 00:00:00 2001 From: Kaan Ozkan Date: Wed, 10 Jun 2026 15:30:33 -0400 Subject: [PATCH 3/4] Render commented block sig params in RBS --- lib/rbi/rbs_printer.rb | 97 ++++++++++++++++++++----- test/rbi/rbs_printer_test.rb | 134 +++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 18 deletions(-) diff --git a/lib/rbi/rbs_printer.rb b/lib/rbi/rbs_printer.rb index eacfd0d4..e7067d28 100644 --- a/lib/rbi/rbs_printer.rb +++ b/lib/rbi/rbs_printer.rb @@ -362,9 +362,17 @@ def visit_method(node) print("self.") if node.is_singleton print(node.name) sigs = node.sigs - print(": ") + print(":") if sigs.any? first, *rest = sigs + if method_sig_starts_on_next_line?( + node, + first, #: as !nil + ) + printn + else + print(" ") + end print_method_sig( node, first, #: as !nil @@ -374,11 +382,19 @@ def visit_method(node) rest.each do |sig| printn printt - print("#{" " * spaces}| ") + print("#{" " * spaces}|") + if method_sig_starts_on_next_line?(node, sig) + printn + print_method_sig(node, sig) + next + end + + print(" ") print_method_sig(node, sig) end end else + print(" ") if node.params.any? params = node.params.grep_v(BlockParam) block = node.params.find { |param| param.is_a?(BlockParam) } @@ -406,7 +422,8 @@ def print_method_sig(node, sig) @out = old_out max_line_length = @max_line_length - if !sig_params_have_comments?(node, sig) && (max_line_length.nil? || new_out.string.size <= max_line_length) + if !sig_params_have_printable_comments?(node, sig) && + (max_line_length.nil? || new_out.string.size <= max_line_length) print(new_out.string) else print_method_sig_multiline(node, sig) @@ -477,10 +494,6 @@ def print_method_sig_inline(node, sig) #: (RBI::Method node, Sig sig) -> void def print_method_sig_multiline(node, sig) - unless sig.type_params.empty? - print("[#{sig.type_params.join(", ")}] ") - end - block_param = node.params.find { |param| param.is_a?(BlockParam) } sig_block_param = sig.params.find { |param| param.name == block_param&.name } @@ -490,6 +503,16 @@ def print_method_sig_multiline(node, sig) param.name == block_param.name end end + print_sig_block_param = sig_block_param && print_sig_block_param?(sig_block_param) + sig_block_param_has_comments = sig_block_param&.comments? && print_sig_block_param + + unless sig.type_params.empty? + if sig_block_param_has_comments && sig_params.empty? + printl("[#{sig.type_params.join(", ")}]") + else + print("[#{sig.type_params.join(", ")}] ") + end + end unless sig_params.empty? printl("(") @@ -502,7 +525,11 @@ def print_method_sig_multiline(node, sig) printn end dedent - printt(") ") + if sig_block_param_has_comments + printl(")") + else + printt(") ") + end end if sig_block_param block_type = sig_block_param.type @@ -526,13 +553,21 @@ def print_method_sig_multiline(node, sig) skip = true if block_type.name == "NilClass" end - if skip - # no-op, we skip the block definition - elsif block_is_nilable - print("?{ #{type_string} } ") - else - print("{ #{type_string} } ") + unless skip + if sig_block_param_has_comments + indent + print_sig_param_comments(sig_block_param) + printt + end + + if block_is_nilable + print("?{ #{type_string} } ") + else + print("{ #{type_string} } ") + end end + + dedent if sig_block_param_has_comments end type = parse_type(sig.return_type) @@ -902,14 +937,40 @@ def print_sig_param(node, param) #: (Method node, Sig sig) -> bool def sig_params_have_comments?(node, sig) - sig_params = sig.params + sig.params.any?(&:comments?) + end + #: (RBI::Method node, Sig sig) -> bool + def sig_params_have_printable_comments?(node, sig) block_param = node.params.find { |param| param.is_a?(BlockParam) } - if block_param - sig_params = sig_params.reject { |param| param.name == block_param.name } + sig.params.any? do |param| + next false unless param.comments? + + param.name != block_param&.name || print_sig_block_param?(param) end + end + + #: (SigParam param) -> bool + def print_sig_block_param?(param) + block_type = param.type + block_type = Type.parse_string(block_type) if block_type.is_a?(String) + block_type = block_type.type if block_type.is_a?(Type::Nilable) + + !block_type.is_a?(Type::Simple) || block_type.name != "NilClass" + end + + #: (RBI::Method node, Sig sig) -> bool + def method_sig_starts_on_next_line?(node, sig) + return false unless sig_params_have_printable_comments?(node, sig) + + block_param = node.params.find { |param| param.is_a?(BlockParam) } + sig_block_param = sig.params.find { |param| param.name == block_param&.name } + sig_params = sig.params.reject { |param| param.name == block_param&.name } + + sig_block_param_has_comments = sig_block_param&.comments? + return false if sig_block_param_has_comments && sig_block_param && !print_sig_block_param?(sig_block_param) - sig_params.any?(&:comments?) + sig.type_params.empty? && sig_params.empty? end #: (SigParam param) -> void diff --git a/test/rbi/rbs_printer_test.rb b/test/rbi/rbs_printer_test.rb index e143299d..3ef9c581 100644 --- a/test/rbi/rbs_printer_test.rb +++ b/test/rbi/rbs_printer_test.rb @@ -638,6 +638,140 @@ def foo: ( RBI end + def test_prints_multiline_signature_with_block_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << BlockParam.new("block") + end + + rbi_sig = Sig.new do |sig| + sig.params << SigParam.new("block", "T.proc.void", comments: [Comment.new("Block param")]) + sig.return_type = "void" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal(" # Block param\n { -> void } -> void", out.string) + end + + def test_prints_multiline_signature_with_param_and_block_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << ReqParam.new("a") + node.params << BlockParam.new("block") + end + + rbi_sig = Sig.new do |sig| + sig.params << SigParam.new("a", "Integer", comments: [Comment.new("Positional param")]) + sig.params << SigParam.new("block", "T.proc.void", comments: [Comment.new("Block param")]) + sig.return_type = "void" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal( + "(\n # Positional param\n Integer a\n)\n # Block param\n { -> void } -> void", + out.string, + ) + end + + def test_prints_multiline_signature_with_type_params_and_block_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << BlockParam.new("block") + end + + rbi_sig = Sig.new do |sig| + sig.type_params << "U" + sig.params << SigParam.new( + "block", + "T.proc.returns(T.type_parameter(:U))", + comments: [Comment.new("Block param")], + ) + sig.return_type = "T.type_parameter(:U)" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal("[U]\n # Block param\n { -> U } -> U", out.string) + end + + def test_prints_signature_with_nil_block_sig_param_comments + rbi_def = Method.new("foo") do |node| + node.params << BlockParam.new("block") + end + + rbi_sig = Sig.new do |sig| + sig.params << SigParam.new("block", "NilClass", comments: [Comment.new("Block param")]) + sig.return_type = "void" + end + + out = StringIO.new + printer = RBI::RBSPrinter.new(out: out) + printer.print_method_sig(rbi_def, rbi_sig) + + assert_equal("-> void", out.string) + end + + def test_prints_multiline_overload_with_block_sig_param_comments + rbi = parse_rbi(<<~RBI) + sig { void } + sig do + params( + # Block param + block: T.proc.void + ).void + end + def foo(&block); end + RBI + + assert_equal(<<~RBI, rbi.rbs_string) + def foo: -> void + | + # Block param + { -> void } -> void + RBI + end + + def test_prints_signature_with_nil_block_sig_param_comments_after_positional_params + rbi = parse_rbi(<<~RBI) + sig do + params( + a: Integer, + # Block param + block: NilClass + ).void + end + def foo(a, &block); end + RBI + + assert_equal(<<~RBI, rbi.rbs_string) + def foo: (Integer a) -> void + RBI + end + + def test_prints_overload_with_nil_block_sig_param_comments + rbi = parse_rbi(<<~RBI) + sig { void } + sig do + params( + a: Integer, + # Block param + block: NilClass + ).void + end + def foo(a, &block); end + RBI + + assert_equal(<<~RBI, rbi.rbs_string) + def foo: -> void + | (Integer a) -> void + RBI + end + def test_print_simplified_types rbi = parse_rbi(<<~RBI) sig { returns(T.any(String, String, NilClass, T.nilable(T.nilable(Integer)), TrueClass, FalseClass)) } From 11d51ebb216a9e84144ec90dd0163fd12f5f9531 Mon Sep 17 00:00:00 2001 From: Kaan Ozkan Date: Wed, 10 Jun 2026 14:55:59 -0400 Subject: [PATCH 4/4] Update exported signatures --- rbi/rbi.rbi | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/rbi/rbi.rbi b/rbi/rbi.rbi index 8a3a3c01..778ba5b3 100644 --- a/rbi/rbi.rbi +++ b/rbi/rbi.rbi @@ -973,8 +973,8 @@ class RBI::Parser::HeredocLocationVisitor < ::Prism::Visitor end class RBI::Parser::SigBuilder < ::RBI::Parser::Visitor - sig { params(content: ::String, file: ::String).void } - def initialize(content, file:); end + sig { params(content: ::String, comments_by_line: T::Hash[::Integer, ::Prism::Comment], file: ::String).void } + def initialize(content, comments_by_line:, file:); end sig { params(node: ::Prism::CallNode, value: ::String).returns(T::Boolean) } def allow_incompatible_override?(node, value); end @@ -982,6 +982,9 @@ class RBI::Parser::SigBuilder < ::RBI::Parser::Visitor sig { returns(::RBI::Sig) } def current; end + sig { returns(T.nilable(::Integer)) } + def params_start_line; end + sig { override.params(node: ::Prism::AssocNode).void } def visit_assoc_node(node); end @@ -1043,12 +1046,6 @@ class RBI::Parser::TreeBuilder < ::RBI::Parser::Visitor sig { params(sigs: T::Array[::RBI::Sig]).returns(T::Array[::RBI::Comment]) } def detach_comments_from_sigs(sigs); end - sig { params(node: ::Prism::Node).returns(T::Array[::RBI::Comment]) } - def node_comments(node); end - - sig { params(node: ::Prism::Comment).returns(::RBI::Comment) } - def parse_comment(node); end - sig { params(node: T.nilable(::Prism::Node)).returns(T::Array[::RBI::Param]) } def parse_params(node); end @@ -1085,14 +1082,23 @@ class RBI::Parser::TreeBuilder < ::RBI::Parser::Visitor end class RBI::Parser::Visitor < ::Prism::Visitor - sig { params(source: ::String, file: ::String).void } - def initialize(source, file:); end + sig do + params( + source: ::String, + file: ::String, + comments_by_line: T.nilable(T::Hash[::Integer, ::Prism::Comment]) + ).void + end + def initialize(source, file:, comments_by_line: T.unsafe(nil)); end private sig { params(node: ::Prism::Node).returns(::Prism::Location) } def adjust_prism_location_for_heredoc(node); end + sig { params(node: ::Prism::Node, min_line: T.nilable(::Integer)).returns(T::Array[::RBI::Comment]) } + def node_comments(node, min_line: T.unsafe(nil)); end + sig { params(node: ::Prism::Node).returns(::RBI::Loc) } def node_loc(node); end @@ -1102,6 +1108,9 @@ class RBI::Parser::Visitor < ::Prism::Visitor sig { params(node: ::Prism::Node).returns(::String) } def node_string!(node); end + sig { params(node: ::Prism::Comment).returns(::RBI::Comment) } + def parse_comment(node); end + sig { params(node: T.nilable(::Prism::Node)).returns(T::Boolean) } def self?(node); end @@ -1675,6 +1684,9 @@ class RBI::RBSPrinter < ::RBI::Visitor private + sig { params(node: ::RBI::Method, sig: ::RBI::Sig).returns(T::Boolean) } + def method_sig_starts_on_next_line?(node, sig); end + sig { params(node: ::RBI::Node).returns(T::Boolean) } def oneline?(node); end @@ -1693,11 +1705,23 @@ class RBI::RBSPrinter < ::RBI::Visitor sig { params(node: ::RBI::Param, last: T::Boolean).void } def print_param_comment_leading_space(node, last:); end + sig { params(param: ::RBI::SigParam).returns(T::Boolean) } + def print_sig_block_param?(param); end + sig { params(node: ::RBI::Method, param: ::RBI::SigParam).void } def print_sig_param(node, param); end sig { params(node: ::RBI::SigParam, last: T::Boolean).void } def print_sig_param_comment_leading_space(node, last:); end + + sig { params(param: ::RBI::SigParam).void } + def print_sig_param_comments(param); end + + sig { params(node: ::RBI::Method, sig: ::RBI::Sig).returns(T::Boolean) } + def sig_params_have_comments?(node, sig); end + + sig { params(node: ::RBI::Method, sig: ::RBI::Sig).returns(T::Boolean) } + def sig_params_have_printable_comments?(node, sig); end end class RBI::RBSPrinter::Error < ::RBI::Error; end