sabat-rubocop 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. data/.gitignore +50 -0
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +7 -0
  5. data/.yardopts +2 -0
  6. data/CHANGELOG.md +268 -0
  7. data/CONTRIBUTING.md +16 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +324 -0
  11. data/Rakefile +29 -0
  12. data/bin/rubocop +22 -0
  13. data/config/default.yml +58 -0
  14. data/config/disabled.yml +5 -0
  15. data/config/enabled.yml +403 -0
  16. data/lib/rubocop.rb +116 -0
  17. data/lib/rubocop/cli.rb +407 -0
  18. data/lib/rubocop/config.rb +250 -0
  19. data/lib/rubocop/config_store.rb +39 -0
  20. data/lib/rubocop/cop/cop.rb +138 -0
  21. data/lib/rubocop/cop/lint/assignment_in_condition.rb +54 -0
  22. data/lib/rubocop/cop/lint/end_alignment.rb +189 -0
  23. data/lib/rubocop/cop/lint/end_in_method.rb +30 -0
  24. data/lib/rubocop/cop/lint/ensure_return.rb +22 -0
  25. data/lib/rubocop/cop/lint/eval.rb +22 -0
  26. data/lib/rubocop/cop/lint/handle_exceptions.rb +20 -0
  27. data/lib/rubocop/cop/lint/literal_in_condition.rb +81 -0
  28. data/lib/rubocop/cop/lint/loop.rb +29 -0
  29. data/lib/rubocop/cop/lint/rescue_exception.rb +29 -0
  30. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +34 -0
  31. data/lib/rubocop/cop/lint/unreachable_code.rb +35 -0
  32. data/lib/rubocop/cop/lint/unused_local_variable.rb +32 -0
  33. data/lib/rubocop/cop/lint/void.rb +58 -0
  34. data/lib/rubocop/cop/offence.rb +136 -0
  35. data/lib/rubocop/cop/rails/validation.rb +30 -0
  36. data/lib/rubocop/cop/style/access_control.rb +58 -0
  37. data/lib/rubocop/cop/style/alias.rb +28 -0
  38. data/lib/rubocop/cop/style/align_parameters.rb +39 -0
  39. data/lib/rubocop/cop/style/and_or.rb +45 -0
  40. data/lib/rubocop/cop/style/ascii_comments.rb +21 -0
  41. data/lib/rubocop/cop/style/ascii_identifiers.rb +22 -0
  42. data/lib/rubocop/cop/style/attr.rb +20 -0
  43. data/lib/rubocop/cop/style/avoid_class_vars.rb +20 -0
  44. data/lib/rubocop/cop/style/avoid_for.rb +18 -0
  45. data/lib/rubocop/cop/style/avoid_global_vars.rb +65 -0
  46. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +21 -0
  47. data/lib/rubocop/cop/style/avoid_perlisms.rb +50 -0
  48. data/lib/rubocop/cop/style/begin_block.rb +18 -0
  49. data/lib/rubocop/cop/style/block_comments.rb +20 -0
  50. data/lib/rubocop/cop/style/block_nesting.rb +47 -0
  51. data/lib/rubocop/cop/style/blocks.rb +27 -0
  52. data/lib/rubocop/cop/style/case_equality.rb +22 -0
  53. data/lib/rubocop/cop/style/case_indentation.rb +28 -0
  54. data/lib/rubocop/cop/style/character_literal.rb +37 -0
  55. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +33 -0
  56. data/lib/rubocop/cop/style/class_methods.rb +22 -0
  57. data/lib/rubocop/cop/style/collection_methods.rb +56 -0
  58. data/lib/rubocop/cop/style/colon_method_call.rb +29 -0
  59. data/lib/rubocop/cop/style/constant_name.rb +31 -0
  60. data/lib/rubocop/cop/style/def_parentheses.rb +70 -0
  61. data/lib/rubocop/cop/style/documentation.rb +58 -0
  62. data/lib/rubocop/cop/style/dot_position.rb +25 -0
  63. data/lib/rubocop/cop/style/empty_line_between_defs.rb +26 -0
  64. data/lib/rubocop/cop/style/empty_lines.rb +40 -0
  65. data/lib/rubocop/cop/style/empty_literal.rb +53 -0
  66. data/lib/rubocop/cop/style/encoding.rb +29 -0
  67. data/lib/rubocop/cop/style/end_block.rb +18 -0
  68. data/lib/rubocop/cop/style/end_of_line.rb +23 -0
  69. data/lib/rubocop/cop/style/favor_join.rb +29 -0
  70. data/lib/rubocop/cop/style/favor_modifier.rb +118 -0
  71. data/lib/rubocop/cop/style/favor_sprintf.rb +28 -0
  72. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +54 -0
  73. data/lib/rubocop/cop/style/hash_syntax.rb +47 -0
  74. data/lib/rubocop/cop/style/if_then_else.rb +29 -0
  75. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -0
  76. data/lib/rubocop/cop/style/lambda.rb +47 -0
  77. data/lib/rubocop/cop/style/leading_comment_space.rb +25 -0
  78. data/lib/rubocop/cop/style/line_continuation.rb +26 -0
  79. data/lib/rubocop/cop/style/line_length.rb +30 -0
  80. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +61 -0
  81. data/lib/rubocop/cop/style/method_call_parentheses.rb +22 -0
  82. data/lib/rubocop/cop/style/method_length.rb +57 -0
  83. data/lib/rubocop/cop/style/multiline_if_then.rb +47 -0
  84. data/lib/rubocop/cop/style/not.rb +24 -0
  85. data/lib/rubocop/cop/style/numeric_literals.rb +25 -0
  86. data/lib/rubocop/cop/style/one_line_conditional.rb +20 -0
  87. data/lib/rubocop/cop/style/op_method.rb +29 -0
  88. data/lib/rubocop/cop/style/parameter_lists.rb +42 -0
  89. data/lib/rubocop/cop/style/parentheses_around_condition.rb +42 -0
  90. data/lib/rubocop/cop/style/proc.rb +30 -0
  91. data/lib/rubocop/cop/style/reduce_arguments.rb +34 -0
  92. data/lib/rubocop/cop/style/regexp_literal.rb +39 -0
  93. data/lib/rubocop/cop/style/rescue_modifier.rb +55 -0
  94. data/lib/rubocop/cop/style/semicolon.rb +51 -0
  95. data/lib/rubocop/cop/style/single_line_methods.rb +48 -0
  96. data/lib/rubocop/cop/style/space_after_comma_etc.rb +69 -0
  97. data/lib/rubocop/cop/style/space_after_control_keyword.rb +32 -0
  98. data/lib/rubocop/cop/style/string_literals.rb +36 -0
  99. data/lib/rubocop/cop/style/surrounding_space.rb +314 -0
  100. data/lib/rubocop/cop/style/symbol_array.rb +31 -0
  101. data/lib/rubocop/cop/style/symbol_name.rb +27 -0
  102. data/lib/rubocop/cop/style/tab.rb +25 -0
  103. data/lib/rubocop/cop/style/ternary_operator.rb +49 -0
  104. data/lib/rubocop/cop/style/trailing_whitespace.rb +24 -0
  105. data/lib/rubocop/cop/style/trivial_accessors.rb +32 -0
  106. data/lib/rubocop/cop/style/unless_else.rb +26 -0
  107. data/lib/rubocop/cop/style/variable_interpolation.rb +32 -0
  108. data/lib/rubocop/cop/style/when_then.rb +25 -0
  109. data/lib/rubocop/cop/style/while_until_do.rb +45 -0
  110. data/lib/rubocop/cop/style/word_array.rb +44 -0
  111. data/lib/rubocop/cop/util.rb +27 -0
  112. data/lib/rubocop/cop/variable_inspector.rb +280 -0
  113. data/lib/rubocop/formatter/base_formatter.rb +119 -0
  114. data/lib/rubocop/formatter/clang_style_formatter.rb +21 -0
  115. data/lib/rubocop/formatter/emacs_style_formatter.rb +17 -0
  116. data/lib/rubocop/formatter/formatter_set.rb +77 -0
  117. data/lib/rubocop/formatter/json_formatter.rb +76 -0
  118. data/lib/rubocop/formatter/progress_formatter.rb +63 -0
  119. data/lib/rubocop/formatter/simple_text_formatter.rb +62 -0
  120. data/lib/rubocop/version.rb +21 -0
  121. data/rubocop.gemspec +36 -0
  122. data/spec/.rubocop.yml +5 -0
  123. data/spec/project_spec.rb +24 -0
  124. data/spec/rubocop/cli_spec.rb +906 -0
  125. data/spec/rubocop/config_spec.rb +470 -0
  126. data/spec/rubocop/config_store_spec.rb +66 -0
  127. data/spec/rubocop/cops/cop_spec.rb +38 -0
  128. data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +111 -0
  129. data/spec/rubocop/cops/lint/end_alignment_spec.rb +333 -0
  130. data/spec/rubocop/cops/lint/end_in_method_spec.rb +35 -0
  131. data/spec/rubocop/cops/lint/ensure_return_spec.rb +37 -0
  132. data/spec/rubocop/cops/lint/eval_spec.rb +41 -0
  133. data/spec/rubocop/cops/lint/handle_exceptions_spec.rb +36 -0
  134. data/spec/rubocop/cops/lint/literal_in_condition_spec.rb +42 -0
  135. data/spec/rubocop/cops/lint/loop_spec.rb +33 -0
  136. data/spec/rubocop/cops/lint/rescue_exception_spec.rb +127 -0
  137. data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +243 -0
  138. data/spec/rubocop/cops/lint/unreachable_code_spec.rb +69 -0
  139. data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +497 -0
  140. data/spec/rubocop/cops/lint/void_spec.rb +63 -0
  141. data/spec/rubocop/cops/offence_spec.rb +133 -0
  142. data/spec/rubocop/cops/rails/validation_spec.rb +27 -0
  143. data/spec/rubocop/cops/style/access_control_spec.rb +142 -0
  144. data/spec/rubocop/cops/style/alias_spec.rb +47 -0
  145. data/spec/rubocop/cops/style/align_parameters_spec.rb +199 -0
  146. data/spec/rubocop/cops/style/and_or_spec.rb +39 -0
  147. data/spec/rubocop/cops/style/ascii_comments_spec.rb +28 -0
  148. data/spec/rubocop/cops/style/ascii_identifiers_spec.rb +28 -0
  149. data/spec/rubocop/cops/style/attr_spec.rb +20 -0
  150. data/spec/rubocop/cops/style/avoid_class_vars_spec.rb +27 -0
  151. data/spec/rubocop/cops/style/avoid_for_spec.rb +37 -0
  152. data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +34 -0
  153. data/spec/rubocop/cops/style/avoid_perl_backrefs_spec.rb +20 -0
  154. data/spec/rubocop/cops/style/avoid_perlisms_spec.rb +47 -0
  155. data/spec/rubocop/cops/style/begin_block_spec.rb +19 -0
  156. data/spec/rubocop/cops/style/block_comments_spec.rb +27 -0
  157. data/spec/rubocop/cops/style/block_nesting_spec.rb +159 -0
  158. data/spec/rubocop/cops/style/blocks_spec.rb +35 -0
  159. data/spec/rubocop/cops/style/case_equality_spec.rb +18 -0
  160. data/spec/rubocop/cops/style/case_indentation_spec.rb +88 -0
  161. data/spec/rubocop/cops/style/character_literal_spec.rb +28 -0
  162. data/spec/rubocop/cops/style/class_and_module_camel_case_spec.rb +46 -0
  163. data/spec/rubocop/cops/style/class_methods_spec.rb +51 -0
  164. data/spec/rubocop/cops/style/collection_methods_spec.rb +41 -0
  165. data/spec/rubocop/cops/style/colon_method_call_spec.rb +55 -0
  166. data/spec/rubocop/cops/style/constant_name_spec.rb +56 -0
  167. data/spec/rubocop/cops/style/def_with_parentheses_spec.rb +40 -0
  168. data/spec/rubocop/cops/style/def_without_parentheses_spec.rb +34 -0
  169. data/spec/rubocop/cops/style/documentation_spec.rb +79 -0
  170. data/spec/rubocop/cops/style/dot_position_spec.rb +30 -0
  171. data/spec/rubocop/cops/style/empty_line_between_defs_spec.rb +85 -0
  172. data/spec/rubocop/cops/style/empty_lines_spec.rb +40 -0
  173. data/spec/rubocop/cops/style/empty_literal_spec.rb +91 -0
  174. data/spec/rubocop/cops/style/encoding_spec.rb +49 -0
  175. data/spec/rubocop/cops/style/end_block_spec.rb +19 -0
  176. data/spec/rubocop/cops/style/end_of_line_spec.rb +25 -0
  177. data/spec/rubocop/cops/style/favor_join_spec.rb +37 -0
  178. data/spec/rubocop/cops/style/favor_modifier_spec.rb +160 -0
  179. data/spec/rubocop/cops/style/favor_sprintf_spec.rb +53 -0
  180. data/spec/rubocop/cops/style/favor_unless_over_negated_if_spec.rb +64 -0
  181. data/spec/rubocop/cops/style/favor_until_over_negated_while_spec.rb +47 -0
  182. data/spec/rubocop/cops/style/hash_syntax_spec.rb +51 -0
  183. data/spec/rubocop/cops/style/if_with_semicolon_spec.rb +25 -0
  184. data/spec/rubocop/cops/style/lambda_spec.rb +45 -0
  185. data/spec/rubocop/cops/style/leading_comment_space_spec.rb +65 -0
  186. data/spec/rubocop/cops/style/line_continuation_spec.rb +26 -0
  187. data/spec/rubocop/cops/style/line_length_spec.rb +25 -0
  188. data/spec/rubocop/cops/style/method_and_variable_snake_case_spec.rb +95 -0
  189. data/spec/rubocop/cops/style/method_call_parentheses_spec.rb +25 -0
  190. data/spec/rubocop/cops/style/method_length_spec.rb +151 -0
  191. data/spec/rubocop/cops/style/multiline_if_then_spec.rb +97 -0
  192. data/spec/rubocop/cops/style/not_spec.rb +28 -0
  193. data/spec/rubocop/cops/style/numeric_literals_spec.rb +51 -0
  194. data/spec/rubocop/cops/style/one_line_conditional_spec.rb +18 -0
  195. data/spec/rubocop/cops/style/op_method_spec.rb +80 -0
  196. data/spec/rubocop/cops/style/parameter_lists_spec.rb +49 -0
  197. data/spec/rubocop/cops/style/parentheses_around_condition_spec.rb +59 -0
  198. data/spec/rubocop/cops/style/proc_spec.rb +28 -0
  199. data/spec/rubocop/cops/style/reduce_arguments_spec.rb +59 -0
  200. data/spec/rubocop/cops/style/regexp_literal_spec.rb +83 -0
  201. data/spec/rubocop/cops/style/rescue_modifier_spec.rb +122 -0
  202. data/spec/rubocop/cops/style/semicolon_spec.rb +95 -0
  203. data/spec/rubocop/cops/style/single_line_methods_spec.rb +54 -0
  204. data/spec/rubocop/cops/style/space_after_colon_spec.rb +29 -0
  205. data/spec/rubocop/cops/style/space_after_comma_spec.rb +31 -0
  206. data/spec/rubocop/cops/style/space_after_control_keyword_spec.rb +69 -0
  207. data/spec/rubocop/cops/style/space_after_semicolon_spec.rb +24 -0
  208. data/spec/rubocop/cops/style/space_around_braces_spec.rb +49 -0
  209. data/spec/rubocop/cops/style/space_around_equals_in_default_parameter_spec.rb +34 -0
  210. data/spec/rubocop/cops/style/space_around_operators_spec.rb +216 -0
  211. data/spec/rubocop/cops/style/space_inside_brackets_spec.rb +51 -0
  212. data/spec/rubocop/cops/style/space_inside_hash_literal_braces_spec.rb +99 -0
  213. data/spec/rubocop/cops/style/space_inside_parens_spec.rb +33 -0
  214. data/spec/rubocop/cops/style/string_literals_spec.rb +62 -0
  215. data/spec/rubocop/cops/style/symbol_array_spec.rb +45 -0
  216. data/spec/rubocop/cops/style/symbol_name_spec.rb +122 -0
  217. data/spec/rubocop/cops/style/tab_spec.rb +23 -0
  218. data/spec/rubocop/cops/style/ternary_operator_spec.rb +42 -0
  219. data/spec/rubocop/cops/style/trailing_whitespace_spec.rb +29 -0
  220. data/spec/rubocop/cops/style/trivial_accessors_spec.rb +338 -0
  221. data/spec/rubocop/cops/style/unless_else_spec.rb +31 -0
  222. data/spec/rubocop/cops/style/variable_interpolation_spec.rb +53 -0
  223. data/spec/rubocop/cops/style/when_then_spec.rb +40 -0
  224. data/spec/rubocop/cops/style/while_until_do_spec.rb +47 -0
  225. data/spec/rubocop/cops/style/word_array_spec.rb +61 -0
  226. data/spec/rubocop/cops/variable_inspector_spec.rb +374 -0
  227. data/spec/rubocop/formatter/base_formatter_spec.rb +190 -0
  228. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +70 -0
  229. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +32 -0
  230. data/spec/rubocop/formatter/formatter_set_spec.rb +132 -0
  231. data/spec/rubocop/formatter/json_formatter_spec.rb +142 -0
  232. data/spec/rubocop/formatter/progress_formatter_spec.rb +196 -0
  233. data/spec/rubocop/formatter/simple_text_formatter_spec.rb +74 -0
  234. data/spec/spec_helper.rb +92 -0
  235. data/spec/support/file_helper.rb +21 -0
  236. data/spec/support/isolated_environment.rb +27 -0
  237. data/spec/support/mri_syntax_checker.rb +69 -0
  238. data/spec/support/shared_examples.rb +33 -0
  239. metadata +517 -0
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks whether the source file has a
7
+ # utf-8 encoding comment. This check makes sense only
8
+ # in Ruby 1.9, since in 2.0+ utf-8 is the default source file
9
+ # encoding.
10
+ class Encoding < Cop
11
+ MSG = 'Missing utf-8 encoding comment.'
12
+
13
+ def inspect(source_buffer, source, tokens, ast, comments)
14
+ unless RUBY_VERSION >= '2.0.0'
15
+ expected_line = 0
16
+ expected_line += 1 if source[expected_line] =~ /^#!/
17
+ unless source[expected_line] =~ /#.*coding: (UTF|utf)-8/
18
+ add_offence(:convention,
19
+ source_range(source_buffer,
20
+ source[0...expected_line],
21
+ 0, 1),
22
+ MSG)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for END blocks.
7
+ class EndBlock < Cop
8
+ MSG = 'Avoid the use of END blocks. Use `Kernel#at_exit` instead.'
9
+
10
+ def on_postexe(node)
11
+ add_offence(:convention, node.loc.keyword, MSG)
12
+
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for Windows-style line endings in the source code.
7
+ class EndOfLine < Cop
8
+ MSG = 'Carriage return character detected.'
9
+
10
+ def inspect(source_buffer, source, tokens, ast, comments)
11
+ source.each_with_index do |line, index|
12
+ if line =~ /\r$/
13
+ add_offence(:convention,
14
+ source_range(source_buffer, source[0...index],
15
+ line.length - 1, 1),
16
+ MSG)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for uses of "*" as a substitute for *join*.
7
+ #
8
+ # Not all cases can reliably checked, due to Ruby's dynamic
9
+ # types, so we consider only cases when the first argument is an
10
+ # array literal or the second is a string literal.
11
+ class FavorJoin < Cop
12
+ MSG = 'Favor Array#join over Array#*.'
13
+
14
+ def on_send(node)
15
+ receiver_node, method_name, *arg_nodes = *node
16
+
17
+ if receiver_node && receiver_node.type == :array &&
18
+ method_name == :* && arg_nodes[0].type == :str
19
+ add_offence(:convention,
20
+ node.loc.selector,
21
+ MSG)
22
+ end
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Common functionality for modifier cops.
7
+ module FavorModifier
8
+ # TODO extremely ugly solution that needs lots of polish
9
+ def check(sexp, comments)
10
+ case sexp.loc.keyword.source
11
+ when 'if' then cond, body, _else = *sexp
12
+ when 'unless' then cond, _else, body = *sexp
13
+ else cond, body = *sexp
14
+ end
15
+
16
+ if length(sexp) > 3
17
+ false
18
+ else
19
+ body_length = body_length(body)
20
+
21
+ if body_length == 0
22
+ false
23
+ else
24
+ indentation = sexp.loc.keyword.column
25
+ kw_length = sexp.loc.keyword.size
26
+ cond_length = cond.loc.expression.size
27
+ space = 1
28
+ total = indentation + body_length + space + kw_length + space +
29
+ cond_length
30
+ total <= LineLength.max && !body_has_comment?(body, comments)
31
+ end
32
+ end
33
+ end
34
+
35
+ def length(sexp)
36
+ sexp.loc.expression.source.lines.to_a.size
37
+ end
38
+
39
+ def body_length(body)
40
+ if body && body.loc.expression
41
+ body.loc.expression.size
42
+ else
43
+ 0
44
+ end
45
+ end
46
+
47
+ def body_has_comment?(body, comments)
48
+ comment_lines = comments.map(&:location).map(&:line)
49
+ body_line = body.loc.expression.line
50
+ comment_lines.include?(body_line)
51
+ end
52
+ end
53
+
54
+ # Checks for if and unless statements that would fit on one line
55
+ # if written as a modifier if/unless.
56
+ class IfUnlessModifier < Cop
57
+ include FavorModifier
58
+
59
+ def error_message
60
+ 'Favor modifier if/unless usage when you have a single-line body. ' +
61
+ 'Another good alternative is the usage of control flow &&/||.'
62
+ end
63
+
64
+ def inspect(source_buffer, source, tokens, ast, comments)
65
+ return unless ast
66
+ on_node(:if, ast) do |node|
67
+ # discard ternary ops, if/else and modifier if/unless nodes
68
+ return if ternary_op?(node)
69
+ return if modifier_if?(node)
70
+ return if elsif?(node)
71
+ return if if_else?(node)
72
+
73
+ if check(node, comments)
74
+ add_offence(:convention, node.loc.expression, error_message)
75
+ end
76
+ end
77
+ end
78
+
79
+ def ternary_op?(node)
80
+ node.loc.respond_to?(:question)
81
+ end
82
+
83
+ def modifier_if?(node)
84
+ node.loc.end.nil?
85
+ end
86
+
87
+ def elsif?(node)
88
+ node.loc.keyword.is?('elsif')
89
+ end
90
+
91
+ def if_else?(node)
92
+ node.loc.respond_to?(:else) && node.loc.else
93
+ end
94
+ end
95
+
96
+ # Checks for while and until statements that would fit on one line
97
+ # if written as a modifier while/until.
98
+ class WhileUntilModifier < Cop
99
+ include FavorModifier
100
+
101
+ MSG =
102
+ 'Favor modifier while/until usage when you have a single-line body.'
103
+
104
+ def inspect(source_buffer, source, tokens, ast, comments)
105
+ return unless ast
106
+ on_node([:while, :until], ast) do |node|
107
+ # discard modifier while/until
108
+ next unless node.loc.end
109
+
110
+ if check(node, comments)
111
+ add_offence(:convention, node.loc.expression, MSG)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for uses of String#%.
7
+ #
8
+ # It cannot be implemented in a reliable manner for all cases, so
9
+ # only two scenarios are considered - if the first argument is a string
10
+ # literal and if the second argument is an array literal.
11
+ class FavorSprintf < Cop
12
+ MSG = 'Favor sprintf over String#%.'
13
+
14
+ def on_send(node)
15
+ receiver_node, method_name, *arg_nodes = *node
16
+
17
+ if method_name == :% &&
18
+ ([:str, :dstr].include?(receiver_node.type) ||
19
+ arg_nodes[0].type == :array)
20
+ add_offence(:convention, node.loc.selector, MSG)
21
+ end
22
+
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Some common code shared between the two cops.
7
+ module FavorOtherKeywordOverNegation
8
+ def check(node)
9
+ condition, _body, _rest = *node
10
+
11
+ # Look at last expression of contents if there's a parenthesis
12
+ # around condition.
13
+ condition = condition.children.last while condition.type == :begin
14
+
15
+ if condition.type == :send
16
+ _object, method = *condition
17
+ if method == :! && !(node.loc.respond_to?(:else) && node.loc.else)
18
+ add_offence(:convention, node.loc.expression, error_message)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ # Checks for uses of if with a negated condition. Only ifs
25
+ # without else are considered.
26
+ class FavorUnlessOverNegatedIf < Cop
27
+ include FavorOtherKeywordOverNegation
28
+
29
+ def on_if(node)
30
+ check(node)
31
+ super
32
+ end
33
+
34
+ def error_message
35
+ 'Favor unless (or control flow or) over if for negative conditions.'
36
+ end
37
+ end
38
+
39
+ # Checks for uses of while with a negated condition.
40
+ class FavorUntilOverNegatedWhile < Cop
41
+ include FavorOtherKeywordOverNegation
42
+
43
+ def on_while(node)
44
+ check(node)
45
+ super
46
+ end
47
+
48
+ def error_message
49
+ 'Favor until over while for negative conditions.'
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for uses of the Ruby 1.8 hash literal syntax,
7
+ # when the 1.9 syntax is applicable as well.
8
+ #
9
+ # A separate offence is registered for each problematic pair.
10
+ class HashSyntax < Cop
11
+ MSG = 'Ruby 1.8 hash syntax detected'
12
+
13
+ def on_hash(node)
14
+ pairs = *node
15
+
16
+ sym_indices = pairs.all? { |p| word_symbol_pair?(p) }
17
+
18
+ if sym_indices
19
+ pairs.each do |pair|
20
+ if pair.loc.operator && pair.loc.operator.is?('=>')
21
+ add_offence(:convention,
22
+ pair.loc.expression.begin.join(pair.loc.operator),
23
+ MSG)
24
+ end
25
+ end
26
+ end
27
+
28
+ super
29
+ end
30
+
31
+ private
32
+
33
+ def word_symbol_pair?(pair)
34
+ key, _value = *pair
35
+
36
+ if key.type == :sym
37
+ sym_name = key.to_a[0]
38
+
39
+ sym_name =~ /\A\w+\z/
40
+ else
41
+ false
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Common functionality for cops checking if and unless statements.
7
+ module IfThenElse
8
+ def on_if(node)
9
+ check(node)
10
+ super
11
+ end
12
+
13
+ def on_unless(node)
14
+ check(node)
15
+ super
16
+ end
17
+
18
+ def check(node)
19
+ # We won't check modifier or ternary conditionals.
20
+ if node.loc.expression.source =~ /\A(if|unless)\b/
21
+ if offending_line(node)
22
+ add_offence(:convention, node.loc.expression, error_message)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Checks for uses of semicolon in if statements.
7
+ class IfWithSemicolon < Cop
8
+ include IfThenElse
9
+
10
+ def offending_line(node)
11
+ node.loc.begin.line if node.loc.begin && node.loc.begin.is?(';')
12
+ end
13
+
14
+ def error_message
15
+ 'Never use if x; Use the ternary operator instead.'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for uses of the pre 1.9 lambda syntax for one-line
7
+ # anonymous functions and uses of the 1.9 lambda syntax for multi-line
8
+ # anonymous functions.
9
+ class Lambda < Cop
10
+ SINGLE_MSG = 'Use the new lambda literal syntax ->(params) {...}.'
11
+ MULTI_MSG = 'Use the lambda method for multi-line lambdas.'
12
+
13
+ TARGET = s(:send, nil, :lambda)
14
+
15
+ def on_block(node)
16
+ # We're looking for
17
+ # (block
18
+ # (send nil :lambda)
19
+ # ...)
20
+ block_method, = *node
21
+
22
+ if block_method == TARGET
23
+ selector = block_method.loc.selector.source
24
+ lambda_length = lambda_length(node)
25
+
26
+ if selector != '->' && lambda_length == 0
27
+ add_offence(:convention, block_method.loc.expression, SINGLE_MSG)
28
+ elsif selector == '->' && lambda_length > 0
29
+ add_offence(:convention, block_method.loc.expression, MULTI_MSG)
30
+ end
31
+ end
32
+
33
+ super
34
+ end
35
+
36
+ private
37
+
38
+ def lambda_length(block_node)
39
+ start_line = block_node.loc.begin.line
40
+ end_line = block_node.loc.end.line
41
+
42
+ end_line - start_line
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end