Skip to content

Commit d6b6e91

Browse files
committed
Preserve inline comments inside sig blocks during RBS translation
Comments inside `sig do params(...) end` blocks were silently dropped because the entire sig node byte range was replaced with the RBS string. Collect any comments within the sig node's range and prepend them to the output before the `#:` annotation.
1 parent 29815dc commit d6b6e91

3 files changed

Lines changed: 71 additions & 0 deletions

File tree

lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def visit_def_node(node)
7878
out = rbs_print(node.location.start_column) do |printer|
7979
printer.print_method_sig(rbi_node, sig)
8080
end
81+
out = add_inline_sig_comments(node, out)
8182
@rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out)
8283
end
8384

@@ -207,6 +208,7 @@ def visit_attr(node)
207208
out = rbs_print(node.location.start_column) do |printer|
208209
printer.print_attr_sig(rbi_node, sig)
209210
end
211+
out = add_inline_sig_comments(node, out)
210212
@rewriter << Source::Replace.new(node.location.start_offset, node.location.end_offset, out)
211213
end
212214
end
@@ -379,6 +381,19 @@ def delete_extend_t_generics
379381
@extend_t_generics.clear
380382
end
381383

384+
#: (Prism::CallNode, String) -> String
385+
def add_inline_sig_comments(sig_node, out)
386+
inline_comments = @comments.select do |comment|
387+
comment.location.start_offset > sig_node.location.start_offset &&
388+
comment.location.end_offset <= sig_node.location.end_offset
389+
end
390+
return out if inline_comments.empty?
391+
392+
indent_str = " " * sig_node.location.start_column
393+
comment_string = inline_comments.map { |c| "#{c.slice}\n#{indent_str}" }.join
394+
comment_string + out
395+
end
396+
382397
# Collects the last signatures visited and clears the current list
383398
#: -> Array[[Prism::CallNode, RBI::Sig]]
384399
def collect_last_sigs

rbi/spoom.rbi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,6 +3023,9 @@ class Spoom::Sorbet::Translate::SorbetSigsToRBSComments < ::Spoom::Sorbet::Trans
30233023

30243024
private
30253025

3026+
sig { params(sig_node: ::Prism::CallNode, out: ::String).returns(::String) }
3027+
def add_inline_sig_comments(sig_node, out); end
3028+
30263029
sig do
30273030
params(
30283031
parent: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),

test/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments_test.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,59 @@ def foo(param1:, param2:); end
466466
RBS
467467
end
468468

469+
def test_translate_to_rbs_sig_with_inline_param_comments
470+
contents = <<~RB
471+
sig do
472+
params(
473+
# First param
474+
a: Integer,
475+
# Second param
476+
b: String
477+
).void
478+
end
479+
def foo(a, b); end
480+
481+
sig do
482+
# A comment
483+
returns(Integer)
484+
end
485+
attr_reader :x
486+
RB
487+
488+
assert_equal(<<~RBS, sorbet_sigs_to_rbs_comments(contents))
489+
# First param
490+
# Second param
491+
#: (Integer a, String b) -> void
492+
def foo(a, b); end
493+
494+
# A comment
495+
#: Integer
496+
attr_reader :x
497+
RBS
498+
end
499+
500+
def test_translate_to_rbs_sig_with_inline_param_comments_indented
501+
contents = <<~RB
502+
class Foo
503+
sig do
504+
params(
505+
# First param
506+
a: Integer
507+
).void
508+
end
509+
def foo(a); end
510+
end
511+
RB
512+
513+
assert_equal(<<~RBS, sorbet_sigs_to_rbs_comments(contents))
514+
class Foo
515+
# First param
516+
#: (Integer a) -> void
517+
def foo(a); end
518+
end
519+
RBS
520+
end
521+
469522
def test_translate_to_rbs_defs_within_send
470523
contents = <<~RB
471524
sig { void }

0 commit comments

Comments
 (0)