@@ -138,6 +138,17 @@ def node_string(node)
138138 def node_string! ( node )
139139 T . must ( node_string ( node ) )
140140 end
141+
142+ #: (Prism::Node node) -> Prism::Location
143+ def adjust_prism_location_for_heredoc ( node )
144+ visitor = HeredocLocationVisitor . new (
145+ node . location . send ( :source ) ,
146+ node . location . start_offset ,
147+ node . location . end_offset ,
148+ )
149+ visitor . visit ( node )
150+ visitor . location
151+ end
141152 end
142153
143154 class TreeBuilder < Visitor
@@ -217,30 +228,40 @@ def visit_constant_assign(node)
217228
218229 current_scope << if struct
219230 struct
220- elsif type_variable_definition? ( node . value )
221- TypeMember . new (
222- case node
223- when Prism ::ConstantWriteNode
224- node . name . to_s
225- when Prism ::ConstantPathWriteNode
226- node_string! ( node . target )
227- end ,
228- node_string! ( node . value ) ,
229- loc : node_loc ( node ) ,
230- comments : node_comments ( node ) ,
231- )
232231 else
233- Const . new (
234- case node
235- when Prism ::ConstantWriteNode
236- node . name . to_s
237- when Prism ::ConstantPathWriteNode
238- node_string! ( node . target )
239- end ,
240- node_string! ( node . value ) ,
241- loc : node_loc ( node ) ,
242- comments : node_comments ( node ) ,
232+ adjusted_node_location = adjust_prism_location_for_heredoc ( node )
233+
234+ adjusted_value_location = Prism ::Location . new (
235+ node . value . location . send ( :source ) ,
236+ node . value . location . start_offset ,
237+ adjusted_node_location . end_offset - node . value . location . start_offset ,
243238 )
239+
240+ if type_variable_definition? ( node . value )
241+ TypeMember . new (
242+ case node
243+ when Prism ::ConstantWriteNode
244+ node . name . to_s
245+ when Prism ::ConstantPathWriteNode
246+ node_string! ( node . target )
247+ end ,
248+ adjusted_value_location . slice ,
249+ loc : Loc . from_prism ( @file , adjusted_node_location ) ,
250+ comments : node_comments ( node ) ,
251+ )
252+ else
253+ Const . new (
254+ case node
255+ when Prism ::ConstantWriteNode
256+ node . name . to_s
257+ when Prism ::ConstantPathWriteNode
258+ node_string! ( node . target )
259+ end ,
260+ adjusted_value_location . slice ,
261+ loc : Loc . from_prism ( @file , adjusted_node_location ) ,
262+ comments : node_comments ( node ) ,
263+ )
264+ end
244265 end
245266 end
246267
@@ -903,5 +924,57 @@ def visit_assoc_node(node)
903924 )
904925 end
905926 end
927+
928+ class HeredocLocationVisitor < Prism ::Visitor
929+ #: (Prism::Source source, Integer begin_offset, Integer end_offset) -> void
930+ def initialize ( source , begin_offset , end_offset )
931+ super ( )
932+ @source = source
933+ @begin_offset = begin_offset
934+ @end_offset = end_offset
935+ @offset_last_newline = false #: bool
936+ end
937+
938+ #: (Prism::StringNode node) -> void
939+ def visit_string_node ( node )
940+ return unless node . heredoc?
941+
942+ closing_loc = node . closing_loc
943+ return unless closing_loc
944+
945+ handle_string_node ( node )
946+ end
947+
948+ #: (Prism::InterpolatedStringNode node) -> void
949+ def visit_interpolated_string_node ( node )
950+ return super unless node . heredoc?
951+
952+ closing_loc = node . closing_loc
953+ return super unless closing_loc
954+
955+ handle_string_node ( node )
956+ end
957+
958+ #: -> Prism::Location
959+ def location
960+ Prism ::Location . new (
961+ @source ,
962+ @begin_offset ,
963+ @end_offset - @begin_offset - ( @offset_last_newline ? 1 : 0 ) ,
964+ )
965+ end
966+
967+ private
968+
969+ #: (Prism::StringNode | Prism::InterpolatedStringNode node) -> void
970+ def handle_string_node ( node )
971+ closing_loc = T . must ( node . closing_loc )
972+
973+ if closing_loc . end_offset > @end_offset
974+ @end_offset = closing_loc . end_offset
975+ @offset_last_newline = true if node . closing_loc &.slice &.end_with? ( "\n " )
976+ end
977+ end
978+ end
906979 end
907980end
0 commit comments