rubocop 0.16.0 → 0.17.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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -1
  4. data/CHANGELOG.md +44 -0
  5. data/CONTRIBUTING.md +40 -8
  6. data/Gemfile +6 -0
  7. data/README.md +65 -20
  8. data/Rakefile +0 -1
  9. data/config/default.yml +15 -3
  10. data/config/enabled.yml +143 -109
  11. data/lib/rubocop.rb +45 -26
  12. data/lib/rubocop/cli.rb +26 -27
  13. data/lib/rubocop/config.rb +0 -1
  14. data/lib/rubocop/config_loader.rb +16 -23
  15. data/lib/rubocop/cop/commissioner.rb +2 -7
  16. data/lib/rubocop/cop/cop.rb +24 -51
  17. data/lib/rubocop/cop/ignored_node.rb +31 -0
  18. data/lib/rubocop/cop/lint/ambiguous_operator.rb +50 -0
  19. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +36 -0
  20. data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -11
  21. data/lib/rubocop/cop/lint/block_alignment.rb +6 -20
  22. data/lib/rubocop/cop/lint/condition_position.rb +52 -0
  23. data/lib/rubocop/cop/lint/else_layout.rb +57 -0
  24. data/lib/rubocop/cop/lint/end_alignment.rb +33 -8
  25. data/lib/rubocop/cop/lint/invalid_character_literal.rb +37 -0
  26. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -4
  27. data/lib/rubocop/cop/lint/syntax.rb +6 -12
  28. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +25 -0
  29. data/lib/rubocop/cop/mixin/array_syntax.rb +20 -0
  30. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +76 -0
  31. data/lib/rubocop/cop/mixin/check_assignment.rb +26 -0
  32. data/lib/rubocop/cop/{check_methods.rb → mixin/check_methods.rb} +0 -0
  33. data/lib/rubocop/cop/mixin/code_length.rb +33 -0
  34. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +53 -0
  35. data/lib/rubocop/cop/mixin/configurable_max.rb +19 -0
  36. data/lib/rubocop/cop/mixin/configurable_naming.rb +45 -0
  37. data/lib/rubocop/cop/{style → mixin}/if_node.rb +0 -0
  38. data/lib/rubocop/cop/mixin/if_then_else.rb +23 -0
  39. data/lib/rubocop/cop/mixin/negative_conditional.rb +24 -0
  40. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +34 -0
  41. data/lib/rubocop/cop/mixin/safe_assignment.rb +19 -0
  42. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +32 -0
  43. data/lib/rubocop/cop/mixin/space_inside.rb +31 -0
  44. data/lib/rubocop/cop/mixin/statement_modifier.rb +59 -0
  45. data/lib/rubocop/cop/mixin/string_help.rb +32 -0
  46. data/lib/rubocop/cop/mixin/surrounding_space.rb +42 -0
  47. data/lib/rubocop/cop/rails/default_scope.rb +3 -1
  48. data/lib/rubocop/cop/style/accessor_method_name.rb +4 -12
  49. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +16 -1
  50. data/lib/rubocop/cop/style/case_indentation.rb +33 -16
  51. data/lib/rubocop/cop/style/character_literal.rb +10 -0
  52. data/lib/rubocop/cop/style/dot_position.rb +23 -6
  53. data/lib/rubocop/cop/style/empty_lines_around_body.rb +5 -5
  54. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -32
  55. data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +20 -0
  56. data/lib/rubocop/cop/style/hash_syntax.rb +5 -1
  57. data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
  58. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
  59. data/lib/rubocop/cop/style/indentation_consistency.rb +51 -0
  60. data/lib/rubocop/cop/style/indentation_width.rb +0 -26
  61. data/lib/rubocop/cop/style/lambda_call.rb +12 -5
  62. data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -11
  63. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -9
  64. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +22 -0
  65. data/lib/rubocop/cop/style/{ternary_operator.rb → nested_ternary_operator.rb} +0 -15
  66. data/lib/rubocop/cop/style/numeric_literals.rb +30 -2
  67. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -1
  68. data/lib/rubocop/cop/style/parameter_lists.rb +7 -3
  69. data/lib/rubocop/cop/style/parentheses_around_condition.rb +9 -11
  70. data/lib/rubocop/cop/style/predicate_name.rb +4 -12
  71. data/lib/rubocop/cop/style/raise_args.rb +19 -11
  72. data/lib/rubocop/cop/style/regexp_literal.rb +19 -6
  73. data/lib/rubocop/cop/style/space_after_colon.rb +36 -0
  74. data/lib/rubocop/cop/style/space_after_comma.rb +16 -0
  75. data/lib/rubocop/cop/style/space_after_semicolon.rb +16 -0
  76. data/lib/rubocop/cop/style/space_around_block_braces.rb +38 -38
  77. data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
  78. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +6 -2
  79. data/lib/rubocop/cop/style/string_literals.rb +5 -5
  80. data/lib/rubocop/cop/style/trailing_comma.rb +94 -0
  81. data/lib/rubocop/cop/style/unless_else.rb +2 -2
  82. data/lib/rubocop/cop/style/while_until_modifier.rb +32 -0
  83. data/lib/rubocop/cop/style/word_array.rb +9 -1
  84. data/lib/rubocop/cop/util.rb +14 -0
  85. data/lib/rubocop/cop/variable_inspector.rb +11 -6
  86. data/lib/rubocop/cop/variable_inspector/scope.rb +4 -3
  87. data/lib/rubocop/file_inspector.rb +22 -6
  88. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  89. data/lib/rubocop/formatter/colorizable.rb +37 -0
  90. data/lib/rubocop/formatter/disabled_config_formatter.rb +27 -6
  91. data/lib/rubocop/formatter/progress_formatter.rb +1 -1
  92. data/lib/rubocop/formatter/simple_text_formatter.rb +9 -5
  93. data/lib/rubocop/options.rb +19 -4
  94. data/lib/rubocop/target_finder.rb +4 -0
  95. data/lib/rubocop/version.rb +1 -1
  96. data/rubocop-todo.yml +10 -2
  97. data/rubocop.gemspec +3 -2
  98. data/spec/project_spec.rb +12 -7
  99. data/spec/rubocop/cli_spec.rb +262 -99
  100. data/spec/rubocop/config_loader_spec.rb +5 -5
  101. data/spec/rubocop/config_spec.rb +3 -3
  102. data/spec/rubocop/config_store_spec.rb +12 -11
  103. data/spec/rubocop/cop/commissioner_spec.rb +21 -5
  104. data/spec/rubocop/cop/cop_spec.rb +1 -1
  105. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
  106. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
  107. data/spec/rubocop/cop/lint/block_alignment_spec.rb +2 -2
  108. data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
  109. data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
  110. data/spec/rubocop/cop/lint/end_alignment_spec.rb +41 -1
  111. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
  112. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +3 -3
  113. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +12 -12
  114. data/spec/rubocop/cop/lint/syntax_spec.rb +2 -2
  115. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +72 -54
  116. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
  117. data/spec/rubocop/cop/offence_spec.rb +1 -1
  118. data/spec/rubocop/cop/rails/default_scope_spec.rb +6 -0
  119. data/spec/rubocop/cop/rails/output_spec.rb +2 -1
  120. data/spec/rubocop/cop/style/align_hash_spec.rb +9 -9
  121. data/spec/rubocop/cop/style/align_parameters_spec.rb +1 -1
  122. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +5 -0
  123. data/spec/rubocop/cop/style/case_indentation_spec.rb +53 -2
  124. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +3 -3
  125. data/spec/rubocop/cop/style/documentation_spec.rb +0 -1
  126. data/spec/rubocop/cop/style/dot_position_spec.rb +18 -3
  127. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +4 -4
  128. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +13 -0
  129. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
  130. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +1 -1
  131. data/spec/rubocop/cop/style/hash_syntax_spec.rb +5 -0
  132. data/spec/rubocop/cop/style/{favor_modifier_spec.rb → if_unless_modifier_spec.rb} +4 -111
  133. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
  134. data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -91
  135. data/spec/rubocop/cop/style/lambda_call_spec.rb +18 -0
  136. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +2 -2
  137. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +35 -1
  138. data/spec/rubocop/cop/style/method_length_spec.rb +1 -0
  139. data/spec/rubocop/cop/style/method_name_spec.rb +27 -5
  140. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +4 -4
  141. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
  142. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
  143. data/spec/rubocop/cop/style/{ternary_operator_spec.rb → nested_ternary_operator_spec.rb} +0 -15
  144. data/spec/rubocop/cop/style/numeric_literals_spec.rb +18 -1
  145. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -1
  146. data/spec/rubocop/cop/style/parameter_lists_spec.rb +1 -0
  147. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +13 -4
  148. data/spec/rubocop/cop/style/raise_args_spec.rb +22 -0
  149. data/spec/rubocop/cop/style/redundant_self_spec.rb +4 -4
  150. data/spec/rubocop/cop/style/regexp_literal_spec.rb +4 -0
  151. data/spec/rubocop/cop/style/space_after_colon_spec.rb +12 -4
  152. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +2 -2
  153. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +30 -1
  154. data/spec/rubocop/cop/style/{space_around_equals_in_default_parameter_spec.rb → space_around_equals_in_parameter_default_spec.rb} +0 -0
  155. data/spec/rubocop/cop/style/space_around_operators_spec.rb +2 -1
  156. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +20 -3
  157. data/spec/rubocop/cop/style/string_literals_spec.rb +33 -0
  158. data/spec/rubocop/cop/style/trailing_comma_spec.rb +200 -0
  159. data/spec/rubocop/cop/style/variable_name_spec.rb +27 -3
  160. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
  161. data/spec/rubocop/cop/style/word_array_spec.rb +1 -0
  162. data/spec/rubocop/cop/team_spec.rb +1 -1
  163. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +3 -4
  164. data/spec/rubocop/file_inspector_spec.rb +1 -1
  165. data/spec/rubocop/formatter/base_formatter_spec.rb +12 -11
  166. data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
  167. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +2 -0
  168. data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
  169. data/spec/rubocop/formatter/json_formatter_spec.rb +4 -3
  170. data/spec/rubocop/formatter/progress_formatter_spec.rb +2 -2
  171. data/spec/rubocop/options_spec.rb +3 -1
  172. data/spec/rubocop/target_finder_spec.rb +13 -11
  173. data/spec/spec_helper.rb +5 -1
  174. data/spec/support/shared_examples.rb +2 -2
  175. data/spec/support/statement_modifier_helper.rb +41 -0
  176. metadata +88 -30
  177. data/lib/rubocop/cop/check_assignment.rb +0 -43
  178. data/lib/rubocop/cop/style/array_syntax.rb +0 -22
  179. data/lib/rubocop/cop/style/autocorrect_alignment.rb +0 -78
  180. data/lib/rubocop/cop/style/code_length.rb +0 -35
  181. data/lib/rubocop/cop/style/configurable_enforced_style.rb +0 -51
  182. data/lib/rubocop/cop/style/configurable_max.rb +0 -17
  183. data/lib/rubocop/cop/style/configurable_naming.rb +0 -41
  184. data/lib/rubocop/cop/style/favor_modifier.rb +0 -118
  185. data/lib/rubocop/cop/style/if_then_else.rb +0 -27
  186. data/lib/rubocop/cop/style/space_after_comma_etc.rb +0 -73
  187. data/lib/rubocop/cop/style/space_inside.rb +0 -33
  188. data/lib/rubocop/cop/style/string_help.rb +0 -30
  189. data/lib/rubocop/cop/style/surrounding_space.rb +0 -44
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Checks for uses of while with a negated condition.
7
+ class FavorUntilOverNegatedWhile < Cop
8
+ include NegativeConditional
9
+
10
+ def on_while(node)
11
+ check(node)
12
+ end
13
+
14
+ def error_message
15
+ 'Favor until over while for negative conditions.'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -67,7 +67,11 @@ module Rubocop
67
67
  if pair.loc.operator && pair.loc.operator.is?(delim)
68
68
  add_offence(pair,
69
69
  pair.loc.expression.begin.join(pair.loc.operator),
70
- msg)
70
+ msg) do
71
+ opposite_style_detected
72
+ end
73
+ else
74
+ correct_style_detected
71
75
  end
72
76
  end
73
77
  end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Checks for if and unless statements that would fit on one line
7
+ # if written as a modifier if/unless.
8
+ class IfUnlessModifier < Cop
9
+ include StatementModifier
10
+
11
+ def error_message(keyword)
12
+ "Favor modifier #{keyword} usage when you have a single-line body." \
13
+ ' Another good alternative is the usage of control flow &&/||.'
14
+ end
15
+
16
+ def investigate(processed_source)
17
+ return unless processed_source.ast
18
+ on_node(:if, processed_source.ast) do |node|
19
+ # discard ternary ops, if/else and modifier if/unless nodes
20
+ next if ternary_op?(node)
21
+ next if modifier_if?(node)
22
+ next if elsif?(node)
23
+ next if if_else?(node)
24
+
25
+ if check(node, processed_source.comments)
26
+ add_offence(node, :keyword,
27
+ error_message(node.loc.keyword.source))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -11,7 +11,7 @@ module Rubocop
11
11
  node.loc.begin.line if node.loc.begin && node.loc.begin.is?(';')
12
12
  end
13
13
 
14
- def error_message
14
+ def error_message(_node)
15
15
  'Never use if x; Use the ternary operator instead.'
16
16
  end
17
17
  end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cops checks for inconsistent indentation.
7
+ #
8
+ # @example
9
+ #
10
+ # class A
11
+ # def test
12
+ # puts 'hello'
13
+ # puts 'world'
14
+ # end
15
+ # end
16
+ class IndentationConsistency < Cop
17
+ MSG = 'Inconsistent indentation detected.'
18
+
19
+ def on_begin(node)
20
+ check(node)
21
+ end
22
+
23
+ def on_kwbegin(node)
24
+ check(node)
25
+ end
26
+
27
+ private
28
+
29
+ def check(node)
30
+ children_to_check = node.children.reject do |child|
31
+ # Don't check nodes that have special indentation and will be
32
+ # checked by the AccessModifierIndentation cop.
33
+ AccessModifierIndentation.modifier_node?(child)
34
+ end
35
+
36
+ children_to_check.map(&:loc).each_cons(2) do |child1, child2|
37
+ if child2.line > child1.line && child2.column != child1.column
38
+ expr = child2.expression
39
+ indentation = expr.source_line =~ /\S/
40
+ end_pos = expr.begin_pos
41
+ begin_pos = end_pos - indentation
42
+ add_offence(nil,
43
+ Parser::Source::Range.new(expr.source_buffer,
44
+ begin_pos, end_pos))
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -19,13 +19,8 @@ module Rubocop
19
19
 
20
20
  CORRECT_INDENTATION = 2
21
21
 
22
- def on_begin(node)
23
- check_consistent(node)
24
- end
25
-
26
22
  def on_kwbegin(node)
27
23
  check_indentation(node.loc.end, node.children.first)
28
- check_consistent(node)
29
24
  end
30
25
 
31
26
  def on_block(node)
@@ -155,27 +150,6 @@ module Rubocop
155
150
  body_node.type == :begin &&
156
151
  AccessModifierIndentation.modifier_node?(body_node.children.first)
157
152
  end
158
-
159
- def check_consistent(node)
160
- children_to_check = node.children.reject do |child|
161
- # Don't check nodes that have special indentation and will be
162
- # checked by the AccessModifierIndentation cop.
163
- AccessModifierIndentation.modifier_node?(child)
164
- end
165
-
166
- children_to_check.map(&:loc).each_cons(2) do |child1, child2|
167
- if child2.line > child1.line && child2.column != child1.column
168
- expr = child2.expression
169
- indentation = expr.source_line =~ /\S/
170
- end_pos = expr.begin_pos
171
- begin_pos = end_pos - indentation
172
- add_offence(nil,
173
- Parser::Source::Range.new(expr.source_buffer,
174
- begin_pos, end_pos),
175
- 'Inconsistent indentation detected.')
176
- end
177
- end
178
- end
179
153
  end
180
154
  end
181
155
  end
@@ -21,14 +21,21 @@ module Rubocop
21
21
  # we care only about `call` methods
22
22
  return unless selector == :call
23
23
 
24
- if style == :call && node.loc.selector.nil?
25
- # lambda.() does not have a selector
26
- add_offence(node, :expression)
27
- elsif style == :braces && node.loc.selector
28
- add_offence(node, :expression)
24
+ if offence?(node)
25
+ add_offence(node, :expression) { opposite_style_detected }
26
+ else
27
+ correct_style_detected
29
28
  end
30
29
  end
31
30
 
31
+ private
32
+
33
+ def offence?(node)
34
+ # lambda.() does not have a selector
35
+ style == :call && node.loc.selector.nil? ||
36
+ style == :braces && node.loc.selector
37
+ end
38
+
32
39
  def autocorrect(node)
33
40
  @corrections << lambda do |corrector|
34
41
  if style == :call
@@ -10,23 +10,31 @@ module Rubocop
10
10
  include ConfigurableEnforcedStyle
11
11
 
12
12
  def check(node, _method_name, args, _body)
13
- if style == :require_parentheses &&
14
- arguments?(args) &&
15
- !parentheses?(args)
16
- add_offence(node,
17
- args.loc.expression,
18
- 'Use def with parentheses when there are parameters.')
19
- elsif style == :require_no_parentheses && parentheses?(args)
20
- add_offence(args,
21
- :expression,
22
- 'Use def without parentheses.')
13
+ if style == :require_parentheses
14
+ if arguments?(args) && !parentheses?(args)
15
+ add_offence(node,
16
+ args.loc.expression,
17
+ 'Use def with parentheses when there are ' \
18
+ 'parameters.') do
19
+ opposite_style_detected
20
+ end
21
+ else
22
+ correct_style_detected
23
+ end
24
+ elsif parentheses?(args)
25
+ add_offence(args, :expression, 'Use def without parentheses.') do
26
+ opposite_style_detected
27
+ end
28
+ else
29
+ correct_style_detected
23
30
  end
24
31
  end
25
32
 
26
33
  def autocorrect(node)
27
34
  @corrections << lambda do |corrector|
28
35
  if style == :require_parentheses
29
- corrector.insert_after(node.children[1].loc.expression, ')')
36
+
37
+ corrector.insert_after(args_node(node).loc.expression, ')')
30
38
  expression = node.loc.expression
31
39
  replacement = expression.source.sub(/(def\s+\S+)\s+/, '\1(')
32
40
  corrector.replace(expression, replacement)
@@ -39,6 +47,16 @@ module Rubocop
39
47
 
40
48
  private
41
49
 
50
+ def args_node(def_node)
51
+ if def_node.type == :def
52
+ _method_name, args, _body = *def_node
53
+ args
54
+ else
55
+ _scope, _method_name, args, _body = *def_node
56
+ args
57
+ end
58
+ end
59
+
42
60
  def arguments?(args)
43
61
  args.children.size > 0
44
62
  end
@@ -16,6 +16,7 @@ module Rubocop
16
16
  # elsif cond then b
17
17
  # end
18
18
  class MultilineIfThen < Cop
19
+ include IfNode
19
20
  include IfThenElse
20
21
 
21
22
  def offending_line(node)
@@ -37,17 +38,11 @@ module Rubocop
37
38
  end
38
39
 
39
40
  def end_position(conditional_node)
40
- node = if conditional_node.type == :match_current_line
41
- conditional_node.children.first
42
- else
43
- conditional_node
44
- end
45
-
46
- node.loc.expression.end.end_pos
41
+ conditional_node.loc.expression.end.end_pos
47
42
  end
48
43
 
49
- def error_message
50
- 'Never use then for multi-line if/unless.'
44
+ def error_message(node)
45
+ "Never use then for multi-line #{node.loc.keyword.source}."
51
46
  end
52
47
  end
53
48
  end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for multi-line ternary op expressions.
7
+ class MultilineTernaryOperator < Cop
8
+ MSG =
9
+ 'Avoid multi-line ?: (the ternary operator); use if/unless instead.'
10
+
11
+ def on_if(node)
12
+ loc = node.loc
13
+
14
+ # discard non-ternary ops
15
+ return unless loc.respond_to?(:question)
16
+
17
+ add_offence(node, :expression) if loc.line != loc.colon.line
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,21 +3,6 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for multi-line ternary op expressions.
7
- class MultilineTernaryOperator < Cop
8
- MSG =
9
- 'Avoid multi-line ?: (the ternary operator); use if/unless instead.'
10
-
11
- def on_if(node)
12
- loc = node.loc
13
-
14
- # discard non-ternary ops
15
- return unless loc.respond_to?(:question)
16
-
17
- add_offence(node, :expression) if loc.line != loc.colon.line
18
- end
19
- end
20
-
21
6
  # This cop checks for nested ternary op expressions.
22
7
  class NestedTernaryOperator < Cop
23
8
  MSG = 'Ternary operators must not be nested. Prefer if/else ' +
@@ -6,6 +6,11 @@ module Rubocop
6
6
  # This cop checks for big numeric literals without _ between groups
7
7
  # of digits in them.
8
8
  class NumericLiterals < Cop
9
+ # The parameter is called MinDigits (meaning the minimum number of
10
+ # digits for which an offence can be registered), but essentially it's
11
+ # a Max parameter (the maximum number of something that's allowed).
12
+ include ConfigurableMax
13
+
9
14
  MSG = 'Separate every 3 digits in the integer portion of a number ' \
10
15
  'with underscores(_).'
11
16
 
@@ -19,6 +24,10 @@ module Rubocop
19
24
 
20
25
  private
21
26
 
27
+ def parameter_name
28
+ 'MinDigits'
29
+ end
30
+
22
31
  def check(node)
23
32
  int = integer_part(node)
24
33
 
@@ -26,12 +35,31 @@ module Rubocop
26
35
  return if int.start_with?('0')
27
36
 
28
37
  if int.size >= min_digits
29
- if int =~ /\d{4}/ || int =~ /_\d{1,2}_/
30
- add_offence(node, :expression)
38
+ case int
39
+ when /^\d+$/
40
+ add_offence(node, :expression) { self.max = int.size }
41
+ when /\d{4}/, /_\d{1,2}_/
42
+ add_offence(node, :expression) do
43
+ self.config_to_allow_offences = { 'Enabled' => false }
44
+ end
31
45
  end
32
46
  end
33
47
  end
34
48
 
49
+ def autocorrect(node)
50
+ @corrections << lambda do |corrector|
51
+ int = node.loc.expression.source.to_i
52
+ formatted_int = int
53
+ .abs
54
+ .to_s
55
+ .reverse
56
+ .gsub(/...(?=.)/, '\&_')
57
+ .reverse
58
+ formatted_int.insert(0, '-') if int < 0
59
+ corrector.replace(node.loc.expression, formatted_int)
60
+ end
61
+ end
62
+
35
63
  def integer_part(node)
36
64
  node.loc.expression.source.sub(/^[+-]/, '').split('.').first
37
65
  end
@@ -3,6 +3,7 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
+ # TODO: Make configurable.
6
7
  # Checks for uses of if/then/else/end on a single line.
7
8
  class OneLineConditional < Cop
8
9
  include IfThenElse
@@ -11,7 +12,7 @@ module Rubocop
11
12
  node.loc.expression.line unless node.loc.expression.source =~ /\n/
12
13
  end
13
14
 
14
- def error_message
15
+ def error_message(_node)
15
16
  'Favor the ternary operator (?:) over if/then/else/end constructs.'
16
17
  end
17
18
  end
@@ -8,12 +8,16 @@ module Rubocop
8
8
  # On Ruby 2.0+ keyword arguments can optionally
9
9
  # be excluded from the total count.
10
10
  class ParameterLists < Cop
11
+ include ConfigurableMax
12
+
11
13
  MSG = 'Avoid parameter lists longer than %d parameters.'
12
14
 
13
15
  def on_args(node)
14
- if args_count(node) > max_params
15
- add_offence(node, :expression,
16
- sprintf(MSG, max_params))
16
+ count = args_count(node)
17
+ if count > max_params
18
+ add_offence(node, :expression, sprintf(MSG, max_params)) do
19
+ self.max = count
20
+ end
17
21
  end
18
22
  end
19
23
 
@@ -4,13 +4,13 @@ module Rubocop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop checks for the presence of superfluous parentheses around the
7
- # condition of if/while/until.
7
+ # condition of if/unless/while/until.
8
8
  class ParenthesesAroundCondition < Cop
9
- ASGN_NODES = [:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn]
10
- MSG = "Don't use parentheses around the condition of an " +
11
- 'if/unless/while/until'
9
+ include IfNode
10
+ include SafeAssignment
12
11
 
13
12
  def on_if(node)
13
+ return if ternary_op?(node)
14
14
  process_control_op(node)
15
15
  end
16
16
 
@@ -31,16 +31,14 @@ module Rubocop
31
31
  # allow safe assignment
32
32
  return if safe_assignment?(cond) && safe_assignment_allowed?
33
33
 
34
- add_offence(cond, :expression)
34
+ add_offence(cond, :expression, message(node))
35
35
  end
36
36
  end
37
37
 
38
- def safe_assignment?(node)
39
- node.children.size == 1 && ASGN_NODES.include?(node.children[0].type)
40
- end
41
-
42
- def safe_assignment_allowed?
43
- cop_config['AllowSafeAssignment']
38
+ def message(node)
39
+ kw = node.loc.keyword.source
40
+ article = kw == 'while' ? 'a' : 'an'
41
+ "Don't use parentheses around the condition of #{article} #{kw}."
44
42
  end
45
43
 
46
44
  def autocorrect(node)