rubocop-ast 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubocop/ast.rb +17 -0
  3. data/lib/rubocop/ast/builder.rb +1 -0
  4. data/lib/rubocop/ast/node.rb +44 -125
  5. data/lib/rubocop/ast/node/array_node.rb +1 -0
  6. data/lib/rubocop/ast/node/block_node.rb +1 -0
  7. data/lib/rubocop/ast/node/keyword_splat_node.rb +1 -0
  8. data/lib/rubocop/ast/node/mixin/collection_node.rb +1 -0
  9. data/lib/rubocop/ast/node/mixin/descendence.rb +116 -0
  10. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +2 -0
  11. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +9 -0
  12. data/lib/rubocop/ast/node/mixin/numeric_node.rb +1 -0
  13. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +7 -3
  14. data/lib/rubocop/ast/node/pair_node.rb +4 -0
  15. data/lib/rubocop/ast/node/regexp_node.rb +1 -0
  16. data/lib/rubocop/ast/node_pattern.rb +44 -870
  17. data/lib/rubocop/ast/node_pattern/builder.rb +72 -0
  18. data/lib/rubocop/ast/node_pattern/comment.rb +45 -0
  19. data/lib/rubocop/ast/node_pattern/compiler.rb +104 -0
  20. data/lib/rubocop/ast/node_pattern/compiler/atom_subcompiler.rb +56 -0
  21. data/lib/rubocop/ast/node_pattern/compiler/binding.rb +78 -0
  22. data/lib/rubocop/ast/node_pattern/compiler/debug.rb +168 -0
  23. data/lib/rubocop/ast/node_pattern/compiler/node_pattern_subcompiler.rb +146 -0
  24. data/lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb +420 -0
  25. data/lib/rubocop/ast/node_pattern/compiler/subcompiler.rb +57 -0
  26. data/lib/rubocop/ast/node_pattern/lexer.rb +69 -0
  27. data/lib/rubocop/ast/node_pattern/lexer.rex +39 -0
  28. data/lib/rubocop/ast/node_pattern/lexer.rex.rb +182 -0
  29. data/lib/rubocop/ast/node_pattern/method_definer.rb +143 -0
  30. data/lib/rubocop/ast/node_pattern/node.rb +275 -0
  31. data/lib/rubocop/ast/node_pattern/parser.racc.rb +470 -0
  32. data/lib/rubocop/ast/node_pattern/parser.rb +66 -0
  33. data/lib/rubocop/ast/node_pattern/parser.y +103 -0
  34. data/lib/rubocop/ast/node_pattern/sets.rb +37 -0
  35. data/lib/rubocop/ast/node_pattern/with_meta.rb +111 -0
  36. data/lib/rubocop/ast/processed_source.rb +1 -0
  37. data/lib/rubocop/ast/traversal.rb +1 -0
  38. data/lib/rubocop/ast/version.rb +1 -1
  39. metadata +36 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35f0c94d6021f2223c413d1751c4e816346b740cf01663e5444325256ba987aa
4
- data.tar.gz: 010a37da8da2e08bea4785821709b9e10cdedb02e133f33b1b8a12051939517e
3
+ metadata.gz: eae5a550b84ac088fb1065c539710b04b9885883c367ab0b26f8d3b455291ccb
4
+ data.tar.gz: 424d68c1b31693d5de3dc83aaf88823147ecf5a446c2b68f39c8e992f9b10c4e
5
5
  SHA512:
6
- metadata.gz: ac8387283324c91278d848e1411cdede002cda15d00e20d2a889a5f7b4b37eed217e05e5538cfc99dfd2022ea68afae87eb4698db9d58aef2e08f15f3e5930e2
7
- data.tar.gz: 3505c65f6921744d681f226f9f2e476a662c2da564db8f2534dd53a5cd17d15a4eadf839e7bf8d9e4bd8d769f0351527ad1a53c7da5a11cc3dc6f4e760a7c955
6
+ metadata.gz: e16362b75f0e898818a6bfd9a17fc83d86f682fd83328d07ed5bd71a561dfc4b8d3f9bab97e8175f367969dd2938666bb6b5d6ea21a18e65d9760fc83df1201e
7
+ data.tar.gz: c32c20ef1936d110845c9564680c57753cb2f22c0fc4a98b13a8a7e7dfe18f7920c8f2ef96f8a3fafcdaf566e0f41b3214d6988dad1dc1416b3c70437cee046f
@@ -6,7 +6,21 @@ require 'set'
6
6
 
7
7
  require_relative 'ast/ext/range'
8
8
  require_relative 'ast/ext/set'
9
+ require_relative 'ast/node_pattern/method_definer'
9
10
  require_relative 'ast/node_pattern'
11
+ require_relative 'ast/node/mixin/descendence'
12
+ require_relative 'ast/node_pattern/builder'
13
+ require_relative 'ast/node_pattern/comment'
14
+ require_relative 'ast/node_pattern/compiler'
15
+ require_relative 'ast/node_pattern/compiler/subcompiler'
16
+ require_relative 'ast/node_pattern/compiler/atom_subcompiler'
17
+ require_relative 'ast/node_pattern/compiler/binding'
18
+ require_relative 'ast/node_pattern/compiler/node_pattern_subcompiler'
19
+ require_relative 'ast/node_pattern/compiler/sequence_subcompiler'
20
+ require_relative 'ast/node_pattern/lexer'
21
+ require_relative 'ast/node_pattern/node'
22
+ require_relative 'ast/node_pattern/parser'
23
+ require_relative 'ast/node_pattern/sets'
10
24
  require_relative 'ast/sexp'
11
25
  require_relative 'ast/node'
12
26
  require_relative 'ast/node/mixin/method_identifier_predicates'
@@ -67,3 +81,6 @@ require_relative 'ast/rubocop_compatibility'
67
81
  require_relative 'ast/token'
68
82
  require_relative 'ast/traversal'
69
83
  require_relative 'ast/version'
84
+
85
+ ::RuboCop::AST::NodePattern::Parser.autoload :WithMeta, "#{__dir__}/ast/node_pattern/with_meta"
86
+ ::RuboCop::AST::NodePattern::Compiler.autoload :Debug, "#{__dir__}/ast/node_pattern/compiler/debug"
@@ -16,6 +16,7 @@ module RuboCop
16
16
  class Builder < Parser::Builders::Default
17
17
  self.emit_forward_arg = true
18
18
 
19
+ # @api private
19
20
  NODE_MAP = {
20
21
  and: AndNode,
21
22
  alias: AliasNode,
@@ -21,41 +21,67 @@ module RuboCop
21
21
  class Node < Parser::AST::Node # rubocop:disable Metrics/ClassLength
22
22
  include RuboCop::AST::Sexp
23
23
  extend NodePattern::Macros
24
+ include RuboCop::AST::Descendence
24
25
 
26
+ # @api private
25
27
  # <=> isn't included here, because it doesn't return a boolean.
26
- COMPARISON_OPERATORS = %i[== === != <= >= > <].freeze
28
+ COMPARISON_OPERATORS = %i[== === != <= >= > <].to_set.freeze
27
29
 
30
+ # @api private
28
31
  TRUTHY_LITERALS = %i[str dstr xstr int float sym dsym array
29
32
  hash regexp true irange erange complex
30
- rational regopt].freeze
31
- FALSEY_LITERALS = %i[false nil].freeze
33
+ rational regopt].to_set.freeze
34
+ # @api private
35
+ FALSEY_LITERALS = %i[false nil].to_set.freeze
36
+ # @api private
32
37
  LITERALS = (TRUTHY_LITERALS + FALSEY_LITERALS).freeze
38
+ # @api private
33
39
  COMPOSITE_LITERALS = %i[dstr xstr dsym array hash irange
34
- erange regexp].freeze
40
+ erange regexp].to_set.freeze
41
+ # @api private
35
42
  BASIC_LITERALS = (LITERALS - COMPOSITE_LITERALS).freeze
43
+ # @api private
36
44
  MUTABLE_LITERALS = %i[str dstr xstr array hash
37
- regexp irange erange].freeze
45
+ regexp irange erange].to_set.freeze
46
+ # @api private
38
47
  IMMUTABLE_LITERALS = (LITERALS - MUTABLE_LITERALS).freeze
39
48
 
49
+ # @api private
40
50
  EQUALS_ASSIGNMENTS = %i[lvasgn ivasgn cvasgn gvasgn
41
- casgn masgn rasgn mrasgn].freeze
42
- SHORTHAND_ASSIGNMENTS = %i[op_asgn or_asgn and_asgn].freeze
51
+ casgn masgn rasgn mrasgn].to_set.freeze
52
+ # @api private
53
+ SHORTHAND_ASSIGNMENTS = %i[op_asgn or_asgn and_asgn].to_set.freeze
54
+ # @api private
43
55
  ASSIGNMENTS = (EQUALS_ASSIGNMENTS + SHORTHAND_ASSIGNMENTS).freeze
44
56
 
45
- BASIC_CONDITIONALS = %i[if while until].freeze
46
- CONDITIONALS = [*BASIC_CONDITIONALS, :case].freeze
47
- POST_CONDITION_LOOP_TYPES = %i[while_post until_post].freeze
57
+ # @api private
58
+ BASIC_CONDITIONALS = %i[if while until].to_set.freeze
59
+ # @api private
60
+ CONDITIONALS = (BASIC_CONDITIONALS + [:case]).freeze
61
+ # @api private
62
+ POST_CONDITION_LOOP_TYPES = %i[while_post until_post].to_set.freeze
63
+ # @api private
48
64
  LOOP_TYPES = (POST_CONDITION_LOOP_TYPES + %i[while until for]).freeze
49
- VARIABLES = %i[ivar gvar cvar lvar].freeze
50
- REFERENCES = %i[nth_ref back_ref].freeze
65
+ # @api private
66
+ VARIABLES = %i[ivar gvar cvar lvar].to_set.freeze
67
+ # @api private
68
+ REFERENCES = %i[nth_ref back_ref].to_set.freeze
69
+ # @api private
51
70
  KEYWORDS = %i[alias and break case class def defs defined?
52
71
  kwbegin do else ensure for if module next
53
72
  not or postexe redo rescue retry return self
54
73
  super zsuper then undef until when while
55
- yield].freeze
56
- OPERATOR_KEYWORDS = %i[and or].freeze
57
- SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].freeze
58
- ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg].freeze
74
+ yield].to_set.freeze
75
+ # @api private
76
+ OPERATOR_KEYWORDS = %i[and or].to_set.freeze
77
+ # @api private
78
+ SPECIAL_KEYWORDS = %w[__FILE__ __LINE__ __ENCODING__].to_set.freeze
79
+ # @api private
80
+ ARGUMENT_TYPES = %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg].to_set.freeze
81
+
82
+ LITERAL_RECURSIVE_METHODS = (COMPARISON_OPERATORS + %i[* ! <=>]).freeze
83
+ LITERAL_RECURSIVE_TYPES = (OPERATOR_KEYWORDS + COMPOSITE_LITERALS + %i[begin pair]).freeze
84
+ private_constant :LITERAL_RECURSIVE_METHODS, :LITERAL_RECURSIVE_TYPES
59
85
 
60
86
  # @see https://www.rubydoc.info/gems/ast/AST/Node:initialize
61
87
  def initialize(type, children = [], properties = {})
@@ -211,104 +237,6 @@ module RuboCop
211
237
  each_ancestor.to_a
212
238
  end
213
239
 
214
- # Calls the given block for each child node.
215
- # If no block is given, an `Enumerator` is returned.
216
- #
217
- # Note that this is different from `node.children.each { |child| ... }`
218
- # which yields all children including non-node elements.
219
- #
220
- # @overload each_child_node
221
- # Yield all nodes.
222
- # @overload each_child_node(type)
223
- # Yield only nodes matching the type.
224
- # @param [Symbol] type a node type
225
- # @overload each_child_node(type_a, type_b, ...)
226
- # Yield only nodes matching any of the types.
227
- # @param [Symbol] type_a a node type
228
- # @param [Symbol] type_b a node type
229
- # @yieldparam [Node] node each child node
230
- # @return [self] if a block is given
231
- # @return [Enumerator] if no block is given
232
- def each_child_node(*types)
233
- return to_enum(__method__, *types) unless block_given?
234
-
235
- children.each do |child|
236
- next unless child.is_a?(Node)
237
-
238
- yield child if types.empty? || types.include?(child.type)
239
- end
240
-
241
- self
242
- end
243
-
244
- # Returns an array of child nodes.
245
- # This is a shorthand for `node.each_child_node.to_a`.
246
- #
247
- # @return [Array<Node>] an array of child nodes
248
- def child_nodes
249
- each_child_node.to_a
250
- end
251
-
252
- # Calls the given block for each descendant node with depth first order.
253
- # If no block is given, an `Enumerator` is returned.
254
- #
255
- # @overload each_descendant
256
- # Yield all nodes.
257
- # @overload each_descendant(type)
258
- # Yield only nodes matching the type.
259
- # @param [Symbol] type a node type
260
- # @overload each_descendant(type_a, type_b, ...)
261
- # Yield only nodes matching any of the types.
262
- # @param [Symbol] type_a a node type
263
- # @param [Symbol] type_b a node type
264
- # @yieldparam [Node] node each descendant node
265
- # @return [self] if a block is given
266
- # @return [Enumerator] if no block is given
267
- def each_descendant(*types, &block)
268
- return to_enum(__method__, *types) unless block_given?
269
-
270
- visit_descendants(types, &block)
271
-
272
- self
273
- end
274
-
275
- # Returns an array of descendant nodes.
276
- # This is a shorthand for `node.each_descendant.to_a`.
277
- #
278
- # @return [Array<Node>] an array of descendant nodes
279
- def descendants
280
- each_descendant.to_a
281
- end
282
-
283
- # Calls the given block for the receiver and each descendant node in
284
- # depth-first order.
285
- # If no block is given, an `Enumerator` is returned.
286
- #
287
- # This method would be useful when you treat the receiver node as the root
288
- # of a tree and want to iterate over all nodes in the tree.
289
- #
290
- # @overload each_node
291
- # Yield all nodes.
292
- # @overload each_node(type)
293
- # Yield only nodes matching the type.
294
- # @param [Symbol] type a node type
295
- # @overload each_node(type_a, type_b, ...)
296
- # Yield only nodes matching any of the types.
297
- # @param [Symbol] type_a a node type
298
- # @param [Symbol] type_b a node type
299
- # @yieldparam [Node] node each node
300
- # @return [self] if a block is given
301
- # @return [Enumerator] if no block is given
302
- def each_node(*types, &block)
303
- return to_enum(__method__, *types) unless block_given?
304
-
305
- yield self if types.empty? || types.include?(type)
306
-
307
- visit_descendants(types, &block)
308
-
309
- self
310
- end
311
-
312
240
  # Note: Some rare nodes may have no source, like `s(:args)` in `foo {}`
313
241
  # @return [String, nil]
314
242
  def source
@@ -439,10 +367,10 @@ module RuboCop
439
367
  define_method(recursive_kind) do
440
368
  case type
441
369
  when :send
442
- [*COMPARISON_OPERATORS, :!, :<=>].include?(method_name) &&
370
+ LITERAL_RECURSIVE_METHODS.include?(method_name) &&
443
371
  receiver.send(recursive_kind) &&
444
372
  arguments.all?(&recursive_kind)
445
- when :begin, :pair, *OPERATOR_KEYWORDS, *COMPOSITE_LITERALS
373
+ when LITERAL_RECURSIVE_TYPES
446
374
  children.compact.all?(&recursive_kind)
447
375
  else
448
376
  send(kind_filter)
@@ -631,15 +559,6 @@ module RuboCop
631
559
  end
632
560
  end
633
561
 
634
- protected
635
-
636
- def visit_descendants(types, &block)
637
- each_child_node do |child|
638
- yield child if types.empty? || types.include?(child.type)
639
- child.visit_descendants(types, &block)
640
- end
641
- end
642
-
643
562
  private
644
563
 
645
564
  def visit_ancestors(types)
@@ -10,6 +10,7 @@ module RuboCop
10
10
  string: /^%[wW]/,
11
11
  symbol: /^%[iI]/
12
12
  }.freeze
13
+ private_constant :PERCENT_LITERAL_TYPES
13
14
 
14
15
  # Returns an array of all value nodes in the `array` literal.
15
16
  #
@@ -12,6 +12,7 @@ module RuboCop
12
12
  include MethodIdentifierPredicates
13
13
 
14
14
  VOID_CONTEXT_METHODS = %i[each tap].freeze
15
+ private_constant :VOID_CONTEXT_METHODS
15
16
 
16
17
  # The `send` node associated with this block.
17
18
  #
@@ -9,6 +9,7 @@ module RuboCop
9
9
  include HashElementNode
10
10
 
11
11
  DOUBLE_SPLAT = '**'
12
+ private_constant :DOUBLE_SPLAT
12
13
 
13
14
  # This is used for duck typing with `pair` nodes which also appear as
14
15
  # `hash` elements.
@@ -8,6 +8,7 @@ module RuboCop
8
8
 
9
9
  ARRAY_METHODS =
10
10
  (Array.instance_methods - Object.instance_methods - [:to_a]).freeze
11
+ private_constant :ARRAY_METHODS
11
12
 
12
13
  def_delegators :to_a, *ARRAY_METHODS
13
14
  end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module AST
5
+ # Common functionality for primitive literal nodes: `sym`, `str`,
6
+ # `int`, `float`, ...
7
+ module Descendence
8
+ # Calls the given block for each child node.
9
+ # If no block is given, an `Enumerator` is returned.
10
+ #
11
+ # Note that this is different from `node.children.each { |child| ... }`
12
+ # which yields all children including non-node elements.
13
+ #
14
+ # @overload each_child_node
15
+ # Yield all nodes.
16
+ # @overload each_child_node(type)
17
+ # Yield only nodes matching the type.
18
+ # @param [Symbol] type a node type
19
+ # @overload each_child_node(type_a, type_b, ...)
20
+ # Yield only nodes matching any of the types.
21
+ # @param [Symbol] type_a a node type
22
+ # @param [Symbol] type_b a node type
23
+ # @yieldparam [Node] node each child node
24
+ # @return [self] if a block is given
25
+ # @return [Enumerator] if no block is given
26
+ def each_child_node(*types)
27
+ return to_enum(__method__, *types) unless block_given?
28
+
29
+ children.each do |child|
30
+ next unless child.is_a?(::AST::Node)
31
+
32
+ yield child if types.empty? || types.include?(child.type)
33
+ end
34
+
35
+ self
36
+ end
37
+
38
+ # Returns an array of child nodes.
39
+ # This is a shorthand for `node.each_child_node.to_a`.
40
+ #
41
+ # @return [Array<Node>] an array of child nodes
42
+ def child_nodes
43
+ each_child_node.to_a
44
+ end
45
+
46
+ # Calls the given block for each descendant node with depth first order.
47
+ # If no block is given, an `Enumerator` is returned.
48
+ #
49
+ # @overload each_descendant
50
+ # Yield all nodes.
51
+ # @overload each_descendant(type)
52
+ # Yield only nodes matching the type.
53
+ # @param [Symbol] type a node type
54
+ # @overload each_descendant(type_a, type_b, ...)
55
+ # Yield only nodes matching any of the types.
56
+ # @param [Symbol] type_a a node type
57
+ # @param [Symbol] type_b a node type
58
+ # @yieldparam [Node] node each descendant node
59
+ # @return [self] if a block is given
60
+ # @return [Enumerator] if no block is given
61
+ def each_descendant(*types, &block)
62
+ return to_enum(__method__, *types) unless block_given?
63
+
64
+ visit_descendants(types, &block)
65
+
66
+ self
67
+ end
68
+
69
+ # Returns an array of descendant nodes.
70
+ # This is a shorthand for `node.each_descendant.to_a`.
71
+ #
72
+ # @return [Array<Node>] an array of descendant nodes
73
+ def descendants
74
+ each_descendant.to_a
75
+ end
76
+
77
+ # Calls the given block for the receiver and each descendant node in
78
+ # depth-first order.
79
+ # If no block is given, an `Enumerator` is returned.
80
+ #
81
+ # This method would be useful when you treat the receiver node as the root
82
+ # of a tree and want to iterate over all nodes in the tree.
83
+ #
84
+ # @overload each_node
85
+ # Yield all nodes.
86
+ # @overload each_node(type)
87
+ # Yield only nodes matching the type.
88
+ # @param [Symbol] type a node type
89
+ # @overload each_node(type_a, type_b, ...)
90
+ # Yield only nodes matching any of the types.
91
+ # @param [Symbol] type_a a node type
92
+ # @param [Symbol] type_b a node type
93
+ # @yieldparam [Node] node each node
94
+ # @return [self] if a block is given
95
+ # @return [Enumerator] if no block is given
96
+ def each_node(*types, &block)
97
+ return to_enum(__method__, *types) unless block_given?
98
+
99
+ yield self if types.empty? || types.include?(type)
100
+
101
+ visit_descendants(types, &block)
102
+
103
+ self
104
+ end
105
+
106
+ protected
107
+
108
+ def visit_descendants(types, &block)
109
+ each_child_node do |child|
110
+ yield child if types.empty? || types.include?(child.type)
111
+ child.visit_descendants(types, &block)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -10,7 +10,9 @@ module RuboCop
10
10
  include MethodIdentifierPredicates
11
11
 
12
12
  ARITHMETIC_OPERATORS = %i[+ - * / % **].freeze
13
+ private_constant :ARITHMETIC_OPERATORS
13
14
  SPECIAL_MODIFIERS = %w[private protected].freeze
15
+ private_constant :SPECIAL_MODIFIERS
14
16
 
15
17
  # The receiving node of the method dispatch.
16
18
  #
@@ -11,17 +11,23 @@ module RuboCop
11
11
  find find_all find_index inject loop map!
12
12
  map reduce reject reject! reverse_each select
13
13
  select! times upto].to_set.freeze
14
+ private_constant :ENUMERATOR_METHODS
14
15
 
15
16
  ENUMERABLE_METHODS = (Enumerable.instance_methods + [:each]).to_set.freeze
17
+ private_constant :ENUMERABLE_METHODS
16
18
 
17
19
  # http://phrogz.net/programmingruby/language.html#table_18.4
18
20
  OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
19
21
  % ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].to_set.freeze
22
+ private_constant :OPERATOR_METHODS
20
23
 
21
24
  NONMUTATING_BINARY_OPERATOR_METHODS = %i[* / % + - == === != < > <= >= <=>].to_set.freeze
25
+ private_constant :NONMUTATING_BINARY_OPERATOR_METHODS
22
26
  NONMUTATING_UNARY_OPERATOR_METHODS = %i[+@ -@ ~ !].to_set.freeze
27
+ private_constant :NONMUTATING_UNARY_OPERATOR_METHODS
23
28
  NONMUTATING_OPERATOR_METHODS = (NONMUTATING_BINARY_OPERATOR_METHODS +
24
29
  NONMUTATING_UNARY_OPERATOR_METHODS).freeze
30
+ private_constant :NONMUTATING_OPERATOR_METHODS
25
31
 
26
32
  NONMUTATING_ARRAY_METHODS = %i[
27
33
  all? any? assoc at bsearch bsearch_index collect
@@ -37,6 +43,7 @@ module RuboCop
37
43
  to_a to_ary to_h to_s transpose union uniq
38
44
  values_at zip |
39
45
  ].to_set.freeze
46
+ private_constant :NONMUTATING_ARRAY_METHODS
40
47
 
41
48
  NONMUTATING_HASH_METHODS = %i[
42
49
  any? assoc compact dig each each_key each_pair
@@ -47,6 +54,7 @@ module RuboCop
47
54
  to_proc to_s transform_keys transform_values value?
48
55
  values values_at
49
56
  ].to_set.freeze
57
+ private_constant :NONMUTATING_HASH_METHODS
50
58
 
51
59
  NONMUTATING_STRING_METHODS = %i[
52
60
  ascii_only? b bytes bytesize byteslice capitalize
@@ -62,6 +70,7 @@ module RuboCop
62
70
  to_str to_sym tr tr_s unicode_normalize unicode_normalized?
63
71
  unpack unpack1 upcase upto valid_encoding?
64
72
  ].to_set.freeze
73
+ private_constant :NONMUTATING_STRING_METHODS
65
74
 
66
75
  # Checks whether the method name matches the argument.
67
76
  #