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