rubocop 0.59.2 → 0.60.0

Sign up to get free protection for your applications and to get access to all the features.
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