rubocop 0.12.0 → 0.13.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 (279) hide show
  1. data/CHANGELOG.md +40 -0
  2. data/README.md +49 -8
  3. data/config/default.yml +40 -0
  4. data/config/enabled.yml +37 -9
  5. data/lib/rubocop.rb +24 -10
  6. data/lib/rubocop/cli.rb +41 -106
  7. data/lib/rubocop/config.rb +3 -2
  8. data/lib/rubocop/cop/commissioner.rb +15 -5
  9. data/lib/rubocop/cop/cop.rb +47 -32
  10. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  11. data/lib/rubocop/cop/lint/block_alignment.rb +30 -9
  12. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  13. data/lib/rubocop/cop/lint/end_alignment.rb +4 -4
  14. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  15. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  16. data/lib/rubocop/cop/lint/eval.rb +1 -3
  17. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  18. data/lib/rubocop/cop/lint/literal_in_condition.rb +6 -4
  19. data/lib/rubocop/cop/lint/loop.rb +1 -1
  20. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  21. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  22. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -8
  23. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  24. data/lib/rubocop/cop/lint/useless_assignment.rb +57 -60
  25. data/lib/rubocop/cop/lint/useless_comparison.rb +1 -1
  26. data/lib/rubocop/cop/lint/useless_setter_call.rb +85 -0
  27. data/lib/rubocop/cop/lint/void.rb +6 -8
  28. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -1
  29. data/lib/rubocop/cop/rails/read_attribute.rb +1 -1
  30. data/lib/rubocop/cop/rails/validation.rb +1 -1
  31. data/lib/rubocop/cop/style/access_control.rb +4 -6
  32. data/lib/rubocop/cop/style/alias.rb +1 -3
  33. data/lib/rubocop/cop/style/align_array.rb +47 -0
  34. data/lib/rubocop/cop/style/align_hash.rb +145 -0
  35. data/lib/rubocop/cop/style/align_parameters.rb +9 -3
  36. data/lib/rubocop/cop/style/and_or.rb +3 -4
  37. data/lib/rubocop/cop/style/ascii_comments.rb +1 -3
  38. data/lib/rubocop/cop/style/ascii_identifiers.rb +1 -1
  39. data/lib/rubocop/cop/style/attr.rb +1 -4
  40. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  41. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  42. data/lib/rubocop/cop/style/block_nesting.rb +2 -2
  43. data/lib/rubocop/cop/style/blocks.rb +14 -2
  44. data/lib/rubocop/cop/style/case_equality.rb +1 -3
  45. data/lib/rubocop/cop/style/case_indentation.rb +1 -1
  46. data/lib/rubocop/cop/style/character_literal.rb +1 -2
  47. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +1 -1
  48. data/lib/rubocop/cop/style/class_methods.rb +1 -3
  49. data/lib/rubocop/cop/style/{avoid_class_vars.rb → class_vars.rb} +6 -2
  50. data/lib/rubocop/cop/style/collection_methods.rb +7 -9
  51. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  52. data/lib/rubocop/cop/style/comment_annotation.rb +6 -6
  53. data/lib/rubocop/cop/style/constant_name.rb +1 -3
  54. data/lib/rubocop/cop/style/def_parentheses.rb +4 -12
  55. data/lib/rubocop/cop/style/documentation.rb +2 -2
  56. data/lib/rubocop/cop/style/dot_position.rb +2 -4
  57. data/lib/rubocop/cop/style/empty_line_between_defs.rb +21 -6
  58. data/lib/rubocop/cop/style/empty_lines.rb +1 -1
  59. data/lib/rubocop/cop/style/empty_literal.rb +3 -12
  60. data/lib/rubocop/cop/style/encoding.rb +6 -6
  61. data/lib/rubocop/cop/style/end_block.rb +1 -1
  62. data/lib/rubocop/cop/style/end_of_line.rb +5 -5
  63. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  64. data/lib/rubocop/cop/style/favor_join.rb +1 -3
  65. data/lib/rubocop/cop/style/favor_modifier.rb +7 -3
  66. data/lib/rubocop/cop/style/favor_sprintf.rb +1 -1
  67. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -1
  68. data/lib/rubocop/cop/style/final_newline.rb +23 -0
  69. data/lib/rubocop/cop/style/{avoid_for.rb → for.rb} +2 -2
  70. data/lib/rubocop/cop/style/{avoid_global_vars.rb → global_vars.rb} +19 -6
  71. data/lib/rubocop/cop/style/hash_methods.rb +3 -5
  72. data/lib/rubocop/cop/style/hash_syntax.rb +4 -4
  73. data/lib/rubocop/cop/style/if_then_else.rb +1 -1
  74. data/lib/rubocop/cop/style/indentation_width.rb +4 -4
  75. data/lib/rubocop/cop/style/lambda.rb +2 -2
  76. data/lib/rubocop/cop/style/leading_comment_space.rb +1 -1
  77. data/lib/rubocop/cop/style/line_length.rb +7 -8
  78. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +1 -1
  79. data/lib/rubocop/cop/style/method_call_parentheses.rb +1 -4
  80. data/lib/rubocop/cop/style/method_length.rb +4 -4
  81. data/lib/rubocop/cop/style/module_function.rb +1 -3
  82. data/lib/rubocop/cop/style/multiline_block_chain.rb +44 -0
  83. data/lib/rubocop/cop/style/nil_comparison.rb +1 -3
  84. data/lib/rubocop/cop/style/not.rb +1 -1
  85. data/lib/rubocop/cop/style/numeric_literals.rb +26 -6
  86. data/lib/rubocop/cop/style/op_method.rb +2 -2
  87. data/lib/rubocop/cop/style/parameter_lists.rb +4 -4
  88. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  89. data/lib/rubocop/cop/style/perl_backrefs.rb +26 -0
  90. data/lib/rubocop/cop/style/proc.rb +1 -3
  91. data/lib/rubocop/cop/style/reduce_arguments.rb +7 -5
  92. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  93. data/lib/rubocop/cop/style/redundant_return.rb +9 -2
  94. data/lib/rubocop/cop/style/redundant_self.rb +9 -2
  95. data/lib/rubocop/cop/style/regexp_literal.rb +7 -8
  96. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  97. data/lib/rubocop/cop/style/semicolon.rb +10 -10
  98. data/lib/rubocop/cop/style/signal_exception.rb +2 -4
  99. data/lib/rubocop/cop/style/single_line_methods.rb +2 -4
  100. data/lib/rubocop/cop/style/space_after_comma_etc.rb +1 -1
  101. data/lib/rubocop/cop/style/space_after_control_keyword.rb +1 -1
  102. data/lib/rubocop/cop/style/space_after_method_name.rb +1 -1
  103. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +34 -0
  104. data/lib/rubocop/cop/style/{avoid_perlisms.rb → special_global_vars.rb} +17 -8
  105. data/lib/rubocop/cop/style/string_literals.rb +1 -2
  106. data/lib/rubocop/cop/style/surrounding_space.rb +9 -8
  107. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  108. data/lib/rubocop/cop/style/symbol_name.rb +9 -2
  109. data/lib/rubocop/cop/style/tab.rb +5 -5
  110. data/lib/rubocop/cop/style/ternary_operator.rb +2 -6
  111. data/lib/rubocop/cop/style/trailing_blank_lines.rb +32 -0
  112. data/lib/rubocop/cop/style/trailing_whitespace.rb +5 -6
  113. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  114. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  115. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -3
  116. data/lib/rubocop/cop/style/when_then.rb +1 -4
  117. data/lib/rubocop/cop/style/while_until_do.rb +7 -5
  118. data/lib/rubocop/cop/style/word_array.rb +1 -1
  119. data/lib/rubocop/cop/team.rb +100 -0
  120. data/lib/rubocop/cop/variable_inspector.rb +323 -235
  121. data/lib/rubocop/cop/variable_inspector/assignment.rb +103 -0
  122. data/lib/rubocop/cop/variable_inspector/locatable.rb +162 -0
  123. data/lib/rubocop/cop/variable_inspector/reference.rb +31 -0
  124. data/lib/rubocop/cop/variable_inspector/scope.rb +70 -0
  125. data/lib/rubocop/cop/variable_inspector/variable.rb +87 -0
  126. data/lib/rubocop/cop/variable_inspector/variable_table.rb +129 -0
  127. data/lib/rubocop/formatter/json_formatter.rb +8 -8
  128. data/lib/rubocop/formatter/progress_formatter.rb +4 -4
  129. data/lib/rubocop/processed_source.rb +22 -1
  130. data/lib/rubocop/version.rb +1 -1
  131. data/rubocop.gemspec +1 -1
  132. data/spec/rubocop/cli_spec.rb +32 -30
  133. data/spec/rubocop/config_spec.rb +4 -6
  134. data/spec/rubocop/cop/commissioner_spec.rb +4 -5
  135. data/spec/rubocop/cop/cop_spec.rb +8 -26
  136. data/spec/rubocop/cop/lint/assignment_in_condition_spec.rb +5 -9
  137. data/spec/rubocop/cop/lint/block_alignment_spec.rb +105 -57
  138. data/spec/rubocop/cop/lint/empty_ensure_spec.rb +1 -1
  139. data/spec/rubocop/cop/lint/end_alignment_spec.rb +1 -1
  140. data/spec/rubocop/cop/lint/end_in_method_spec.rb +1 -1
  141. data/spec/rubocop/cop/lint/ensure_return_spec.rb +1 -1
  142. data/spec/rubocop/cop/lint/eval_spec.rb +3 -3
  143. data/spec/rubocop/cop/lint/handle_exceptions_spec.rb +2 -2
  144. data/spec/rubocop/cop/lint/literal_in_condition_spec.rb +1 -1
  145. data/spec/rubocop/cop/lint/loop_spec.rb +1 -1
  146. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +1 -1
  147. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +5 -5
  148. data/spec/rubocop/cop/lint/unreachable_code_spec.rb +1 -1
  149. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +1545 -108
  150. data/spec/rubocop/cop/lint/useless_comparison_spec.rb +1 -1
  151. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +101 -0
  152. data/spec/rubocop/cop/lint/void_spec.rb +1 -1
  153. data/spec/rubocop/cop/offence_spec.rb +4 -4
  154. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +1 -1
  155. data/spec/rubocop/cop/rails/read_attribute_spec.rb +1 -1
  156. data/spec/rubocop/cop/rails/validation_spec.rb +1 -1
  157. data/spec/rubocop/cop/style/access_control_spec.rb +20 -20
  158. data/spec/rubocop/cop/style/alias_spec.rb +3 -3
  159. data/spec/rubocop/cop/style/align_array_spec.rb +62 -0
  160. data/spec/rubocop/cop/style/align_hash_spec.rb +267 -0
  161. data/spec/rubocop/cop/style/align_parameters_spec.rb +2 -2
  162. data/spec/rubocop/cop/style/and_or_spec.rb +1 -1
  163. data/spec/rubocop/cop/style/ascii_comments_spec.rb +2 -2
  164. data/spec/rubocop/cop/style/ascii_identifiers_spec.rb +2 -2
  165. data/spec/rubocop/cop/style/attr_spec.rb +1 -1
  166. data/spec/rubocop/cop/style/begin_block_spec.rb +1 -1
  167. data/spec/rubocop/cop/style/block_comments_spec.rb +1 -1
  168. data/spec/rubocop/cop/style/block_nesting_spec.rb +3 -3
  169. data/spec/rubocop/cop/style/blocks_spec.rb +25 -1
  170. data/spec/rubocop/cop/style/case_equality_spec.rb +1 -1
  171. data/spec/rubocop/cop/style/case_indentation_spec.rb +5 -5
  172. data/spec/rubocop/cop/style/character_literal_spec.rb +1 -1
  173. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +1 -1
  174. data/spec/rubocop/cop/style/class_methods_spec.rb +1 -1
  175. data/spec/rubocop/cop/style/class_vars_spec.rb +25 -0
  176. data/spec/rubocop/cop/style/collection_methods_spec.rb +5 -6
  177. data/spec/rubocop/cop/style/colon_method_call_spec.rb +0 -3
  178. data/spec/rubocop/cop/style/comment_annotation_spec.rb +20 -18
  179. data/spec/rubocop/cop/style/constant_name_spec.rb +1 -1
  180. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +1 -1
  181. data/spec/rubocop/cop/style/def_without_parentheses_spec.rb +1 -1
  182. data/spec/rubocop/cop/style/documentation_spec.rb +1 -1
  183. data/spec/rubocop/cop/style/dot_position_spec.rb +5 -5
  184. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +35 -4
  185. data/spec/rubocop/cop/style/empty_lines_spec.rb +1 -1
  186. data/spec/rubocop/cop/style/empty_literal_spec.rb +7 -7
  187. data/spec/rubocop/cop/style/encoding_spec.rb +11 -5
  188. data/spec/rubocop/cop/style/end_block_spec.rb +1 -1
  189. data/spec/rubocop/cop/style/end_of_line_spec.rb +4 -3
  190. data/spec/rubocop/cop/style/even_odd_spec.rb +1 -1
  191. data/spec/rubocop/cop/style/favor_join_spec.rb +2 -2
  192. data/spec/rubocop/cop/style/favor_modifier_spec.rb +13 -10
  193. data/spec/rubocop/cop/style/favor_sprintf_spec.rb +4 -4
  194. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
  195. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +4 -4
  196. data/spec/rubocop/cop/style/final_newline_spec.rb +25 -0
  197. data/spec/rubocop/cop/style/{avoid_for_spec.rb → for_spec.rb} +8 -12
  198. data/spec/rubocop/cop/style/{avoid_global_vars_spec.rb → global_vars_spec.rb} +13 -3
  199. data/spec/rubocop/cop/style/hash_methods_spec.rb +1 -1
  200. data/spec/rubocop/cop/style/hash_syntax_spec.rb +20 -9
  201. data/spec/rubocop/cop/style/if_with_semicolon_spec.rb +3 -3
  202. data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -19
  203. data/spec/rubocop/cop/style/lambda_spec.rb +6 -6
  204. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +1 -1
  205. data/spec/rubocop/cop/style/line_length_spec.rb +3 -3
  206. data/spec/rubocop/cop/style/method_and_variable_snake_case_spec.rb +8 -9
  207. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +1 -1
  208. data/spec/rubocop/cop/style/method_length_spec.rb +18 -17
  209. data/spec/rubocop/cop/style/module_function_spec.rb +1 -1
  210. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +84 -0
  211. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
  212. data/spec/rubocop/cop/style/nil_comparison_spec.rb +1 -1
  213. data/spec/rubocop/cop/style/not_spec.rb +1 -1
  214. data/spec/rubocop/cop/style/numeric_literals_spec.rb +15 -25
  215. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -2
  216. data/spec/rubocop/cop/style/op_method_spec.rb +3 -3
  217. data/spec/rubocop/cop/style/parameter_lists_spec.rb +5 -5
  218. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +4 -8
  219. data/spec/rubocop/cop/style/perl_backrefs_spec.rb +23 -0
  220. data/spec/rubocop/cop/style/proc_spec.rb +1 -1
  221. data/spec/rubocop/cop/style/reduce_arguments_spec.rb +18 -11
  222. data/spec/rubocop/cop/style/redundant_begin_spec.rb +1 -1
  223. data/spec/rubocop/cop/style/redundant_return_spec.rb +16 -1
  224. data/spec/rubocop/cop/style/redundant_self_spec.rb +6 -1
  225. data/spec/rubocop/cop/style/regexp_literal_spec.rb +19 -23
  226. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +3 -3
  227. data/spec/rubocop/cop/style/semicolon_spec.rb +3 -3
  228. data/spec/rubocop/cop/style/signal_exception_spec.rb +1 -1
  229. data/spec/rubocop/cop/style/single_line_methods_spec.rb +22 -18
  230. data/spec/rubocop/cop/style/space_after_colon_spec.rb +4 -4
  231. data/spec/rubocop/cop/style/space_after_comma_spec.rb +4 -4
  232. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +1 -1
  233. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +1 -1
  234. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +3 -3
  235. data/spec/rubocop/cop/style/space_around_braces_spec.rb +13 -12
  236. data/spec/rubocop/cop/style/space_around_equals_in_default_parameter_spec.rb +3 -3
  237. data/spec/rubocop/cop/style/space_around_operators_spec.rb +25 -25
  238. data/spec/rubocop/cop/style/space_before_modifier_keyword_spec.rb +53 -0
  239. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +9 -9
  240. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +47 -61
  241. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +4 -4
  242. data/spec/rubocop/cop/style/special_global_vars_spec.rb +52 -0
  243. data/spec/rubocop/cop/style/string_literals_spec.rb +5 -5
  244. data/spec/rubocop/cop/style/symbol_array_spec.rb +1 -1
  245. data/spec/rubocop/cop/style/symbol_name_spec.rb +27 -18
  246. data/spec/rubocop/cop/style/tab_spec.rb +1 -1
  247. data/spec/rubocop/cop/style/ternary_operator_spec.rb +2 -2
  248. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +24 -0
  249. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +7 -7
  250. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +6 -14
  251. data/spec/rubocop/cop/style/unless_else_spec.rb +3 -3
  252. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +5 -5
  253. data/spec/rubocop/cop/style/when_then_spec.rb +15 -15
  254. data/spec/rubocop/cop/style/while_until_do_spec.rb +3 -3
  255. data/spec/rubocop/cop/style/word_array_spec.rb +1 -1
  256. data/spec/rubocop/cop/team_spec.rb +158 -0
  257. data/spec/rubocop/cop/variable_inspector/assignment_spec.rb +217 -0
  258. data/spec/rubocop/cop/variable_inspector/locatable_spec.rb +740 -0
  259. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +191 -0
  260. data/spec/rubocop/cop/variable_inspector/variable_spec.rb +79 -0
  261. data/spec/rubocop/cop/variable_inspector/variable_table_spec.rb +275 -0
  262. data/spec/rubocop/cop/variable_inspector_spec.rb +13 -533
  263. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +4 -4
  264. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +1 -1
  265. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +3 -3
  266. data/spec/rubocop/formatter/file_list_formatter_spec.rb +3 -3
  267. data/spec/rubocop/formatter/progress_formatter_spec.rb +1 -1
  268. data/spec/spec_helper.rb +5 -1
  269. data/spec/support/ast_helper.rb +15 -0
  270. data/spec/support/shared_context.rb +18 -0
  271. data/spec/support/shared_examples.rb +1 -1
  272. metadata +95 -32
  273. checksums.yaml +0 -7
  274. data/lib/rubocop/cop/lint/unused_local_variable.rb +0 -32
  275. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +0 -19
  276. data/spec/rubocop/cop/lint/unused_local_variable_spec.rb +0 -588
  277. data/spec/rubocop/cop/style/avoid_class_vars_spec.rb +0 -27
  278. data/spec/rubocop/cop/style/avoid_perl_backrefs_spec.rb +0 -20
  279. data/spec/rubocop/cop/style/avoid_perlisms_spec.rb +0 -47
@@ -31,7 +31,7 @@ module Rubocop
31
31
  puts "configuration from #{path}" if debug?
32
32
  contains_auto_generated_config = false
33
33
 
34
- base_configs(path, hash['inherit_from']).reverse.each do |base_config|
34
+ base_configs(path, hash['inherit_from']).reverse_each do |base_config|
35
35
  if File.basename(base_config.loaded_path) == DOTFILE
36
36
  make_excludes_absolute(base_config)
37
37
  end
@@ -179,11 +179,12 @@ module Rubocop
179
179
  end
180
180
 
181
181
  def for_cop(cop)
182
+ cop = cop.cop_name if cop.respond_to?(:cop_name)
182
183
  self[cop]
183
184
  end
184
185
 
185
186
  def cop_enabled?(cop)
186
- self[cop].nil? || self[cop]['Enabled']
187
+ for_cop(cop).nil? || for_cop(cop)['Enabled']
187
188
  end
188
189
 
189
190
  def warn_unless_valid
@@ -38,8 +38,9 @@ module Rubocop
38
38
  class_eval <<-EOS
39
39
  def #{callback}(node)
40
40
  @cops.each do |cop|
41
- if cop.respond_to?(:#{callback})
42
- delegate_to(cop, :#{callback}, node)
41
+ next unless cop.respond_to?(:#{callback})
42
+ with_cop_error_handling(cop) do
43
+ cop.send(:#{callback}, node)
43
44
  end
44
45
  end
45
46
 
@@ -50,6 +51,7 @@ module Rubocop
50
51
 
51
52
  def investigate(processed_source)
52
53
  reset_errors
54
+ prepare(processed_source)
53
55
  invoke_cops_callback(processed_source)
54
56
  process(processed_source.ast) if processed_source.ast
55
57
  @cops.reduce([]) do |offences, cop|
@@ -64,18 +66,26 @@ module Rubocop
64
66
  @errors = Hash.new { |hash, k| hash[k] = [] }
65
67
  end
66
68
 
69
+ # TODO: Bad design.
70
+ def prepare(processed_source)
71
+ @cops.each { |cop| cop.processed_source = processed_source }
72
+ end
73
+
67
74
  # There are cops that require their own custom processing.
68
75
  # If they define the #investigate method all input parameters passed
69
76
  # to the commissioner will be passed to the cop too in order to do
70
77
  # its own processing.
71
78
  def invoke_cops_callback(processed_source)
72
79
  @cops.each do |cop|
73
- cop.investigate(processed_source) if cop.respond_to?(:investigate)
80
+ next unless cop.respond_to?(:investigate)
81
+ with_cop_error_handling(cop) do
82
+ cop.investigate(processed_source)
83
+ end
74
84
  end
75
85
  end
76
86
 
77
- def delegate_to(cop, callback, node)
78
- cop.send callback, node
87
+ def with_cop_error_handling(cop)
88
+ yield
79
89
  rescue => e
80
90
  if @options[:raise_error]
81
91
  raise e
@@ -46,18 +46,10 @@ module Rubocop
46
46
  + - * / % ** ~ +@ -@ [] []= ! != !~
47
47
  ).map(&:to_sym) + [:'`']
48
48
 
49
- attr_accessor :offences
50
- attr_accessor :debug
51
- attr_accessor :autocorrect
52
- attr_writer :disabled_lines
53
- attr_reader :corrections
49
+ attr_reader :config, :offences, :corrections
50
+ attr_accessor :processed_source # TODO: Bad design.
54
51
 
55
52
  @all = CopStore.new
56
- @config = {}
57
-
58
- class << self
59
- attr_accessor :config
60
- end
61
53
 
62
54
  def self.all
63
55
  @all.clone
@@ -83,53 +75,76 @@ module Rubocop
83
75
  cop_type == :lint
84
76
  end
85
77
 
86
- # Extracts the first line out of the description
87
- def self.short_description
88
- desc = full_description
89
- desc ? desc.lines.first.strip : ''
90
- end
91
-
92
- # Gets the full description of the cop or nil if no description is set.
93
- def self.full_description
94
- config['Description']
95
- end
96
-
97
78
  def self.rails?
98
79
  cop_type == :rails
99
80
  end
100
81
 
101
- def initialize
82
+ def initialize(config = nil, options = nil)
83
+ @config = config || Config.new
84
+ @options = options || { autocorrect: false, debug: false }
85
+
102
86
  @offences = []
103
- @debug = false
104
- @autocorrect = false
105
- @ignored_nodes = []
106
87
  @corrections = []
88
+ @ignored_nodes = []
107
89
  end
108
90
 
109
- def do_autocorrect(node, *args)
110
- autocorrect_action(node, *args) if autocorrect
91
+ def cop_config
92
+ @config.for_cop(self)
111
93
  end
112
94
 
113
- def autocorrect_action(node, *args)
95
+ def autocorrect?
96
+ @options[:autocorrect]
114
97
  end
115
98
 
116
- def add_offence(severity, location, message)
117
- unless @disabled_lines && @disabled_lines.include?(location.line)
118
- message = debug ? "#{name}: #{message}" : message
99
+ def debug?
100
+ @options[:debug]
101
+ end
102
+
103
+ def autocorrect_action(node)
104
+ end
105
+
106
+ def message(node = nil)
107
+ self.class::MSG
108
+ end
109
+
110
+ def add_offence(severity, node, loc, message = nil)
111
+ location = loc.is_a?(Symbol) ? node.loc.send(loc) : loc
112
+
113
+ unless disabled_line?(location.line)
114
+ message = message ? message : message(node)
115
+ message = debug? ? "#{name}: #{message}" : message
119
116
  @offences << Offence.new(severity, location, message, name)
117
+ autocorrect_action(node) if autocorrect?
120
118
  end
121
119
  end
122
120
 
123
- def name
121
+ def convention(node, location, message = nil)
122
+ add_offence(:convention, node, location, message)
123
+ end
124
+
125
+ def warning(node, location, message = nil)
126
+ add_offence(:warning, node, location, message)
127
+ end
128
+
129
+ def cop_name
124
130
  self.class.cop_name
125
131
  end
126
132
 
133
+ alias_method :name, :cop_name
134
+
127
135
  def ignore_node(node)
128
136
  @ignored_nodes << node
129
137
  end
130
138
 
131
139
  private
132
140
 
141
+ def disabled_line?(line_number)
142
+ return false unless @processed_source
143
+ disabled_lines = @processed_source.disabled_lines_for_cops[name]
144
+ return false unless disabled_lines
145
+ disabled_lines.include?(line_number)
146
+ end
147
+
133
148
  def part_of_ignored_node?(node)
134
149
  expression = node.loc.expression
135
150
  @ignored_nodes.each do |ignored_node|
@@ -35,7 +35,7 @@ module Rubocop
35
35
 
36
36
  # assignment nodes from shorthand ops like ||= don't have operator
37
37
  if asgn_node.type != :begin && asgn_node.loc.operator
38
- add_offence(:warning, asgn_node.loc.operator, MSG)
38
+ warning(asgn_node, :operator)
39
39
  end
40
40
  end
41
41
  end
@@ -46,7 +46,7 @@ module Rubocop
46
46
  end
47
47
 
48
48
  def safe_assignment_allowed?
49
- AssignmentInCondition.config['AllowSafeAssignment']
49
+ cop_config['AllowSafeAssignment']
50
50
  end
51
51
  end
52
52
  end
@@ -12,9 +12,9 @@ module Rubocop
12
12
  # i
13
13
  # end
14
14
  class BlockAlignment < Cop
15
- MSG = 'end at %d, %d is not aligned with %s at %d, %d'
15
+ MSG = 'end at %d, %d is not aligned with %s at %d, %d%s'
16
16
 
17
- def initialize
17
+ def initialize(config = nil, options = nil)
18
18
  super
19
19
  @inspected_blocks = []
20
20
  end
@@ -118,16 +118,37 @@ module Rubocop
118
118
  def check_block_alignment(start_node, block_node)
119
119
  start_loc = start_node.loc.expression
120
120
  end_loc = block_node.loc.end
121
- if block_node.loc.begin.line != end_loc.line &&
122
- start_loc.column != end_loc.column
123
- add_offence(:warning,
124
- end_loc,
125
- sprintf(MSG, end_loc.line, end_loc.column,
126
- start_loc.source.lines.to_a.first.chomp,
127
- start_loc.line, start_loc.column))
121
+ do_loc = block_node.loc.begin # Actually it's either do or {.
122
+ return if do_loc.line == end_loc.line # One-liner, not interesting.
123
+ if start_loc.column != end_loc.column
124
+ # We've found that "end" is not aligned with the start node (which
125
+ # can be a block, a variable assignment, etc). But we also allow
126
+ # the "end" to be aligned with the start of the line where the "do"
127
+ # is, which is a style some people use in multi-line chains of
128
+ # blocks.
129
+ match = /\S.*/.match(do_loc.source_line)
130
+ indentation_of_do_line = match.begin(0)
131
+ if end_loc.column != indentation_of_do_line
132
+ alt_start_msg = if start_loc.line == do_loc.line &&
133
+ start_loc.column == indentation_of_do_line
134
+ ''
135
+ else
136
+ " or #{match[0]} at #{do_loc.line}, " +
137
+ "#{indentation_of_do_line}"
138
+ end
139
+ warning(nil,
140
+ end_loc,
141
+ sprintf(MSG, end_loc.line, end_loc.column,
142
+ start_loc.source.lines.to_a.first.chomp,
143
+ start_loc.line, start_loc.column,
144
+ alt_start_msg))
145
+ end
128
146
  end
129
147
  end
130
148
 
149
+ def message
150
+ end
151
+
131
152
  def already_processed_node?(node)
132
153
  @inspected_blocks.include?(node)
133
154
  end
@@ -10,7 +10,7 @@ module Rubocop
10
10
  def on_ensure(node)
11
11
  _body, ensure_body = *node
12
12
 
13
- add_offence(:warning, node.loc.keyword, MSG) unless ensure_body
13
+ warning(node, :keyword) unless ensure_body
14
14
  end
15
15
  end
16
16
  end
@@ -53,10 +53,10 @@ module Rubocop
53
53
  end_loc = node.loc.end
54
54
 
55
55
  if kw_loc.line != end_loc.line && kw_loc.column != end_loc.column
56
- add_offence(:warning,
57
- end_loc,
58
- sprintf(MSG, end_loc.line, end_loc.column,
59
- kw_loc.source, kw_loc.line, kw_loc.column))
56
+ warning(nil,
57
+ end_loc,
58
+ sprintf(MSG, end_loc.line, end_loc.column,
59
+ kw_loc.source, kw_loc.line, kw_loc.column))
60
60
  end
61
61
  end
62
62
  end
@@ -19,7 +19,7 @@ module Rubocop
19
19
 
20
20
  def check(node)
21
21
  on_node(:postexe, node) do |end_node|
22
- add_offence(:warning, end_node.loc.keyword, MSG)
22
+ warning(end_node, :keyword)
23
23
  end
24
24
  end
25
25
  end
@@ -13,7 +13,7 @@ module Rubocop
13
13
  return unless ensure_body
14
14
 
15
15
  on_node(:return, ensure_body) do |e|
16
- add_offence(:warning, e.loc.expression, MSG)
16
+ warning(e, :expression)
17
17
  end
18
18
  end
19
19
  end
@@ -10,9 +10,7 @@ module Rubocop
10
10
  def on_send(node)
11
11
  receiver, method_name, = *node
12
12
 
13
- if receiver.nil? && method_name == :eval
14
- add_offence(:warning, node.loc.selector, MSG)
15
- end
13
+ warning(node, :selector) if receiver.nil? && method_name == :eval
16
14
  end
17
15
  end
18
16
  end
@@ -10,7 +10,7 @@ module Rubocop
10
10
  def on_resbody(node)
11
11
  _exc_list_node, _exc_var_node, body_node = *node
12
12
 
13
- add_offence(:warning, node.loc.expression, MSG) unless body_node
13
+ warning(node, :expression) unless body_node
14
14
  end
15
15
  end
16
16
  end
@@ -43,6 +43,10 @@ module Rubocop
43
43
  check_for_literal(node)
44
44
  end
45
45
 
46
+ def message(node)
47
+ MSG.format(node.loc.expression.source)
48
+ end
49
+
46
50
  private
47
51
 
48
52
  def check_for_literal(node)
@@ -50,8 +54,7 @@ module Rubocop
50
54
 
51
55
  # if the cond node is literal we obviously have a problem
52
56
  if literal?(cond)
53
- add_offence(:warning, cond.loc.expression,
54
- format(MSG, cond.loc.expression.source))
57
+ warning(cond, :expression)
55
58
  else
56
59
  # alternatively we have to consider a logical node with a
57
60
  # literal argument
@@ -91,8 +94,7 @@ module Rubocop
91
94
 
92
95
  def handle_node(node)
93
96
  if literal?(node)
94
- add_offence(:warning, node.loc.expression,
95
- format(MSG, node.loc.expression.source))
97
+ warning(node, :expression)
96
98
  elsif [:send, :and, :or, :begin].include?(node.type)
97
99
  check_node(node)
98
100
  end
@@ -19,7 +19,7 @@ module Rubocop
19
19
  private
20
20
 
21
21
  def register_offence(node)
22
- add_offence(:warning, node.loc.keyword, MSG)
22
+ warning(node, :keyword)
23
23
  end
24
24
  end
25
25
  end
@@ -37,7 +37,7 @@ module Rubocop
37
37
  Parser::Source::Range.new(expr.source_buffer,
38
38
  expr.begin_pos - space_length,
39
39
  expr.begin_pos)
40
- add_offence(:warning, space_range, MSG)
40
+ warning(nil, space_range)
41
41
  end
42
42
  end
43
43
  end
@@ -11,7 +11,7 @@ module Rubocop
11
11
  return unless node.children.first
12
12
  rescue_args = node.children.first.children
13
13
  if rescue_args.any? { |a| targets_exception?(a) }
14
- add_offence(:warning, node.location.expression, MSG)
14
+ warning(node, :expression)
15
15
  end
16
16
  end
17
17
 
@@ -16,17 +16,14 @@ module Rubocop
16
16
  inspect_variables(processed_source.ast)
17
17
  end
18
18
 
19
- def before_declaring_variable(entry)
20
- # Only block scope can reference outer local variables.
21
- return unless variable_table.current_scope.node.type == :block
22
- return unless ARGUMENT_DECLARATION_TYPES.include?(entry.node.type)
23
- return if entry.name.to_s.start_with?('_')
19
+ def before_declaring_variable(variable)
20
+ return if variable.name.to_s.start_with?('_')
24
21
 
25
- outer_local_variable = variable_table.find_variable_entry(entry.name)
22
+ outer_local_variable = variable_table.find_variable(variable.name)
26
23
  return unless outer_local_variable
27
24
 
28
- message = sprintf(MSG, entry.name)
29
- add_offence(:warning, entry.node.loc.expression, message)
25
+ message = sprintf(MSG, variable.name)
26
+ warning(variable.declaration_node, :expression, message)
30
27
  end
31
28
  end
32
29
  end
@@ -17,7 +17,7 @@ module Rubocop
17
17
 
18
18
  expressions.each_cons(2) do |e1, e2|
19
19
  if NODE_TYPES.include?(e1.type) || flow_command?(e1)
20
- add_offence(:warning, e2.loc.expression, MSG)
20
+ warning(e2, :expression)
21
21
  end
22
22
  end
23
23
  end
@@ -3,87 +3,84 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Lint
6
- # This cop checks for useless assignment as the final expression
7
- # of a function definition.
6
+ # This cop checks for every useless assignment to local variable in every
7
+ # scope.
8
+ # The basic idea for this cop was from the warning of `ruby -cw`:
8
9
  #
9
- # @example
10
+ # assigned but unused variable - foo
10
11
  #
11
- # def something
12
- # x = 5
13
- # end
14
- #
15
- # def something
16
- # x = Something.new
17
- # x.attr = 5
18
- # end
12
+ # Currently this cop has advanced logic that detects unreferenced
13
+ # reassignments and properly handles varied cases such as branch, loop,
14
+ # rescue, ensure, etc.
19
15
  class UselessAssignment < Cop
20
- MSG = 'Useless assignment to local variable %s.'
16
+ include VariableInspector
21
17
 
22
- def on_def(node)
23
- _name, args, body = *node
18
+ MSG = 'Useless assignment to variable - %s'
24
19
 
25
- check_for_useless_assignment(body, args)
20
+ def investigate(processed_source)
21
+ inspect_variables(processed_source.ast)
26
22
  end
27
23
 
28
- def on_defs(node)
29
- _target, _name, args, body = *node
30
-
31
- check_for_useless_assignment(body, args)
24
+ def after_leaving_scope(scope)
25
+ scope.variables.each_value do |variable|
26
+ check_for_unused_assignments(variable)
27
+ check_for_unused_block_local_variable(variable)
28
+ end
32
29
  end
33
30
 
34
- private
31
+ def check_for_unused_assignments(variable)
32
+ return if variable.name.to_s.start_with?('_')
35
33
 
36
- def check_for_useless_assignment(body, args)
37
- return unless body
34
+ variable.assignments.each do |assignment|
35
+ next if assignment.used?
38
36
 
39
- if body.type == :begin
40
- expression = body.children
41
- else
42
- expression = body
43
- end
37
+ message = message_for_useless_assignment(assignment)
38
+
39
+ location = if assignment.regexp_named_capture?
40
+ assignment.node.children.first.loc.expression
41
+ else
42
+ assignment.node.loc.name
43
+ end
44
44
 
45
- last_expr = expression.is_a?(Array) ? expression.last : expression
46
- return unless last_expr
47
-
48
- case last_expr.type
49
- when :lvasgn
50
- var_name, = *last_expr
51
- add_offence(:warning, last_expr.loc.name, MSG.format(var_name))
52
- when :send
53
- receiver, method, _args = *last_expr
54
- return unless receiver
55
- return unless receiver.type == :lvar
56
- return unless method =~ /\w=$/
57
-
58
- var_name, = *receiver
59
- return if contains_object_passed_as_argument?(var_name, body, args)
60
-
61
- add_offence(:warning,
62
- receiver.loc.name,
63
- MSG.format(receiver.loc.name.source))
45
+ warning(nil, location, message)
64
46
  end
65
47
  end
66
48
 
67
- def contains_object_passed_as_argument?(lvar_name, body, args)
68
- variable_table = {}
49
+ def message_for_useless_assignment(assignment)
50
+ variable = assignment.variable
51
+
52
+ message = sprintf(MSG, variable.name)
69
53
 
70
- args.children.each do |arg_node|
71
- arg_name, = *arg_node
72
- variable_table[arg_name] = true
54
+ if assignment.multiple_assignment?
55
+ message << ". Use _ or _#{variable.name} as a variable name " +
56
+ "to indicate that it won't be used."
57
+ elsif assignment.operator_assignment?
58
+ return_value_node = return_value_node_of_scope(variable.scope)
59
+ if assignment.meta_assignment_node.equal?(return_value_node)
60
+ non_assignment_operator = assignment.operator.sub(/=$/, '')
61
+ message << ". Use just operator #{non_assignment_operator}."
62
+ end
73
63
  end
74
64
 
75
- on_node([:lvasgn, :ivasgn, :cvasgn, :gvasgn], body) do |asgn_node|
76
- lhs_var_name, rhs_node = *asgn_node
65
+ message
66
+ end
77
67
 
78
- if [:lvar, :ivar, :cvar, :gvar].include?(rhs_node.type)
79
- rhs_var_name, = *rhs_node
80
- variable_table[lhs_var_name] = variable_table[rhs_var_name]
81
- else
82
- variable_table[lhs_var_name] = false
83
- end
68
+ # TODO: More precise handling (rescue, ensure, nested begin, etc.)
69
+ def return_value_node_of_scope(scope)
70
+ body_node = scope.body_node
71
+
72
+ if body_node.type == :begin
73
+ body_node.children.last
74
+ else
75
+ body_node
84
76
  end
77
+ end
85
78
 
86
- variable_table[lvar_name]
79
+ def check_for_unused_block_local_variable(variable)
80
+ return unless variable.block_local_variable?
81
+ return unless variable.assignments.empty?
82
+ message = sprintf(MSG, variable.name)
83
+ warning(variable.declaration_node, :expression, message)
87
84
  end
88
85
  end
89
86
  end