class Rufo::Formatter
def consume_end_of_line(at_prefix: false, want_semicolon: false, want_multiline: true, needs_two_lines_on_comment: false)
- want_semicolon: do we want do print a semicolon to separate expressions?
- at_prefix: are we at a point before an expression? (if so, we don't need a space before the first comment)
Consume and print an end of line, handling semicolons and comments
def consume_end_of_line(at_prefix: false, want_semicolon: false, want_multiline: true, needs_two_lines_on_comment: false) found_newline = false # Did we find any newline during this method? last = nil # Last token kind found multilple_lines = false # Did we pass through more than one newline? last_comment_has_newline = false # Does the last comment has a newline? newline_count = 0 # Number of newlines we passed loop do case current_token_kind when :on_sp # Ignore spaces next_token when :on_nl, :on_ignored_nl # I don't know why but sometimes a on_ignored_nl # can appear with nil as the "text", and that's wrong if current_token[2].nil? next_token next end if last == :newline # If we pass through consecutive newlines, don't print them # yet, but remember this fact multilple_lines = true unless last_comment_has_newline else # If we just printed a comment that had a newline, # we must print two newlines because we remove newlines from comments (rstrip call) if last == :comment && last_comment_has_newline write_line multilple_lines = true else write_line multilple_lines = false end end found_newline = true next_token last = :newline newline_count += 1 when :on_semicolon next_token # If we want to print semicolons and we didn't find a newline yet, # print it, but only if it's not followed by a newline if !found_newline && want_semicolon && last != :semicolon skip_space case current_token_kind when :on_ignored_nl, :on_eof else write "; " last = :semicolon end end multilple_lines = false when :on_comment if last == :comment # Since we remove newlines from comments, we must add the last # one if it was a comment write_line write_indent else if found_newline if newline_count == 1 && needs_two_lines_on_comment if multilple_lines write_line multilple_lines = false else multilple_lines = true end needs_two_lines_on_comment = false end # Write line or second line if needed write_line if last != :newline || multilple_lines write_indent else # If we didn't find any newline yet, this is the first comment, # so append a space if needed (for example after an expression) write_space unless at_prefix track_comment end end last_comment_has_newline = current_token_value.end_with?("\n") write current_token_value.rstrip next_token last = :comment multilple_lines = false when :on_embdoc_beg write_line if multilple_lines consume_embedded_comment last = :comment last_comment_has_newline = true else break end end # Output a newline if we didn't do so yet: # either we didn't find a newline and we are at the end of a line (and we didn't just pass a semicolon), # or the last thing was a comment (from which we removed the newline) # or we just passed multiple lines (but printed only one) if (!found_newline && !at_prefix && !(want_semicolon && last == :semicolon)) || last == :comment || (multilple_lines && want_multiline) write_line end end