class RuboCop::Cop::Style::QuotedSymbols
:“a'b”
:“#{str}”
:“abc-def”
# good
:‘abc-def’
# bad
@example EnforcedStyle: double_quotes
:“a'b”
:“#{str}”
:‘abc-def’
# good
:“abc-def”
# bad
@example EnforcedStyle: same_as_string_literals (default) / single_quotes
style to use for symbols that require quotes.
are not quoted that don’t need to be. This cop is for configuring the quoting
Note: ‘Lint/SymbolConversion` can be used in parallel to ensure that symbols
String interpolation is always kept in double quotes.
cop is not enabled, the default `EnforcedStyle` is `single_quotes`.
By default uses the same configuration as `Style/StringLiterals`; if that
Checks if the quotes used for quoted symbols match the configured defaults.
def alternative_style
def alternative_style (supported_styles - [style, :same_as_string_literals]).first end
def autocorrect(corrector, node)
def autocorrect(corrector, node) str = if hash_colon_key?(node) # strip quotes correct_quotes(node.source[1..-2]) else # strip leading `:` and quotes ":#{correct_quotes(node.source[2..-2])}" end corrector.replace(node, str) end
def correct_quotes(str)
def correct_quotes(str) correction = if style == :single_quotes to_string_literal(str) else str.gsub("\\'", "'").inspect end # The conversion process doubles escaped slashes, so they have to be reverted correction.gsub('\\\\', '\\').gsub('\"', '"') end
def hash_colon_key?(node)
def hash_colon_key?(node) # Is the node a hash key with the colon style? hash_key?(node) && node.parent.colon? end
def invalid_double_quotes?(source)
def invalid_double_quotes?(source) return false unless style == :double_quotes # The string needs single quotes if: # 1. It contains a double quote # 2. It contains text that would become an escape sequence with double quotes # 3. It contains text that would become an interpolation with double quotes !/" | (?<!\\)\\[aAbcdefkMnprsStuUxzZ0-7] | \#[@{$]/x.match?(source) end
def on_sym(node)
def on_sym(node) return unless quoted?(node) message = style == :single_quotes ? MSG_SINGLE : MSG_DOUBLE if wrong_quotes?(node) || invalid_double_quotes?(node.source) add_offense(node, message: message) do |corrector| opposite_style_detected autocorrect(corrector, node) end else correct_style_detected end end
def quoted?(sym_node)
def quoted?(sym_node) sym_node.source.match?(/\A:?(['"]).*?\1\z/m) end
def style
def style return super unless super == :same_as_string_literals string_literals_config = config.for_cop('Style/StringLiterals') return :single_quotes unless string_literals_config['Enabled'] string_literals_config['EnforcedStyle'].to_sym end
def wrong_quotes?(node)
def wrong_quotes?(node) return super if hash_key?(node) super(node.source[1..]) end