Class: RuboCop::Cop::Layout::SpaceAroundOperators
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::RuboCop::Cop::AutoCorrector,
::RuboCop::Cop::Base,
::RuboCop::ExcludeLimit,
NodePattern::Macros,
RuboCop::AST::Sexp
|
|
|
Instance Chain:
|
|
| Inherits: |
RuboCop::Cop::Base
|
| Defined in: | lib/rubocop/cop/layout/space_around_operators.rb |
Overview
Checks that operators have space around them, except for ** which should or shouldn’t have surrounding space depending on configuration. It allows vertical alignment consisting of one or more whitespace around operators.
This cop has AllowForAlignment option. When true, allows most
uses of extra spacing if the intent is to align with an operator on
the previous or next line, not counting empty lines or comment lines.
Constant Summary
-
EXCESSIVE_SPACE =
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 74' ' -
IRREGULAR_METHODS =
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 73%i[[] ! []=].freeze
::RuboCop::Cop::Base - Inherited
EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::PrecedingFollowingAlignment - Included
ASSIGNMENT_OR_COMPARISON_TOKENS
::RuboCop::Cop::RangeHelp - Included
Class Attribute Summary
::RuboCop::Cop::AutoCorrector - Extended
::RuboCop::Cop::Base - Inherited
| .gem_requirements, .lint?, | |
| .support_autocorrect? | Returns if class supports autocorrect. |
| .support_multiple_source? | Override if your cop should be called repeatedly for multiple investigations Between calls to |
Class Method Summary
::RuboCop::Cop::Base - Inherited
| .autocorrect_incompatible_with | List of cops that should not try to autocorrect at the same time as this cop. |
| .badge | Naming. |
| .callbacks_needed, .cop_name, .department, | |
| .documentation_url | Returns a url to view this cops documentation online. |
| .exclude_from_registry | Call for abstract Cop classes. |
| .inherited, | |
| .joining_forces | Override and return the Force class(es) you need to join. |
| .match? | Returns true if the cop name or the cop namespace matches any of the given names. |
| .new, | |
| .requires_gem | Register a version requirement for the given gem name. |
| .restrict_on_send | |
::RuboCop::ExcludeLimit - Extended
| exclude_limit | Sets up a configuration option to have an exclude limit tracked. |
| transform | |
Instance Attribute Summary
- #force_equal_sign_alignment? ⇒ Boolean readonly private
- #hash_table_style? ⇒ Boolean readonly private
- #space_around_exponent_operator? ⇒ Boolean readonly private
::RuboCop::Cop::PrecedingFollowingAlignment - Included
::RuboCop::Cop::Base - Inherited
::RuboCop::Cop::AutocorrectLogic - Included
Instance Method Summary
-
#on_and(node)
Alias for #on_binary.
-
#on_and_asgn(node)
Alias for #on_assignment.
- #on_assignment(node) (also: #on_lvasgn, #on_casgn, #on_masgn, #on_ivasgn, #on_cvasgn, #on_gvasgn, #on_or_asgn, #on_and_asgn, #on_op_asgn)
- #on_binary(node) (also: #on_or, #on_and)
-
#on_casgn(node)
Alias for #on_assignment.
- #on_class(node)
-
#on_cvasgn(node)
Alias for #on_assignment.
-
#on_gvasgn(node)
Alias for #on_assignment.
- #on_if(node)
-
#on_ivasgn(node)
Alias for #on_assignment.
-
#on_lvasgn(node)
Alias for #on_assignment.
-
#on_masgn(node)
Alias for #on_assignment.
- #on_match_alt(node)
- #on_match_as(node)
- #on_match_pattern(node)
-
#on_op_asgn(node)
Alias for #on_assignment.
-
#on_or(node)
Alias for #on_binary.
-
#on_or_asgn(node)
Alias for #on_assignment.
- #on_pair(node)
- #on_resbody(node)
- #on_sclass(node)
- #on_send(node)
- #on_setter_method(node)
- #align_hash_cop_config private
- #autocorrect(corrector, range, right_operand) private
- #check_operator(type, operator, right_operand) private
- #enclose_operator_with_space(corrector, range) private
- #excess_leading_space?(type, operator, with_space) ⇒ Boolean private
- #excess_trailing_space?(right_operand, with_space) ⇒ Boolean private
- #offense(type, operator, with_space, right_operand) {|msg| ... } private
- #offense_message(type, operator, with_space, right_operand) private
- #operator_with_regular_syntax?(send_node) ⇒ Boolean private
- #regular_operator?(send_node) ⇒ Boolean private
- #should_not_have_surrounding_space?(operator, right_operand) ⇒ Boolean private
- #space_around_slash_operator?(right_operand) ⇒ Boolean private
::RuboCop::Cop::RationalLiteral - Included
::RuboCop::Cop::RangeHelp - Included
| #add_range, | |
| #arguments_range | A range containing the first to the last argument of a method call or method definition. |
| #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 | |
::RuboCop::Cop::PrecedingFollowingAlignment - Included
| #aligned_comment_lines, #aligned_equals_operator?, #aligned_identical?, #aligned_operator?, #aligned_token?, #aligned_with_adjacent_line?, #aligned_with_any_line?, #aligned_with_any_line_range?, #aligned_with_append_operator?, #aligned_with_equals_sign, #aligned_with_line?, #aligned_with_operator?, #aligned_with_preceding_equals?, | |
| #aligned_with_preceding_equals_operator | Allows alignment with a preceding operator that ends with an |
| #aligned_with_something?, | |
| #aligned_with_subsequent_equals_operator | Allows alignment with a subsequent operator that ends with an |
| #aligned_words?, #assignment_lines, #assignment_tokens, | |
| #relevant_assignment_lines | Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength. |
| #remove_equals_in_def | Metrics/CyclomaticComplexity rubocop:enable Metrics/PerceivedComplexity, Metrics/MethodLength. |
::RuboCop::Cop::Base - Inherited
| #add_global_offense | Adds an offense that has no particular location. |
| #add_offense | Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense. |
| #begin_investigation | Called before any investigation. |
| #callbacks_needed, | |
| #cop_config | Configuration Helpers. |
| #cop_name, #excluded_file?, | |
| #external_dependency_checksum | This method should be overridden when a cop’s behavior depends on state that lives outside of these locations: |
| #inspect, | |
| #message | Gets called if no message is specified when calling |
| #name | Alias for Base#cop_name. |
| #offenses, | |
| #on_investigation_end | Called after all on_… |
| #on_new_investigation | Called before all on_… |
| #on_other_file | Called instead of all on_… |
| #parse | There should be very limited reasons for a Cop to do it’s own parsing. |
| #parser_engine, | |
| #ready | Called between investigations. |
| #relevant_file?, | |
| #target_gem_version | Returns a gems locked versions (i.e. |
| #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction, | |
| #callback_argument | Reserved for Cop::Cop. |
| #complete_investigation | Called to complete an investigation. |
| #correct, #current_corrector, | |
| #current_offense_locations | Reserved for Commissioner: |
| #current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, #file_name_matches_any?, #find_message, #find_severity, #range_for_original, #range_from_node_or_range, | |
| #reset_investigation | Actually private methods. |
| #use_corrector | |
::RuboCop::Cop::AutocorrectLogic - Included
::RuboCop::Cop::IgnoredNode - Included
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Class Method Details
.autocorrect_incompatible_with
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 76
def self.autocorrect_incompatible_with [Style::SelfAssignment] end
Instance Attribute Details
#force_equal_sign_alignment? ⇒ Boolean (readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 287
def force_equal_sign_alignment? config.for_cop('Layout/ExtraSpacing')['ForceEqualSignAlignment'] end
#hash_table_style? ⇒ Boolean (readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 270
def hash_table_style? return false unless align_hash_cop_config enforced_styles = Array(align_hash_cop_config['EnforcedHashRocketStyle']) enforced_styles.include?('table') end
#space_around_exponent_operator? ⇒ Boolean (readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 277
def space_around_exponent_operator? cop_config['EnforcedStyleForExponentOperator'] == 'space' end
Instance Method Details
#align_hash_cop_config (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 266
def align_hash_cop_config config.for_cop('Layout/HashAlignment') end
#autocorrect(corrector, range, right_operand) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 205
def autocorrect(corrector, range, right_operand) range_source = range.source if range_source.include?('**') && !space_around_exponent_operator? corrector.replace(range, '**') elsif range_source.include?('/') && !space_around_slash_operator?(right_operand) corrector.replace(range, '/') elsif range_source.end_with?("\n") corrector.replace(range, " #{range_source.strip}\n") else enclose_operator_with_space(corrector, range) end end
#check_operator(type, operator, right_operand) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 186
def check_operator(type, operator, right_operand) with_space = range_with_surrounding_space(operator) return if with_space.source.start_with?("\n") comment = processed_source.comment_at_line(operator.line) return if comment && with_space.last_column == comment.loc.column offense(type, operator, with_space, right_operand) do |msg| add_offense(operator, message: msg) do |corrector| autocorrect(corrector, with_space, right_operand) end end end
#enclose_operator_with_space(corrector, range) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 219
def enclose_operator_with_space(corrector, range) operator = range.source # If `ForceEqualSignAlignment` is true, `Layout/ExtraSpacing` cop # inserts spaces before operator. If `Layout/SpaceAroundOperators` cop # inserts a space, it collides and raises the infinite loop error. if force_equal_sign_alignment? && !operator.end_with?(' ') corrector.insert_after(range, ' ') else corrector.replace(range, " #{operator.strip} ") end end
#excess_leading_space?(type, operator, with_space) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 246
def excess_leading_space?(type, operator, with_space) return false unless allow_for_alignment? return false unless with_space.source.start_with?(EXCESSIVE_SPACE) return !aligned_with_operator?(operator) unless type == :assignment token = Token.new(operator, nil, operator.source) align_preceding = aligned_with_preceding_equals_operator(token) return false if align_preceding == :yes || aligned_with_subsequent_equals_operator(token) == :none aligned_with_subsequent_equals_operator(token) != :yes end
#excess_trailing_space?(right_operand, with_space) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 261
def excess_trailing_space?(right_operand, with_space) with_space.source.end_with?(EXCESSIVE_SPACE) && (!allow_for_alignment? || !aligned_with_something?(right_operand)) end
#offense(type, operator, with_space, right_operand) {|msg| ... } (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 200
def offense(type, operator, with_space, right_operand) msg = (type, operator, with_space, right_operand) yield msg if msg end
#offense_message(type, operator, with_space, right_operand) (private)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 232
def (type, operator, with_space, right_operand) if should_not_have_surrounding_space?(operator, right_operand) return if with_space.is?(operator.source) "Space around operator `#{operator.source}` detected." elsif !/^\s.*\s$/.match?(with_space.source) "Surrounding space missing for operator `#{operator.source}`." elsif excess_leading_space?(type, operator, with_space) || excess_trailing_space?(right_operand.source_range, with_space) "Operator `#{operator.source}` should be surrounded " \ 'by a single space.' end end
#on_and(node)
Alias for #on_binary.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 163
alias on_and on_binary
#on_and_asgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 171
alias on_and_asgn on_assignment
#on_assignment(node) Also known as: #on_lvasgn, #on_casgn, #on_masgn, #on_ivasgn, #on_cvasgn, #on_gvasgn, #on_or_asgn, #on_and_asgn, #on_op_asgn
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 115
def on_assignment(node) rhs = node.rhs return unless rhs type = node.op_asgn_type? ? :special_asgn : :assignment check_operator(type, node.loc.operator, rhs) end
#on_binary(node) Also known as: #on_or, #on_and
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 132
def on_binary(node) rhs = node.rhs return unless rhs check_operator(:binary, node.loc.operator, rhs) end
#on_casgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 165
alias on_casgn on_assignment
#on_class(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 124
def on_class(node) rhs = node.parent_class return unless rhs check_operator(:class, node.loc.operator, rhs) end
#on_cvasgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 168
alias on_cvasgn on_assignment
#on_gvasgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 169
alias on_gvasgn on_assignment
#on_if(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 92
def on_if(node) return unless node.ternary? check_operator(:if, node.loc.question, node.if_branch) check_operator(:if, node.loc.colon, node.else_branch) end
#on_ivasgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 167
alias on_ivasgn on_assignment
#on_lvasgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 164
alias on_lvasgn on_assignment
#on_masgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 166
alias on_masgn on_assignment
#on_match_alt(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 154
def on_match_alt(node) check_operator(:match_alt, node.loc.operator, node) end
#on_match_as(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 158
def on_match_as(node) check_operator(:match_as, node.loc.operator, node) end
#on_match_pattern(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 148
def on_match_pattern(node) return if target_ruby_version < 3.0 check_operator(:match_pattern, node.loc.operator, node) end
#on_op_asgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 172
alias on_op_asgn on_assignment
#on_or(node)
Alias for #on_binary.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 162
alias on_or on_binary
#on_or_asgn(node)
Alias for #on_assignment.
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 170
alias on_or_asgn on_assignment
#on_pair(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 84
def on_pair(node) return unless node.hash_rocket? return if hash_table_style? && !node.parent.pairs_on_same_line? check_operator(:pair, node.loc.operator, node) end
#on_resbody(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 99
def on_resbody(node) return unless node.loc.assoc check_operator(:resbody, node.loc.assoc, node.exception_variable) end
#on_sclass(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 80
def on_sclass(node) check_operator(:sclass, node.loc.operator, node) end
#on_send(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 105
def on_send(node) return if rational_literal?(node) if node.setter_method? on_setter_method(node) elsif regular_operator?(node) check_operator(:send, node.loc.selector, node.first_argument) end end
#on_setter_method(node)
[ GitHub ]# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 140
def on_setter_method(node) rhs = node.first_argument return unless rhs check_operator(:special_asgn, node.loc.operator, node.first_argument) end
#operator_with_regular_syntax?(send_node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 182
def operator_with_regular_syntax?(send_node) send_node.operator_method? && !IRREGULAR_METHODS.include?(send_node.method_name) end
#regular_operator?(send_node) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 176
def regular_operator?(send_node) return false if send_node.unary_operation? || send_node.dot? || send_node.double_colon? operator_with_regular_syntax?(send_node) end
#should_not_have_surrounding_space?(operator, right_operand) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 291
def should_not_have_surrounding_space?(operator, right_operand) if operator.is?('**') !space_around_exponent_operator? elsif operator.is?('/') !space_around_slash_operator?(right_operand) else false end end
#space_around_slash_operator?(right_operand) ⇒ Boolean (private)
# File 'lib/rubocop/cop/layout/space_around_operators.rb', line 281
def space_around_slash_operator?(right_operand) return true unless right_operand.rational_type? cop_config['EnforcedStyleForRationalLiterals'] == 'space' end