Class: Wool::OperatorSpacing

Inherits:
LineWarning show all
Includes:
Advice::CommentAdvice
Defined in:
lib/wool/warnings/operator_spacing.rb

Overview

Warning for not putting space around operators

Constant Summary collapse

OPERATORS =
%w(+ - / * != !== = == === ~= !~ += -= *= /= ** **= ||= || && &&= &= |= | & ^)

Instance Attribute Summary

Attributes inherited from Warning

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

Instance Method Summary collapse

Methods included from Advice::CommentAdvice

included

Methods inherited from LineWarning

options

Methods inherited from Warning

all_types, all_warnings, concrete_warnings, #count_occurrences, #desc, #fixable?, #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

Instance Method Details

#fixObject



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/wool/warnings/operator_spacing.rb', line 51

def fix
  line = self.line.dup
  OPERATORS.each do |op|
    next if op == '==' && line =~ /!==/
    next if op == '=' && line =~ /!=/
    next if op == '|' && self.is_block_line?(line)
    embed = op.gsub(/(\+|\-|\*|\||\^)/, '\\\\\\1')
    line.gsub!(/([A-Za-z0-9_]!|[A-Za-z0-9_?])(#{embed})/, '\1 \2')
    line.gsub!(/(#{embed})([$A-Za-z0-9_?!])/, '\1 \2')
  end
  line
end

#generated_warnings(*args) ⇒ Object



27
28
29
# File 'lib/wool/warnings/operator_spacing.rb', line 27

def generated_warnings(*args)
  match?(*args) ? [self] : []
end

#ignore_array_splat_idiom(line) ⇒ Object



39
40
41
# File 'lib/wool/warnings/operator_spacing.rb', line 39

def ignore_array_splat_idiom(line)
  line.gsub(/\[\*([a-z][A-Za-z0-9_]*)\]/, '\1')
end

#ignore_block_params(line) ⇒ Object



31
32
33
# File 'lib/wool/warnings/operator_spacing.rb', line 31

def ignore_block_params(line)
  line.gsub(/(\{|(do))\s*\|.*\|/, '\1')
end

#ignore_splat_args(line) ⇒ Object



35
36
37
# File 'lib/wool/warnings/operator_spacing.rb', line 35

def ignore_splat_args(line)
  line.gsub(/(\(|(, ))\&([a-z][A-Za-z0-9_]*)((, )|\)|\Z)/, '\1')
end

#ignore_to_proc_args(line) ⇒ Object



43
44
45
# File 'lib/wool/warnings/operator_spacing.rb', line 43

def ignore_to_proc_args(line)
  line.gsub(/(\(|(, ))\*([a-z][A-Za-z0-9_]*)((, )|\)|\Z)/, '\1')
end

#is_block_line?(line) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/wool/warnings/operator_spacing.rb', line 47

def is_block_line?(line)
  line =~ /do\s*\|/ || line =~ /\{\s*\|/
end

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

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/wool/warnings/operator_spacing.rb', line 11

def match?(line = self.body)
  working_line = ignore_block_params line
  working_line = ignore_splat_args working_line
  working_line = ignore_to_proc_args working_line
  working_line = ignore_array_splat_idiom working_line
  lexed = lex(working_line)
  lexed.each_with_index do |token, idx|
    next unless token.type == :on_op
    next if idx == lexed.size - 1  # Last token on line (continuation) is ok
    next if token.body == '-' && [:on_float, :on_int].include?(lexed[idx+1].type)
    return token if lexed[idx+1].type != :on_sp && lexed[idx+1].type != :on_op
    return token if idx > 0 && ![:on_sp, :on_op].include?(lexed[idx-1].type)
  end
  nil
end