class RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets
bar = [ ]
foo = [ ]
# good
bar = [ ]
foo = []
# bad
# empty array brackets contain exactly one space.
# The ‘space` EnforcedStyleForEmptyBrackets style enforces that
@example EnforcedStyleForEmptyBrackets: space
bar = []
foo = []
# good
bar = [ ]
foo = [ ]
# bad
# empty array brackets do not contain spaces.
# The `no_space` EnforcedStyleForEmptyBrackets style enforces that
@example EnforcedStyleForEmptyBrackets: no_space (default)
[ b, c ]]
array = [[ a ],
array = [ a, [ b, c ]]
# good
]
[ b, c ]
[ a ],
array = [
array = [ a, [ b, c ] ]
# bad
# or right brackets are collapsed together in nested arrays.
# array brackets, with the exception that successive left
# The `compact` style normally requires a space inside
@example EnforcedStyle: compact
array = [ a, b, c, d ]
# good
array = [a, b, c, d]
# bad
# surrounding space.
# The `space` style enforces that array literals have
@example EnforcedStyle: space
array = [a, b, c, d]
# good
array = [ a, b, c, d ]
# bad
# no surrounding space.
# The `no_space` style enforces that array literals have
@example EnforcedStyle: no_space (default)
surrounding space depending on configuration.
Checks that brackets used for array literals have or don’t have
def array_brackets(node)
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
def autocorrect(corrector, node)
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
def compact(corrector, bracket, side)
def compact(corrector, bracket, side) range = side_space_range(range: bracket.pos, side: side, include_newlines: true) corrector.remove(range) end
def compact_corrections(corrector, node, left, right)
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
def compact_offense(node, token, side: :right)
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
def compact_offenses(node, left, right, start_ok, end_ok)
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
def empty_config
def empty_config cop_config['EnforcedStyleForEmptyBrackets'] end
def end_has_own_line?(token)
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
def index_for(node, token)
def index_for(node, token) processed_source.tokens_within(node).index(token) end
def issue_offenses(node, left, right, start_ok, end_ok)
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
def line_and_column_for(token)
def line_and_column_for(token) [token.line - 1, token.column - 1] end
def multi_dimensional_array?(node, token, side: :right)
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
def next_to_bracket?(token, side: :right)
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
def next_to_comment?(node, token)
def next_to_comment?(node, token) processed_source.tokens_within(node)[index_for(node, token) + 1].comment? end
def next_to_newline?(node, token)
def next_to_newline?(node, token) processed_source.tokens_within(node)[index_for(node, token) + 1].line != token.line end
def on_array(node)
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
def qualifies_for_compact?(node, token, side: :right)
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