rubocop 0.4.0 → 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 (190) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +50 -0
  3. data/.rubocop.yml +5 -127
  4. data/.travis.yml +7 -1
  5. data/CHANGELOG.md +157 -0
  6. data/CONTRIBUTING.md +13 -6
  7. data/Gemfile +3 -8
  8. data/README.md +160 -9
  9. data/Rakefile +3 -17
  10. data/bin/rubocop +16 -10
  11. data/config/default.yml +46 -0
  12. data/config/disabled.yml +5 -0
  13. data/config/enabled.yml +322 -0
  14. data/lib/rubocop/cli.rb +248 -93
  15. data/lib/rubocop/config.rb +205 -0
  16. data/lib/rubocop/config_store.rb +37 -0
  17. data/lib/rubocop/cop/access_control.rb +41 -0
  18. data/lib/rubocop/cop/alias.rb +17 -0
  19. data/lib/rubocop/cop/align_parameters.rb +20 -95
  20. data/lib/rubocop/cop/and_or.rb +26 -0
  21. data/lib/rubocop/cop/ascii_comments.rb +13 -0
  22. data/lib/rubocop/cop/ascii_identifiers.rb +19 -0
  23. data/lib/rubocop/cop/avoid_class_vars.rb +15 -0
  24. data/lib/rubocop/cop/avoid_for.rb +17 -0
  25. data/lib/rubocop/cop/avoid_global_vars.rb +61 -0
  26. data/lib/rubocop/cop/avoid_perl_backrefs.rb +17 -0
  27. data/lib/rubocop/cop/avoid_perlisms.rb +47 -0
  28. data/lib/rubocop/cop/block_comments.rb +15 -0
  29. data/lib/rubocop/cop/blocks.rb +11 -47
  30. data/lib/rubocop/cop/case_indentation.rb +22 -0
  31. data/lib/rubocop/cop/class_and_module_camel_case.rb +20 -11
  32. data/lib/rubocop/cop/class_methods.rb +15 -0
  33. data/lib/rubocop/cop/collection_methods.rb +16 -16
  34. data/lib/rubocop/cop/colon_method_call.rb +20 -0
  35. data/lib/rubocop/cop/constant_name.rb +24 -0
  36. data/lib/rubocop/cop/cop.rb +34 -47
  37. data/lib/rubocop/cop/def_parentheses.rb +43 -35
  38. data/lib/rubocop/cop/empty_line_between_defs.rb +22 -0
  39. data/lib/rubocop/cop/empty_lines.rb +21 -13
  40. data/lib/rubocop/cop/empty_literal.rb +47 -0
  41. data/lib/rubocop/cop/encoding.rb +3 -3
  42. data/lib/rubocop/cop/end_of_line.rb +3 -3
  43. data/lib/rubocop/cop/ensure_return.rb +19 -0
  44. data/lib/rubocop/cop/eval.rb +19 -0
  45. data/lib/rubocop/cop/favor_join.rb +22 -0
  46. data/lib/rubocop/cop/favor_modifier.rb +38 -48
  47. data/lib/rubocop/cop/favor_percent_r.rb +19 -0
  48. data/lib/rubocop/cop/favor_sprintf.rb +21 -0
  49. data/lib/rubocop/cop/favor_unless_over_negated_if.rb +19 -17
  50. data/lib/rubocop/cop/handle_exceptions.rb +17 -0
  51. data/lib/rubocop/cop/hash_syntax.rb +29 -14
  52. data/lib/rubocop/cop/if_then_else.rb +32 -29
  53. data/lib/rubocop/cop/leading_comment_space.rb +17 -0
  54. data/lib/rubocop/cop/line_continuation.rb +15 -0
  55. data/lib/rubocop/cop/line_length.rb +4 -4
  56. data/lib/rubocop/cop/loop.rb +33 -0
  57. data/lib/rubocop/cop/method_and_variable_snake_case.rb +41 -17
  58. data/lib/rubocop/cop/method_length.rb +52 -0
  59. data/lib/rubocop/cop/new_lambda_literal.rb +8 -6
  60. data/lib/rubocop/cop/not.rb +21 -0
  61. data/lib/rubocop/cop/numeric_literals.rb +9 -7
  62. data/lib/rubocop/cop/offence.rb +12 -1
  63. data/lib/rubocop/cop/op_method.rb +26 -0
  64. data/lib/rubocop/cop/parameter_lists.rb +12 -6
  65. data/lib/rubocop/cop/parentheses_around_condition.rb +11 -11
  66. data/lib/rubocop/cop/percent_r.rb +19 -0
  67. data/lib/rubocop/cop/reduce_arguments.rb +29 -0
  68. data/lib/rubocop/cop/rescue_exception.rb +26 -0
  69. data/lib/rubocop/cop/rescue_modifier.rb +17 -0
  70. data/lib/rubocop/cop/semicolon.rb +31 -0
  71. data/lib/rubocop/cop/single_line_methods.rb +44 -0
  72. data/lib/rubocop/cop/space_after_comma_etc.rb +30 -10
  73. data/lib/rubocop/cop/space_after_control_keyword.rb +29 -0
  74. data/lib/rubocop/cop/string_literals.rb +9 -23
  75. data/lib/rubocop/cop/surrounding_space.rb +223 -83
  76. data/lib/rubocop/cop/symbol_array.rb +31 -0
  77. data/lib/rubocop/cop/symbol_name.rb +23 -0
  78. data/lib/rubocop/cop/syntax.rb +35 -5
  79. data/lib/rubocop/cop/tab.rb +3 -3
  80. data/lib/rubocop/cop/ternary_operator.rb +26 -24
  81. data/lib/rubocop/cop/trailing_whitespace.rb +3 -5
  82. data/lib/rubocop/cop/trivial_accessors.rb +26 -0
  83. data/lib/rubocop/cop/unless_else.rb +11 -7
  84. data/lib/rubocop/cop/util.rb +26 -0
  85. data/lib/rubocop/cop/variable_interpolation.rb +29 -0
  86. data/lib/rubocop/cop/when_then.rb +6 -14
  87. data/lib/rubocop/cop/word_array.rb +37 -0
  88. data/lib/rubocop/report/emacs_style.rb +2 -2
  89. data/lib/rubocop/report/plain_text.rb +1 -1
  90. data/lib/rubocop/version.rb +3 -1
  91. data/lib/rubocop.rb +48 -8
  92. data/rubocop.gemspec +32 -151
  93. data/spec/project_spec.rb +27 -0
  94. data/spec/rubocop/cli_spec.rb +573 -200
  95. data/spec/rubocop/config_spec.rb +409 -0
  96. data/spec/rubocop/config_store_spec.rb +66 -0
  97. data/spec/rubocop/cops/access_control_spec.rb +129 -0
  98. data/spec/rubocop/cops/alias_spec.rb +39 -0
  99. data/spec/rubocop/cops/align_parameters_spec.rb +66 -70
  100. data/spec/rubocop/cops/and_or_spec.rb +37 -0
  101. data/spec/rubocop/cops/ascii_comments_spec.rb +26 -0
  102. data/spec/rubocop/cops/ascii_identifiers_spec.rb +26 -0
  103. data/spec/rubocop/cops/avoid_class_vars_spec.rb +25 -0
  104. data/spec/rubocop/cops/avoid_for_spec.rb +35 -0
  105. data/spec/rubocop/cops/avoid_global_vars_spec.rb +32 -0
  106. data/spec/rubocop/cops/avoid_perl_backrefs_spec.rb +18 -0
  107. data/spec/rubocop/cops/avoid_perlisms_spec.rb +44 -0
  108. data/spec/rubocop/cops/block_comments_spec.rb +25 -0
  109. data/spec/rubocop/cops/blocks_spec.rb +33 -0
  110. data/spec/rubocop/cops/{indentation_spec.rb → case_indentation_spec.rb} +7 -7
  111. data/spec/rubocop/cops/class_and_module_camel_case_spec.rb +15 -5
  112. data/spec/rubocop/cops/class_methods_spec.rb +49 -0
  113. data/spec/rubocop/cops/collection_methods_spec.rb +9 -4
  114. data/spec/rubocop/cops/colon_method_call_spec.rb +53 -0
  115. data/spec/rubocop/cops/constant_name_spec.rb +42 -0
  116. data/spec/rubocop/cops/def_with_parentheses_spec.rb +13 -8
  117. data/spec/rubocop/cops/def_without_parentheses_spec.rb +11 -5
  118. data/spec/rubocop/cops/empty_line_between_defs_spec.rb +83 -0
  119. data/spec/rubocop/cops/empty_lines_spec.rb +14 -59
  120. data/spec/rubocop/cops/empty_literal_spec.rb +90 -0
  121. data/spec/rubocop/cops/encoding_spec.rb +11 -11
  122. data/spec/rubocop/cops/end_of_line_spec.rb +2 -2
  123. data/spec/rubocop/cops/ensure_return_spec.rb +35 -0
  124. data/spec/rubocop/cops/eval_spec.rb +39 -0
  125. data/spec/rubocop/cops/favor_join_spec.rb +35 -0
  126. data/spec/rubocop/cops/favor_modifier_spec.rb +16 -14
  127. data/spec/rubocop/cops/favor_percent_r_spec.rb +29 -0
  128. data/spec/rubocop/cops/favor_sprintf_spec.rb +51 -0
  129. data/spec/rubocop/cops/favor_unless_over_negated_if_spec.rb +4 -4
  130. data/spec/rubocop/cops/favor_until_over_negated_while_spec.rb +3 -3
  131. data/spec/rubocop/cops/handle_exceptions_spec.rb +34 -0
  132. data/spec/rubocop/cops/hash_syntax_spec.rb +11 -6
  133. data/spec/rubocop/cops/if_with_semicolon_spec.rb +7 -1
  134. data/spec/rubocop/cops/leading_comment_space_spec.rb +54 -0
  135. data/spec/rubocop/cops/line_continuation_spec.rb +24 -0
  136. data/spec/rubocop/cops/line_length_spec.rb +3 -2
  137. data/spec/rubocop/cops/loop_spec.rb +31 -0
  138. data/spec/rubocop/cops/method_and_variable_snake_case_spec.rb +55 -9
  139. data/spec/rubocop/cops/method_length_spec.rb +147 -0
  140. data/spec/rubocop/cops/multiline_if_then_spec.rb +15 -15
  141. data/spec/rubocop/cops/new_lambda_literal_spec.rb +5 -6
  142. data/spec/rubocop/cops/not_spec.rb +31 -0
  143. data/spec/rubocop/cops/numeric_literals_spec.rb +13 -13
  144. data/spec/rubocop/cops/offence_spec.rb +13 -0
  145. data/spec/rubocop/cops/one_line_conditional_spec.rb +1 -1
  146. data/spec/rubocop/cops/op_method_spec.rb +78 -0
  147. data/spec/rubocop/cops/parameter_lists_spec.rb +7 -7
  148. data/spec/rubocop/cops/parentheses_around_condition_spec.rb +41 -44
  149. data/spec/rubocop/cops/percent_r_spec.rb +29 -0
  150. data/spec/rubocop/cops/reduce_arguments_spec.rb +57 -0
  151. data/spec/rubocop/cops/rescue_exception_spec.rb +125 -0
  152. data/spec/rubocop/cops/rescue_modifier_spec.rb +37 -0
  153. data/spec/rubocop/cops/semicolon_spec.rb +88 -0
  154. data/spec/rubocop/cops/single_line_methods_spec.rb +50 -0
  155. data/spec/rubocop/cops/space_after_colon_spec.rb +3 -3
  156. data/spec/rubocop/cops/space_after_comma_spec.rb +14 -2
  157. data/spec/rubocop/cops/space_after_control_keyword_spec.rb +67 -0
  158. data/spec/rubocop/cops/space_after_semicolon_spec.rb +6 -1
  159. data/spec/rubocop/cops/space_around_braces_spec.rb +18 -3
  160. data/spec/rubocop/cops/space_around_equals_in_default_parameter_spec.rb +12 -2
  161. data/spec/rubocop/cops/space_around_operators_spec.rb +88 -26
  162. data/spec/rubocop/cops/space_inside_brackets_spec.rb +13 -7
  163. data/spec/rubocop/cops/space_inside_hash_literal_braces_spec.rb +79 -0
  164. data/spec/rubocop/cops/space_inside_parens_spec.rb +7 -3
  165. data/spec/rubocop/cops/string_literals_spec.rb +21 -6
  166. data/spec/rubocop/cops/symbol_array_spec.rb +41 -0
  167. data/spec/rubocop/cops/symbol_name_spec.rb +119 -0
  168. data/spec/rubocop/cops/syntax_spec.rb +28 -5
  169. data/spec/rubocop/cops/tab_spec.rb +2 -2
  170. data/spec/rubocop/cops/ternary_operator_spec.rb +13 -17
  171. data/spec/rubocop/cops/trailing_whitespace_spec.rb +3 -3
  172. data/spec/rubocop/cops/trivial_accessors_spec.rb +329 -0
  173. data/spec/rubocop/cops/unless_else_spec.rb +8 -8
  174. data/spec/rubocop/cops/variable_interpolation_spec.rb +49 -0
  175. data/spec/rubocop/cops/when_then_spec.rb +14 -14
  176. data/spec/rubocop/cops/word_array_spec.rb +47 -0
  177. data/spec/spec_helper.rb +30 -9
  178. data/spec/support/file_helper.rb +21 -0
  179. data/spec/support/isolated_environment.rb +27 -0
  180. metadata +235 -76
  181. data/.document +0 -5
  182. data/Gemfile.lock +0 -41
  183. data/VERSION +0 -1
  184. data/lib/rubocop/cop/ampersands_pipes_vs_and_or.rb +0 -25
  185. data/lib/rubocop/cop/grammar.rb +0 -135
  186. data/lib/rubocop/cop/indentation.rb +0 -44
  187. data/spec/rubocop/cops/ampersands_pipes_vs_and_or_spec.rb +0 -57
  188. data/spec/rubocop/cops/grammar_spec.rb +0 -71
  189. data/spec/rubocop/cops/multiline_blocks_spec.rb +0 -24
  190. data/spec/rubocop/cops/single_line_blocks_spec.rb +0 -22
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class Alias < Cop
6
+ MSG = 'Use alias_method instead of alias.'
7
+
8
+ def on_alias(node)
9
+ add_offence(:convention,
10
+ node.loc.keyword.line,
11
+ MSG)
12
+
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,109 +3,34 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class AlignParameters < Cop
6
- ERROR_MESSAGE = 'Align the parameters of a method call if they span ' +
6
+ MSG = 'Align the parameters of a method call if they span ' +
7
7
  'more than one line.'
8
8
 
9
- def inspect(file, source, tokens, sexp)
10
- @file = file
11
- @tokens = tokens
12
- @token_indexes = {}
13
- @tokens.each_with_index { |t, ix| @token_indexes[t.pos] = ix }
9
+ def on_send(node)
10
+ _receiver, method, *args = *node
14
11
 
15
- each(:method_add_arg, sexp) do |method_add_arg|
16
- args = get_args(method_add_arg) or next
17
- first_arg, rest_of_args = divide_args(args)
18
- @first_lparen_ix = get_lparen_ix(method_add_arg)
19
- pos_of_1st_arg = position_of(first_arg) or next # Give up.
20
- rest_of_args.each do |arg|
21
- pos = position_of(arg) or next # Give up if no position found.
22
- if pos.lineno != pos_of_1st_arg.lineno
23
- if pos.column != pos_of_1st_arg.column
24
- add_offence(:convention, pos.lineno, ERROR_MESSAGE)
25
- end
26
- end
27
- end
28
- end
29
- end
30
-
31
- private
32
-
33
- def get_args(method_add_arg)
34
- fcall = method_add_arg[1]
35
- return nil if fcall[0] != :fcall
36
- return nil if fcall[1][0..1] == [:@ident, 'lambda']
37
- arg_paren = method_add_arg[2..-1][0]
38
- return nil if arg_paren[0] != :arg_paren || arg_paren[1].nil?
39
-
40
- # A command (call wihtout parentheses) as first parameter
41
- # means there's only one parameter.
42
- return nil if [:command, :command_call].include?(arg_paren[1][0][0])
43
-
44
- args_add_block = arg_paren[1]
45
- unless args_add_block[0] == :args_add_block
46
- fail "\n#{@file}: #{method_add_arg}"
47
- end
48
- args_add_block[1].empty? ? [args_add_block[2]] : args_add_block[1]
49
- end
50
-
51
- def divide_args(args)
52
- if args[0] == :args_add_star
53
- first_arg = args[1]
54
- rest_of_args = args[2..-1]
55
- else
56
- first_arg = args[0]
57
- rest_of_args = args[1..-1]
58
- end
59
- [first_arg, rest_of_args]
60
- end
61
-
62
- def get_lparen_ix(method_add_arg)
63
- method_name_pos = method_add_arg[1][1][-1]
64
- method_name_ix = @token_indexes[method_name_pos]
65
- method_name_ix +
66
- @tokens[method_name_ix..-1].map(&:type).index(:on_lparen)
67
- end
68
-
69
- def position_of(sexp)
70
- # Indentation inside a string literal is irrelevant.
71
- return nil if sexp[0] == :string_literal
12
+ if method != :[]= && args.size > 1
13
+ first_arg_col = args.first.loc.expression.column
14
+ prev_arg_line = args.first.loc.expression.line
15
+ prev_arg_col = first_arg_col
72
16
 
73
- pos = find_pos_in_sexp(sexp) or return nil # Nil means not found.
74
- ix = find_first_non_whitespace_token(pos) or return nil
75
- @tokens[ix].pos
76
- end
17
+ args.each do |arg|
18
+ cur_arg_line = arg.loc.expression.line
19
+ cur_arg_col = arg.loc.expression.column
77
20
 
78
- def find_pos_in_sexp(sexp)
79
- return sexp[2] if Position === sexp[2]
80
- sexp.grep(Array).each do |s|
81
- pos = find_pos_in_sexp(s) and return pos
82
- end
83
- nil
84
- end
85
-
86
- def find_first_non_whitespace_token(pos)
87
- ix = @token_indexes[pos]
88
- newline_found = false
89
- start_ix = ix.downto(0) do |i|
90
- case @tokens[i].text
91
- when '('
92
- break i + 1 if i == @first_lparen_ix
93
- when "\n"
94
- newline_found = true
95
- when /\t/
96
- # Bail out if tabs are used. Too difficult to calculate column.
97
- return nil
98
- when ','
99
- if newline_found
100
- break i + 1
101
- else
102
- # Bail out if there's a preceding comma on the same line.
103
- return nil
21
+ if cur_arg_line != prev_arg_line &&
22
+ cur_arg_col != first_arg_col
23
+ add_offence(:convetion,
24
+ cur_arg_line,
25
+ MSG)
104
26
  end
27
+
28
+ prev_arg_col = cur_arg_col
29
+ prev_arg_line = cur_arg_line
105
30
  end
106
31
  end
107
- offset = @tokens[start_ix..-1].index { |t| not whitespace?(t) }
108
- start_ix + offset
32
+
33
+ super
109
34
  end
110
35
  end
111
36
  end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AndOr < Cop
6
+ MSG = 'Use %s instead of %s.'
7
+
8
+ OPS = { 'and' => '&&', 'or' => '||' }
9
+
10
+ def on_and(node)
11
+ op = node.loc.operator.source
12
+ op_type = node.type.to_s
13
+
14
+ if op == op_type
15
+ add_offence(:convention,
16
+ node.loc.operator.line,
17
+ sprintf(MSG, OPS[op], op))
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ alias_method :on_or, :on_and
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AsciiComments < Cop
6
+ MSG = 'Use only ascii symbols in comments.'
7
+
8
+ def on_comment(c)
9
+ add_offence(:convention, c.loc.line, MSG) if c.text =~ /[^\x00-\x7f]/
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ # rubocop:disable SymbolName
4
+
5
+ module Rubocop
6
+ module Cop
7
+ class AsciiIdentifiers < Cop
8
+ MSG = 'Use only ascii symbols in identifiers.'
9
+
10
+ def inspect(source, tokens, ast, comments)
11
+ tokens.each do |t|
12
+ if t.type == :tIDENTIFIER && t.text =~ /[^\x00-\x7f]/
13
+ add_offence(:convention, t.pos.line, MSG)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AvoidClassVars < Cop
6
+ MSG = 'Replace class var %s with a class instance var.'
7
+
8
+ def on_cvasgn(node)
9
+ class_var, = *node
10
+ add_offence(:convention, node.loc.name.line, sprintf(MSG, class_var))
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AvoidFor < Cop
6
+ MSG = 'Prefer *each* over *for*.'
7
+
8
+ def on_for(node)
9
+ add_offence(:convention,
10
+ node.loc.keyword.line,
11
+ MSG)
12
+
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AvoidGlobalVars < Cop
6
+ MSG = 'Do not introduce global variables.'
7
+
8
+ # predefined global variables their English aliases
9
+ # http://www.zenspider.com/Languages/Ruby/QuickRef.html
10
+ BUILT_IN_VARS = %w(
11
+ $: $LOAD_PATH
12
+ $" $LOADED_FEATURES
13
+ $0 $PROGRAM_NAME
14
+ $! $ERROR_INFO
15
+ $@ $ERROR_POSITION
16
+ $; $FS $FIELD_SEPARATOR
17
+ $, $OFS $OUTPUT_FIELD_SEPARATOR
18
+ $/ $RS $INPUT_RECORD_SEPARATOR
19
+ $\\ $ORS $OUTPUT_RECORD_SEPARATOR
20
+ $. $NR $INPUT_LINE_NUMBER
21
+ $_ $LAST_READ_LINE
22
+ $> $DEFAULT_OUTPUT
23
+ $< $DEFAULT_INPUT
24
+ $$ $PID $PROCESS_ID
25
+ $? $CHILD_STATUS
26
+ $~ $LAST_MATCH_INFO
27
+ $= $IGNORECASE
28
+ $* $ARGV
29
+ $& $MATCH
30
+ $` $PREMATCH
31
+ $' $POSTMATCH
32
+ $+ $LAST_PAREN_MATCH
33
+ $stdin $stdout $stderr
34
+ $DEBUG $FILENAME $VERBOSE
35
+ $-0 $-a $-d $-F $-i $-I $-l $-p $-v $-w
36
+ )
37
+
38
+ def on_gvar(node)
39
+ check(node)
40
+
41
+ super
42
+ end
43
+
44
+ def on_gvasgn(node)
45
+ check(node)
46
+
47
+ super
48
+ end
49
+
50
+ def check(node)
51
+ global_var, = *node
52
+
53
+ unless BUILT_IN_VARS.include?(global_var.to_s)
54
+ add_offence(:convention,
55
+ node.loc.name.line,
56
+ MSG)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AvoidPerlBackrefs < Cop
6
+ def on_nth_ref(node)
7
+ backref, = *node
8
+
9
+ add_offence(:convention,
10
+ node.loc.line,
11
+ "Prefer the use of MatchData over $#{backref}.")
12
+
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class AvoidPerlisms < Cop
6
+ PREFERRED_VARS = {
7
+ '$:' => '$LOAD_PATH',
8
+ '$"' => '$LOADED_FEATURES',
9
+ '$0' => '$PROGRAM_NAME',
10
+ '$!' => '$ERROR_INFO from English library',
11
+ '$@' => '$ERROR_POSITION from English library',
12
+ '$;' => '$FS or $FIELD_SEPARATOR from English library',
13
+ '$,' => '$OFS or $OUTPUT_FIELD_SEPARATOR from English library',
14
+ '$/' => '$RS or $INPUT_RECORD_SEPARATOR from English library',
15
+ '$\\' => '$ORS or $OUTPUT_RECORD_SEPARATOR from English library',
16
+ '$.' => '$NR or $INPUT_LINE_NUMBER from English library',
17
+ '$_' => '$LAST_READ_LINE from English library',
18
+ '$>' => '$DEFAULT_OUTPUT from English library',
19
+ '$<' => '$DEFAULT_INPUT from English library',
20
+ '$$' => '$PID or $PROCESS_ID from English library',
21
+ '$?' => '$CHILD_STATUS from English library',
22
+ '$~' => '$LAST_MATCH_INFO from English library',
23
+ '$=' => '$IGNORECASE from English library',
24
+ '$*' => '$ARGV from English library or ARGV constant',
25
+ '$&' => '$MATCH from English library',
26
+ '$`' => '$PREMATCH from English library',
27
+ '$\'' => '$POSTMATCH from English library',
28
+ '$+' => '$LAST_PAREN_MATCH from English library'
29
+ }
30
+
31
+ def on_gvar(node)
32
+ global_var, = *node
33
+ global_var = global_var.to_s
34
+
35
+ if PREFERRED_VARS[global_var]
36
+ add_offence(
37
+ :convention,
38
+ node.loc.line,
39
+ "Prefer #{PREFERRED_VARS[global_var]} over #{global_var}."
40
+ )
41
+ end
42
+
43
+ super
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class BlockComments < Cop
6
+ MSG = 'Do not use block comments.'
7
+
8
+ def on_comment(comment)
9
+ if comment.text.start_with?('=begin')
10
+ add_offence(:convention, comment.loc.line, MSG)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,57 +2,21 @@
2
2
 
3
3
  module Rubocop
4
4
  module Cop
5
- module Blocks
6
- def inspect(file, source, tokens, sexp)
7
- @file = file
5
+ class Blocks < Cop
6
+ MULTI_LINE_MSG = 'Avoid using {...} for multi-line blocks.'
7
+ SINGLE_LINE_MSG = 'Prefer {...} over do...end for single-line blocks.'
8
8
 
9
- # The @reverse_correlations maps grammar path object ids to
10
- # token indexes, so we can use it to find the corresponding }
11
- # for each {.
12
- @reverse_correlations = Hash.new([])
13
- @correlations.each do |ix, path|
14
- @reverse_correlations[path.object_id] += [ix]
15
- end
16
-
17
- tokens.each_index { |ix| check(tokens, ix) }
18
- end
19
- end
20
-
21
- class MultilineBlocks < Cop
22
- include Blocks
23
- ERROR_MESSAGE = 'Avoid using {...} for multi-line blocks.'
9
+ def on_block(node)
10
+ block_length = Util.block_length(node)
11
+ block_begin = node.loc.begin.source
24
12
 
25
- def check(tokens, ix)
26
- t = tokens[ix]
27
- if [t.type, t.text] == [:on_lbrace, '{']
28
- path = @correlations[ix] or return
29
- if path.last == :brace_block
30
- rbrace_ix = @reverse_correlations[path.object_id] - [ix]
31
- if rbrace_ix.empty?
32
- fail "\n#@file:#{t.pos.lineno}:#{t.pos.column}: " +
33
- 'Matching brace not found'
34
- end
35
- if tokens[*rbrace_ix].pos.lineno > t.pos.lineno
36
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
37
- end
38
- end
13
+ if block_length > 0 && block_begin == '{'
14
+ add_offence(:convention, node.loc.line, MULTI_LINE_MSG)
15
+ elsif block_length == 0 && block_begin != '{'
16
+ add_offence(:convention, node.loc.line, SINGLE_LINE_MSG)
39
17
  end
40
- end
41
- end
42
18
 
43
- class SingleLineBlocks < Cop
44
- include Blocks
45
- ERROR_MESSAGE = 'Prefer {...} over do...end for single-line blocks.'
46
-
47
- def check(tokens, ix)
48
- t = tokens[ix]
49
- if [t.type, t.text] == [:on_kw, 'do']
50
- end_offset = tokens[ix..-1].index { |t2| t2.text == 'end' } or return
51
- end_token_ix = ix + end_offset
52
- if tokens[end_token_ix].pos.lineno == t.pos.lineno
53
- add_offence(:convention, t.pos.lineno, ERROR_MESSAGE)
54
- end
55
- end
19
+ super
56
20
  end
57
21
  end
58
22
  end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class CaseIndentation < Cop
6
+ MSG = 'Indent when as deep as case.'
7
+
8
+ def on_case(case_node)
9
+ _condition, *whens, _else = *case_node
10
+
11
+ case_column = case_node.location.keyword.column
12
+
13
+ whens.each do |when_node|
14
+ pos = when_node.loc.keyword
15
+ add_offence(:convention, pos.line, MSG) if pos.column != case_column
16
+ end
17
+
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,17 +3,26 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class ClassAndModuleCamelCase < Cop
6
- ERROR_MESSAGE = 'Use CamelCase for classes and modules.'
7
-
8
- def inspect(file, source, tokens, sexp)
9
- [:class, :module].each do |keyword|
10
- each(keyword, sexp) do |s|
11
- if s[1][0] == :const_ref && s[1][1][0] == :@const &&
12
- s[1][1][1] =~ /_/
13
- add_offence(:convention, s[1][1][2].lineno, ERROR_MESSAGE)
14
- end
15
- end
16
- end
6
+ MSG = 'Use CamelCase for classes and modules.'
7
+
8
+ def on_class(node)
9
+ check_name(node)
10
+
11
+ super
12
+ end
13
+
14
+ def on_module(node)
15
+ check_name(node)
16
+
17
+ super
18
+ end
19
+
20
+ private
21
+
22
+ def check_name(node)
23
+ name = node.loc.name.source
24
+
25
+ add_offence(:convention, node.loc.line, MSG) if name =~ /_/
17
26
  end
18
27
  end
19
28
  end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class ClassMethods < Cop
6
+ MSG = 'Prefer self over class/module for class/module methods.'
7
+
8
+ def on_defs(node)
9
+ definee, _name, _args, _body = *node
10
+
11
+ add_offence(:convention, node.loc.line, MSG) if definee.type == :const
12
+ end
13
+ end
14
+ end
15
+ end
@@ -3,25 +3,25 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  class CollectionMethods < Cop
6
+ MSG = 'Prefer %s over %s.'
7
+
6
8
  PREFERRED_METHODS = {
7
- 'collect' => 'map',
8
- 'inject' => 'reduce',
9
- 'detect' => 'find',
10
- 'find_all' => 'select',
9
+ collect: 'map',
10
+ inject: 'reduce',
11
+ detect: 'find',
12
+ find_all: 'select'
11
13
  }
12
14
 
13
- def inspect(file, source, tokens, sexp)
14
- each(:call, sexp) do |s|
15
- s.drop(2).each_slice(2) do |m|
16
- method_name = m[1][1]
17
- if PREFERRED_METHODS[method_name]
18
- add_offence(
19
- :convention,
20
- m[1][2].lineno,
21
- "Prefer #{PREFERRED_METHODS[method_name]} over #{method_name}."
22
- )
23
- end
24
- end
15
+ def on_send(node)
16
+ receiver, method_name, *_args = *node
17
+
18
+ # a simple(but flawed way) to reduce false positives
19
+ if receiver && PREFERRED_METHODS[method_name]
20
+ add_offence(
21
+ :convention,
22
+ node.loc.line,
23
+ sprintf(MSG, PREFERRED_METHODS[method_name], method_name)
24
+ )
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class ColonMethodCall < Cop
6
+ MSG = 'Do not use :: for method invocation.'
7
+
8
+ def on_send(node)
9
+ receiver, _method_name, *_args = *node
10
+
11
+ # discard methods with nil receivers and op methods(like [])
12
+ if receiver && node.loc.dot && node.loc.dot.source == '::'
13
+ add_offence(:convention, node.loc.line, MSG)
14
+ end
15
+
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ class ConstantName < Cop
6
+ MSG = 'Use SCREAMING_SNAKE_CASE for constants.'
7
+ SNAKE_CASE = /^[\dA-Z_]+$/
8
+
9
+ def on_casgn(node)
10
+ _scope, const_name, value = *node
11
+
12
+ # we cannot know the result of method calls line
13
+ # NewClass = something_that_returns_a_class
14
+ if value.type != :send && const_name !~ SNAKE_CASE
15
+ add_offence(:convention,
16
+ node.loc.line,
17
+ MSG)
18
+ end
19
+
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end