@@ -112,12 +112,13 @@ def parse(source, file:)
112112 end
113113
114114 class Visitor < Prism ::Visitor
115- #: (String source, file: String) -> void
116- def initialize ( source , file :)
115+ #: (String source, file: String, ?comments_by_line: Hash[Integer, Prism::Comment]? ) -> void
116+ def initialize ( source , file :, comments_by_line : nil )
117117 super ( )
118118
119119 @source = source
120120 @file = file
121+ @comments_by_line = comments_by_line || { } #: Hash[Integer, Prism::Comment]
121122 end
122123
123124 private
@@ -159,6 +160,75 @@ def self?(node)
159160 def t_sig_without_runtime? ( node )
160161 !!( node . is_a? ( Prism ::ConstantPathNode ) && node_string ( node ) =~ /(::)?T::Sig::WithoutRuntime/ )
161162 end
163+
164+ #: (Prism::Node node) -> Array[Comment]
165+ def node_comments ( node )
166+ comments = [ ]
167+
168+ start_line = node . location . start_line
169+ start_line -= 1 unless @comments_by_line . key? ( start_line )
170+
171+ rbs_continuation = [ ] #: Array[Prism::Comment]
172+
173+ start_line . downto ( 1 ) do |line |
174+ comment = @comments_by_line [ line ]
175+ break unless comment
176+
177+ text = comment . location . slice
178+
179+ # If we find a RBS comment continuation `#|`, we store it until we find the start with `#:`
180+ if text . start_with? ( "#|" )
181+ rbs_continuation << comment
182+ @comments_by_line . delete ( line )
183+ next
184+ end
185+
186+ loc = Loc . from_prism ( @file , comment . location )
187+
188+ # If we find the start of a RBS comment, we create a new RBSComment
189+ # Note that we ignore RDoc directives such as `:nodoc:`
190+ # See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives
191+ if text . start_with? ( "#:" ) && !( text =~ /^#:[a-z_]+:/ )
192+ text = text . sub ( /^#: ?/ , "" ) . rstrip
193+
194+ # If we found continuation comments, we merge them in reverse order (since we go from bottom to top)
195+ rbs_continuation . reverse_each do |rbs_comment |
196+ continuation_text = rbs_comment . location . slice . sub ( /^#\| ?/ , "" ) . strip
197+ continuation_loc = Loc . from_prism ( @file , rbs_comment . location )
198+ loc = loc . join ( continuation_loc )
199+ text = "#{ text } #{ continuation_text } "
200+ end
201+
202+ rbs_continuation . clear
203+ comments . unshift ( RBSComment . new ( text , loc : loc ) )
204+ else
205+ # If we have unused continuation comments, we should inject them back to not lose them
206+ rbs_continuation . each do |rbs_comment |
207+ comments . unshift ( parse_comment ( rbs_comment ) )
208+ end
209+
210+ rbs_continuation . clear
211+ comments . unshift ( parse_comment ( comment ) )
212+ end
213+
214+ @comments_by_line . delete ( line )
215+ end
216+
217+ # If we have unused continuation comments, we should inject them back to not lose them
218+ rbs_continuation . each do |rbs_comment |
219+ comments . unshift ( parse_comment ( rbs_comment ) )
220+ end
221+ rbs_continuation . clear
222+
223+ comments
224+ end
225+
226+ #: (Prism::Comment node) -> Comment
227+ def parse_comment ( node )
228+ text = node . location . slice . sub ( /^# ?/ , "" ) . rstrip
229+ loc = Loc . from_prism ( @file , node . location )
230+ Comment . new ( text , loc : loc )
231+ end
162232 end
163233
164234 class TreeBuilder < Visitor
@@ -170,9 +240,12 @@ class TreeBuilder < Visitor
170240
171241 #: (String source, comments: Array[Prism::Comment], file: String) -> void
172242 def initialize ( source , comments :, file :)
173- super ( source , file : file )
243+ super (
244+ source ,
245+ comments_by_line : comments . to_h { |c | [ c . location . start_line , c ] } ,
246+ file : file ,
247+ )
174248
175- @comments_by_line = comments . to_h { |c | [ c . location . start_line , c ] } #: Hash[Integer, Prism::Comment]
176249 @tree = Tree . new #: Tree
177250
178251 @scopes_stack = [ @tree ] #: Array[Tree]
@@ -600,75 +673,6 @@ def detach_comments_from_sigs(sigs)
600673 comments
601674 end
602675
603- #: (Prism::Node node) -> Array[Comment]
604- def node_comments ( node )
605- comments = [ ]
606-
607- start_line = node . location . start_line
608- start_line -= 1 unless @comments_by_line . key? ( start_line )
609-
610- rbs_continuation = [ ] #: Array[Prism::Comment]
611-
612- start_line . downto ( 1 ) do |line |
613- comment = @comments_by_line [ line ]
614- break unless comment
615-
616- text = comment . location . slice
617-
618- # If we find a RBS comment continuation `#|`, we store it until we find the start with `#:`
619- if text . start_with? ( "#|" )
620- rbs_continuation << comment
621- @comments_by_line . delete ( line )
622- next
623- end
624-
625- loc = Loc . from_prism ( @file , comment . location )
626-
627- # If we find the start of a RBS comment, we create a new RBSComment
628- # Note that we ignore RDoc directives such as `:nodoc:`
629- # See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives
630- if text . start_with? ( "#:" ) && !( text =~ /^#:[a-z_]+:/ )
631- text = text . sub ( /^#: ?/ , "" ) . rstrip
632-
633- # If we found continuation comments, we merge them in reverse order (since we go from bottom to top)
634- rbs_continuation . reverse_each do |rbs_comment |
635- continuation_text = rbs_comment . location . slice . sub ( /^#\| ?/ , "" ) . strip
636- continuation_loc = Loc . from_prism ( @file , rbs_comment . location )
637- loc = loc . join ( continuation_loc )
638- text = "#{ text } #{ continuation_text } "
639- end
640-
641- rbs_continuation . clear
642- comments . unshift ( RBSComment . new ( text , loc : loc ) )
643- else
644- # If we have unused continuation comments, we should inject them back to not lose them
645- rbs_continuation . each do |rbs_comment |
646- comments . unshift ( parse_comment ( rbs_comment ) )
647- end
648-
649- rbs_continuation . clear
650- comments . unshift ( parse_comment ( comment ) )
651- end
652-
653- @comments_by_line . delete ( line )
654- end
655-
656- # If we have unused continuation comments, we should inject them back to not lose them
657- rbs_continuation . each do |rbs_comment |
658- comments . unshift ( parse_comment ( rbs_comment ) )
659- end
660- rbs_continuation . clear
661-
662- comments
663- end
664-
665- #: (Prism::Comment node) -> Comment
666- def parse_comment ( node )
667- text = node . location . slice . sub ( /^# ?/ , "" ) . rstrip
668- loc = Loc . from_prism ( @file , node . location )
669- Comment . new ( text , loc : loc )
670- end
671-
672676 #: (Prism::Node? node) -> Array[Arg]
673677 def parse_send_args ( node )
674678 args = [ ] #: Array[Arg]
0 commit comments