class RuboCop::Cop::Style::RegexpLiteral

x =~ /home//
# good
@example AllowInnerSlashes: true
x =~ %r{home/}
# good
x =~ /home//
# bad
# slashes are found in the regexp string.
# If ‘false`, the cop will always recommend using `%r` if one or more
@example AllowInnerSlashes: false (default)
}x
(baz)
(bar)
foo
regex = %r{
# good
snake_case = /^[dA-Z_]+$/
# good
/x
(baz)
(bar)
foo
regex = /
# bad
snake_case = %r{^[dA-Z_]+$}
# bad
@example EnforcedStyle: mixed
}x
(baz)
(bar)
foo
regex = %r{
# good
snake_case = %r{^[dA-Z_]+$}
# good
/x
(baz)
(bar)
foo
regex = /
# bad
snake_case = /^[dA-Z_]+$/
# bad
@example EnforcedStyle: percent_r
/x
(baz)
(bar)
foo
regex = /
# good
snake_case = /^[dA-Z_]+$/
# good
}x
(baz)
(bar)
foo
regex = %r{
# bad
snake_case = %r{^[dA-Z_]+$}
# bad
@example EnforcedStyle: slashes (default)
—-
do_something %r{=regexp} # `do_something /=regexp/` is an invalid syntax.
do_something %r{ regexp} # `do_something / regexp/` is an invalid syntax.
—-
[source,ruby]

as a method argument allowed to prevent syntax errors.
NOTE: The following `%r` cases using a regexp starts with a blank or `=`
Enforces using `//` or `%r` around regular expressions.

def allow_inner_slashes?

def allow_inner_slashes?
  cop_config['AllowInnerSlashes']
end

def allowed_mixed_percent_r?(node)

def allowed_mixed_percent_r?(node)
  (style == :mixed && node.multiline?) || contains_disallowed_slash?(node)
end

def allowed_mixed_slash?(node)

def allowed_mixed_slash?(node)
  style == :mixed && node.single_line? && !contains_disallowed_slash?(node)
end

def allowed_omit_parentheses_with_percent_r_literal?(node)

def allowed_omit_parentheses_with_percent_r_literal?(node)
  return false unless node.parent&.call_type?
  return true if node.content.start_with?(' ', '=')
  enforced_style = config.for_cop('Style/MethodCallWithArgsParentheses')['EnforcedStyle']
  enforced_style == 'omit_parentheses'
end

def allowed_percent_r_literal?(node)

def allowed_percent_r_literal?(node)
  (style == :slashes && contains_disallowed_slash?(node)) ||
    style == :percent_r ||
    allowed_mixed_percent_r?(node) || allowed_omit_parentheses_with_percent_r_literal?(node)
end

def allowed_slash_literal?(node)

def allowed_slash_literal?(node)
  (style == :slashes && !contains_disallowed_slash?(node)) || allowed_mixed_slash?(node)
end

def calculate_replacement(node)

def calculate_replacement(node)
  if slash_literal?(node)
    ['%r', ''].zip(preferred_delimiters).map(&:join)
  else
    %w[/ /]
  end
end

def contains_disallowed_slash?(node)

def contains_disallowed_slash?(node)
  !allow_inner_slashes? && contains_slash?(node)
end

def contains_slash?(node)

def contains_slash?(node)
  node_body(node).include?('/')
end

def correct_delimiters(node, corrector)

def correct_delimiters(node, corrector)
  replacement = calculate_replacement(node)
  corrector.replace(node.loc.begin, replacement.first)
  corrector.replace(node.loc.end, replacement.last)
end

def correct_inner_slashes(node, corrector)

def correct_inner_slashes(node, corrector)
  regexp_begin = node.loc.begin.end_pos
  inner_slash_indices(node).each do |index|
    start = regexp_begin + index
    corrector.replace(
      range_between(
        start,
        start + inner_slash_before_correction(node).length
      ),
      inner_slash_after_correction(node)
    )
  end
end

def inner_slash_after_correction(node)

def inner_slash_after_correction(node)
  inner_slash_for(calculate_replacement(node).first)
end

def inner_slash_before_correction(node)

def inner_slash_before_correction(node)
  inner_slash_for(node.loc.begin.source)
end

def inner_slash_for(opening_delimiter)

def inner_slash_for(opening_delimiter)
  if ['/', '%r/'].include?(opening_delimiter)
    '\/'
  else
    '/'
  end
end

def inner_slash_indices(node)

def inner_slash_indices(node)
  text    = node_body(node, include_begin_nodes: true)
  pattern = inner_slash_before_correction(node)
  index   = -1
  indices = []
  while (index = text.index(pattern, index + 1))
    indices << index
  end
  indices
end

def node_body(node, include_begin_nodes: false)

def node_body(node, include_begin_nodes: false)
  types = include_begin_nodes ? %i[str begin] : %i[str]
  node.each_child_node(*types).map(&:source).join
end

def on_regexp(node)

def on_regexp(node)
  message = if slash_literal?(node)
              MSG_USE_PERCENT_R unless allowed_slash_literal?(node)
            else
              MSG_USE_SLASHES unless allowed_percent_r_literal?(node)
            end
  return unless message
  add_offense(node, message: message) do |corrector|
    correct_delimiters(node, corrector)
    correct_inner_slashes(node, corrector)
  end
end

def preferred_delimiters

def preferred_delimiters
  config.for_cop('Style/PercentLiteralDelimiters') ['PreferredDelimiters']['%r'].chars
end

def slash_literal?(node)

def slash_literal?(node)
  node.loc.begin.source == '/'
end