class RuboCop::Cop::Style::RedundantPercentQ
question = ‘“What did you say?”’
time = “8 o’clock”
name = ‘Bruce Wayne’
# good
question = %q(“What did you say?”)
time = %q(8 o’clock)
name = %q(Bruce Wayne)
# bad
@example
Checks for usage of the %q/%Q syntax when ” or “” would do.
def acceptable_capital_q?(node)
def acceptable_capital_q?(node) src = node.source src.include?(QUOTE) && (STRING_INTERPOLATION_REGEXP.match?(src) || (node.str_type? && double_quotes_required?(src))) end
def acceptable_q?(node)
def acceptable_q?(node) src = node.source return true if STRING_INTERPOLATION_REGEXP.match?(src) src.scan(/\\./).any?(ESCAPED_NON_BACKSLASH) end
def allowed_percent_q?(node)
def allowed_percent_q?(node) (node.source.start_with?(PERCENT_Q) && acceptable_q?(node)) || (node.source.start_with?(PERCENT_CAPITAL_Q) && acceptable_capital_q?(node)) end
def check(node)
def check(node) return unless start_with_percent_q_variant?(node) return if interpolated_quotes?(node) || allowed_percent_q?(node) add_offense(node) do |corrector| delimiter = /\A%Q[^"]+\z|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE corrector.replace(node.loc.begin, delimiter) corrector.replace(node.loc.end, delimiter) end end
def interpolated_quotes?(node)
def interpolated_quotes?(node) node.source.include?(SINGLE_QUOTE) && node.source.include?(QUOTE) end
def message(node)
def message(node) src = node.source extra = if src.start_with?(PERCENT_CAPITAL_Q) DYNAMIC_MSG else EMPTY end format(MSG, q_type: src[0, 2], extra: extra) end
def on_dstr(node)
def on_dstr(node) return unless string_literal?(node) check(node) end
def on_str(node)
def on_str(node) # Interpolated strings that contain more than just interpolation # will call `on_dstr` for the entire string and `on_str` for the # non interpolated portion of the string return unless string_literal?(node) check(node) end
def start_with_percent_q_variant?(string)
def start_with_percent_q_variant?(string) string.source.start_with?(PERCENT_Q, PERCENT_CAPITAL_Q) end
def string_literal?(node)
def string_literal?(node) node.loc.respond_to?(:begin) && node.loc.respond_to?(:end) && node.loc.begin && node.loc.end end