class RuboCop::Cop::Layout::MultilineMethodCallIndentation
This cop checks the indentation of the method name part in method calls that span more than one line.
@example
# bad while myvariable .b # do something end # good, EnforcedStyle: aligned while myvariable .b # do something end # good, EnforcedStyle: aligned Thing.a .b .c # good, EnforcedStyle: indented, IndentationWidth: 2 while myvariable .b # do something end # good, EnforcedStyle: indented_relative_to_receiver, IndentationWidth: 2 while myvariable .a .b # do something end # good, EnforcedStyle: indented_relative_to_receiver, IndentationWidth: 2 myvariable = Thing .a .b .c
Public Instance Methods
validate_config()
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 55 def validate_config return unless style == :aligned && cop_config['IndentationWidth'] raise ValidationError, 'The `Layout/MultilineMethodCallIndentation`' \ ' cop only accepts an `IndentationWidth` ' \ 'configuration parameter when ' \ '`EnforcedStyle` is `indented`.' end
Private Instance Methods
align_with_base_message(rhs)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 116 def align_with_base_message(rhs) "Align `#{rhs.source}` with `#{base_source}` on line #{@base.line}." end
alignment_base(node, rhs, given_style)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 132 def alignment_base(node, rhs, given_style) case given_style when :aligned semantic_alignment_base(node, rhs) || syntactic_alignment_base(node, rhs) when :indented nil when :indented_relative_to_receiver receiver_alignment_base(node) end end
base_source()
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 120 def base_source @base.source[/[^\n]*/] end
extra_indentation(given_style)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 85 def extra_indentation(given_style) if given_style == :indented_relative_to_receiver configured_indentation_width else 0 end end
message(node, lhs, rhs)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 93 def message(node, lhs, rhs) if should_indent_relative_to_receiver? relative_to_receiver_message(rhs) elsif should_align_with_base? align_with_base_message(rhs) else no_base_message(lhs, rhs, node) end end
no_base_message(lhs, rhs, node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 124 def no_base_message(lhs, rhs, node) used_indentation = rhs.column - indentation(lhs) what = operation_description(node, rhs) "Use #{correct_indentation(node)} (not #{used_indentation}) " \ "spaces for indenting #{what} spanning multiple lines." end
offending_range(node, lhs, rhs, given_style)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 71 def offending_range(node, lhs, rhs, given_style) return false unless begins_its_line?(rhs) return false if not_for_this_cop?(node) @base = alignment_base(node, rhs, given_style) correct_column = if @base @base.column + extra_indentation(given_style) else indentation(lhs) + correct_indentation(node) end @column_delta = correct_column - rhs.column rhs if @column_delta.nonzero? end
operation_rhs(node) { |first_argument| ... }
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 199 def operation_rhs(node) receiver, = *node operation_rhs = receiver.each_ancestor(:send).find do |rhs| operator_rhs?(rhs, receiver) end return unless operation_rhs yield operation_rhs.first_argument end
operator_rhs?(node, receiver)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 211 def operator_rhs?(node, receiver) node.operator_method? && node.arguments? && within_node?(receiver, node.first_argument) end
receiver_alignment_base(node)
click to toggle source
a
.b .c
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 178 def receiver_alignment_base(node) node = node.receiver while node.receiver node = node.parent node = node.parent until node.loc.dot node.receiver.source_range if node end
relative_to_receiver_message(rhs)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 111 def relative_to_receiver_message(rhs) "Indent `#{rhs.source}` #{configured_indentation_width} spaces " \ "more than `#{base_source}` on line #{@base.line}." end
relevant_node?(send_node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 67 def relevant_node?(send_node) send_node.loc.dot # Only check method calls with dot operator end
semantic_alignment_base(node, rhs)
click to toggle source
a.b
.c
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 166 def semantic_alignment_base(node, rhs) return unless rhs.source.start_with?('.') node = semantic_alignment_node(node) return unless node node.loc.dot.join(node.loc.selector) end
semantic_alignment_node(node)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 186 def semantic_alignment_node(node) return if argument_in_method_call(node, :with_parentheses) # descend to root of method chain node = node.receiver while node.receiver # ascend to first call which has a dot node = node.parent node = node.parent until node.loc.dot return if node.loc.dot.line != node.loc.line node end
should_align_with_base?()
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 107 def should_align_with_base? @base && style != :indented_relative_to_receiver end
should_indent_relative_to_receiver?()
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 103 def should_indent_relative_to_receiver? @base && style == :indented_relative_to_receiver end
syntactic_alignment_base(lhs, rhs)
click to toggle source
# File lib/rubocop/cop/layout/multiline_method_call_indentation.rb, line 144 def syntactic_alignment_base(lhs, rhs) # a if b # .c kw_node_with_special_indentation(lhs) do |base| return indented_keyword_expression(base).source_range end # a = b # .c part_of_assignment_rhs(lhs, rhs) do |base| return assignment_rhs(base).source_range end # a + b # .c operation_rhs(lhs) do |base| return base.source_range end end