123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets

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_inside_array_literal_brackets.rb

Overview

Checks that brackets used for array literals have or don’t have surrounding space depending on configuration.

Examples:

EnforcedStyle: no_space (default)

# The {no_space} style enforces that array literals have
# no surrounding space.

# bad
array = [ a, b, c, d ]
array = [ a, [ b, c ]]

# good
array = [a, b, c, d]
array = [a, [b, c]]

EnforcedStyle: space

# The {space} style enforces that array literals have
# surrounding space.

# bad
array = [a, b, c, d]
array = [ a, [ b, c ]]

# good
array = [ a, b, c, d ]
array = [ a, [ b, c ] ]

EnforcedStyle: compact

# The {compact} style normally requires a space inside
# array brackets, with the exception that successive left
# or right brackets are collapsed together in nested arrays.

# bad
array = [a, b, c, d]
array = [ a, [ b, c ] ]
array = [
  [ a ],
  [ b, c ]
]

# good
array = [ a, b, c, d ]
array = [ a, [ b, c ]]
array = [[ a ],
  [ b, c ]]

EnforcedStyleForEmptyBrackets: no_space (default)

# The {no_space} EnforcedStyleForEmptyBrackets style enforces that
# empty array brackets do not contain spaces.

# bad
foo = [ ]
bar = [     ]

# good
foo = []
bar = []

EnforcedStyleForEmptyBrackets: space

# The {space} EnforcedStyleForEmptyBrackets style enforces that
# empty array brackets contain exactly one space.

# bad
foo = []
bar = [    ]

# good
foo = [ ]
bar = [ ]

Constant Summary

::RuboCop::Cop::Base - Inherited

EMPTY_OFFENSES, RESTRICT_ON_SEND

::RuboCop::Cop::RangeHelp - Included

BYTE_ORDER_MARK, NOT_GIVEN

::RuboCop::Cop::SurroundingSpace - Included

NO_SPACE_COMMAND, SINGLE_SPACE_REGEXP, SPACE_COMMAND

::RuboCop::Cop::ConfigurableEnforcedStyle - Included

SYMBOL_TO_STRING_CACHE

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 on_new_investigation and on_investigation_end, the result of processed_source will remain constant.

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

Instance Method Summary

::RuboCop::Cop::ConfigurableEnforcedStyle - Included

::RuboCop::Cop::SurroundingSpace - Included

::RuboCop::Cop::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

::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 add_offense or add_global_offense Cops are discouraged to override this; instead pass your message directly.

#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_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

Instance Method Details

#array_brackets(node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 115

def array_brackets(node)
  tokens = processed_source.tokens_within(node)

  left = tokens.find(&:left_array_bracket?)
  right = tokens.reverse_each.find(&:right_bracket?)

  [tokens, left, right]
end

#autocorrect(corrector, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 101

def autocorrect(corrector, node)
  tokens, left, right = array_brackets(node)

  if empty_brackets?(left, right, tokens: tokens)
    SpaceCorrector.empty_corrections(processed_source, corrector, empty_config, left, right)
  elsif style == :no_space
    SpaceCorrector.remove_space(processed_source, corrector, left, right)
  elsif style == :space
    SpaceCorrector.add_space(processed_source, corrector, left, right)
  else
    compact_corrections(corrector, node, left, right)
  end
end

#compact(corrector, bracket, side) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 223

def compact(corrector, bracket, side)
  range = side_space_range(range: bracket.pos, side: side, include_newlines: true)
  corrector.remove(range)
end

#compact_corrections(corrector, node, left, right) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 209

def compact_corrections(corrector, node, left, right)
  if multi_dimensional_array?(node, left, side: :left)
    compact(corrector, left, :right)
  elsif !left.space_after?
    corrector.insert_after(left.pos, ' ')
  end

  if multi_dimensional_array?(node, right)
    compact(corrector, right, :left)
  elsif !right.space_before?
    corrector.insert_before(right.pos, ' ')
  end
end

#compact_offense(node, token, side: :right) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 201

def compact_offense(node, token, side: :right)
  if side == :right
    space_offense(node, token, :left, MSG, NO_SPACE_COMMAND)
  else
    space_offense(node, token, :right, MSG, NO_SPACE_COMMAND)
  end
end

#compact_offenses(node, left, right, start_ok, end_ok) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 163

def compact_offenses(node, left, right, start_ok, end_ok)
  if qualifies_for_compact?(node, left, side: :left)
    compact_offense(node, left, side: :left)
  elsif !multi_dimensional_array?(node, left, side: :left)
    space_offenses(node, left, nil, MSG, start_ok: start_ok, end_ok: true)
  end
  if qualifies_for_compact?(node, right)
    compact_offense(node, right)
  elsif !multi_dimensional_array?(node, right)
    space_offenses(node, nil, right, MSG, start_ok: true, end_ok: end_ok)
  end
end

#empty_config (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 124

def empty_config
  cop_config['EnforcedStyleForEmptyBrackets']
end

#end_has_own_line?(token) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 132

def end_has_own_line?(token)
  line, col = line_and_column_for(token)
  return true if col == -1

  !/\S/.match?(processed_source.lines[line][0..col])
end

#index_for(node, token) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 139

def index_for(node, token)
  processed_source.tokens_within(node).index(token)
end

#issue_offenses(node, left, right, start_ok, end_ok) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 147

def issue_offenses(node, left, right, start_ok, end_ok)
  case style
  when :no_space
    start_ok = next_to_comment?(node, left)
    no_space_offenses(node, left, right, MSG, start_ok: start_ok, end_ok: end_ok)
  when :space
    space_offenses(node, left, right, MSG, start_ok: start_ok, end_ok: end_ok)
  else
    compact_offenses(node, left, right, start_ok, end_ok)
  end
end

#line_and_column_for(token) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 143

def line_and_column_for(token)
  [token.line - 1, token.column - 1]
end

#multi_dimensional_array?(node, token, side: :right) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 184

def multi_dimensional_array?(node, token, side: :right)
  offset = side == :right ? -1 : +1
  i = index_for(node, token) + offset
  i += offset while processed_source.tokens_within(node)[i].new_line?
  if side == :right
    processed_source.tokens_within(node)[i].right_bracket?
  else
    processed_source.tokens_within(node)[i].left_array_bracket?
  end
end

#next_to_bracket?(token, side: :right) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 195

def next_to_bracket?(token, side: :right)
  line_index, col = line_and_column_for(token)
  line = processed_source.lines[line_index]
  side == :right ? line[col] == ']' : line[col + 2] == '['
end

#next_to_comment?(node, token) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 159

def next_to_comment?(node, token)
  processed_source.tokens_within(node)[index_for(node, token) + 1].comment?
end

#next_to_newline?(node, token) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 128

def next_to_newline?(node, token)
  processed_source.tokens_within(node)[index_for(node, token) + 1].line != token.line
end

#on_array(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 84

def on_array(node)
  return unless node.square_brackets?

  tokens, left, right = array_brackets(node)

  if empty_brackets?(left, right, tokens: tokens)
    return empty_offenses(node, left, right, EMPTY_MSG)
  end

  start_ok = next_to_newline?(node, left)
  end_ok = node.single_line? ? false : end_has_own_line?(right)

  issue_offenses(node, left, right, start_ok, end_ok)
end

#qualifies_for_compact?(node, token, side: :right) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb', line 176

def qualifies_for_compact?(node, token, side: :right)
  if side == :right
    multi_dimensional_array?(node, token) && token.space_before?
  else
    multi_dimensional_array?(node, token, side: :left) && token.space_after?
  end
end