class RuboCop::Cop::Style::PercentLiteralDelimiters

%I(alpha beta)
# bad
%W(alpha #{beta})
# bad
%w[alpha beta] + %i(gamma delta)
# good
# ‘%i’: ‘()’
# default: ‘[]’
# PreferredDelimiters:
# Style/PercentLiteralDelimiters:
@example
default.
can continue to specify individual preferred delimiters to override the
Specify the ‘default’ key to set all preferred delimiters at once. You
Enforces the consistent usage of ‘%`-literal delimiters.

def contains_delimiter?(node, delimiters)

def contains_delimiter?(node, delimiters)
  delimiters_regexp = Regexp.union(delimiters)
  node.children.filter_map { |n| string_source(n) }.any?(delimiters_regexp)
end

def contains_preferred_delimiter?(node, type)

def contains_preferred_delimiter?(node, type)
  contains_delimiter?(node, preferred_delimiters_for(type))
end

def include_same_character_as_used_for_delimiter?(node, type)

def include_same_character_as_used_for_delimiter?(node, type)
  return false unless %w[%w %i].include?(type)
  used_delimiters = matchpairs(begin_source(node)[-1])
  contains_delimiter?(node, used_delimiters)
end

def matchpairs(begin_delimiter)

def matchpairs(begin_delimiter)
  {
    '(' => %w[( )],
    '[' => %w[[ ]],
    '{' => %w[{ }],
    '<' => %w[< >]
  }.fetch(begin_delimiter, [begin_delimiter])
end

def message(type)

def message(type)
  delimiters = preferred_delimiters_for(type)
  "`#{type}`-literals should be delimited by " \
    "`#{delimiters[0]}` and `#{delimiters[1]}`."
end

def on_array(node)

def on_array(node)
  process(node, '%w', '%W', '%i', '%I')
end

def on_percent_literal(node)

def on_percent_literal(node)
  type = type(node)
  return if uses_preferred_delimiter?(node, type) ||
            contains_preferred_delimiter?(node, type) ||
            include_same_character_as_used_for_delimiter?(node, type)
  add_offense(node, message: message(type)) do |corrector|
    opening_delimiter, closing_delimiter = preferred_delimiters_for(type)
    corrector.replace(node.loc.begin, "#{type}#{opening_delimiter}")
    corrector.replace(node.loc.end, closing_delimiter)
  end
end

def on_regexp(node)

def on_regexp(node)
  process(node, '%r')
end

def on_str(node)

def on_str(node)
  process(node, '%', '%Q', '%q')
end

def on_sym(node)

def on_sym(node)
  process(node, '%s')
end

def on_xstr(node)

def on_xstr(node)
  process(node, '%x')
end

def preferred_delimiters_for(type)

def preferred_delimiters_for(type)
  PreferredDelimiters.new(type, @config, nil).delimiters
end

def string_source(node)

def string_source(node)
  if node.is_a?(String)
    node.scrub
  elsif node.respond_to?(:type) && node.type?(:str, :sym)
    node.source
  end
end

def uses_preferred_delimiter?(node, type)

def uses_preferred_delimiter?(node, type)
  preferred_delimiters_for(type)[0] == begin_source(node)[-1]
end