class RuboCop::Cop::Style::WordArray

This cop can check for array literals made up of word-like strings, that are not using the %w() syntax.

Alternatively, it can check for uses of the %w() syntax, in projects which do not want to include that syntax.

Constants

ARRAY_MSG
PERCENT_MSG
QUESTION_MARK_SIZE

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 35
def autocorrect(node)
  words = node.children
  if style == :percent
    escape = words.any? { |w| double_quotes_required?(w.children[0]) }
    char = escape ? 'W' : 'w'
    contents = autocorrect_words(words, escape, node.loc.line)
    lambda do |corrector|
      corrector.replace(node.source_range, "%#{char}(#{contents})")
    end
  else
    words = words.map { |w| to_string_literal(w.children[0]) }
    lambda do |corrector|
      corrector.replace(node.source_range, "[#{words.join(', ')}]")
    end
  end
end
on_array(node) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 18
def on_array(node)
  array_elems = node.children

  if bracketed_array_of?(:str, node)
    return if complex_content?(array_elems) ||
              comments_in_array?(node)
    style_detected(:brackets, array_elems.size)

    if style == :percent && array_elems.size >= min_size
      add_offense(node, :expression, PERCENT_MSG)
    end
  elsif node.loc.begin && node.loc.begin.source =~ /\A%[wW]/
    style_detected(:percent, array_elems.size)
    add_offense(node, :expression, ARRAY_MSG) if style == :brackets
  end
end

Private Instance Methods

autocorrect_words(word_nodes, escape, base_line_number) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 82
def autocorrect_words(word_nodes, escape, base_line_number)
  previous_node_line_number = base_line_number
  word_nodes.map do |node|
    number_of_line_breaks = node.loc.line - previous_node_line_number
    line_breaks = "\n" * number_of_line_breaks
    previous_node_line_number = node.loc.line
    content = node.children[0]
    content = escape ? escape_string(content) : content
    content.gsub!(/\)/, '\)')
    line_breaks + content
  end.join(' ')
end
comments_in_array?(node) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 54
def comments_in_array?(node)
  comments = processed_source.comments
  array_range = node.source_range.to_a

  comments.any? do |comment|
    !(comment.loc.expression.to_a & array_range).empty?
  end
end
complex_content?(strings) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 63
def complex_content?(strings)
  strings.any? do |s|
    string = s.str_content
    !string.valid_encoding? || string !~ word_regex || string =~ / /
  end
end
escape_string(string) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 95
def escape_string(string)
  string.inspect[1..-2].tap { |s| s.gsub!(/\"/, '"') }
end
min_size() click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 74
def min_size
  cop_config['MinSize']
end
style() click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 70
def style
  cop_config['EnforcedStyle'].to_sym
end
style_detected(style, ary_size) click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 99
def style_detected(style, ary_size)
  cfg = config_to_allow_offenses
  return if cfg['Enabled'] == false

  @largest_brackets ||= -Float::INFINITY
  @smallest_percent ||= Float::INFINITY

  if style == :percent
    @smallest_percent = ary_size if ary_size < @smallest_percent
  elsif ary_size > @largest_brackets
    @largest_brackets = ary_size
  end

  if cfg['EnforcedStyle'] == style.to_s
    # do nothing
  elsif cfg['EnforcedStyle'].nil?
    cfg['EnforcedStyle'] = style.to_s
  elsif @smallest_percent <= @largest_brackets
    self.config_to_allow_offenses = { 'Enabled' => false }
  else
    cfg['EnforcedStyle'] = 'percent'
    cfg['MinSize'] = @largest_brackets + 1
  end
end
word_regex() click to toggle source
# File lib/rubocop/cop/style/word_array.rb, line 78
def word_regex
  cop_config['WordRegex']
end