rubocop-ast 0.4.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubocop/ast.rb +18 -0
  3. data/lib/rubocop/ast/builder.rb +1 -0
  4. data/lib/rubocop/ast/node.rb +57 -126
  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 +16 -24
  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 +9 -4
  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 +6 -4
  37. data/lib/rubocop/ast/rubocop_compatibility.rb +31 -0
  38. data/lib/rubocop/ast/traversal.rb +1 -0
  39. data/lib/rubocop/ast/version.rb +1 -1
  40. metadata +39 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bf5651a5da2be43d773d152c2f2260dfd1850ce1075aca7c4d21c08dd31a92a
4
- data.tar.gz: c9addcd67e29e797109dc2f523c9c2094f94908b40c2e60c56061d6a8bf0e0f5
3
+ metadata.gz: eae5a550b84ac088fb1065c539710b04b9885883c367ab0b26f8d3b455291ccb
4
+ data.tar.gz: 424d68c1b31693d5de3dc83aaf88823147ecf5a446c2b68f39c8e992f9b10c4e
5
5
  SHA512:
6
- metadata.gz: 1aa33edeacd95a65468093b80248a5908c69d30bf7d19afd6141044d00830f31c12aa489caf8ef705364d63771cade73651d9697635ab22941137df467ce4e92
7
- data.tar.gz: fb820b52d69df72ab17a5ee06d06bdf7256b3318d8094b96467f79d314bad1b52bcb3938cb2ef98ca07b300f56132ac14921ef24aadf299d4c5754bb118b119f
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'
@@ -63,6 +77,10 @@ require_relative 'ast/node/while_node'
63
77
  require_relative 'ast/node/yield_node'
64
78
  require_relative 'ast/builder'
65
79
  require_relative 'ast/processed_source'
80
+ require_relative 'ast/rubocop_compatibility'
66
81
  require_relative 'ast/token'
67
82
  require_relative 'ast/traversal'
68
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 = {})
@@ -92,6 +118,16 @@ module RuboCop
92
118
  @mutable_attributes[:parent] = node
93
119
  end
94
120
 
121
+ # @return [Boolean]
122
+ def parent?
123
+ !!parent
124
+ end
125
+
126
+ # @return [Boolean]
127
+ def root?
128
+ !parent
129
+ end
130
+
95
131
  def complete!
96
132
  @mutable_attributes.freeze
97
133
  each_child_node(&:complete!)
@@ -201,106 +237,10 @@ module RuboCop
201
237
  each_ancestor.to_a
202
238
  end
203
239
 
204
- # Calls the given block for each child node.
205
- # If no block is given, an `Enumerator` is returned.
206
- #
207
- # Note that this is different from `node.children.each { |child| ... }`
208
- # which yields all children including non-node elements.
209
- #
210
- # @overload each_child_node
211
- # Yield all nodes.
212
- # @overload each_child_node(type)
213
- # Yield only nodes matching the type.
214
- # @param [Symbol] type a node type
215
- # @overload each_child_node(type_a, type_b, ...)
216
- # Yield only nodes matching any of the types.
217
- # @param [Symbol] type_a a node type
218
- # @param [Symbol] type_b a node type
219
- # @yieldparam [Node] node each child node
220
- # @return [self] if a block is given
221
- # @return [Enumerator] if no block is given
222
- def each_child_node(*types)
223
- return to_enum(__method__, *types) unless block_given?
224
-
225
- children.each do |child|
226
- next unless child.is_a?(Node)
227
-
228
- yield child if types.empty? || types.include?(child.type)
229
- end
230
-
231
- self
232
- end
233
-
234
- # Returns an array of child nodes.
235
- # This is a shorthand for `node.each_child_node.to_a`.
236
- #
237
- # @return [Array<Node>] an array of child nodes
238
- def child_nodes
239
- each_child_node.to_a
240
- end
241
-
242
- # Calls the given block for each descendant node with depth first order.
243
- # If no block is given, an `Enumerator` is returned.
244
- #
245
- # @overload each_descendant
246
- # Yield all nodes.
247
- # @overload each_descendant(type)
248
- # Yield only nodes matching the type.
249
- # @param [Symbol] type a node type
250
- # @overload each_descendant(type_a, type_b, ...)
251
- # Yield only nodes matching any of the types.
252
- # @param [Symbol] type_a a node type
253
- # @param [Symbol] type_b a node type
254
- # @yieldparam [Node] node each descendant node
255
- # @return [self] if a block is given
256
- # @return [Enumerator] if no block is given
257
- def each_descendant(*types, &block)
258
- return to_enum(__method__, *types) unless block_given?
259
-
260
- visit_descendants(types, &block)
261
-
262
- self
263
- end
264
-
265
- # Returns an array of descendant nodes.
266
- # This is a shorthand for `node.each_descendant.to_a`.
267
- #
268
- # @return [Array<Node>] an array of descendant nodes
269
- def descendants
270
- each_descendant.to_a
271
- end
272
-
273
- # Calls the given block for the receiver and each descendant node in
274
- # depth-first order.
275
- # If no block is given, an `Enumerator` is returned.
276
- #
277
- # This method would be useful when you treat the receiver node as the root
278
- # of a tree and want to iterate over all nodes in the tree.
279
- #
280
- # @overload each_node
281
- # Yield all nodes.
282
- # @overload each_node(type)
283
- # Yield only nodes matching the type.
284
- # @param [Symbol] type a node type
285
- # @overload each_node(type_a, type_b, ...)
286
- # Yield only nodes matching any of the types.
287
- # @param [Symbol] type_a a node type
288
- # @param [Symbol] type_b a node type
289
- # @yieldparam [Node] node each node
290
- # @return [self] if a block is given
291
- # @return [Enumerator] if no block is given
292
- def each_node(*types, &block)
293
- return to_enum(__method__, *types) unless block_given?
294
-
295
- yield self if types.empty? || types.include?(type)
296
-
297
- visit_descendants(types, &block)
298
-
299
- self
300
- end
301
-
240
+ # Note: Some rare nodes may have no source, like `s(:args)` in `foo {}`
241
+ # @return [String, nil]
302
242
  def source
303
- loc.expression.source
243
+ loc.expression&.source
304
244
  end
305
245
 
306
246
  def source_range
@@ -427,10 +367,10 @@ module RuboCop
427
367
  define_method(recursive_kind) do
428
368
  case type
429
369
  when :send
430
- [*COMPARISON_OPERATORS, :!, :<=>].include?(method_name) &&
370
+ LITERAL_RECURSIVE_METHODS.include?(method_name) &&
431
371
  receiver.send(recursive_kind) &&
432
372
  arguments.all?(&recursive_kind)
433
- when :begin, :pair, *OPERATOR_KEYWORDS, *COMPOSITE_LITERALS
373
+ when LITERAL_RECURSIVE_TYPES
434
374
  children.compact.all?(&recursive_kind)
435
375
  else
436
376
  send(kind_filter)
@@ -619,15 +559,6 @@ module RuboCop
619
559
  end
620
560
  end
621
561
 
622
- protected
623
-
624
- def visit_descendants(types, &block)
625
- each_child_node do |child|
626
- yield child if types.empty? || types.include?(child.type)
627
- child.visit_descendants(types, &block)
628
- end
629
- end
630
-
631
562
  private
632
563
 
633
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
  #
@@ -42,7 +44,7 @@ module RuboCop
42
44
  #
43
45
  # @return [Boolean] whether the dispatched method is a macro method
44
46
  def macro?
45
- !receiver && macro_scope?
47
+ !receiver && in_macro_scope?
46
48
  end
47
49
 
48
50
  # Checks whether the dispatched method is an access modifier.
@@ -222,31 +224,21 @@ module RuboCop
222
224
 
223
225
  private
224
226
 
225
- def_node_matcher :macro_scope?, <<~PATTERN
226
- {^{({sclass class module block} ...) class_constructor?}
227
- ^^{({sclass class module block} ... ({begin if} ...)) class_constructor?}
228
- ^#macro_kwbegin_wrapper?
229
- #root_node?}
227
+ def_node_matcher :in_macro_scope?, <<~PATTERN
228
+ {
229
+ root? # Either a root node,
230
+ ^{ # or the parent is...
231
+ sclass class module class_constructor? # a class-like node
232
+ [ { # or some "wrapper"
233
+ kwbegin begin block
234
+ (if _condition <%0 _>) # note: we're excluding the condition of `if` nodes
235
+ }
236
+ #in_macro_scope? # that is itself in a macro scope
237
+ ]
238
+ }
239
+ }
230
240
  PATTERN
231
241
 
232
- # Check if a node's parent is a kwbegin wrapper within a macro scope
233
- #
234
- # @param parent [Node] parent of the node being checked
235
- #
236
- # @return [Boolean] true if the parent is a kwbegin in a macro scope
237
- def macro_kwbegin_wrapper?(parent)
238
- parent.kwbegin_type? && macro_scope?(parent)
239
- end
240
-
241
- # Check if a node does not have a parent
242
- #
243
- # @param node [Node]
244
- #
245
- # @return [Boolean] if the parent is nil
246
- def root_node?(node)
247
- node.parent.nil?
248
- end
249
-
250
242
  def_node_matcher :adjacent_def_modifier?, <<~PATTERN
251
243
  (send nil? _ ({def defs} ...))
252
244
  PATTERN