Class: ERBLint::Linters::HardCodedString

Inherits:
ERBLint::Linter show all
Includes:
ERBLint::LinterRegistry
Defined in:
lib/erb_lint/linters/hard_coded_string.rb

Overview

Checks for hardcoded strings. Useful if you want to ensure a string can be translated using i18n.

Defined Under Namespace

Classes: ConfigSchema

Constant Summary collapse

ForbiddenCorrector =
Class.new(StandardError)
MissingCorrector =
Class.new(StandardError)
MissingI18nLoadPath =
Class.new(StandardError)
ALLOWED_CORRECTORS =
%w(
  I18nCorrector
  RuboCop::Corrector::I18n::HardCodedString
)
NON_TEXT_TAGS =
Set.new(%w(script style xmp iframe noembed noframes listing))
BLACK_LISTED_TEXT =
Set.new(%w(
   
  &
  <
  >
  "
  ©
  ®
  ™
  …
  —
  •
  “
  ”
  ‘
  ’
  ←
  →
  ↓
  ↑
))

Constants included from ERBLint::LinterRegistry

ERBLint::LinterRegistry::CUSTOM_LINTERS_DIR

Instance Attribute Summary

Attributes inherited from ERBLint::Linter

#offenses

Instance Method Summary collapse

Methods included from ERBLint::LinterRegistry

clear, find_by_name, included, linters, load_custom_linters

Methods inherited from ERBLint::Linter

#add_offense, #clear_offenses, #enabled?, #excludes_file?, inherited, #initialize, support_autocorrect?

Constructor Details

This class inherits a constructor from ERBLint::Linter

Instance Method Details

#autocorrect(processed_source, offense) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/erb_lint/linters/hard_coded_string.rb', line 82

def autocorrect(processed_source, offense)
  string = offense.source_range.source
  return unless (klass = load_corrector)
  return unless string.strip.length > 1
  node = ::RuboCop::AST::StrNode.new(:str, [string])
  corrector = klass.new(node, processed_source.filename, corrector_i18n_load_path, offense.source_range)
  corrector.autocorrect(tag_start: '<%= ', tag_end: ' %>')
rescue MissingCorrector, MissingI18nLoadPath
  nil
end

#find_range(node, str) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/erb_lint/linters/hard_coded_string.rb', line 73

def find_range(node, str)
  match = node.loc.source.match(Regexp.new(Regexp.quote(str.strip)))
  return unless match

  range_begin = match.begin(0) + node.loc.begin_pos
  range_end   = match.end(0) + node.loc.begin_pos
  (range_begin...range_end)
end

#run(processed_source) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/erb_lint/linters/hard_coded_string.rb', line 50

def run(processed_source)
  hardcoded_strings = processed_source.ast.descendants(:text).each_with_object([]) do |text_node, to_check|
    next if non_text_tag?(processed_source, text_node)

    offended_strings = text_node.to_a.select { |node| relevant_node(node) }
    offended_strings.each do |offended_string|
      offended_string.split("\n").each do |str|
        to_check << [text_node, str] if check_string?(str)
      end
    end
  end

  hardcoded_strings.compact.each do |text_node, offended_str|
    range = find_range(text_node, offended_str)
    source_range = processed_source.to_source_range(range)

    add_offense(
      source_range,
      message(source_range.source)
    )
  end
end