@@ -141,7 +141,6 @@ class Lexer # :nodoc:
141141 MINUS_EQUAL : :tOP_ASGN ,
142142 MINUS_GREATER : :tLAMBDA ,
143143 NEWLINE : :tNL ,
144- NEWLINE_TERMINATOR : :tNL ,
145144 NUMBERED_REFERENCE : :tNTH_REF ,
146145 PARENTHESIS_LEFT : :tLPAREN2 ,
147146 PARENTHESIS_LEFT_GROUPING : :tLPAREN ,
@@ -188,6 +187,11 @@ class Lexer # :nodoc:
188187 XSTRING_BEGIN : :tXSTRING_BEG
189188 }
190189
190+ # Types of tokens that are allowed to continue a method call with comments in-between.
191+ # For these, the parser gem doesn't emit a newline token after the last comment.
192+ COMMENT_CONTINUATION_TYPES = Set . new ( [ :COMMENT , :AMPERSAND_DOT , :DOT ] )
193+ private_constant :COMMENT_CONTINUATION_TYPES
194+
191195 # Heredocs are complex and require us to keep track of a bit of info to refer to later
192196 HeredocData = Struct . new ( :identifier , :common_whitespace , keyword_init : true )
193197
@@ -238,13 +242,6 @@ def to_a
238242 value = token . value
239243 location = range ( token . location . start_offset , token . location . end_offset )
240244
241- # A newline deferred past a run of comments is emitted before the
242- # token that follows the last comment.
243- if comment_newline_location && type != :tCOMMENT
244- tokens << [ :tNL , [ nil , comment_newline_location ] ]
245- comment_newline_location = nil
246- end
247-
248245 case type
249246 when :tCHARACTER
250247 value . delete_prefix! ( "?" )
@@ -262,9 +259,27 @@ def to_a
262259 location = range ( token . location . start_offset , next_token . location . end_offset )
263260 index += 1
264261 else
265- # A carriage return before the terminating newline is part of
266- # the comment token but not of the comment's value.
267- location = range ( token . location . start_offset , token . location . end_offset - 1 ) if value . chomp!
262+ is_at_eol = value . chomp! . nil?
263+ location = range ( token . location . start_offset , token . location . end_offset + ( is_at_eol ? 0 : -1 ) )
264+
265+ prev_token , _ = lexed [ index - 2 ] if index - 2 >= 0
266+ next_token , _ = lexed [ index ]
267+
268+ is_inline_comment = prev_token &.location &.start_line == token . location . start_line
269+ if is_inline_comment && !is_at_eol && !COMMENT_CONTINUATION_TYPES . include? ( next_token &.type )
270+ tokens << [ :tCOMMENT , [ value , location ] ]
271+
272+ nl_location = range ( token . location . end_offset - 1 , token . location . end_offset )
273+ tokens << [ :tNL , [ nil , nl_location ] ]
274+ next
275+ elsif is_inline_comment && next_token &.type == :COMMENT
276+ comment_newline_location = range ( token . location . end_offset - 1 , token . location . end_offset )
277+ elsif comment_newline_location && !COMMENT_CONTINUATION_TYPES . include? ( next_token &.type )
278+ tokens << [ :tCOMMENT , [ value , location ] ]
279+ tokens << [ :tNL , [ nil , comment_newline_location ] ]
280+ comment_newline_location = nil
281+ next
282+ end
268283 end
269284 when :tNL
270285 next_token , _ = lexed [ index ]
@@ -486,10 +501,6 @@ def to_a
486501 end
487502 end
488503
489- if comment_newline_location
490- tokens << [ :tNL , [ nil , comment_newline_location ] ]
491- end
492-
493504 tokens
494505 end
495506
0 commit comments