123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::PercentLiteralCorrector

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: lib/rubocop/cop/correctors/percent_literal_corrector.rb

Overview

This autocorrects percent literals

Constant Summary

::RuboCop::PathUtil - Included

HIDDEN_FILE_PATTERN, SMART_PATH_CACHE

Util - Included

LINE_BEGINS_REGEX_CACHE, LITERAL_REGEX, MAX_LINE_BEGINS_REGEX_INDEX

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Util - Included

#add_parentheses

Metrics/MethodLength.

#any_descendant?

Metrics/MethodLength.

#args_begin, #args_end, #begins_its_line?,
#comment_line?

This is a bad API.

#comment_lines?, #compatible_external_encoding_for?,
#double_quotes_required?

If converting a string to Ruby string literal source code, must double quotes be used?

#escape_string,
#first_part_of_call_chain

Returns, for example, a bare if node if the given node is an if with calls chained to the end of it.

#include_or_equal?, #indent, #interpret_string_escapes, #line, #line_range, #needs_escaping?, #on_node, #parentheses?, #same_line?, #to_string_literal, #to_supported_styles, #trim_string_interpolation_escape_character

::RuboCop::PathUtil - Included

#absolute?

Returns true for an absolute Unix or Windows path.

#glob?

Returns true for a glob.

#hidden_dir?, #hidden_file?, #hidden_file_in_not_hidden_dir?,
#match_path?

Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.

#maybe_hidden_file?

Loose check to reduce memory allocations.

#relative_path, #smart_path

Constructor Details

.new(config, preferred_delimiters) ⇒ PercentLiteralCorrector

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 11

def initialize(config, preferred_delimiters)
  @config = config
  @preferred_delimiters = preferred_delimiters
end

Instance Attribute Details

#config (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 9

attr_reader :config, :preferred_delimiters

#preferred_delimiters (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 9

attr_reader :config, :preferred_delimiters

Instance Method Details

#autocorrect_multiline_words(node, escape, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 46

def autocorrect_multiline_words(node, escape, delimiters)
  contents = process_multiline_words(node, escape, delimiters)
  contents << end_content(node.source)
  contents.join
end

#autocorrect_words(node, escape, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 52

def autocorrect_words(node, escape, delimiters)
  node.children.map do |word_node|
    fix_escaped_content(word_node, escape, delimiters)
  end.join(' ')
end

#correct(corrector, node, char)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 16

def correct(corrector, node, char)
  escape = escape_words?(node)
  char = char.upcase if escape
  delimiters = delimiters_for("%#{char}")
  contents = new_contents(node, escape, delimiters)
  wrap_contents(corrector, node, contents, char, delimiters)
end

#delimiters_for(type) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 34

def delimiters_for(type)
  PreferredDelimiters.new(type, config, preferred_delimiters).delimiters
end

#end_content(source) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 110

def end_content(source)
  result = /\A(\s*)\]/.match(source.split("\n").last)
  "\n#{result[1]}" if result
end

#escape_words?(node) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 30

def escape_words?(node)
  node.children.any? { |w| needs_escaping?(w.children[0]) }
end

#first_line?(node, previous_line_num) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 78

def first_line?(node, previous_line_num)
  node.first_line == previous_line_num
end

#fix_escaped_content(word_node, escape, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 89

def fix_escaped_content(word_node, escape, delimiters)
  content = +word_node.children.first.to_s
  content = escape_string(content) if escape
  substitute_escaped_delimiters(content, delimiters)
  content
end

#line_breaks(node, source, previous_line_num, base_line_num, node_index) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 69

def line_breaks(node, source, previous_line_num, base_line_num, node_index)
  source_in_lines = source.split("\n")
  if first_line?(node, previous_line_num)
    node_index.zero? && node.first_line == base_line_num ? '' : ' '
  else
    process_lines(node, previous_line_num, base_line_num, source_in_lines)
  end
end

#new_contents(node, escape, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 38

def new_contents(node, escape, delimiters)
  if node.multiline?
    autocorrect_multiline_words(node, escape, delimiters)
  else
    autocorrect_words(node, escape, delimiters)
  end
end

#process_lines(node, previous_line_num, base_line_num, source_in_lines) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 82

def process_lines(node, previous_line_num, base_line_num, source_in_lines)
  begin_line_num = previous_line_num - base_line_num + 1
  end_line_num = node.first_line - base_line_num + 1
  lines = source_in_lines[begin_line_num...end_line_num]
  "\n#{lines.join("\n").split(node.source).first || ''}"
end

#process_multiline_words(node, escape, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 58

def process_multiline_words(node, escape, delimiters)
  base_line_num = node.first_line
  prev_line_num = base_line_num
  node.children.map.with_index do |word_node, index|
    line_breaks = line_breaks(word_node, node.source, prev_line_num, base_line_num, index)
    prev_line_num = word_node.last_line
    content = fix_escaped_content(word_node, escape, delimiters)
    line_breaks + content
  end
end

#substitute_escaped_delimiters(content, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 96

def substitute_escaped_delimiters(content, delimiters)
  if delimiters.first != delimiters.last
    # With different delimiters (eg. `[]`, `()`), if there are the same
    # number of each, escaping is not necessary
    delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
      counts[delimiter] = content.count(delimiter)
    end

    return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
  end

  delimiters.each { |delim| content.gsub!(delim, "\\#{delim}") }
end

#wrap_contents(corrector, node, contents, char, delimiters) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/correctors/percent_literal_corrector.rb', line 26

def wrap_contents(corrector, node, contents, char, delimiters)
  corrector.replace(node, "%#{char}#{delimiters[0]}#{contents}#{delimiters[1]}")
end