rubocop 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -1
  3. data/CHANGELOG.md +19 -0
  4. data/README.md +4 -8
  5. data/bin/rubocop +2 -2
  6. data/config/default.yml +8 -0
  7. data/config/enabled.yml +21 -24
  8. data/lib/rubocop.rb +9 -7
  9. data/lib/rubocop/cli.rb +73 -52
  10. data/lib/rubocop/config.rb +8 -5
  11. data/lib/rubocop/cop/access_control.rb +41 -0
  12. data/lib/rubocop/cop/alias.rb +7 -5
  13. data/lib/rubocop/cop/align_parameters.rb +20 -96
  14. data/lib/rubocop/cop/and_or.rb +26 -0
  15. data/lib/rubocop/cop/ascii_comments.rb +3 -8
  16. data/lib/rubocop/cop/ascii_identifiers.rb +6 -5
  17. data/lib/rubocop/cop/avoid_class_vars.rb +5 -10
  18. data/lib/rubocop/cop/avoid_for.rb +7 -5
  19. data/lib/rubocop/cop/avoid_global_vars.rb +19 -7
  20. data/lib/rubocop/cop/avoid_perl_backrefs.rb +7 -10
  21. data/lib/rubocop/cop/avoid_perlisms.rb +11 -10
  22. data/lib/rubocop/cop/block_comments.rb +4 -6
  23. data/lib/rubocop/cop/blocks.rb +11 -47
  24. data/lib/rubocop/cop/case_indentation.rb +9 -31
  25. data/lib/rubocop/cop/class_and_module_camel_case.rb +20 -11
  26. data/lib/rubocop/cop/class_methods.rb +5 -10
  27. data/lib/rubocop/cop/collection_methods.rb +16 -16
  28. data/lib/rubocop/cop/colon_method_call.rb +8 -32
  29. data/lib/rubocop/cop/constant_name.rb +24 -0
  30. data/lib/rubocop/cop/cop.rb +20 -78
  31. data/lib/rubocop/cop/def_parentheses.rb +43 -35
  32. data/lib/rubocop/cop/empty_line_between_defs.rb +11 -15
  33. data/lib/rubocop/cop/empty_lines.rb +20 -9
  34. data/lib/rubocop/cop/empty_literal.rb +47 -0
  35. data/lib/rubocop/cop/encoding.rb +3 -3
  36. data/lib/rubocop/cop/end_of_line.rb +3 -3
  37. data/lib/rubocop/cop/ensure_return.rb +6 -23
  38. data/lib/rubocop/cop/eval.rb +7 -10
  39. data/lib/rubocop/cop/favor_join.rb +9 -24
  40. data/lib/rubocop/cop/favor_modifier.rb +38 -48
  41. data/lib/rubocop/cop/favor_percent_r.rb +7 -7
  42. data/lib/rubocop/cop/favor_sprintf.rb +8 -24
  43. data/lib/rubocop/cop/favor_unless_over_negated_if.rb +19 -17
  44. data/lib/rubocop/cop/handle_exceptions.rb +7 -11
  45. data/lib/rubocop/cop/hash_syntax.rb +29 -14
  46. data/lib/rubocop/cop/if_then_else.rb +32 -29
  47. data/lib/rubocop/cop/leading_comment_space.rb +5 -8
  48. data/lib/rubocop/cop/line_continuation.rb +4 -7
  49. data/lib/rubocop/cop/line_length.rb +3 -3
  50. data/lib/rubocop/cop/loop.rb +33 -0
  51. data/lib/rubocop/cop/method_and_variable_snake_case.rb +42 -19
  52. data/lib/rubocop/cop/method_length.rb +34 -37
  53. data/lib/rubocop/cop/new_lambda_literal.rb +8 -6
  54. data/lib/rubocop/cop/not.rb +10 -4
  55. data/lib/rubocop/cop/numeric_literals.rb +9 -7
  56. data/lib/rubocop/cop/offence.rb +1 -1
  57. data/lib/rubocop/cop/op_method.rb +12 -22
  58. data/lib/rubocop/cop/parameter_lists.rb +12 -6
  59. data/lib/rubocop/cop/parentheses_around_condition.rb +11 -11
  60. data/lib/rubocop/cop/percent_r.rb +7 -7
  61. data/lib/rubocop/cop/reduce_arguments.rb +13 -51
  62. data/lib/rubocop/cop/rescue_exception.rb +13 -29
  63. data/lib/rubocop/cop/rescue_modifier.rb +5 -8
  64. data/lib/rubocop/cop/semicolon.rb +15 -74
  65. data/lib/rubocop/cop/single_line_methods.rb +28 -44
  66. data/lib/rubocop/cop/space_after_comma_etc.rb +29 -9
  67. data/lib/rubocop/cop/space_after_control_keyword.rb +16 -15
  68. data/lib/rubocop/cop/string_literals.rb +9 -35
  69. data/lib/rubocop/cop/surrounding_space.rb +213 -112
  70. data/lib/rubocop/cop/symbol_array.rb +9 -7
  71. data/lib/rubocop/cop/symbol_name.rb +23 -0
  72. data/lib/rubocop/cop/syntax.rb +14 -7
  73. data/lib/rubocop/cop/tab.rb +3 -3
  74. data/lib/rubocop/cop/ternary_operator.rb +26 -24
  75. data/lib/rubocop/cop/trailing_whitespace.rb +3 -5
  76. data/lib/rubocop/cop/trivial_accessors.rb +18 -95
  77. data/lib/rubocop/cop/unless_else.rb +11 -7
  78. data/lib/rubocop/cop/util.rb +26 -0
  79. data/lib/rubocop/cop/variable_interpolation.rb +18 -10
  80. data/lib/rubocop/cop/when_then.rb +6 -17
  81. data/lib/rubocop/cop/word_array.rb +18 -19
  82. data/lib/rubocop/version.rb +1 -1
  83. data/rubocop.gemspec +1 -0
  84. data/spec/project_spec.rb +1 -1
  85. data/spec/rubocop/cli_spec.rb +16 -9
  86. data/spec/rubocop/config_spec.rb +13 -3
  87. data/spec/rubocop/cops/access_control_spec.rb +129 -0
  88. data/spec/rubocop/cops/alias_spec.rb +2 -6
  89. data/spec/rubocop/cops/align_parameters_spec.rb +58 -71
  90. data/spec/rubocop/cops/and_or_spec.rb +37 -0
  91. data/spec/rubocop/cops/ascii_comments_spec.rb +3 -4
  92. data/spec/rubocop/cops/ascii_identifiers_spec.rb +3 -4
  93. data/spec/rubocop/cops/avoid_class_vars_spec.rb +7 -2
  94. data/spec/rubocop/cops/avoid_for_spec.rb +1 -4
  95. data/spec/rubocop/cops/{avoid_global_vars.rb → avoid_global_vars_spec.rb} +4 -4
  96. data/spec/rubocop/cops/avoid_perl_backrefs_spec.rb +1 -1
  97. data/spec/rubocop/cops/avoid_perlisms_spec.rb +5 -5
  98. data/spec/rubocop/cops/block_comments_spec.rb +0 -4
  99. data/spec/rubocop/cops/blocks_spec.rb +33 -0
  100. data/spec/rubocop/cops/case_indentation_spec.rb +5 -5
  101. data/spec/rubocop/cops/class_and_module_camel_case_spec.rb +15 -5
  102. data/spec/rubocop/cops/class_methods_spec.rb +4 -4
  103. data/spec/rubocop/cops/collection_methods_spec.rb +9 -4
  104. data/spec/rubocop/cops/colon_method_call_spec.rb +11 -5
  105. data/spec/rubocop/cops/constant_name_spec.rb +42 -0
  106. data/spec/rubocop/cops/def_with_parentheses_spec.rb +13 -8
  107. data/spec/rubocop/cops/def_without_parentheses_spec.rb +11 -5
  108. data/spec/rubocop/cops/empty_line_between_defs_spec.rb +38 -38
  109. data/spec/rubocop/cops/empty_lines_spec.rb +15 -3
  110. data/spec/rubocop/cops/empty_literal_spec.rb +90 -0
  111. data/spec/rubocop/cops/encoding_spec.rb +9 -9
  112. data/spec/rubocop/cops/end_of_line_spec.rb +2 -2
  113. data/spec/rubocop/cops/ensure_return_spec.rb +1 -3
  114. data/spec/rubocop/cops/eval_spec.rb +8 -5
  115. data/spec/rubocop/cops/favor_join_spec.rb +1 -5
  116. data/spec/rubocop/cops/favor_modifier_spec.rb +16 -14
  117. data/spec/rubocop/cops/{favor_percent_r.rb → favor_percent_r_spec.rb} +6 -6
  118. data/spec/rubocop/cops/favor_sprintf_spec.rb +3 -9
  119. data/spec/rubocop/cops/favor_unless_over_negated_if_spec.rb +4 -4
  120. data/spec/rubocop/cops/favor_until_over_negated_while_spec.rb +3 -3
  121. data/spec/rubocop/cops/handle_exceptions_spec.rb +1 -3
  122. data/spec/rubocop/cops/hash_syntax_spec.rb +11 -6
  123. data/spec/rubocop/cops/if_with_semicolon_spec.rb +7 -1
  124. data/spec/rubocop/cops/leading_comment_space_spec.rb +0 -7
  125. data/spec/rubocop/cops/line_continuation_spec.rb +2 -2
  126. data/spec/rubocop/cops/line_length_spec.rb +2 -2
  127. data/spec/rubocop/cops/loop_spec.rb +31 -0
  128. data/spec/rubocop/cops/method_and_variable_snake_case_spec.rb +38 -12
  129. data/spec/rubocop/cops/method_length_spec.rb +85 -85
  130. data/spec/rubocop/cops/multiline_if_then_spec.rb +15 -15
  131. data/spec/rubocop/cops/new_lambda_literal_spec.rb +3 -3
  132. data/spec/rubocop/cops/not_spec.rb +1 -4
  133. data/spec/rubocop/cops/numeric_literals_spec.rb +13 -13
  134. data/spec/rubocop/cops/one_line_conditional_spec.rb +1 -1
  135. data/spec/rubocop/cops/op_method_spec.rb +2 -9
  136. data/spec/rubocop/cops/parameter_lists_spec.rb +7 -7
  137. data/spec/rubocop/cops/parentheses_around_condition_spec.rb +41 -44
  138. data/spec/rubocop/cops/percent_r_spec.rb +6 -6
  139. data/spec/rubocop/cops/reduce_arguments_spec.rb +4 -4
  140. data/spec/rubocop/cops/rescue_exception_spec.rb +48 -8
  141. data/spec/rubocop/cops/rescue_modifier_spec.rb +2 -5
  142. data/spec/rubocop/cops/semicolon_spec.rb +2 -30
  143. data/spec/rubocop/cops/single_line_methods_spec.rb +13 -13
  144. data/spec/rubocop/cops/space_after_colon_spec.rb +3 -3
  145. data/spec/rubocop/cops/space_after_comma_spec.rb +14 -2
  146. data/spec/rubocop/cops/space_after_control_keyword_spec.rb +42 -3
  147. data/spec/rubocop/cops/space_after_semicolon_spec.rb +2 -2
  148. data/spec/rubocop/cops/space_around_braces_spec.rb +18 -3
  149. data/spec/rubocop/cops/space_around_equals_in_default_parameter_spec.rb +4 -4
  150. data/spec/rubocop/cops/space_around_operators_spec.rb +82 -27
  151. data/spec/rubocop/cops/space_inside_brackets_spec.rb +13 -7
  152. data/spec/rubocop/cops/space_inside_hash_literal_braces_spec.rb +14 -9
  153. data/spec/rubocop/cops/space_inside_parens_spec.rb +7 -3
  154. data/spec/rubocop/cops/string_literals_spec.rb +17 -5
  155. data/spec/rubocop/cops/symbol_array_spec.rb +18 -2
  156. data/spec/rubocop/cops/symbol_name_spec.rb +119 -0
  157. data/spec/rubocop/cops/syntax_spec.rb +25 -18
  158. data/spec/rubocop/cops/tab_spec.rb +2 -2
  159. data/spec/rubocop/cops/ternary_operator_spec.rb +13 -17
  160. data/spec/rubocop/cops/trailing_whitespace_spec.rb +3 -3
  161. data/spec/rubocop/cops/trivial_accessors_spec.rb +17 -20
  162. data/spec/rubocop/cops/unless_else_spec.rb +8 -8
  163. data/spec/rubocop/cops/variable_interpolation_spec.rb +0 -5
  164. data/spec/rubocop/cops/when_then_spec.rb +14 -21
  165. data/spec/rubocop/cops/word_array_spec.rb +12 -4
  166. data/spec/spec_helper.rb +12 -4
  167. metadata +40 -31
  168. data/.document +0 -5
  169. data/lib/rubocop/cop/ampersands_pipes_vs_and_or.rb +0 -25
  170. data/lib/rubocop/cop/array_literal.rb +0 -61
  171. data/lib/rubocop/cop/brace_after_percent.rb +0 -32
  172. data/lib/rubocop/cop/grammar.rb +0 -138
  173. data/lib/rubocop/cop/hash_literal.rb +0 -61
  174. data/lib/rubocop/cop/percent_literals.rb +0 -25
  175. data/lib/rubocop/cop/symbol_snake_case.rb +0 -47
  176. data/spec/rubocop/cops/ampersands_pipes_vs_and_or_spec.rb +0 -57
  177. data/spec/rubocop/cops/array_literal_spec.rb +0 -46
  178. data/spec/rubocop/cops/brace_after_percent_spec.rb +0 -33
  179. data/spec/rubocop/cops/grammar_spec.rb +0 -81
  180. data/spec/rubocop/cops/hash_literal_spec.rb +0 -46
  181. data/spec/rubocop/cops/multiline_blocks_spec.rb +0 -24
  182. data/spec/rubocop/cops/percent_literals_spec.rb +0 -47
  183. data/spec/rubocop/cops/single_line_blocks_spec.rb +0 -22
  184. data/spec/rubocop/cops/symbol_snake_case_spec.rb +0 -93
@@ -3,14 +3,16 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class NewLambdaLiteral < Cop
6
- ERROR_MESSAGE = 'The new lambda literal syntax is preferred in Ruby 1.9.'
6
+ MSG = 'Use the new lambda literal syntax ->(params) {...}.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- each(:fcall, sexp) do |s|
10
- if s[1][0..1] == [:@ident, 'lambda']
11
- add_offence(:convention, s[1][-1].lineno, ERROR_MESSAGE)
12
- end
8
+ TARGET = s(:send, nil, :lambda)
9
+
10
+ def on_send(node)
11
+ if node == TARGET && node.loc.selector.source != '->'
12
+ add_offence(:convention, node.loc.line, MSG)
13
13
  end
14
+
15
+ super
14
16
  end
15
17
  end
16
18
  end
@@ -3,12 +3,18 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class Not < Cop
6
- ERROR_MESSAGE = 'Use ! instead of not.'
6
+ MSG = 'Use ! instead of not.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- each_keyword('not', tokens) do |t|
10
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
8
+ def on_send(node)
9
+ _receiver, method_name, *args = *node
10
+
11
+ # not does not take any arguments
12
+ if args.empty? && method_name == :! &&
13
+ node.loc.selector.source == 'not'
14
+ add_offence(:convention, node.loc.line, MSG)
11
15
  end
16
+
17
+ super
12
18
  end
13
19
  end
14
20
  end
@@ -3,17 +3,19 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class NumericLiterals < Cop
6
- ERROR_MESSAGE = 'Add underscores to large numeric literals to ' +
6
+ MSG = 'Add underscores to large numeric literals to ' +
7
7
  'improve their readability.'
8
8
 
9
- def inspect(file, source, tokens, sexp)
10
- tokens.each do |t|
11
- if [:on_int, :on_float].include?(t.type) &&
12
- t.text.split('.').grep(/\d{6}/).any?
13
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
14
- end
9
+ def on_int(node)
10
+ value, = *node
11
+
12
+ if value > 10000 &&
13
+ node.loc.expression.source.split('.').grep(/\d{6}/).any?
14
+ add_offence(:convention, node.loc.expression.line, MSG)
15
15
  end
16
16
  end
17
+
18
+ alias_method :on_float, :on_int
17
19
  end
18
20
  end
19
21
  end
@@ -24,7 +24,7 @@ module Rubocop
24
24
  end
25
25
 
26
26
  def ==(other)
27
- severity == other.severity and line_number == other.line_number and
27
+ severity == other.severity && line_number == other.line_number &&
28
28
  message == other.message
29
29
  end
30
30
 
@@ -3,33 +3,23 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class OpMethod < Cop
6
- ERROR_MESSAGE = 'When defining the %s operator, name its argument other.'
6
+ MSG = 'When defining the %s operator, name its argument other.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- each(:def, sexp) do |s|
10
- if binary_operator?(s) && !%w([] []= <<).include?(s[1][1])
11
- params = parameters(s[2])
12
- unless params[0][1] == 'other'
13
- add_offence(:convention,
14
- params[0][2].lineno,
15
- sprintf(ERROR_MESSAGE, s[1][1]))
16
- end
17
- end
18
- end
19
- end
8
+ BLACKLISTED = [:+@, :-@, :[], :[]=, :<<]
20
9
 
21
- private
10
+ TARGET_ARGS = s(:args, s(:arg, :other))
22
11
 
23
- def binary_operator?(def_sexp)
24
- def_sexp[1][0] == :@op && parameters(def_sexp[2]).size == 1
25
- end
12
+ def on_def(node)
13
+ name, args, _body = *node
26
14
 
27
- def parameters(param_sexp)
28
- if param_sexp[0] == :paren # param is surrounded by braces?
29
- parameters(param_sexp[1])
30
- else
31
- param_sexp[1] || []
15
+ if name !~ /\A\w/ && !BLACKLISTED.include?(name) &&
16
+ args.children.size == 1 && args != TARGET_ARGS
17
+ add_offence(:convention,
18
+ node.loc.line,
19
+ sprintf(MSG, name))
32
20
  end
21
+
22
+ super
33
23
  end
34
24
  end
35
25
  end
@@ -3,14 +3,20 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class ParameterLists < Cop
6
- ERROR_MESSAGE = 'Avoid parameter lists longer than four parameters.'
6
+ MSG = 'Avoid parameter lists longer than %d parameters.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- each(:params, sexp) do |params|
10
- if params[1] && params[1].size > 4
11
- add_offence(:convention, params[1][0][-1].lineno, ERROR_MESSAGE)
12
- end
8
+ def on_args(node)
9
+ args_count = node.children.size
10
+
11
+ if args_count > max_params
12
+ add_offence(:convention, node.loc.line, sprintf(MSG, max_params))
13
13
  end
14
+
15
+ super
16
+ end
17
+
18
+ def max_params
19
+ ParameterLists.config['Max']
14
20
  end
15
21
  end
16
22
  end
@@ -3,19 +3,19 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class ParenthesesAroundCondition < Cop
6
- ERROR_MESSAGE = "Don't use parentheses around the condition of an " +
6
+ MSG = "Don't use parentheses around the condition of an " +
7
7
  'if/unless/while/until, unless the condition contains an assignment.'
8
8
 
9
- def inspect(file, source, tokens, sexp)
10
- [:if, :elsif, :unless, :while, :until,
11
- :if_mod, :unless_mod, :while_mod, :until_mod].each do |keyword|
12
- each(keyword, sexp) do |s|
13
- if s[1][0] == :paren && s[1][1][0][0] != :assign
14
- positions = all_positions(s[1])
15
- if positions.first.lineno == positions.last.lineno
16
- add_offence(:convention, positions.first.lineno, ERROR_MESSAGE)
17
- end
18
- end
9
+ def inspect(source, tokens, ast, comments)
10
+ on_node([:if, :while, :until], ast) do |node|
11
+ cond, _body = *node
12
+
13
+ cond_source = cond.loc.expression.source
14
+
15
+ if cond_source.start_with?('(') && cond_source.end_with?(')')
16
+ add_offence(:convetion,
17
+ cond.loc.line,
18
+ MSG)
19
19
  end
20
20
  end
21
21
  end
@@ -3,16 +3,16 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class PercentR < Cop
6
- ERROR_MESSAGE = 'Use %r only for regular expressions matching more ' +
6
+ MSG = 'Use %r only for regular expressions matching more ' +
7
7
  "than one '/' character."
8
8
 
9
- def inspect(file, source, tokens, sexp)
10
- tokens.each_cons(2) do |t1, t2|
11
- if t1.type == :on_regexp_beg && t1.text =~ /^%r/ &&
12
- t2.text !~ %r(/.*/)
13
- add_offence(:convention, t1.pos.lineno, ERROR_MESSAGE)
14
- end
9
+ def on_regexp(node)
10
+ if node.loc.begin.source != '/' &&
11
+ node.loc.expression.source[1...-1].scan(/\//).size <= 1
12
+ add_offence(:convention, node.loc.line, MSG)
15
13
  end
14
+
15
+ super
16
16
  end
17
17
  end
18
18
  end
@@ -3,64 +3,26 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class ReduceArguments < Cop
6
- ERROR_MESSAGE = 'Name reduce arguments |a, e| (accumulator, element)'
6
+ MSG = 'Name reduce arguments |a, e| (accumulator, element)'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- find_reduce_blocks(tokens).each do |reduce_block|
10
- l_ix, r_ix = reduce_block
11
- unless arguments_named_properly?(l_ix, r_ix, tokens)
12
- add_offence(:convention, tokens[l_ix].pos.lineno, ERROR_MESSAGE)
13
- end
14
- end
15
- end
16
-
17
- private
18
-
19
- def arguments_named_properly?(l_ix, r_ix, tokens)
20
- a, e = false, false
21
- tokens[l_ix..r_ix].each do |t|
22
- if a == true && [t.type, t.text] == [:on_ident, 'e']
23
- e = true
24
- elsif [t.type, t.text] == [:on_ident, 'a']
25
- a = true
26
- end
27
- end
28
- a && e
29
- end
8
+ ARGS_NODE = s(:args, s(:arg, :a), s(:arg, :e))
30
9
 
31
- def find_reduce_blocks(tokens)
32
- blocks = []
33
- tokens.each_with_index do |t, ix|
34
- if [t.type, t.text] == [:on_ident, 'reduce']
35
- # Make sure we didn't select a :reduce symbol
36
- next if tokens[ix - 1].text == ':'
10
+ def on_block(node)
11
+ # we care only for single line blocks
12
+ return unless Util.block_length(node) == 0
37
13
 
38
- block = find_brace_block(tokens, ix)
39
- blocks << block if block
40
- end
41
- end
42
- blocks
43
- end
14
+ method_node, args_node, _body_node = *node
15
+ receiver, method_name, _method_args = *method_node
44
16
 
45
- def find_brace_block(tokens, reduce_ix)
46
- stack = []
47
- block = false
17
+ # discard other scenarios
18
+ return unless receiver
19
+ return unless [:reduce, :inject].include?(method_name)
48
20
 
49
- # When we find the braces we need to add reduce_ix in order to
50
- # find the real tokens index, since we're looping through a subset
51
- tokens[reduce_ix..-1].each_with_index do |t, ix|
52
- break if t.pos.lineno != tokens[reduce_ix].pos.lineno
53
- if [:on_lbrace, :on_tlambeg].include? t.type
54
- stack.push ix + reduce_ix
55
- elsif t.type == :on_rbrace
56
- left_ix = stack.pop
57
- ix += reduce_ix
58
- block = [left_ix, ix] if (stack.empty? &&
59
- tokens[left_ix].type != :on_tlambeg)
60
- end
21
+ unless args_node == ARGS_NODE
22
+ add_offence(:convention, node.loc.line, MSG)
61
23
  end
62
24
 
63
- block
25
+ super
64
26
  end
65
27
  end
66
28
  end
@@ -3,39 +3,23 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class RescueException < Cop
6
- ERROR_MESSAGE = 'Avoid rescuing the Exception class.'
6
+ MSG = 'Avoid rescuing the Exception class.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- each(:rescue, sexp) do |s|
10
- # TODO Improve handling of rescue One, Two => e
11
- if valid_case?(s)
12
- target_class = s[1][0][1][1]
13
-
14
- lineno = s[1][0][1][2].lineno
15
-
16
- add_offence(:warning,
17
- lineno,
18
- ERROR_MESSAGE) if target_class == 'Exception'
19
- end
8
+ def on_resbody(node)
9
+ return unless node.children.first
10
+ rescue_args = node.children.first.children
11
+ if rescue_args.any? { |a| targets_exception?(a) }
12
+ add_offence(:warning, node.location.line, MSG)
20
13
  end
14
+
15
+ super
21
16
  end
22
17
 
23
- def valid_case?(s)
24
- if s[1].nil?
25
- # rescue with no args
26
- false
27
- elsif s[1][0] == :mrhs_new_from_args
28
- # rescue One, Two => e
29
- false
30
- elsif s[1][0][0] == :const_path_ref
31
- # rescue Module::Class
32
- false
33
- elsif s[1][0] == :mrhs_add_star
34
- # rescue *ERRORS
35
- false
36
- else
37
- true
38
- end
18
+ def targets_exception?(rescue_arg_node)
19
+ return false unless rescue_arg_node.type == :const
20
+ namespace, klass_name = *rescue_arg_node
21
+ return false unless namespace.nil? || namespace.type == :cbase
22
+ klass_name == :Exception
39
23
  end
40
24
  end
41
25
  end
@@ -3,16 +3,13 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class RescueModifier < Cop
6
- ERROR_MESSAGE = 'Avoid using rescue in its modifier form.'
7
-
8
- def inspect(file, source, tokens, sexp)
9
- each(:rescue_mod, sexp) do |s|
10
- ident = find_first(:@ident, s)
11
- lineno = ident ? ident[2].lineno : nil
6
+ MSG = 'Avoid using rescue in its modifier form.'
12
7
 
8
+ def inspect(source, tokens, ast, comments)
9
+ on_node(:rescue, ast, :begin) do |s|
13
10
  add_offence(:convention,
14
- lineno,
15
- ERROR_MESSAGE) if lineno
11
+ s.loc.line,
12
+ MSG)
16
13
  end
17
14
  end
18
15
  end
@@ -3,86 +3,27 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class Semicolon < Cop
6
- ERROR_MESSAGE = 'Do not use semicolons to terminate expressions.'
6
+ MSG = 'Do not use semicolons to terminate expressions.'
7
7
 
8
- def inspect(file, source, tokens, sexp)
9
- @tokens = tokens
10
- already_checked_line = nil
11
- tokens.each_with_index do |t, ix|
12
- if t.type == :on_semicolon
13
- next if t.pos.lineno == already_checked_line # fast-forward
14
- token_1_ix = index_of_first_token_on_line(ix, t.pos.lineno)
15
- if %w(def class module).include?(tokens[token_1_ix].text)
16
- handle_exceptions_to_the_rule(token_1_ix)
17
- if source[t.pos.lineno - 1] =~ /;\s*(#.*)?$/
18
- # Semicolons at end of a lines are always reported.
19
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
20
- end
21
- # When dealing with these one line definitions, we check
22
- # the whole line at once. That's why we use the variable
23
- # already_checked_line to know when to fast-forward past
24
- # the current line.
25
- already_checked_line = t.pos.lineno
26
- else
27
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
28
- end
29
- end
30
- end
31
- end
8
+ def inspect(source, tokens, ast, comments)
9
+ on_node(:begin, ast) do |node|
10
+ exprs = node.children
32
11
 
33
- def index_of_first_token_on_line(ix, lineno)
34
- # Index of last token on the previous line
35
- prev_line_ix =
36
- @tokens[0...ix].rindex { |t| t.pos.lineno < lineno } || -1
37
- first = prev_line_ix + 1
38
- # Index of first non-whitespace token on the current line.
39
- first + @tokens[first..ix].index { |t| !whitespace?(t) }
40
- end
12
+ next if exprs.size < 2
13
+
14
+ # create a map matching lines to the number of expressions on them
15
+ exprs_lines = exprs.map { |e| e.loc.expression.line }
16
+ lines = exprs_lines.group_by { |i| i }
41
17
 
42
- def handle_exceptions_to_the_rule(token_1_ix)
43
- # We only do further checking of the def case, which means
44
- # that there are some cases of semicolon usage within
45
- # non-empty one-line class or method definitions that we don't
46
- # catch, but these should be rare.
47
- if @tokens[token_1_ix].text == 'def'
48
- state = :initial
49
- @tokens[token_1_ix..-1].each do |t|
50
- state = next_state(state, t) || state
51
- break if t.text == 'end'
18
+ # every line with more than 1 expression on it is an offence
19
+ lines.each do |line, expr_on_line|
20
+ add_offence(:convention, line, MSG) if expr_on_line.size > 1
52
21
  end
53
22
  end
54
- end
55
-
56
- def next_state(state, token)
57
- return nil if whitespace?(token) # no state change for whitespace
58
23
 
59
- case state
60
- when :initial
61
- :def_kw if token.type == :on_kw
62
- when :def_kw
63
- :method_name if token.type == :on_ident
64
- when :method_name
65
- case token.type
66
- when :on_lparen then :inside_param_list
67
- when :on_semicolon then :method_body
68
- end
69
- when :inside_param_list
70
- :right_after_param_list if token.type == :on_rparen
71
- when :right_after_param_list
72
- if token.type == :on_semicolon
73
- unless Semicolon.config['AllowAfterParameterListInOneLineMethods']
74
- add_offence(:convention, token.pos.lineno, ERROR_MESSAGE)
75
- end
76
- end
77
- :method_body
78
- when :method_body
79
- :semicolon_used if token.type == :on_semicolon
80
- when :semicolon_used
81
- if token.text != 'end' ||
82
- !Semicolon.config['AllowBeforeEndInOneLineMethods']
83
- add_offence(:convention, token.pos.lineno, ERROR_MESSAGE)
84
- end
85
- :method_body
24
+ # not pretty reliable, but the best we can do for now
25
+ source.each_with_index do |line, index|
26
+ add_offence(:convention, index, MSG) if line =~ /;\s*\z/
86
27
  end
87
28
  end
88
29
  end