rubocop 0.59.2 → 0.60.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 (155) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -2
  3. data/config/default.yml +2960 -552
  4. data/lib/rubocop.rb +1 -0
  5. data/lib/rubocop/ast/builder.rb +29 -29
  6. data/lib/rubocop/ast/node.rb +29 -25
  7. data/lib/rubocop/ast/node/args_node.rb +1 -1
  8. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +1 -1
  9. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +26 -0
  10. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +5 -1
  11. data/lib/rubocop/ast/node/pair_node.rb +8 -1
  12. data/lib/rubocop/ast/node/str_node.rb +1 -1
  13. data/lib/rubocop/cached_data.rb +2 -2
  14. data/lib/rubocop/config.rb +1 -1
  15. data/lib/rubocop/config_loader.rb +8 -0
  16. data/lib/rubocop/cop/autocorrect_logic.rb +7 -1
  17. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  18. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -1
  19. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -1
  20. data/lib/rubocop/cop/generator.rb +10 -3
  21. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  22. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
  23. data/lib/rubocop/cop/layout/align_hash.rb +9 -1
  24. data/lib/rubocop/cop/layout/block_end_newline.rb +2 -4
  25. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +7 -7
  26. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  28. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  29. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +1 -2
  30. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  31. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +25 -25
  32. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +1 -1
  34. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
  35. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  36. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  37. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +1 -1
  38. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -1
  39. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  40. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  41. data/lib/rubocop/cop/layout/indent_hash.rb +1 -1
  42. data/lib/rubocop/cop/layout/indent_heredoc.rb +2 -2
  43. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -1
  44. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  45. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  46. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +1 -1
  47. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +84 -43
  49. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  51. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -2
  52. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +1 -1
  53. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +2 -2
  54. data/lib/rubocop/cop/lint/ambiguous_operator.rb +5 -5
  55. data/lib/rubocop/cop/lint/assignment_in_condition.rb +10 -20
  56. data/lib/rubocop/cop/lint/ensure_return.rb +3 -0
  57. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +3 -3
  58. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  59. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -2
  60. data/lib/rubocop/cop/lint/percent_symbol_array.rb +10 -7
  61. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +3 -4
  62. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -2
  63. data/lib/rubocop/cop/lint/syntax.rb +3 -2
  64. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -3
  65. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -7
  66. data/lib/rubocop/cop/metrics/abc_size.rb +1 -17
  67. data/lib/rubocop/cop/metrics/line_length.rb +14 -10
  68. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +45 -0
  69. data/lib/rubocop/cop/mixin/check_assignment.rb +12 -6
  70. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  71. data/lib/rubocop/cop/mixin/configurable_formatting.rb +0 -2
  72. data/lib/rubocop/cop/mixin/configurable_max.rb +4 -2
  73. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  74. data/lib/rubocop/cop/mixin/configurable_numbering.rb +2 -2
  75. data/lib/rubocop/cop/mixin/hash_alignment.rb +32 -5
  76. data/lib/rubocop/cop/mixin/heredoc.rb +1 -1
  77. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -4
  78. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  79. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -0
  80. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  81. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  82. data/lib/rubocop/cop/naming/constant_name.rb +1 -1
  83. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  84. data/lib/rubocop/cop/naming/method_name.rb +2 -0
  85. data/lib/rubocop/cop/naming/variable_number.rb +1 -1
  86. data/lib/rubocop/cop/offense.rb +1 -1
  87. data/lib/rubocop/cop/performance/regexp_match.rb +1 -1
  88. data/lib/rubocop/cop/performance/sample.rb +3 -2
  89. data/lib/rubocop/cop/performance/start_with.rb +1 -1
  90. data/lib/rubocop/cop/performance/string_replacement.rb +1 -1
  91. data/lib/rubocop/cop/rails/date.rb +8 -8
  92. data/lib/rubocop/cop/rails/dynamic_find_by.rb +1 -1
  93. data/lib/rubocop/cop/rails/exit.rb +8 -9
  94. data/lib/rubocop/cop/rails/output_safety.rb +3 -3
  95. data/lib/rubocop/cop/rails/read_write_attribute.rb +5 -4
  96. data/lib/rubocop/cop/rails/refute_methods.rb +13 -13
  97. data/lib/rubocop/cop/rails/reversible_migration.rb +2 -1
  98. data/lib/rubocop/cop/rails/skips_model_validations.rb +17 -0
  99. data/lib/rubocop/cop/registry.rb +11 -2
  100. data/lib/rubocop/cop/style/and_or.rb +3 -3
  101. data/lib/rubocop/cop/style/collection_methods.rb +26 -0
  102. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  103. data/lib/rubocop/cop/style/encoding.rb +1 -1
  104. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  105. data/lib/rubocop/cop/style/for.rb +3 -3
  106. data/lib/rubocop/cop/style/global_vars.rb +1 -1
  107. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  108. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -13
  109. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  110. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  111. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +4 -7
  112. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  113. data/lib/rubocop/cop/style/module_function.rb +1 -1
  114. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  115. data/lib/rubocop/cop/style/mutable_constant.rb +15 -1
  116. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  117. data/lib/rubocop/cop/style/not.rb +2 -1
  118. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +6 -6
  119. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  120. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  121. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  122. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
  123. data/lib/rubocop/cop/style/proc.rb +1 -1
  124. data/lib/rubocop/cop/style/redundant_freeze.rb +10 -0
  125. data/lib/rubocop/cop/style/redundant_parentheses.rb +6 -2
  126. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  127. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  128. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  129. data/lib/rubocop/cop/style/ternary_parentheses.rb +4 -3
  130. data/lib/rubocop/cop/style/unneeded_condition.rb +2 -2
  131. data/lib/rubocop/cop/style/unneeded_percent_q.rb +2 -2
  132. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  133. data/lib/rubocop/cop/team.rb +3 -2
  134. data/lib/rubocop/cop/util.rb +2 -22
  135. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  136. data/lib/rubocop/cop/variable_force/variable.rb +3 -4
  137. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  138. data/lib/rubocop/formatter/base_formatter.rb +3 -3
  139. data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -1
  140. data/lib/rubocop/formatter/formatter_set.rb +14 -14
  141. data/lib/rubocop/formatter/html_formatter.rb +4 -4
  142. data/lib/rubocop/formatter/json_formatter.rb +13 -13
  143. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -4
  144. data/lib/rubocop/magic_comment.rb +4 -4
  145. data/lib/rubocop/node_pattern.rb +17 -17
  146. data/lib/rubocop/options.rb +93 -82
  147. data/lib/rubocop/result_cache.rb +9 -1
  148. data/lib/rubocop/rspec/expect_offense.rb +2 -2
  149. data/lib/rubocop/rspec/shared_contexts.rb +11 -11
  150. data/lib/rubocop/rspec/shared_examples.rb +4 -4
  151. data/lib/rubocop/string_interpreter.rb +1 -1
  152. data/lib/rubocop/version.rb +1 -1
  153. metadata +6 -13
  154. data/config/disabled.yml +0 -161
  155. data/config/enabled.yml +0 -2092
@@ -7,6 +7,8 @@ module RuboCop
7
7
  # validations which are listed in
8
8
  # http://guides.rubyonrails.org/active_record_validations.html#skipping-validations
9
9
  #
10
+ # Methods may be ignored from this rule by configuring a `Whitelist`.
11
+ #
10
12
  # @example
11
13
  # # bad
12
14
  # Article.first.decrement!(:view_count)
@@ -23,6 +25,16 @@ module RuboCop
23
25
  # # good
24
26
  # user.update(website: 'example.com')
25
27
  # FileUtils.touch('file')
28
+ #
29
+ # @example Whitelist: ["touch"]
30
+ # # bad
31
+ # DiscussionBoard.decrement_counter(:post_count, 5)
32
+ # DiscussionBoard.increment_counter(:post_count, 5)
33
+ # person.toggle :active
34
+ #
35
+ # # good
36
+ # user.touch
37
+ #
26
38
  class SkipsModelValidations < Cop
27
39
  MSG = 'Avoid using `%<method>s` because it skips validations.'.freeze
28
40
 
@@ -42,6 +54,7 @@ module RuboCop
42
54
  PATTERN
43
55
 
44
56
  def on_send(node)
57
+ return if whitelist.include?(node.method_name.to_s)
45
58
  return unless blacklist.include?(node.method_name.to_s)
46
59
 
47
60
  _receiver, method_name, *args = *node
@@ -64,6 +77,10 @@ module RuboCop
64
77
  def blacklist
65
78
  cop_config['Blacklist'] || []
66
79
  end
80
+
81
+ def whitelist
82
+ cop_config['Whitelist'] || []
83
+ end
67
84
  end
68
85
  end
69
86
  end
@@ -117,9 +117,18 @@ module RuboCop
117
117
  @registry.size
118
118
  end
119
119
 
120
- def enabled(config, only)
120
+ def enabled(config, only, only_safe = false)
121
121
  select do |cop|
122
- config.for_cop(cop).fetch('Enabled') || only.include?(cop.cop_name)
122
+ only.include?(cop.cop_name) || enabled?(cop, config, only_safe)
123
+ end
124
+ end
125
+
126
+ def enabled?(cop, config, only_safe)
127
+ cfg = config.for_cop(cop)
128
+ if only_safe
129
+ cfg.fetch('Enabled') && cfg.fetch('Safe', true)
130
+ else
131
+ cfg.fetch('Enabled')
123
132
  end
124
133
  end
125
134
 
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop checks for uses of `and` and `or`, and suggests using `&&` and
7
- # `||` instead. It can be configured to check only in conditions, or in
7
+ # `||` instead. It can be configured to check only in conditions or in
8
8
  # all contexts.
9
9
  #
10
10
  # @example EnforcedStyle: always (default)
@@ -74,8 +74,8 @@ module RuboCop
74
74
  private
75
75
 
76
76
  def on_conditionals(node)
77
- node.condition.each_node(*LOGICAL_OPERATOR_NODES) do |logical_node|
78
- process_logical_operator(logical_node)
77
+ node.condition.each_node(*AST::Node::OPERATOR_KEYWORDS) do |operator|
78
+ process_logical_operator(operator)
79
79
  end
80
80
  end
81
81
 
@@ -9,6 +9,32 @@ module RuboCop
9
9
  # Unfortunately we cannot actually know if a method is from
10
10
  # Enumerable or not (static analysis limitation), so this cop
11
11
  # can yield some false positives.
12
+ #
13
+ # You can customize the mapping from undesired method to desired method.
14
+ #
15
+ # e.g. to use `detect` over `find`:
16
+ #
17
+ # Style/CollectionMethods:
18
+ # PreferredMethods:
19
+ # find: detect
20
+ #
21
+ # The default mapping for `PreferredMethods` behaves as follows.
22
+ #
23
+ # @example
24
+ # # bad
25
+ # items.collect
26
+ # items.collect!
27
+ # items.inject
28
+ # items.detect
29
+ # items.find_all
30
+ #
31
+ # # good
32
+ # items.map
33
+ # items.map!
34
+ # items.reduce
35
+ # items.find
36
+ # items.select
37
+ #
12
38
  class CollectionMethods < Cop
13
39
  include MethodPreference
14
40
 
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop checks for the use of a method, the result of which
7
- # would be a literal, like an empty array, hash or string.
7
+ # would be a literal, like an empty array, hash, or string.
8
8
  #
9
9
  # @example
10
10
  # # bad
@@ -13,7 +13,7 @@ module RuboCop
13
13
  include RangeHelp
14
14
 
15
15
  MSG_UNNECESSARY = 'Unnecessary utf-8 encoding comment.'.freeze
16
- ENCODING_PATTERN = /#.*coding\s?[:=]\s?(?:UTF|utf)-8/
16
+ ENCODING_PATTERN = /#.*coding\s?[:=]\s?(?:UTF|utf)-8/.freeze
17
17
  SHEBANG = '#!'.freeze
18
18
 
19
19
  def investigate(processed_source)
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for places where Integer#even? or Integer#odd?
7
- # should have been used.
6
+ # This cop checks for places where `Integer#even?` or `Integer#odd?`
7
+ # can be used.
8
8
  #
9
9
  # @example
10
10
  #
@@ -3,10 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop looks for uses of the *for* keyword, or *each* method. The
6
+ # This cop looks for uses of the `for` keyword or `each` method. The
7
7
  # preferred alternative is set in the EnforcedStyle configuration
8
- # parameter. An *each* call with a block on a single line is always
9
- # allowed, however.
8
+ # parameter. An `each` call with a block on a single line is always
9
+ # allowed.
10
10
  #
11
11
  # @example EnforcedStyle: each (default)
12
12
  # # bad
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cops looks for uses of global variables.
6
+ # This cop looks for uses of global variables.
7
7
  # It does not report offenses for built-in global variables.
8
8
  # Built-in global variables are allowed by default. Additionally
9
9
  # users can allow additional variables via the AllowedVariables option.
@@ -71,7 +71,7 @@ module RuboCop
71
71
  branches = expand_elses(node.else_branch).unshift(node.if_branch)
72
72
 
73
73
  # return if any branch is empty. An empty branch can be an `if`
74
- # without an `else`, or a branch that contains only comments.
74
+ # without an `else` or a branch that contains only comments.
75
75
  return if branches.any?(&:nil?)
76
76
 
77
77
  check_branches(branches)
@@ -31,8 +31,6 @@ module RuboCop
31
31
  ASSIGNMENT_TYPES = %i[lvasgn casgn cvasgn
32
32
  gvasgn ivasgn masgn].freeze
33
33
 
34
- NAMED_CAPTURE = /\?<.+>/
35
-
36
34
  def on_if(node)
37
35
  return unless eligible_node?(node)
38
36
  return if named_capture_in_condition?(node)
@@ -69,17 +67,7 @@ module RuboCop
69
67
  return false if node.parent.nil?
70
68
  return true if ASSIGNMENT_TYPES.include?(node.parent.type)
71
69
 
72
- if node.parent.send_type?
73
- _receiver, _name, *args = *node.parent
74
- return !method_uses_parens?(node.parent, args.first)
75
- end
76
-
77
- false
78
- end
79
-
80
- def method_uses_parens?(node, limit)
81
- source = node.source_range.source_line[0...limit.loc.column]
82
- source =~ /\s*\(\s*$/
70
+ node.parent.send_type? && !node.parent.parenthesized?
83
71
  end
84
72
 
85
73
  def to_modifier_form(node)
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # work
17
17
  # end
18
18
  class InfiniteLoop < Cop
19
- LEADING_SPACE = /\A(\s*)/
19
+ LEADING_SPACE = /\A(\s*)/.freeze
20
20
 
21
21
  MSG = 'Use `Kernel#loop` for infinite loops.'.freeze
22
22
 
@@ -35,7 +35,7 @@ module RuboCop
35
35
  CLASS_COMPARISON_METHODS = %i[<= >= < >].freeze
36
36
  EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
37
37
  NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
38
- CAMEL_CASE = /[A-Z]+[a-z]+/
38
+ CAMEL_CASE = /[A-Z]+[a-z]+/.freeze
39
39
 
40
40
  def_node_matcher :inverse_candidate?, <<-PATTERN
41
41
  {
@@ -17,15 +17,13 @@ module RuboCop
17
17
  MSG = 'Do not use parentheses for method calls with ' \
18
18
  'no arguments.'.freeze
19
19
 
20
- ASGN_NODES = %i[lvasgn masgn] + SHORTHAND_ASGN_NODES
21
-
22
20
  def on_send(node)
23
21
  return if ineligible_node?(node)
24
22
  return unless !node.arguments? && node.parenthesized?
25
23
  return if ignored_method?(node.method_name)
26
24
  return if same_name_assignment?(node)
27
25
 
28
- add_offense(node, location: :begin)
26
+ add_offense(node, location: node.loc.begin.join(node.loc.end))
29
27
  end
30
28
 
31
29
  def autocorrect(node)
@@ -52,14 +50,13 @@ module RuboCop
52
50
  end
53
51
 
54
52
  def any_assignment?(node)
55
- node.each_ancestor(*ASGN_NODES).any? do |asgn_node|
53
+ node.each_ancestor(*AST::Node::ASSIGNMENTS).any? do |asgn_node|
56
54
  # `obj.method = value` parses as (send ... :method= ...), and will
57
55
  # not be returned as an `asgn_node` here, however,
58
56
  # `obj.method ||= value` parses as (or-asgn (send ...) ...)
59
57
  # which IS an `asgn_node`. Similarly, `obj.method += value` parses
60
58
  # as (op-asgn (send ...) ...), which is also an `asgn_node`.
61
- if asgn_node.or_asgn_type? || asgn_node.and_asgn_type? ||
62
- asgn_node.op_asgn_type?
59
+ if asgn_node.shorthand_asgn?
63
60
  asgn_node, _value = *asgn_node
64
61
  next if asgn_node.send_type?
65
62
  end
@@ -72,7 +69,7 @@ module RuboCop
72
69
  mlhs_node, _mrhs_node = *node
73
70
  var_nodes = *mlhs_node
74
71
 
75
- var_nodes.map { |n| n.to_a.first }.include?(variable_name)
72
+ var_nodes.any? { |n| n.to_a.first == variable_name }
76
73
  end
77
74
  end
78
75
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cops checks for parentheses around the arguments in method
6
+ # This cop checks for parentheses around the arguments in method
7
7
  # definitions. Both instance and class/singleton methods are checked.
8
8
  #
9
9
  # @example EnforcedStyle: require_parentheses (default)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cops checks for use of `extend self` or `module_function` in a
6
+ # This cop checks for use of `extend self` or `module_function` in a
7
7
  # module.
8
8
  #
9
9
  # Supported styles are: module_function, extend_self.
@@ -20,7 +20,7 @@ module RuboCop
20
20
  include OnNormalIfUnless
21
21
  include RangeHelp
22
22
 
23
- NON_MODIFIER_THEN = /then\s*(#.*)?$/
23
+ NON_MODIFIER_THEN = /then\s*(#.*)?$/.freeze
24
24
 
25
25
  MSG = 'Do not use `then` for multi-line `%<keyword>s`.'.freeze
26
26
 
@@ -42,6 +42,9 @@ module RuboCop
42
42
  if node.array_type? && !node.bracketed?
43
43
  corrector.insert_before(expr, '[')
44
44
  corrector.insert_after(expr, '].freeze')
45
+ elsif node.irange_type? || node.erange_type?
46
+ corrector.insert_before(expr, '(')
47
+ corrector.insert_after(expr, ').freeze')
45
48
  else
46
49
  corrector.insert_after(expr, '.freeze')
47
50
  end
@@ -51,18 +54,29 @@ module RuboCop
51
54
  private
52
55
 
53
56
  def on_assignment(value)
57
+ range_enclosed_in_parentheses = range_enclosed_in_parentheses?(value)
58
+
54
59
  value = splat_value(value) if splat_value(value)
55
60
 
56
- return unless value && value.mutable_literal?
61
+ return unless mutable_literal?(value) ||
62
+ range_enclosed_in_parentheses
57
63
  return if FROZEN_STRING_LITERAL_TYPES.include?(value.type) &&
58
64
  frozen_string_literals_enabled?
59
65
 
60
66
  add_offense(value)
61
67
  end
62
68
 
69
+ def mutable_literal?(value)
70
+ value && value.mutable_literal?
71
+ end
72
+
63
73
  def_node_matcher :splat_value, <<-PATTERN
64
74
  (array (splat $_))
65
75
  PATTERN
76
+
77
+ def_node_matcher :range_enclosed_in_parentheses?, <<-PATTERN
78
+ (begin ({irange erange} _ _))
79
+ PATTERN
66
80
  end
67
81
  end
68
82
  end
@@ -39,7 +39,7 @@ module RuboCop
39
39
  end
40
40
 
41
41
  def modifier?(node)
42
- node && MODIFIER_NODES.include?(node.type) && node.modifier_form?
42
+ node && node.basic_conditional? && node.modifier_form?
43
43
  end
44
44
 
45
45
  def autocorrect(node)
@@ -53,7 +53,8 @@ module RuboCop
53
53
  end
54
54
 
55
55
  def requires_parens?(child)
56
- child.and_type? || child.or_type? || child.binary_operation? ||
56
+ child.and_type? || child.or_type? ||
57
+ child.send_type? && child.binary_operation? ||
57
58
  child.if_type? && child.ternary?
58
59
  end
59
60
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for octal, hex, binary and decimal literals using
6
+ # This cop checks for octal, hex, binary, and decimal literals using
7
7
  # uppercase prefixes and corrects them to lowercase prefix
8
8
  # or no prefix (in case of decimals).
9
9
  #
@@ -36,11 +36,11 @@ module RuboCop
36
36
  class NumericLiteralPrefix < Cop
37
37
  include IntegerNode
38
38
 
39
- OCTAL_ZERO_ONLY_REGEX = /^0[Oo][0-7]+$/
40
- OCTAL_REGEX = /^0O?[0-7]+$/
41
- HEX_REGEX = /^0X[0-9A-F]+$/
42
- BINARY_REGEX = /^0B[01]+$/
43
- DECIMAL_REGEX = /^0[dD][0-9]+$/
39
+ OCTAL_ZERO_ONLY_REGEX = /^0[Oo][0-7]+$/.freeze
40
+ OCTAL_REGEX = /^0O?[0-7]+$/.freeze
41
+ HEX_REGEX = /^0X[0-9A-F]+$/.freeze
42
+ BINARY_REGEX = /^0B[01]+$/.freeze
43
+ DECIMAL_REGEX = /^0[dD][0-9]+$/.freeze
44
44
 
45
45
  OCTAL_ZERO_ONLY_MSG = 'Use 0 for octal literals.'.freeze
46
46
  OCTAL_MSG = 'Use 0o for octal literals.'.freeze
@@ -30,7 +30,7 @@ module RuboCop
30
30
  include ConfigurableMax
31
31
  include IntegerNode
32
32
 
33
- MSG = 'Use underscores(_) as decimal mark and ' \
33
+ MSG = 'Use underscores(_) as thousands separator and ' \
34
34
  'separate every 3 digits with them.'.freeze
35
35
 
36
36
  def on_int(node)
@@ -109,7 +109,7 @@ module RuboCop
109
109
  end
110
110
 
111
111
  def require_parentheses?(node)
112
- node.binary_operation? && node.source !~ /^\(.*\)$/
112
+ node.send_type? && node.binary_operation? && !node.parenthesized?
113
113
  end
114
114
 
115
115
  def replacement_supported?(operator)
@@ -53,7 +53,7 @@ module RuboCop
53
53
  return "(#{to_ternary(node)})"
54
54
  end
55
55
 
56
- if node.parent.send_type? && operator?(node.parent.method_name)
56
+ if node.parent.send_type? && node.parent.operator_method?
57
57
  return "(#{to_ternary(node)})"
58
58
  end
59
59
 
@@ -82,7 +82,7 @@ module RuboCop
82
82
  return false unless node.send_type? && node.arguments?
83
83
  return false if node.parenthesized_call?
84
84
 
85
- !operator?(node.method_name)
85
+ !node.operator_method?
86
86
  end
87
87
 
88
88
  def keyword_with_changed_precedence?(node)
@@ -79,7 +79,7 @@ module RuboCop
79
79
  return false if node.if_type? && node.ternary?
80
80
  return true if node.rescue_type?
81
81
 
82
- MODIFIER_NODES.include?(node.type) && node.modifier_form?
82
+ node.basic_conditional? && node.modifier_form?
83
83
  end
84
84
 
85
85
  def message(node)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cops checks for uses of Proc.new where Kernel#proc
6
+ # This cop checks for uses of Proc.new where Kernel#proc
7
7
  # would be more appropriate.
8
8
  #
9
9
  # @example