rubocop 0.76.0 → 0.80.1

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 +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +325 -283
  5. data/lib/rubocop.rb +43 -23
  6. data/lib/rubocop/ast/builder.rb +43 -42
  7. data/lib/rubocop/ast/node.rb +1 -13
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/def_node.rb +11 -0
  10. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  11. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  12. data/lib/rubocop/ast/traversal.rb +20 -3
  13. data/lib/rubocop/cli.rb +11 -230
  14. data/lib/rubocop/cli/command.rb +21 -0
  15. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  16. data/lib/rubocop/cli/command/base.rb +33 -0
  17. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  18. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  19. data/lib/rubocop/cli/command/show_cops.rb +80 -0
  20. data/lib/rubocop/cli/command/version.rb +17 -0
  21. data/lib/rubocop/cli/environment.rb +21 -0
  22. data/lib/rubocop/comment_config.rb +6 -1
  23. data/lib/rubocop/config.rb +28 -10
  24. data/lib/rubocop/config_loader.rb +19 -19
  25. data/lib/rubocop/config_obsoletion.rb +65 -11
  26. data/lib/rubocop/config_validator.rb +56 -98
  27. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  28. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  30. data/lib/rubocop/cop/cop.rb +21 -0
  31. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  32. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  33. data/lib/rubocop/cop/generator.rb +3 -4
  34. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  36. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  37. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  38. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  39. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
  40. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  41. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  42. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +5 -5
  43. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  44. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +3 -3
  45. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  46. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +10 -6
  47. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
  48. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
  49. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  50. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +67 -108
  51. data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
  52. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  53. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  54. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  55. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  56. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -7
  57. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  58. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  59. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  60. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  61. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  62. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  63. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  64. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  65. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  66. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  67. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +13 -8
  70. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  71. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
  72. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  73. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  74. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  75. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  76. data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
  77. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  78. data/lib/rubocop/cop/migration/department_name.rb +30 -2
  79. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  80. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  81. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  82. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  83. data/lib/rubocop/cop/mixin/hash_transform_method.rb +171 -0
  84. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  85. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  86. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  87. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
  88. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -12
  89. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  90. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  91. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  92. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
  93. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  94. data/lib/rubocop/cop/offense.rb +11 -0
  95. data/lib/rubocop/cop/registry.rb +7 -2
  96. data/lib/rubocop/cop/style/alias.rb +1 -1
  97. data/lib/rubocop/cop/style/array_join.rb +1 -1
  98. data/lib/rubocop/cop/style/attr.rb +8 -0
  99. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  100. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  101. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  102. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  103. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
  104. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  105. data/lib/rubocop/cop/style/hash_each_methods.rb +87 -0
  106. data/lib/rubocop/cop/style/hash_transform_keys.rb +79 -0
  107. data/lib/rubocop/cop/style/hash_transform_values.rb +79 -0
  108. data/lib/rubocop/cop/style/if_unless_modifier.rb +38 -3
  109. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  110. data/lib/rubocop/cop/style/inverse_methods.rb +8 -4
  111. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  112. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  113. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  114. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  115. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  116. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  117. data/lib/rubocop/cop/style/multiline_when_then.rb +5 -1
  118. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +7 -7
  119. data/lib/rubocop/cop/style/next.rb +5 -5
  120. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  121. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
  122. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  123. data/lib/rubocop/cop/style/or_assignment.rb +3 -2
  124. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  125. data/lib/rubocop/cop/style/redundant_condition.rb +17 -4
  126. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
  127. data/lib/rubocop/cop/style/redundant_return.rb +2 -8
  128. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  129. data/lib/rubocop/cop/style/symbol_array.rb +2 -2
  130. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  131. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +0 -22
  132. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  133. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  134. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  135. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  136. data/lib/rubocop/cop/team.rb +5 -0
  137. data/lib/rubocop/cop/variable_force.rb +4 -1
  138. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  139. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
  140. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  141. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  142. data/lib/rubocop/formatter/junit_formatter.rb +63 -0
  143. data/lib/rubocop/formatter/tap_formatter.rb +1 -3
  144. data/lib/rubocop/node_pattern.rb +97 -11
  145. data/lib/rubocop/options.rb +8 -8
  146. data/lib/rubocop/processed_source.rb +1 -1
  147. data/lib/rubocop/rake_task.rb +1 -0
  148. data/lib/rubocop/result_cache.rb +23 -7
  149. data/lib/rubocop/rspec/shared_contexts.rb +5 -0
  150. data/lib/rubocop/runner.rb +18 -2
  151. data/lib/rubocop/target_ruby.rb +151 -0
  152. data/lib/rubocop/version.rb +1 -1
  153. metadata +60 -27
  154. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
  155. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -19,9 +19,9 @@ module RuboCop
19
19
  #
20
20
  # @example
21
21
  # # bad
22
- # # rubocop:disable Metrics/LineLength
22
+ # # rubocop:disable Layout/LineLength
23
23
  # x += 1
24
- # # rubocop:enable Metrics/LineLength
24
+ # # rubocop:enable Layout/LineLength
25
25
  #
26
26
  # # good
27
27
  # x += 1
@@ -213,7 +213,7 @@ module RuboCop
213
213
  end
214
214
 
215
215
  def matching_range(haystack, needle)
216
- offset = (haystack.source =~ Regexp.new(Regexp.escape(needle)))
216
+ offset = haystack.source.index(needle)
217
217
  return unless offset
218
218
 
219
219
  offset += haystack.begin_pos
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # The Lint/RedundantCopEnableDirective cop needs to be disabled so as
4
- # to be able to provide a (bad) example of an unneeded enable.
3
+ # The Lint/RedundantCopEnableDirective and Lint/RedundantCopDisableDirective
4
+ # cops need to be disabled so as to be able to provide a (bad) example of an
5
+ # unneeded enable.
5
6
 
6
7
  # rubocop:disable Lint/RedundantCopEnableDirective
8
+ # rubocop:disable Lint/RedundantCopDisableDirective
7
9
  module RuboCop
8
10
  module Cop
9
11
  module Lint
@@ -15,21 +17,21 @@ module RuboCop
15
17
  # @example
16
18
  # # bad
17
19
  # foo = 1
18
- # # rubocop:enable Metrics/LineLength
20
+ # # rubocop:enable Layout/LineLength
19
21
  #
20
22
  # # good
21
23
  # foo = 1
22
24
  # @example
23
25
  # # bad
24
- # # rubocop:disable Metrics/LineLength
25
- # baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrr
26
- # # rubocop:enable Metrics/LineLength
26
+ # # rubocop:disable Style/StringLiterals
27
+ # foo = "1"
28
+ # # rubocop:enable Style/StringLiterals
27
29
  # baz
28
30
  # # rubocop:enable all
29
31
  #
30
32
  # # good
31
- # # rubocop:disable Metrics/LineLength
32
- # baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrr
33
+ # # rubocop:disable Style/StringLiterals
34
+ # foo = "1"
33
35
  # # rubocop:enable all
34
36
  # baz
35
37
  class RedundantCopEnableDirective < Cop
@@ -112,3 +114,6 @@ module RuboCop
112
114
  end
113
115
  end
114
116
  end
117
+
118
+ # rubocop:enable Lint/RedundantCopDisableDirective
119
+ # rubocop:enable Lint/RedundantCopEnableDirective
@@ -146,7 +146,7 @@ module RuboCop
146
146
  grandparent = node.parent.parent
147
147
 
148
148
  parent.when_type? || parent.send_type? || part_of_an_array?(node) ||
149
- (grandparent&.resbody_type?)
149
+ grandparent&.resbody_type?
150
150
  end
151
151
 
152
152
  def remove_brackets(array)
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # # good
18
18
  #
19
19
  # "result is #{something}"
20
- class StringConversionInInterpolation < Cop
20
+ class RedundantStringCoercion < Cop
21
21
  include Interpolation
22
22
 
23
23
  MSG_DEFAULT = 'Redundant use of `Object#to_s` in interpolation.'
@@ -50,7 +50,7 @@ module RuboCop
50
50
  def autocorrect(node)
51
51
  lambda do |corrector|
52
52
  redundant_with_index?(node) do |send|
53
- if send.method_name == :each_with_index
53
+ if send.method?(:each_with_index)
54
54
  corrector.replace(send.loc.selector, 'each')
55
55
  else
56
56
  corrector.remove(with_index_range(send))
@@ -63,7 +63,7 @@ module RuboCop
63
63
  private
64
64
 
65
65
  def message(node)
66
- if node.method_name == :each_with_index
66
+ if node.method?(:each_with_index)
67
67
  MSG_EACH_WITH_INDEX
68
68
  else
69
69
  MSG_WITH_INDEX
@@ -51,7 +51,7 @@ module RuboCop
51
51
  def autocorrect(node)
52
52
  lambda do |corrector|
53
53
  redundant_with_object?(node) do |send|
54
- if send.method_name == :each_with_object
54
+ if send.method?(:each_with_object)
55
55
  corrector.replace(with_object_range(send), 'each')
56
56
  else
57
57
  corrector.remove(with_object_range(send))
@@ -64,7 +64,7 @@ module RuboCop
64
64
  private
65
65
 
66
66
  def message(node)
67
- if node.method_name == :each_with_object
67
+ if node.method?(:each_with_object)
68
68
  MSG_EACH_WITH_OBJECT
69
69
  else
70
70
  MSG_WITH_OBJECT
@@ -74,7 +74,7 @@ module RuboCop
74
74
  # rescue
75
75
  # # do nothing but comment
76
76
  # end
77
- class HandleExceptions < Cop
77
+ class SuppressedException < Cop
78
78
  MSG = 'Do not suppress exceptions.'
79
79
 
80
80
  def on_resbody(node)
@@ -9,23 +9,64 @@ module RuboCop
9
9
  # always being defined, and thus access modifiers guarding such methods
10
10
  # are not redundant.
11
11
  #
12
- # @example
12
+ # This cop has `ContextCreatingMethods` option. The default setting value
13
+ # is an empty array that means no method is specified.
14
+ # This setting is an array of methods which, when called, are known to
15
+ # create its own context in the module's current access context.
16
+ #
17
+ # It also has `MethodCreatingMethods` option. The default setting value
18
+ # is an empty array that means no method is specified.
19
+ # This setting is an array of methods which, when called, are known to
20
+ # create other methods in the module's current access context.
13
21
  #
22
+ # @example
23
+ # # bad
14
24
  # class Foo
15
25
  # public # this is redundant (default access is public)
16
26
  #
17
27
  # def method
18
28
  # end
29
+ # end
19
30
  #
20
- # private # this is not redundant (a method is defined)
21
- # def method2
31
+ # # bad
32
+ # class Foo
33
+ # # The following is redundant (methods defined on the class'
34
+ # # singleton class are not affected by the public modifier)
35
+ # public
36
+ #
37
+ # def self.method3
22
38
  # end
39
+ # end
23
40
  #
41
+ # # bad
42
+ # class Foo
43
+ # protected
44
+ #
45
+ # define_method(:method2) do
46
+ # end
47
+ #
48
+ # protected # this is redundant (repeated from previous modifier)
49
+ #
50
+ # [1,2,3].each do |i|
51
+ # define_method("foo#{i}") do
52
+ # end
53
+ # end
54
+ # end
55
+ #
56
+ # # bad
57
+ # class Foo
24
58
  # private # this is redundant (no following methods are defined)
25
59
  # end
26
60
  #
27
- # @example
61
+ # # good
62
+ # class Foo
63
+ # private # this is not redundant (a method is defined)
64
+ #
65
+ # def method2
66
+ # end
67
+ # end
28
68
  #
69
+ # # good
29
70
  # class Foo
30
71
  # # The following is not redundant (conditionally defined methods are
31
72
  # # considered as always defining a method)
@@ -35,31 +76,22 @@ module RuboCop
35
76
  # def method
36
77
  # end
37
78
  # end
79
+ # end
38
80
  #
39
- # protected # this is not redundant (method is defined)
81
+ # # good
82
+ # class Foo
83
+ # protected # this is not redundant (a method is defined)
40
84
  #
41
85
  # define_method(:method2) do
42
86
  # end
43
- #
44
- # protected # this is redundant (repeated from previous modifier)
45
- #
46
- # [1,2,3].each do |i|
47
- # define_method("foo#{i}") do
48
- # end
49
- # end
50
- #
51
- # # The following is redundant (methods defined on the class'
52
- # # singleton class are not affected by the public modifier)
53
- # public
54
- #
55
- # def self.method3
56
- # end
57
87
  # end
58
88
  #
59
- # @example
89
+ # @example ContextCreatingMethods: concerning
60
90
  # # Lint/UselessAccessModifier:
61
91
  # # ContextCreatingMethods:
62
92
  # # - concerning
93
+ #
94
+ # # good
63
95
  # require 'active_support/concern'
64
96
  # class Foo
65
97
  # concerning :Bar do
@@ -79,10 +111,12 @@ module RuboCop
79
111
  # end
80
112
  # end
81
113
  #
82
- # @example
114
+ # @example MethodCreatingMethods: delegate
83
115
  # # Lint/UselessAccessModifier:
84
116
  # # MethodCreatingMethods:
85
117
  # # - delegate
118
+ #
119
+ # # good
86
120
  # require 'active_support/core_ext/module/delegation'
87
121
  # class Foo
88
122
  # # this is not redundant because `delegate` creates methods
@@ -141,7 +175,7 @@ module RuboCop
141
175
 
142
176
  def access_modifier?(node)
143
177
  node.bare_access_modifier? ||
144
- node.method_name == :private_class_method
178
+ node.method?(:private_class_method)
145
179
  end
146
180
 
147
181
  def check_scope(node)
@@ -169,7 +203,7 @@ module RuboCop
169
203
  def check_send_node(node, cur_vis, unused)
170
204
  if node.bare_access_modifier?
171
205
  check_new_visibility(node, unused, node.method_name, cur_vis)
172
- elsif node.method_name == :private_class_method && !node.arguments?
206
+ elsif node.method?(:private_class_method) && !node.arguments?
173
207
  add_offense(node, message: format(MSG, current: node.method_name))
174
208
  [cur_vis, unused]
175
209
  end
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # This cop checks for setter call to local variable as the final
7
7
  # expression of a function definition.
8
8
  #
9
+ # Note: There are edge cases in which the local variable references a
10
+ # value that is also accessible outside the local scope. This is not
11
+ # detected by the cop, and it can yield a false positive.
12
+ #
9
13
  # @example
10
14
  #
11
15
  # # bad
@@ -155,7 +159,7 @@ module RuboCop
155
159
  return true if node.literal?
156
160
  return false unless node.send_type?
157
161
 
158
- node.method_name == :new
162
+ node.method?(:new)
159
163
  end
160
164
  end
161
165
  end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  alias on_defs on_def
21
21
 
22
22
  def on_block(node)
23
- return unless node.send_node.method_name == :define_method
23
+ return unless node.send_node.method?(:define_method)
24
24
 
25
25
  check_code_length(node)
26
26
  end
@@ -10,13 +10,24 @@ module RuboCop
10
10
 
11
11
  MSG = 'Department name is missing.'
12
12
 
13
+ DISABLE_COMMENT_FORMAT =
14
+ /\A(# *rubocop *: *((dis|en)able|todo) +)(.*)/.freeze
15
+
16
+ # The token that makes up a disable comment.
17
+ # The token used after `# rubocop: disable` are `A-z`, `/`, and `,`.
18
+ # Also `A-z` includes `all`.
19
+ DISABLING_COPS_CONTENT_TOKEN = %r{[A-z/,]+}.freeze
20
+
13
21
  def investigate(processed_source)
14
22
  processed_source.each_comment do |comment|
15
- next if comment.text !~ /\A(# *rubocop:((dis|en)able|todo) +)(.*)/
23
+ next if comment.text !~ DISABLE_COMMENT_FORMAT
16
24
 
17
25
  offset = Regexp.last_match(1).length
18
26
  Regexp.last_match(4).scan(%r{[\w/]+|\W+}) do |name|
27
+ break unless valid_content_token?(name.strip)
28
+
19
29
  check_cop_name(name, comment, offset)
30
+
20
31
  offset += name.length
21
32
  end
22
33
  end
@@ -24,8 +35,13 @@ module RuboCop
24
35
 
25
36
  def autocorrect(range)
26
37
  shall_warn = false
27
- qualified_cop_name = Cop.registry.qualified_cop_name(range.source,
38
+ cop_name = range.source
39
+ qualified_cop_name = Cop.registry.qualified_cop_name(cop_name,
28
40
  nil, shall_warn)
41
+ unless qualified_cop_name.include?('/')
42
+ qualified_cop_name = qualified_legacy_cop_name(cop_name)
43
+ end
44
+
29
45
  ->(corrector) { corrector.replace(range, qualified_cop_name) }
30
46
  end
31
47
 
@@ -38,6 +54,18 @@ module RuboCop
38
54
  range = range_between(start, start + name.length)
39
55
  add_offense(range, location: range)
40
56
  end
57
+
58
+ def valid_content_token?(content_token)
59
+ !DISABLING_COPS_CONTENT_TOKEN.match(content_token).nil?
60
+ end
61
+
62
+ def qualified_legacy_cop_name(cop_name)
63
+ legacy_cop_names = RuboCop::ConfigObsoletion::OBSOLETE_COPS.keys
64
+
65
+ legacy_cop_names.detect do |legacy_cop_name|
66
+ legacy_cop_name.split('/')[1] == cop_name
67
+ end
68
+ end
41
69
  end
42
70
  end
43
71
  end
@@ -35,7 +35,7 @@ module RuboCop
35
35
  # If this offense is within a line range that is already being
36
36
  # realigned by autocorrect, we report the offense without
37
37
  # autocorrecting it. Two rewrites in the same area by the same
38
- # cop can not be handled. The next iteration will find the
38
+ # cop cannot be handled. The next iteration will find the
39
39
  # offense again and correct it.
40
40
  add_offense(nil, location: expr)
41
41
  else
@@ -60,6 +60,10 @@ module RuboCop
60
60
  alias conflicting_styles_detected no_acceptable_style!
61
61
  alias unrecognized_style_detected no_acceptable_style!
62
62
 
63
+ def style_configured?
64
+ cop_config.key?(style_parameter_name)
65
+ end
66
+
63
67
  def style
64
68
  @style ||= begin
65
69
  s = cop_config[style_parameter_name].to_sym
@@ -39,15 +39,15 @@ module RuboCop
39
39
  end
40
40
  end
41
41
 
42
- def leading_comment_lines
43
- comments = processed_source.comments
44
-
45
- comments.each_with_object([]) do |comment, leading_comments|
46
- next if comment.loc.line > 3
47
-
48
- leading_comments << comment.text
42
+ def frozen_string_literal_specified?
43
+ leading_comment_lines.any? do |line|
44
+ MagicComment.parse(line).frozen_string_literal_specified?
49
45
  end
50
46
  end
47
+
48
+ def leading_comment_lines
49
+ processed_source.comments.first(3).map(&:text)
50
+ end
51
51
  end
52
52
  end
53
53
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  # Common functionality for checking hash alignment.
6
- module HashAlignment
6
+ module HashAlignmentStyles
7
7
  # Handles calculation of deltas when the enforced style is 'key'.
8
8
  class KeyAlignment
9
9
  def checkable_layout?(_node)
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # Common functionality for Style/HashTransformKeys and
6
+ # Style/HashTransformValues
7
+ module HashTransformMethod
8
+ def on_block(node)
9
+ on_bad_each_with_object(node) do |*match|
10
+ handle_possible_offense(node, match, 'each_with_object')
11
+ end
12
+ end
13
+
14
+ def on_send(node)
15
+ on_bad_hash_brackets_map(node) do |*match|
16
+ handle_possible_offense(node, match, 'Hash[_.map {...}]')
17
+ end
18
+ on_bad_map_to_h(node) do |*match|
19
+ handle_possible_offense(node, match, 'map {...}.to_h')
20
+ end
21
+ end
22
+
23
+ def on_csend(node)
24
+ on_bad_map_to_h(node) do |*match|
25
+ handle_possible_offense(node, match, 'map {...}.to_h')
26
+ end
27
+ end
28
+
29
+ def autocorrect(node)
30
+ lambda do |corrector|
31
+ correction = prepare_correction(node)
32
+ execute_correction(corrector, node, correction)
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # @abstract Implemented with `def_node_matcher`
39
+ def on_bad_each_with_object(_node)
40
+ raise NotImplementedError
41
+ end
42
+
43
+ # @abstract Implemented with `def_node_matcher`
44
+ def on_bad_hash_brackets_map(_node)
45
+ raise NotImplementedError
46
+ end
47
+
48
+ # @abstract Implemented with `def_node_matcher`
49
+ def on_bad_map_to_h(_node)
50
+ raise NotImplementedError
51
+ end
52
+
53
+ def handle_possible_offense(node, match, match_desc)
54
+ captures = extract_captures(match)
55
+
56
+ # If key didn't actually change either, this is most likely a false
57
+ # positive (receiver isn't a hash).
58
+ return if captures.noop_transformation?
59
+
60
+ # Can't `transform_keys` if key transformation uses value, or
61
+ # `transform_values` if value transformation uses key.
62
+ return if captures.transformation_uses_both_args?
63
+
64
+ add_offense(
65
+ node,
66
+ message: "Prefer `#{new_method_name}` over `#{match_desc}`."
67
+ )
68
+ end
69
+
70
+ # @abstract
71
+ #
72
+ # @return [Captures]
73
+ def extract_captures(_match)
74
+ raise NotImplementedError
75
+ end
76
+
77
+ # @abstract
78
+ #
79
+ # @return [String]
80
+ def new_method_name
81
+ raise NotImplementedError
82
+ end
83
+
84
+ def prepare_correction(node)
85
+ if (match = on_bad_each_with_object(node))
86
+ Autocorrection.from_each_with_object(node, match)
87
+ elsif (match = on_bad_hash_brackets_map(node))
88
+ Autocorrection.from_hash_brackets_map(node, match)
89
+ elsif (match = on_bad_map_to_h(node))
90
+ Autocorrection.from_map_to_h(node, match)
91
+ else
92
+ raise 'unreachable'
93
+ end
94
+ end
95
+
96
+ def execute_correction(corrector, node, correction)
97
+ correction.strip_prefix_and_suffix(node, corrector)
98
+ correction.set_new_method_name(new_method_name, corrector)
99
+
100
+ captures = extract_captures(correction.match)
101
+ correction.set_new_arg_name(captures.transformed_argname, corrector)
102
+ correction.set_new_body_expression(
103
+ captures.transforming_body_expr,
104
+ corrector
105
+ )
106
+ end
107
+
108
+ # Internal helper class to hold match data
109
+ Captures = Struct.new(
110
+ :transformed_argname,
111
+ :transforming_body_expr,
112
+ :unchanged_body_expr
113
+ ) do
114
+ def noop_transformation?
115
+ transforming_body_expr.lvar_type? &&
116
+ transforming_body_expr.children == [transformed_argname]
117
+ end
118
+
119
+ def transformation_uses_both_args?
120
+ transforming_body_expr.descendants.include?(unchanged_body_expr)
121
+ end
122
+ end
123
+
124
+ # Internal helper class to hold autocorrect data
125
+ Autocorrection = Struct.new(:match, :block_node, :leading, :trailing) do # rubocop:disable Metrics/BlockLength
126
+ def self.from_each_with_object(node, match)
127
+ new(match, node, 0, 0)
128
+ end
129
+
130
+ def self.from_hash_brackets_map(node, match)
131
+ new(match, node.children.last, 'Hash['.length, ']'.length)
132
+ end
133
+
134
+ def self.from_map_to_h(node, match)
135
+ strip_trailing_chars = node.parent&.block_type? ? 0 : '.to_h'.length
136
+ new(match, node.children.first, 0, strip_trailing_chars)
137
+ end
138
+
139
+ def strip_prefix_and_suffix(node, corrector)
140
+ expression = node.loc.expression
141
+ corrector.remove_leading(expression, leading)
142
+ corrector.remove_trailing(expression, trailing)
143
+ end
144
+
145
+ def set_new_method_name(new_method_name, corrector)
146
+ range = block_node.send_node.loc.selector
147
+ if (send_end = block_node.send_node.loc.end)
148
+ # If there are arguments (only true in the `each_with_object`
149
+ # case)
150
+ range = range.begin.join(send_end)
151
+ end
152
+ corrector.replace(range, new_method_name)
153
+ end
154
+
155
+ def set_new_arg_name(transformed_argname, corrector)
156
+ corrector.replace(
157
+ block_node.arguments.loc.expression,
158
+ "|#{transformed_argname}|"
159
+ )
160
+ end
161
+
162
+ def set_new_body_expression(transforming_body_expr, corrector)
163
+ corrector.replace(
164
+ block_node.body.loc.expression,
165
+ transforming_body_expr.loc.expression.source
166
+ )
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end