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