lib/rubocop/cop/method_length.rb in rubocop-0.7.2 vs lib/rubocop/cop/method_length.rb in rubocop-0.8.0

- old
+ new

@@ -1,55 +1,52 @@ # encoding: utf-8 module Rubocop module Cop class MethodLength < Cop - ERROR_MESSAGE = 'Method has too many lines. [%d/%d]' + MSG = 'Method has too many lines. [%d/%d]' - def inspect(file, source, tokens, sexp) - def_token_indices(tokens, source).each do |t_ix| - def_lineno, end_lineno = def_and_end_lines(tokens, t_ix) - length = calculate_length(def_lineno, end_lineno, source) + def on_def(node) + check(node) - max = MethodLength.config['Max'] - if length > max - message = sprintf(ERROR_MESSAGE, length, max) - add_offence(:convention, def_lineno, message) - end - end + super end - private + def on_defs(node) + check(node) - def calculate_length(def_lineno, end_lineno, source) - lines = source[def_lineno..(end_lineno - 2)].reject(&:empty?) - unless MethodLength.config['CountComments'] - lines = lines.reject { |line| line =~ /^\s*#/ } - end - lines.size + super end - def def_token_indices(tokens, source) - tokens.each_index.select do |ix| - t = tokens[ix] + def max_length + MethodLength.config['Max'] + end - # Need to check: - # 1. if the previous character is a ':' to prevent matching ':def' - # 2. if the method is a one line, which we will ignore - [t.type, t.text] == [:on_kw, 'def'] && - source[t.pos.lineno - 1][t.pos.column - 1] != ':' && - source[t.pos.lineno - 1] !~ /^\s*def.*(?:\(.*\)|;).*end\s*$/ - end + def count_comments? + MethodLength.config['CountComments'] end - # Find the matching 'end' based on the indentation of 'def' - # Fall back to last token if indentation cannot be matched - def def_and_end_lines(tokens, t_ix) - t1 = tokens[t_ix] - t2 = tokens[(t_ix + 1)..-1].find(-> { tokens[-1] }) do |t| - [t1.pos.column, t.type, t.text] == [t.pos.column, :on_kw, 'end'] + private + + def check(node) + method_length = calculate_length(node.loc.expression.source) + + if method_length > max_length + message = sprintf(MSG, method_length, max_length) + add_offence(:convention, node.loc.keyword.line, message) end - [t1.pos.lineno, t2.pos.lineno] + end + + def calculate_length(source) + lines = source.lines.to_a[1...-1] + + return 0 unless lines + + lines.map!(&:strip).reject!(&:empty?) + + lines.reject! { |line| line =~ /^\s*#/ } unless count_comments? + + lines.size end end end end