Class: Wool::GenericLineLengthWarning

Inherits:
LineWarning show all
Defined in:
lib/wool/warnings/line_length.rb

Instance Attribute Summary

Attributes inherited from Warning

#body, #file, #line_number, #name, #settings, #severity

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from LineWarning

options

Methods inherited from Warning

all_types, all_warnings, concrete_warnings, #count_occurrences, #desc, #fixable?, #generated_warnings, #get_indent, #indent, inherited, #initialize, opt, options, setting_accessor, type

Methods included from Advice

#advice_counter, #after_advice, #argument_advice, #before_advice, #bump_advice_counter!, #with_advice

Methods included from ModuleExtensions

#attr_accessor_with_default, #cattr_accessor, #cattr_accessor_with_default, #cattr_get_and_setter, #cattr_reader, #cattr_writer

Methods included from SexpAnalysis

#find_sexps, #parse

Methods included from LexicalAnalysis

#find_keyword, #find_token, #lex, #select_token, #split_on_keyword, #split_on_token, #text_between_token_positions

Constructor Details

This class inherits a constructor from Wool::Warning

Class Method Details

.inspectObject



7
8
9
# File 'lib/wool/warnings/line_length.rb', line 7

def self.inspect
  "Wool::GenericLineLengthWarning<#{line_length_limit}>"
end

Instance Method Details

#fix(content_stack = nil) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/wool/warnings/line_length.rb', line 15

def fix(content_stack = nil)
  result = handle_long_comments(self.line)
  return result if result
  result = try_to_fix_guarded_lines(self.line)
  return result if result
  self.line
end

#fix_long_comment(text) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/wool/warnings/line_length.rb', line 60

def fix_long_comment(text)
  # Must have no leading text
  return nil unless text =~ /^(\s*)(#+\s*)(.*)\Z/
  indent, hashes, comment = $1, $2, $3
  indent_size = indent.size
  # The "+ 2" is (indent)#(single space)
  space_for_text_per_line = self.class.line_length_limit - (indent_size + hashes.size)
  lines = ['']
  words = comment.split(/\s/)
  quota = space_for_text_per_line
  current_line = 0
  while words.any?
    word = words.shift
    # break on word big enough to make a new line, unless its the first word
    if quota - (word.size + 1) < 0 && quota < space_for_text_per_line
      current_line += 1
      lines << ''
      quota = space_for_text_per_line
    end
    unless lines[current_line].empty?
      lines[current_line] << ' '
      quota -= 1
    end
    lines[current_line] << word
    quota -= word.size
  end
  lines.map { |line| indent + hashes + line }.join("\n")
end

#handle_long_comments(line) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/wool/warnings/line_length.rb', line 50

def handle_long_comments(line)
  code, comment = split_on_token(line, :on_comment)
  return nil if comment.empty?
  indent, code = code.match(/^(\s*)(.*)$/)[1..2]
  hashes, comment = comment.match(/^(#+\s*)(.*)$/)[1..2]
  comment_cleaned = fix_long_comment(indent + hashes + comment)
  code_cleaned = !code.strip.empty? ? "\n" + indent + code.rstrip : ''
  comment_cleaned + code_cleaned
end

#match?(body = self.body) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
# File 'lib/wool/warnings/line_length.rb', line 11

def match?(body = self.body)
  !!(line.rstrip.size > self.class.line_length_limit)
end

#try_to_fix_guarded_lines(line) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/wool/warnings/line_length.rb', line 23

def try_to_fix_guarded_lines(line)
  return nil if line !~ /\b(if|unless)\s/  # quick fast check
  code, guard = split_on_keyword(:if, :unless)
  code.rstrip!
  return nil if code.empty? || guard.empty? || code.strip == 'end'
  # check guard for closing braces
  return nil if count_occurrences(guard, '}') != count_occurrences(guard, '{')
  indent = get_indent(line)
  indent_unit = ' ' * @settings[:indent_size]

  result = code
  until guard.empty?
    condition = indent + guard.strip
    body = result.split(/\n/).map { |line| indent_unit + line}.join("\n")
    new_condition, guard = split_on_keyword(condition[indent.size+1..-1], :if, :unless)
    if new_condition.empty?
      new_condition, guard = guard.rstrip, ''
    else
      new_condition = "#{condition[indent.size,1]}#{new_condition.rstrip}"
    end
    condition = indent + new_condition unless guard.empty?
    result = condition + "\n" + body + "\n" + indent + 'end'
  end

  result
end