lib/skeptic/rules/spaces_around_operators.rb in skeptic-0.0.6 vs lib/skeptic/rules/spaces_around_operators.rb in skeptic-0.0.7

- old
+ new

@@ -1,22 +1,28 @@ module Skeptic module Rules class SpacesAroundOperators DESCRIPTION = 'Check for spaces around operators' - OPERATORS_WITHOUT_SPACES_AROUND_THEM = ['**'] + include SexpVisitor + OPERATORS_WITHOUT_SPACES_AROUND_THEM = ['**', '::', '...', '..'] + IGNORED_TOKEN_TYPES = [:on_sp, :on_ignored_nl, :on_nl, :on_lparen, :on_symbeg] + def initialize(data) @violations = [] + @special_tokens_locations = [] end def apply_to(code, tokens, sexp) + visit sexp + @violations = tokens.each_cons(3).select do |_, token, _| operator_expecting_spaces? token end.select do |left, operator, right| - no_spaces_between?(operator, left) or - no_spaces_between?(operator, right) + no_spaces_on_left_of?(operator, left) or + no_spaces_on_right_of?(operator, right) end.map do |_, operator, _| [operator.last, operator.first[0]] end self end @@ -36,11 +42,70 @@ def operator_expecting_spaces?(token) token[1] == :on_op and not OPERATORS_WITHOUT_SPACES_AROUND_THEM.include? token.last end - def no_spaces_between?(operator, neighbour) - neighbour.first[0] == operator.first[0] and neighbour[1] != :on_sp + def no_spaces_on_left_of?(operator, neighbour) + neighbour.first[0] == operator.first[0] and neighbour[1] != :on_lparen and + !special_token? neighbour + end + + def no_spaces_on_right_of?(operator, neighbour) + neighbour.first[0] == operator.first[0] and neighbour[1] != :on_rparen and + !special_token? neighbour + end + + def whitespace_token?(token) + token[1] == :on_sp or token[1] == :on_ignored_nl + end + + def mark_special_tokens(*token_locations) + @special_tokens_locations.concat(token_locations) + end + + def special_token?(token) + IGNORED_TOKEN_TYPES.include? token[1] or + @special_tokens_locations.include? token.first + end + + on :blockarg, :rest_param do |ident| + mark_special_tokens ident.last + end + + on :args_add_block do |args, block| + visit args + if block + case block.first + when :symbol_literal, :dyna_symbol + sexp_location = block.last.last.last + symbol_location = [sexp_location[0], sexp_location[1] - 1] + mark_special_tokens symbol_location + when :vcall, :var_ref + mark_special_tokens block.last.last + end + end + end + + on :mlhs_add_star, :args_add_star do |_, ident| + if ident.first == :var_ref or ident.first == :vcall + mark_special_tokens ident.last.last + else + mark_special_tokens ident.last + end + end + + on :block_var do |params| + normal_params = params[1] + unless normal_params.empty? + right_param = normal_params.last + right_location = [right_param.last[0], + right_param.last[1] ] + mark_special_tokens normal_params.first.last, normal_params.last.last + end + end + + on :unary do |_, token| + mark_special_tokens token.last end end end end