Module: RuboCop::Cop::TrailingComma
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
|
|
Defined in: | lib/rubocop/cop/mixin/trailing_comma.rb |
Overview
Common methods shared by Style/TrailingCommaInArguments and Style/TrailingCommaInLiteral
Constant Summary
-
MSG =
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 11'%<command>s comma after the last %<unit>s.'
ConfigurableEnforcedStyle
- Included
RangeHelp
- Included
Instance Attribute Summary
ConfigurableEnforcedStyle
- Included
Instance Method Summary
-
#allowed_multiline_argument?(node) ⇒ Boolean
private
A single argument with the closing bracket on the same line as the end of the argument is not considered multiline, even if the argument itself might span multiple lines.
- #any_heredoc?(items) ⇒ Boolean private
- #autocorrect_range(item) private
- #avoid_comma(kind, comma_begin_pos, extra_info) private
-
#brackets?(node) ⇒ Boolean
private
Returns true if the node has round/square/curly brackets.
- #check(node, items, kind, begin_pos, end_pos) private
- #check_comma(node, kind, comma_pos) private
- #check_literal(node, kind) private
- #comma_offset(items, range) private
- #elements(node) private
- #extra_avoid_comma_info private
- #heredoc?(node) ⇒ Boolean private
- #heredoc_send?(node) ⇒ Boolean private
- #inside_comment?(range, comma_offset) ⇒ Boolean private
- #method_name_and_arguments_on_same_line?(node) ⇒ Boolean private
-
#multiline?(node) ⇒ Boolean
private
Returns true if the round/square/curly brackets of the given node are on different lines, each item within is on its own line, and the closing bracket is on its own line.
- #no_elements_on_same_line?(node) ⇒ Boolean private
- #on_same_line?(range1, range2) ⇒ Boolean private
- #put_comma(items, kind) private
- #should_have_comma?(style, node) ⇒ Boolean private
- #style_parameter_name private
RangeHelp
- Included
#add_range, #column_offset_between, | |
#contents_range | A range containing only the contents of a literal with delimiters (e.g. |
#directions, | |
#effective_column | Returns the column attribute of the range, except if the range is on the first line and there’s a byte order mark at the beginning of that line, in which case 1 is subtracted from the column value. |
#final_pos, #move_pos, #move_pos_str, #range_between, #range_by_whole_lines, #range_with_comments, #range_with_comments_and_lines, #range_with_surrounding_comma, #range_with_surrounding_space, #source_range |
ConfigurableEnforcedStyle
- Included
Instance Method Details
#allowed_multiline_argument?(node) ⇒ Boolean
(private)
A single argument with the closing bracket on the same line as the end of the argument is not considered multiline, even if the argument itself might span multiple lines.
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 104
def allowed_multiline_argument?(node) elements(node).one? && !Util.begins_its_line?(node.loc.end) end
#any_heredoc?(items) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 167
def any_heredoc?(items) items.any? { |item| heredoc?(item) } end
#autocorrect_range(item) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 159
def autocorrect_range(item) expr = item.source_range ix = expr.source.rindex("\n") || 0 ix += expr.source[ix..] =~ /\S/ range_between(expr.begin_pos + ix, expr.end_pos) end
#avoid_comma(kind, comma_begin_pos, extra_info) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 133
def avoid_comma(kind, comma_begin_pos, extra_info) range = range_between(comma_begin_pos, comma_begin_pos + 1) article = kind.include?('array') ? 'an' : 'a' msg = format( MSG, command: 'Avoid', unit: format(kind, article: article) + extra_info.to_s ) add_offense(range, message: msg) do |corrector| PunctuationCorrector.swap_comma(corrector, range) end end
#brackets?(node) ⇒ Boolean
(private)
Returns true if the node has round/square/curly brackets.
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 82
def brackets?(node) node.loc.end end
#check(node, items, kind, begin_pos, end_pos) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 19
def check(node, items, kind, begin_pos, end_pos) after_last_item = range_between(begin_pos, end_pos) comma_offset = comma_offset(items, after_last_item) if comma_offset && !inside_comment?(after_last_item, comma_offset) check_comma(node, kind, after_last_item.begin_pos + comma_offset) elsif should_have_comma?(style, node) put_comma(items, kind) end end
#check_comma(node, kind, comma_pos) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 37
def check_comma(node, kind, comma_pos) return if should_have_comma?(style, node) avoid_comma(kind, comma_pos, extra_avoid_comma_info) end
#check_literal(node, kind) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 43
def check_literal(node, kind) return if node.children.empty? # A braceless hash is the last parameter of a method call and will be # checked as such. return unless brackets?(node) check(node, node.children, kind, node.children.last.source_range.end_pos, node.loc.end.begin_pos) end
#comma_offset(items, range) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 30
def comma_offset(items, range) # If there is any heredoc in items, then match the comma succeeding # any whitespace (except newlines), otherwise allow for newlines comma_regex = any_heredoc?(items) ? /\A[^\S\n]*,/ : /\A\s*,/ comma_regex.match?(range.source) && range.source.index(',') end
#elements(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 108
def elements(node) return node.children unless node.call_type? node.arguments.flat_map do |argument| # For each argument, if it is a multi-line hash without braces, # then promote the hash elements to method arguments # for the purpose of determining multi-line-ness. if argument.hash_type? && argument.multiline? && !argument.braces? argument.children else argument end end end
#extra_avoid_comma_info (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 54
def extra_avoid_comma_info case style when :comma ', unless each item is on its own line' when :consistent_comma ', unless items are split onto multiple lines' else '' end end
#heredoc?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 171
def heredoc?(node) return false unless node.is_a?(RuboCop::AST::Node) return true if node.loc.respond_to?(:heredoc_body) return heredoc_send?(node) if node.send_type? # handle hash values # # some_method({ # 'auth' => <<-SOURCE # ... # SOURCE # }) return heredoc?(node.children.last) if node.pair_type? || node.hash_type? false end
#heredoc_send?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 189
def heredoc_send?(node) # handle heredocs with methods # # some_method(<<-CODE.strip.chomp) # ... # CODE return heredoc?(node.children.first) if node.children.size == 2 # handle nested methods # # some_method( # another_method(<<-CODE.strip.chomp) # ... # CODE # ) return heredoc?(node.children.last) if node.children.size > 2 false end
#inside_comment?(range, comma_offset) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 76
def inside_comment?(range, comma_offset) comment = processed_source.comment_at_line(range.line) comment && comment.source_range.begin_pos < range.begin_pos + comma_offset end
#method_name_and_arguments_on_same_line?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 93
def method_name_and_arguments_on_same_line?(node) return false unless node.call_type? line = node.loc.selector.nil? ? node.loc.line : node.loc.selector.line line == node.last_argument.last_line && node.last_line == node.last_argument.last_line end
#multiline?(node) ⇒ Boolean
(private)
Returns true if the round/square/curly brackets of the given node are on different lines, each item within is on its own line, and the closing bracket is on its own line.
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 89
def multiline?(node) node.multiline? && !allowed_multiline_argument?(node) end
#no_elements_on_same_line?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 123
def no_elements_on_same_line?(node) items = elements(node).map(&:source_range) items << node.loc.end items.each_cons(2).none? { |a, b| on_same_line?(a, b) } end
#on_same_line?(range1, range2) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 129
def on_same_line?(range1, range2) range1.last_line == range2.line end
#put_comma(items, kind) (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 147
def put_comma(items, kind) last_item = items.last return if last_item.block_pass_type? range = autocorrect_range(last_item) msg = format(MSG, command: 'Put a', unit: format(kind, article: 'a multiline')) add_offense(range, message: msg) do |corrector| PunctuationCorrector.swap_comma(corrector, range) end end
#should_have_comma?(style, node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 65
def should_have_comma?(style, node) case style when :comma multiline?(node) && no_elements_on_same_line?(node) when :consistent_comma multiline?(node) && !method_name_and_arguments_on_same_line?(node) else false end end
#style_parameter_name (private)
[ GitHub ]# File 'lib/rubocop/cop/mixin/trailing_comma.rb', line 15
def style_parameter_name 'EnforcedStyleForMultiline' end