rubocop 1.40.0 → 1.41.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +18 -0
  4. data/lib/rubocop/config.rb +28 -5
  5. data/lib/rubocop/config_loader.rb +9 -0
  6. data/lib/rubocop/config_validator.rb +1 -1
  7. data/lib/rubocop/cop/badge.rb +9 -4
  8. data/lib/rubocop/cop/base.rb +25 -9
  9. data/lib/rubocop/cop/commissioner.rb +8 -3
  10. data/lib/rubocop/cop/cop.rb +1 -1
  11. data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
  12. data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
  13. data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
  14. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
  15. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
  16. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
  17. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
  18. data/lib/rubocop/cop/layout/indentation_style.rb +3 -1
  19. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
  20. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  21. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  22. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
  23. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
  24. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
  25. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
  26. data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
  27. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  28. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -2
  29. data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
  30. data/lib/rubocop/cop/lint/debugger.rb +3 -1
  31. data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
  32. data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
  33. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
  34. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  35. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -19
  36. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  37. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  38. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  39. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  40. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
  41. data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
  42. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
  43. data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
  44. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -1
  45. data/lib/rubocop/cop/mixin/line_length_help.rb +8 -1
  46. data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
  47. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
  48. data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
  49. data/lib/rubocop/cop/mixin/require_library.rb +2 -0
  50. data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
  51. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  52. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
  53. data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
  54. data/lib/rubocop/cop/registry.rb +6 -3
  55. data/lib/rubocop/cop/style/concat_array_literals.rb +66 -0
  56. data/lib/rubocop/cop/style/documentation.rb +1 -1
  57. data/lib/rubocop/cop/style/guard_clause.rb +5 -1
  58. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -3
  59. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  60. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
  61. data/lib/rubocop/cop/style/redundant_constant_base.rb +13 -0
  62. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +39 -0
  63. data/lib/rubocop/cop/style/require_order.rb +61 -9
  64. data/lib/rubocop/cop/style/semicolon.rb +2 -1
  65. data/lib/rubocop/cop/util.rb +31 -4
  66. data/lib/rubocop/cops_documentation_generator.rb +22 -3
  67. data/lib/rubocop/directive_comment.rb +1 -1
  68. data/lib/rubocop/file_patterns.rb +43 -0
  69. data/lib/rubocop/options.rb +1 -1
  70. data/lib/rubocop/path_util.rb +20 -14
  71. data/lib/rubocop/target_finder.rb +1 -1
  72. data/lib/rubocop/version.rb +1 -1
  73. data/lib/rubocop.rb +3 -1
  74. metadata +6 -4
  75. data/lib/rubocop/optimized_patterns.rb +0 -38
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for redundant uses of double splat hash braces.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # do_something(**{foo: bar, baz: qux})
12
+ #
13
+ # # good
14
+ # do_something(foo: bar, baz: qux)
15
+ #
16
+ class RedundantDoubleSplatHashBraces < Base
17
+ extend AutoCorrector
18
+
19
+ MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.'
20
+
21
+ # @!method double_splat_hash_braces?(node)
22
+ def_node_matcher :double_splat_hash_braces?, <<~PATTERN
23
+ (hash (kwsplat (hash ...)))
24
+ PATTERN
25
+
26
+ def on_hash(node)
27
+ return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?)
28
+
29
+ grandparent = node.parent&.parent
30
+ return unless double_splat_hash_braces?(grandparent)
31
+
32
+ add_offense(grandparent) do |corrector|
33
+ corrector.replace(grandparent, node.pairs.map(&:source).join(', '))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -36,6 +36,33 @@ module RuboCop
36
36
  # require 'b'
37
37
  # require_relative 'c'
38
38
  # require 'a'
39
+ #
40
+ # # bad
41
+ # require 'a'
42
+ # require 'c' if foo
43
+ # require 'b'
44
+ #
45
+ # # good
46
+ # require 'a'
47
+ # require 'b'
48
+ # require 'c' if foo
49
+ #
50
+ # # bad
51
+ # require 'c'
52
+ # if foo
53
+ # require 'd'
54
+ # require 'b'
55
+ # end
56
+ # require 'a'
57
+ #
58
+ # # good
59
+ # require 'c'
60
+ # if foo
61
+ # require 'b'
62
+ # require 'd'
63
+ # end
64
+ # require 'a'
65
+ #
39
66
  class RequireOrder < Base
40
67
  extend AutoCorrector
41
68
 
@@ -43,17 +70,27 @@ module RuboCop
43
70
 
44
71
  RESTRICT_ON_SEND = %i[require require_relative].freeze
45
72
 
73
+ MSG = 'Sort `%<name>s` in alphabetical order.'
74
+
75
+ # @!method if_inside_only_require(node)
76
+ def_node_matcher :if_inside_only_require, <<~PATTERN
77
+ {
78
+ (if _ _ $(send nil? {:require :require_relative} _))
79
+ (if _ $(send nil? {:require :require_relative} _) _)
80
+ }
81
+ PATTERN
82
+
46
83
  def on_send(node)
84
+ return unless node.arguments?
85
+ return if not_modifier_form?(node.parent)
86
+
47
87
  previous_older_sibling = find_previous_older_sibling(node)
48
88
  return unless previous_older_sibling
49
89
 
50
- add_offense(
51
- node,
52
- message: "Sort `#{node.method_name}` in alphabetical order."
53
- ) do |corrector|
90
+ add_offense(node, message: format(MSG, name: node.method_name)) do |corrector|
54
91
  swap(
55
92
  range_with_comments_and_lines(previous_older_sibling),
56
- range_with_comments_and_lines(node),
93
+ range_with_comments_and_lines(node.parent.if_type? ? node.parent : node),
57
94
  corrector: corrector
58
95
  )
59
96
  end
@@ -61,16 +98,31 @@ module RuboCop
61
98
 
62
99
  private
63
100
 
64
- def find_previous_older_sibling(node)
65
- node.left_siblings.reverse.find do |sibling|
66
- break unless sibling.send_type?
67
- break unless sibling.method?(node.method_name)
101
+ def not_modifier_form?(node)
102
+ node.if_type? && !node.modifier_form?
103
+ end
104
+
105
+ def find_previous_older_sibling(node) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
106
+ search_node(node).left_siblings.reverse.find do |sibling|
107
+ sibling = sibling_node(sibling)
108
+ break unless sibling&.send_type? && sibling&.method?(node.method_name)
109
+ break unless sibling.arguments? && !sibling.receiver
68
110
  break unless in_same_section?(sibling, node)
69
111
 
70
112
  node.first_argument.source < sibling.first_argument.source
71
113
  end
72
114
  end
73
115
 
116
+ def search_node(node)
117
+ node.parent.if_type? ? node.parent : node
118
+ end
119
+
120
+ def sibling_node(node)
121
+ return if not_modifier_form?(node)
122
+
123
+ node.if_type? ? if_inside_only_require(node) : node
124
+ end
125
+
74
126
  def in_same_section?(node1, node2)
75
127
  !node1.location.expression.with(
76
128
  end_pos: node2.location.expression.end_pos
@@ -37,13 +37,14 @@ module RuboCop
37
37
  end
38
38
 
39
39
  def on_new_investigation
40
- return if processed_source.blank?
40
+ return if processed_source.blank? || !processed_source.raw_source.include?(';')
41
41
 
42
42
  check_for_line_terminator_or_opener
43
43
  end
44
44
 
45
45
  def on_begin(node)
46
46
  return if cop_config['AllowAsExpressionSeparator']
47
+ return unless node.source.include?(';')
47
48
 
48
49
  exprs = node.children
49
50
 
@@ -52,6 +52,21 @@ module RuboCop
52
52
  end
53
53
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
54
54
 
55
+ def any_descendant?(node, *types)
56
+ if block_given?
57
+ node.each_descendant(*types) do |descendant|
58
+ return true if yield(descendant)
59
+ end
60
+ else
61
+ # Use a block version to avoid allocating enumerators.
62
+ node.each_descendant do # rubocop:disable Lint/UnreachableLoop
63
+ return true
64
+ end
65
+ end
66
+
67
+ false
68
+ end
69
+
55
70
  def args_begin(node)
56
71
  loc = node.loc
57
72
  selector = if node.super_type? || node.yield_type?
@@ -71,14 +86,19 @@ module RuboCop
71
86
  def on_node(syms, sexp, excludes = [], &block)
72
87
  return to_enum(:on_node, syms, sexp, excludes) unless block
73
88
 
74
- yield sexp if Array(syms).include?(sexp.type)
75
- return if Array(excludes).include?(sexp.type)
89
+ yield sexp if include_or_equal?(syms, sexp.type)
90
+ return if include_or_equal?(excludes, sexp.type)
76
91
 
77
92
  sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
78
93
  end
79
94
 
95
+ LINE_BEGINS_REGEX_CACHE = Hash.new do |hash, index|
96
+ hash[index] = /^\s{#{index}}\S/
97
+ end
98
+ private_constant :LINE_BEGINS_REGEX_CACHE
99
+
80
100
  def begins_its_line?(range)
81
- range.source_line.index(/\S/) == range.column
101
+ range.source_line.match?(LINE_BEGINS_REGEX_CACHE[range.column])
82
102
  end
83
103
 
84
104
  # Returns, for example, a bare `if` node if the given node is an `if`
@@ -152,8 +172,11 @@ module RuboCop
152
172
  ' ' * (node.loc.column + offset)
153
173
  end
154
174
 
175
+ @to_supported_styles_cache = {}
176
+
155
177
  def to_supported_styles(enforced_style)
156
- enforced_style.sub(/^Enforced/, 'Supported').sub('Style', 'Styles')
178
+ @to_supported_styles_cache[enforced_style] ||=
179
+ enforced_style.sub(/^Enforced/, 'Supported').sub('Style', 'Styles')
157
180
  end
158
181
 
159
182
  private
@@ -162,6 +185,10 @@ module RuboCop
162
185
  src = src.dup if RUBY_ENGINE == 'jruby'
163
186
  src.force_encoding(Encoding.default_external).valid_encoding?
164
187
  end
188
+
189
+ def include_or_equal?(source, target)
190
+ source == target || (source.is_a?(Array) && source.include?(target))
191
+ end
165
192
  end
166
193
  end
167
194
  end
@@ -42,7 +42,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
42
42
  content << "#{description}\n"
43
43
  content << safety_object(safety_objects) if safety_objects.any? { |s| !s.text.blank? }
44
44
  content << examples(examples_objects) if examples_objects.any?
45
- content << configurations(pars)
45
+ content << configurations(cop.department, pars)
46
46
  content << references(cop)
47
47
  content
48
48
  end
@@ -136,7 +136,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
136
136
  content
137
137
  end
138
138
 
139
- def configurations(pars)
139
+ def configurations(department, pars)
140
140
  return '' if pars.empty?
141
141
 
142
142
  header = ['Name', 'Default value', 'Configurable values']
@@ -147,12 +147,20 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
147
147
  content = configs.map do |name|
148
148
  configurable = configurable_values(pars, name)
149
149
  default = format_table_value(pars[name])
150
- [name, default, configurable]
150
+
151
+ [configuration_name(department, name), default, configurable]
151
152
  end
152
153
 
153
154
  h3('Configurable attributes') + to_table(header, content)
154
155
  end
155
156
 
157
+ def configuration_name(department, name)
158
+ return name unless name == 'AllowMultilineFinalElement'
159
+
160
+ filename = "#{department_to_basename(department)}.adoc"
161
+ "xref:#{filename}#allowmultilinefinalelement[AllowMultilineFinalElement]"
162
+ end
163
+
156
164
  # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
157
165
  def configurable_values(pars, name)
158
166
  case name
@@ -227,10 +235,21 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
227
235
  content
228
236
  end
229
237
 
238
+ def footer_for_department(department)
239
+ return '' unless department == :Layout
240
+
241
+ filename = "#{department_to_basename(department)}_footer.adoc"
242
+ file = "#{Dir.pwd}/docs/modules/ROOT/partials/#{filename}"
243
+ return '' unless File.exist?(file)
244
+
245
+ "\ninclude::../partials/#{filename}[]\n"
246
+ end
247
+
230
248
  def print_cops_of_department(department)
231
249
  selected_cops = cops_of_department(department)
232
250
  content = +"= #{department}\n"
233
251
  selected_cops.each { |cop| content << print_cop_with_doc(cop) }
252
+ content << footer_for_department(department)
234
253
  file_name = "#{Dir.pwd}/docs/modules/ROOT/pages/#{department_to_basename(department)}.adoc"
235
254
  File.open(file_name, 'w') do |file|
236
255
  puts "* generated #{file_name}"
@@ -35,7 +35,7 @@ module RuboCop
35
35
 
36
36
  # Checks if this directive relates to single line
37
37
  def single_line?
38
- !self.class.before_comment(comment.text).empty?
38
+ !comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP)
39
39
  end
40
40
 
41
41
  # Checks if this directive contains all the given cop names
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # A wrapper around patterns array to perform optimized search.
5
+ #
6
+ # For projects with a large set of rubocop todo files, most items in `Exclude`/`Include`
7
+ # are exact file names. It is wasteful to linearly check the list of patterns over and over
8
+ # to check if the file is relevant to the cop.
9
+ #
10
+ # This class partitions an array of patterns into a set of exact match strings and the rest
11
+ # of the patterns. This way we can firstly do a cheap check in the set and then proceed via
12
+ # the costly patterns check, if needed.
13
+ # @api private
14
+ class FilePatterns
15
+ @cache = {}.compare_by_identity
16
+
17
+ def self.from(patterns)
18
+ @cache[patterns] ||= new(patterns)
19
+ end
20
+
21
+ def initialize(patterns)
22
+ @strings = Set.new
23
+ @patterns = []
24
+ partition_patterns(patterns)
25
+ end
26
+
27
+ def match?(path)
28
+ @strings.include?(path) || @patterns.any? { |pattern| PathUtil.match_path?(pattern, path) }
29
+ end
30
+
31
+ private
32
+
33
+ def partition_patterns(patterns)
34
+ patterns.each do |pattern|
35
+ if pattern.is_a?(String) && !pattern.match?(/[*{\[?]/)
36
+ @strings << pattern
37
+ else
38
+ @patterns << pattern
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -465,7 +465,7 @@ module RuboCop
465
465
 
466
466
  # This module contains help texts for command line options.
467
467
  # @api private
468
- module OptionsHelp # rubocop:disable Metrics/ModuleLength
468
+ module OptionsHelp
469
469
  MAX_EXCL = RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS.to_s
470
470
  FORMATTER_OPTION_LIST = RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys
471
471
 
@@ -3,23 +3,29 @@
3
3
  module RuboCop
4
4
  # Common methods and behaviors for dealing with paths.
5
5
  module PathUtil
6
+ class << self
7
+ attr_accessor :relative_paths_cache
8
+ end
9
+ self.relative_paths_cache = Hash.new { |hash, key| hash[key] = {} }
10
+
6
11
  module_function
7
12
 
8
13
  def relative_path(path, base_dir = Dir.pwd)
9
- # Optimization for the common case where path begins with the base
10
- # dir. Just cut off the first part.
11
- if path.start_with?(base_dir)
12
- base_dir_length = base_dir.length
13
- result_length = path.length - base_dir_length - 1
14
- return path[base_dir_length + 1, result_length]
15
- end
16
-
17
- path_name = Pathname.new(File.expand_path(path))
18
- begin
19
- path_name.relative_path_from(Pathname.new(base_dir)).to_s
20
- rescue ArgumentError
21
- path
22
- end
14
+ PathUtil.relative_paths_cache[base_dir][path] ||=
15
+ # Optimization for the common case where path begins with the base
16
+ # dir. Just cut off the first part.
17
+ if path.start_with?(base_dir)
18
+ base_dir_length = base_dir.length
19
+ result_length = path.length - base_dir_length - 1
20
+ path[base_dir_length + 1, result_length]
21
+ else
22
+ path_name = Pathname.new(File.expand_path(path))
23
+ begin
24
+ path_name.relative_path_from(Pathname.new(base_dir)).to_s
25
+ rescue ArgumentError
26
+ path
27
+ end
28
+ end
23
29
  end
24
30
 
25
31
  def smart_path(path)
@@ -88,7 +88,7 @@ module RuboCop
88
88
  patterns.map! { |dir| File.join(dir, '*') }
89
89
  # We need this special case to avoid creating the pattern
90
90
  # /**/* which searches the entire file system.
91
- patterns = [File.join(dir, '**/*')] if patterns.empty?
91
+ patterns = [File.join(base_dir, '**/*')] if patterns.empty?
92
92
 
93
93
  Dir.glob(patterns, flags).select { |path| FileTest.file?(path) }
94
94
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.40.0'
6
+ STRING = '1.41.0'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
data/lib/rubocop.rb CHANGED
@@ -23,8 +23,8 @@ require_relative 'rubocop/ext/processed_source'
23
23
 
24
24
  require_relative 'rubocop/error'
25
25
  require_relative 'rubocop/file_finder'
26
+ require_relative 'rubocop/file_patterns'
26
27
  require_relative 'rubocop/name_similarity'
27
- require_relative 'rubocop/optimized_patterns'
28
28
  require_relative 'rubocop/path_util'
29
29
  require_relative 'rubocop/platform'
30
30
  require_relative 'rubocop/string_interpreter'
@@ -470,6 +470,7 @@ require_relative 'rubocop/cop/style/combinable_loops'
470
470
  require_relative 'rubocop/cop/style/command_literal'
471
471
  require_relative 'rubocop/cop/style/comment_annotation'
472
472
  require_relative 'rubocop/cop/style/commented_keyword'
473
+ require_relative 'rubocop/cop/style/concat_array_literals'
473
474
  require_relative 'rubocop/cop/style/conditional_assignment'
474
475
  require_relative 'rubocop/cop/style/constant_visibility'
475
476
  require_relative 'rubocop/cop/style/copyright'
@@ -545,6 +546,7 @@ require_relative 'rubocop/cop/style/open_struct_use'
545
546
  require_relative 'rubocop/cop/style/operator_method_call'
546
547
  require_relative 'rubocop/cop/style/redundant_assignment'
547
548
  require_relative 'rubocop/cop/style/redundant_constant_base'
549
+ require_relative 'rubocop/cop/style/redundant_double_splat_hash_braces'
548
550
  require_relative 'rubocop/cop/style/redundant_each'
549
551
  require_relative 'rubocop/cop/style/redundant_fetch_block'
550
552
  require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.40.0
4
+ version: 1.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-12-08 00:00:00.000000000 Z
13
+ date: 2022-12-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -691,6 +691,7 @@ files:
691
691
  - lib/rubocop/cop/style/command_literal.rb
692
692
  - lib/rubocop/cop/style/comment_annotation.rb
693
693
  - lib/rubocop/cop/style/commented_keyword.rb
694
+ - lib/rubocop/cop/style/concat_array_literals.rb
694
695
  - lib/rubocop/cop/style/conditional_assignment.rb
695
696
  - lib/rubocop/cop/style/constant_visibility.rb
696
697
  - lib/rubocop/cop/style/copyright.rb
@@ -824,6 +825,7 @@ files:
824
825
  - lib/rubocop/cop/style/redundant_condition.rb
825
826
  - lib/rubocop/cop/style/redundant_conditional.rb
826
827
  - lib/rubocop/cop/style/redundant_constant_base.rb
828
+ - lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb
827
829
  - lib/rubocop/cop/style/redundant_each.rb
828
830
  - lib/rubocop/cop/style/redundant_exception.rb
829
831
  - lib/rubocop/cop/style/redundant_fetch_block.rb
@@ -918,6 +920,7 @@ files:
918
920
  - lib/rubocop/ext/regexp_parser.rb
919
921
  - lib/rubocop/feature_loader.rb
920
922
  - lib/rubocop/file_finder.rb
923
+ - lib/rubocop/file_patterns.rb
921
924
  - lib/rubocop/formatter.rb
922
925
  - lib/rubocop/formatter/auto_gen_config_formatter.rb
923
926
  - lib/rubocop/formatter/base_formatter.rb
@@ -944,7 +947,6 @@ files:
944
947
  - lib/rubocop/lockfile.rb
945
948
  - lib/rubocop/magic_comment.rb
946
949
  - lib/rubocop/name_similarity.rb
947
- - lib/rubocop/optimized_patterns.rb
948
950
  - lib/rubocop/options.rb
949
951
  - lib/rubocop/path_util.rb
950
952
  - lib/rubocop/platform.rb
@@ -990,7 +992,7 @@ metadata:
990
992
  homepage_uri: https://rubocop.org/
991
993
  changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
992
994
  source_code_uri: https://github.com/rubocop/rubocop/
993
- documentation_uri: https://docs.rubocop.org/rubocop/1.40/
995
+ documentation_uri: https://docs.rubocop.org/rubocop/1.41/
994
996
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
995
997
  rubygems_mfa_required: 'true'
996
998
  post_install_message:
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- # @api private
5
- module OptimizedPatterns
6
- # A wrapper around patterns array to perform optimized search.
7
- # @api private
8
- class PatternsSet
9
- def initialize(patterns)
10
- @strings = Set.new
11
- @patterns = []
12
- partition_patterns(patterns)
13
- end
14
-
15
- def match?(path)
16
- @strings.include?(path) || @patterns.any? { |pattern| PathUtil.match_path?(pattern, path) }
17
- end
18
-
19
- private
20
-
21
- def partition_patterns(patterns)
22
- patterns.each do |pattern|
23
- if pattern.is_a?(String) && !pattern.match?(/[*{\[?]/)
24
- @strings << pattern
25
- else
26
- @patterns << pattern
27
- end
28
- end
29
- end
30
- end
31
-
32
- @cache = {}.compare_by_identity
33
-
34
- def self.from(patterns)
35
- @cache[patterns] ||= PatternsSet.new(patterns)
36
- end
37
- end
38
- end