rubocop 0.39.0 → 0.40.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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -1
  3. data/config/default.yml +65 -2
  4. data/config/disabled.yml +0 -28
  5. data/config/enabled.yml +40 -0
  6. data/lib/rubocop.rb +3 -0
  7. data/lib/rubocop/ast_node.rb +28 -13
  8. data/lib/rubocop/cached_data.rb +15 -2
  9. data/lib/rubocop/cli.rb +24 -8
  10. data/lib/rubocop/config.rb +3 -3
  11. data/lib/rubocop/config_loader.rb +0 -7
  12. data/lib/rubocop/cop/cop.rb +2 -2
  13. data/lib/rubocop/cop/lint/condition_position.rb +3 -1
  14. data/lib/rubocop/cop/lint/else_layout.rb +3 -2
  15. data/lib/rubocop/cop/lint/end_alignment.rb +2 -2
  16. data/lib/rubocop/cop/lint/nested_method_definition.rb +15 -9
  17. data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
  18. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
  19. data/lib/rubocop/cop/lint/useless_access_modifier.rb +86 -20
  20. data/lib/rubocop/cop/lint/useless_array_splat.rb +56 -0
  21. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  22. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +11 -25
  23. data/lib/rubocop/cop/mixin/if_node.rb +4 -0
  24. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +14 -12
  25. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +75 -9
  26. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -1
  27. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -2
  28. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -5
  29. data/lib/rubocop/cop/performance/case_when_splat.rb +71 -44
  30. data/lib/rubocop/cop/performance/detect.rb +28 -18
  31. data/lib/rubocop/cop/performance/end_with.rb +1 -1
  32. data/lib/rubocop/cop/performance/redundant_merge.rb +29 -11
  33. data/lib/rubocop/cop/performance/start_with.rb +1 -1
  34. data/lib/rubocop/cop/performance/string_replacement.rb +39 -20
  35. data/lib/rubocop/cop/rails/action_filter.rb +1 -2
  36. data/lib/rubocop/cop/rails/date.rb +2 -5
  37. data/lib/rubocop/cop/rails/time_zone.rb +3 -6
  38. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +57 -0
  39. data/lib/rubocop/cop/style/alias.rb +10 -3
  40. data/lib/rubocop/cop/style/align_parameters.rb +8 -2
  41. data/lib/rubocop/cop/style/and_or.rb +29 -21
  42. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  43. data/lib/rubocop/cop/style/collection_methods.rb +1 -2
  44. data/lib/rubocop/cop/style/comment_indentation.rb +1 -1
  45. data/lib/rubocop/cop/style/conditional_assignment.rb +13 -7
  46. data/lib/rubocop/cop/style/empty_case_condition.rb +96 -0
  47. data/lib/rubocop/cop/style/encoding.rb +9 -5
  48. data/lib/rubocop/cop/style/extra_spacing.rb +22 -7
  49. data/lib/rubocop/cop/style/file_name.rb +7 -2
  50. data/lib/rubocop/cop/style/guard_clause.rb +18 -10
  51. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  52. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -1
  53. data/lib/rubocop/cop/style/indentation_width.rb +7 -4
  54. data/lib/rubocop/cop/style/lambda.rb +98 -30
  55. data/lib/rubocop/cop/style/line_end_concatenation.rb +5 -0
  56. data/lib/rubocop/cop/style/multiline_array_brace_layout.rb +34 -9
  57. data/lib/rubocop/cop/style/multiline_assignment_layout.rb +2 -1
  58. data/lib/rubocop/cop/style/multiline_hash_brace_layout.rb +42 -17
  59. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +39 -14
  60. data/lib/rubocop/cop/style/multiline_method_definition_brace_layout.rb +36 -15
  61. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +8 -6
  62. data/lib/rubocop/cop/style/negated_while.rb +2 -1
  63. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +15 -0
  64. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -8
  65. data/lib/rubocop/cop/style/next.rb +1 -1
  66. data/lib/rubocop/cop/style/not.rb +5 -2
  67. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  68. data/lib/rubocop/cop/style/raise_args.rb +70 -7
  69. data/lib/rubocop/cop/style/redundant_exception.rb +34 -20
  70. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -1
  71. data/lib/rubocop/cop/style/space_after_colon.rb +14 -10
  72. data/lib/rubocop/cop/style/space_after_comma.rb +5 -0
  73. data/lib/rubocop/cop/style/space_after_not.rb +3 -4
  74. data/lib/rubocop/cop/style/space_after_semicolon.rb +5 -0
  75. data/lib/rubocop/cop/style/space_around_operators.rb +2 -1
  76. data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
  77. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  78. data/lib/rubocop/cop/style/string_methods.rb +1 -2
  79. data/lib/rubocop/cop/style/symbol_proc.rb +7 -1
  80. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +25 -0
  81. data/lib/rubocop/cop/style/word_array.rb +50 -22
  82. data/lib/rubocop/cop/util.rb +0 -4
  83. data/lib/rubocop/formatter/clang_style_formatter.rb +38 -22
  84. data/lib/rubocop/options.rb +45 -10
  85. data/lib/rubocop/path_util.rb +2 -34
  86. data/lib/rubocop/result_cache.rb +10 -4
  87. data/lib/rubocop/runner.rb +5 -3
  88. data/lib/rubocop/version.rb +1 -1
  89. metadata +7 -4
@@ -41,6 +41,11 @@ module RuboCop
41
41
  operator_range = range_with_surrounding_space(operator_range,
42
42
  :right,
43
43
  !:with_newline)
44
+ one_more_char = operator_range.resize(operator_range.size + 1)
45
+ # Don't create a double backslash at the end of the line, in case
46
+ # there already was a backslash after the concatenation operator.
47
+ operator_range = one_more_char if one_more_char.source.end_with?('\\')
48
+
44
49
  ->(corrector) { corrector.replace(operator_range, '\\') }
45
50
  end
46
51
 
@@ -4,35 +4,54 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # This cop checks that the closing brace in an array literal is
8
- # symmetrical with respect to the opening brace and the array
9
- # elements.
7
+ # This cop checks that the closing brace in an array literal is either
8
+ # on the same line as the last array element, or a new line.
9
+ #
10
+ # When using the `symmetrical` (default) style:
10
11
  #
11
12
  # If an array's opening brace is on the same line as the first element
12
13
  # of the array, then the closing brace should be on the same line as
13
14
  # the last element of the array.
14
15
  #
15
- # If an array's opening brace is on a separate line from the first
16
- # element of the array, then the closing brace should be on the line
16
+ # If an array's opening brace is on the line above the first element
17
+ # of the array, then the closing brace should be on the line below
18
+ # the last element of the array.
19
+ #
20
+ # When using the `new_line` style:
21
+ #
22
+ # The closing brace of a multi-line array literal must be on the line
17
23
  # after the last element of the array.
18
24
  #
25
+ # When using the `same_line` style:
26
+ #
27
+ # The closing brace of a multi-line array literal must be on the same
28
+ # line as the last element of the array.
29
+ #
19
30
  # @example
20
31
  #
21
- # # bad
32
+ # # symmetrical: bad
33
+ # # new_line: good
34
+ # # same_line: bad
22
35
  # [ :a,
23
36
  # :b
24
37
  # ]
25
38
  #
26
- # # bad
39
+ # # symmetrical: bad
40
+ # # new_line: bad
41
+ # # same_line: good
27
42
  # [
28
43
  # :a,
29
44
  # :b ]
30
45
  #
31
- # # good
46
+ # # symmetrical: good
47
+ # # new_line: bad
48
+ # # same_line: good
32
49
  # [ :a,
33
50
  # :b ]
34
51
  #
35
- # #good
52
+ # # symmetrical: good
53
+ # # new_line: good
54
+ # # same_line: bad
36
55
  # [
37
56
  # :a,
38
57
  # :b
@@ -48,6 +67,12 @@ module RuboCop
48
67
  'the last array element when opening brace is on a separate line ' \
49
68
  'from the first array element.'.freeze
50
69
 
70
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing array brace must be on the line ' \
71
+ 'after the last array element.'.freeze
72
+
73
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing array brace must be on the same ' \
74
+ 'line as teh last array element.'.freeze
75
+
51
76
  def on_array(node)
52
77
  check_brace_layout(node)
53
78
  end
@@ -74,7 +74,8 @@ module RuboCop
74
74
  range = Parser::Source::Range.new(
75
75
  node.source_range.source_buffer,
76
76
  node.loc.operator.end_pos,
77
- extract_rhs(node).source_range.begin_pos)
77
+ extract_rhs(node).source_range.begin_pos
78
+ )
78
79
 
79
80
  ->(corrector) { corrector.replace(range, ' ') }
80
81
  end
@@ -4,38 +4,57 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # This cop checks that the closing brace in an a hash literal is
8
- # symmetrical with respect to the opening brace and the hash
9
- # elements.
7
+ # This cop checks that the closing brace in a hash literal is either
8
+ # on the same line as the last hash element, or a new line.
9
+ #
10
+ # When using the `symmetrical` (default) style:
10
11
  #
11
12
  # If a hash's opening brace is on the same line as the first element
12
13
  # of the hash, then the closing brace should be on the same line as
13
14
  # the last element of the hash.
14
15
  #
15
- # If a hash's opening brace is on a separate line from the first
16
- # element of the hash, then the closing brace should be on the line
16
+ # If a hash's opening brace is on the line above the first element
17
+ # of the hash, then the closing brace should be on the line below
18
+ # the last element of the hash.
19
+ #
20
+ # When using the `new_line` style:
21
+ #
22
+ # The closing brace of a multi-line hash literal must be on the line
17
23
  # after the last element of the hash.
18
24
  #
25
+ # When using the `same_line` style:
26
+ #
27
+ # The closing brace of a multi-line hash literal must be on the same
28
+ # line as the last element of the hash.
29
+ #
19
30
  # @example
20
31
  #
21
- # # bad
22
- # { a: 'a',
23
- # b: 'b'
32
+ # # symmetrical: bad
33
+ # # new_line: good
34
+ # # same_line: bad
35
+ # { a: 1,
36
+ # b: 2
24
37
  # }
25
38
  #
26
- # # bad
39
+ # # symmetrical: bad
40
+ # # new_line: bad
41
+ # # same_line: good
27
42
  # {
28
- # a: 'a',
29
- # b: 'b' }
43
+ # a: 1,
44
+ # b: 2 }
30
45
  #
31
- # # good
32
- # { a: 'a',
33
- # b: 'b' }
46
+ # # symmetrical: good
47
+ # # new_line: bad
48
+ # # same_line: good
49
+ # { a: 1,
50
+ # b: 2 }
34
51
  #
35
- # #good
52
+ # # symmetrical: good
53
+ # # new_line: good
54
+ # # same_line: bad
36
55
  # {
37
- # a: 'a',
38
- # b: 'b'
56
+ # a: 1,
57
+ # b: 2
39
58
  # }
40
59
  class MultilineHashBraceLayout < Cop
41
60
  include MultilineLiteralBraceLayout
@@ -48,6 +67,12 @@ module RuboCop
48
67
  'the last hash element when opening brace is on a separate line ' \
49
68
  'from the first hash element.'.freeze
50
69
 
70
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing hash brace must be on the line ' \
71
+ 'after the last hash element.'.freeze
72
+
73
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing hash brace must be on the same ' \
74
+ 'line as the last hash element.'.freeze
75
+
51
76
  def on_hash(node)
52
77
  check_brace_layout(node)
53
78
  end
@@ -4,35 +4,54 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # This cop checks that the closing brace in a method call is
8
- # symmetrical with respect to the opening brace and the method
9
- # arguments.
7
+ # This cop checks that the closing brace in a method call is either
8
+ # on the same line as the last method argument, or a new line.
10
9
  #
11
- # If a method call's opening brace is on the same line as the
12
- # first argument of the call, then the closing brace should be
13
- # on the same line as the last argument of the call.
10
+ # When using the `symmetrical` (default) style:
14
11
  #
15
- # If a method call's opening brace is on a separate line from
16
- # the first argument of the call, then the closing brace should
17
- # be on the line after the last argument of the call.
12
+ # If a method call's opening brace is on the same line as the first
13
+ # argument of the call, then the closing brace should be on the same
14
+ # line as the last argument of the call.
15
+ #
16
+ # If an method call's opening brace is on the line above the first
17
+ # argument of the call, then the closing brace should be on the line
18
+ # below the last argument of the call.
19
+ #
20
+ # When using the `new_line` style:
21
+ #
22
+ # The closing brace of a multi-line method call must be on the line
23
+ # after the last argument of the call.
24
+ #
25
+ # When using the `same_line` style:
26
+ #
27
+ # The closing brace of a multi-line method call must be on the same
28
+ # line as the last argument of the call.
18
29
  #
19
30
  # @example
20
31
  #
21
- # # bad
32
+ # # symmetrical: bad
33
+ # # new_line: good
34
+ # # same_line: bad
22
35
  # foo(a,
23
36
  # b
24
- # )
37
+ # )
25
38
  #
26
- # # bad
39
+ # # symmetrical: bad
40
+ # # new_line: bad
41
+ # # same_line: good
27
42
  # foo(
28
43
  # a,
29
44
  # b)
30
45
  #
31
- # # good
46
+ # # symmetrical: good
47
+ # # new_line: bad
48
+ # # same_line: good
32
49
  # foo(a,
33
50
  # b)
34
51
  #
35
- # #good
52
+ # # symmetrical: good
53
+ # # new_line: good
54
+ # # same_line: bad
36
55
  # foo(
37
56
  # a,
38
57
  # b
@@ -48,6 +67,12 @@ module RuboCop
48
67
  'line after the last argument when opening brace is on a separate ' \
49
68
  'line from the first argument.'.freeze
50
69
 
70
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing method call brace must be on ' \
71
+ 'the line after the last argument.'.freeze
72
+
73
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing method call brace must be on ' \
74
+ 'the same line as the last argument.'.freeze
75
+
51
76
  def on_send(node)
52
77
  check_brace_layout(node)
53
78
  end
@@ -4,43 +4,58 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # This cop checks that the closing brace in a method definition is
8
- # symmetrical with respect to the opening brace and the method
9
- # parameters.
7
+ # This cop checks that the closing brace in a method definition is either
8
+ # on the same line as the last method parameter, or a new line.
9
+ #
10
+ # When using the `symmetrical` (default) style:
10
11
  #
11
12
  # If a method definition's opening brace is on the same line as the
12
13
  # first parameter of the definition, then the closing brace should be
13
14
  # on the same line as the last parameter of the definition.
14
15
  #
15
- # If a method definition's opening brace is on a separate line from
16
- # the first parameter of the definition, then the closing brace should
17
- # be on the line after the last parameter of the definition.
16
+ # If an method definition's opening brace is on the line above the first
17
+ # parameter of the definition, then the closing brace should be on the
18
+ # line below the last parameter of the definition.
19
+ #
20
+ # When using the `new_line` style:
21
+ #
22
+ # The closing brace of a multi-line method definition must be on the line
23
+ # after the last parameter of the definition.
24
+ #
25
+ # When using the `same_line` style:
26
+ #
27
+ # The closing brace of a multi-line method definition must be on the same
28
+ # line as the last parameter of the definition.
18
29
  #
19
30
  # @example
20
31
  #
21
- # # bad
32
+ # # symmetrical: bad
33
+ # # new_line: good
34
+ # # same_line: bad
22
35
  # def foo(a,
23
36
  # b
24
- # )
25
- # end
37
+ # )
26
38
  #
27
- # # bad
39
+ # # symmetrical: bad
40
+ # # new_line: bad
41
+ # # same_line: good
28
42
  # def foo(
29
43
  # a,
30
44
  # b)
31
- # end
32
45
  #
33
- # # good
46
+ # # symmetrical: good
47
+ # # new_line: bad
48
+ # # same_line: good
34
49
  # def foo(a,
35
50
  # b)
36
- # end
37
51
  #
38
- # #good
52
+ # # symmetrical: good
53
+ # # new_line: good
54
+ # # same_line: bad
39
55
  # def foo(
40
56
  # a,
41
57
  # b
42
58
  # )
43
- # end
44
59
  class MultilineMethodDefinitionBraceLayout < Cop
45
60
  include OnMethodDef
46
61
  include MultilineLiteralBraceLayout
@@ -53,6 +68,12 @@ module RuboCop
53
68
  'line after the last parameter when opening brace is on a separate ' \
54
69
  'line from the first parameter.'.freeze
55
70
 
71
+ ALWAYS_NEW_LINE_MESSAGE = 'Closing method definition brace must be ' \
72
+ 'on the line after the last parameter.'.freeze
73
+
74
+ ALWAYS_SAME_LINE_MESSAGE = 'Closing method definition brace must be ' \
75
+ 'on the same line as the last parameter.'.freeze
76
+
56
77
  def on_method_def(_node, _method_name, args, _body)
57
78
  check_brace_layout(args)
58
79
  end
@@ -6,17 +6,19 @@ module RuboCop
6
6
  module Style
7
7
  # This cop checks for multi-line ternary op expressions.
8
8
  class MultilineTernaryOperator < Cop
9
- MSG = 'Avoid multi-line ?: (the ternary operator);' \
10
- ' use `if`/`unless` instead.'.freeze
9
+ include IfNode
10
+
11
+ MSG = 'Avoid multi-line ternary operators, ' \
12
+ 'use `if` or `unless` instead.'.freeze
11
13
 
12
14
  def on_if(node)
13
15
  _condition, _if_branch, else_branch = *node
14
- loc = node.loc
15
16
 
16
- # discard non-ternary ops
17
- return unless loc.respond_to?(:question)
17
+ return unless ternary?(node)
18
18
 
19
- add_offense(node, :expression) if loc.line != else_branch.loc.line
19
+ unless node.loc.line == else_branch.loc.line
20
+ add_offense(node, :expression)
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -37,7 +37,8 @@ module RuboCop
37
37
  pos_condition, _method, = *condition
38
38
  corrector.replace(
39
39
  node.loc.keyword,
40
- node.type == :while ? 'until' : 'while')
40
+ node.type == :while ? 'until' : 'while'
41
+ )
41
42
  corrector.replace(condition.source_range, pos_condition.source)
42
43
  end
43
44
  end
@@ -39,6 +39,21 @@ module RuboCop
39
39
  RSPEC_MATCHERS.include?(send.method_name) &&
40
40
  send.method_args.one?
41
41
  end
42
+
43
+ def autocorrect(nested)
44
+ _scope, _method_name, *args = *nested
45
+
46
+ first_arg = args.first.source_range
47
+ last_arg = args.last.source_range
48
+
49
+ first_arg_with_space = range_with_surrounding_space(first_arg, :left)
50
+ leading_space = first_arg_with_space.begin.resize(1)
51
+
52
+ lambda do |corrector|
53
+ corrector.replace(leading_space, '(')
54
+ corrector.insert_after(last_arg, ')')
55
+ end
56
+ end
42
57
  end
43
58
  end
44
59
  end
@@ -6,19 +6,16 @@ module RuboCop
6
6
  module Style
7
7
  # This cop checks for nested ternary op expressions.
8
8
  class NestedTernaryOperator < Cop
9
- MSG = 'Ternary operators must not be nested. Prefer `if`/`else` ' \
9
+ include IfNode
10
+
11
+ MSG = 'Ternary operators must not be nested. Prefer `if` or `else` ' \
10
12
  'constructs instead.'.freeze
11
13
 
12
14
  def on_if(node)
13
- loc = node.loc
14
-
15
- # discard non-ternary ops
16
- return unless loc.respond_to?(:question)
15
+ return unless ternary?(node)
17
16
 
18
17
  node.each_descendant(:if) do |nested_if_node|
19
- if nested_if_node.loc.respond_to?(:question)
20
- add_offense(nested_if_node, :expression)
21
- end
18
+ add_offense(nested_if_node, :expression) if ternary?(nested_if_node)
22
19
  end
23
20
  end
24
21
  end
@@ -82,7 +82,7 @@ module RuboCop
82
82
 
83
83
  def simple_if_without_break?(node)
84
84
  return false unless node.if_type?
85
- return false if ternary_op?(node)
85
+ return false if ternary?(node)
86
86
  return false if if_else?(node)
87
87
  return false if style == :skip_modifier_ifs && modifier_if?(node)
88
88
  return false if !modifier_if?(node) && !min_body_length?(node)