tree_haver 3.2.6 → 4.0.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +41 -3
- data/README.md +94 -12
- data/lib/tree_haver/backend_registry.rb +234 -0
- data/lib/tree_haver/backends/citrus.rb +7 -1
- data/lib/tree_haver/backends/ffi.rb +36 -9
- data/lib/tree_haver/backends/java.rb +59 -61
- data/lib/tree_haver/backends/mri.rb +38 -11
- data/lib/tree_haver/backends/prism.rb +67 -234
- data/lib/tree_haver/backends/psych.rb +75 -346
- data/lib/tree_haver/backends/rust.rb +32 -11
- data/lib/tree_haver/base/language.rb +98 -0
- data/lib/tree_haver/base/node.rb +315 -0
- data/lib/tree_haver/base/parser.rb +24 -0
- data/lib/tree_haver/base/point.rb +48 -0
- data/lib/tree_haver/base/tree.rb +128 -0
- data/lib/tree_haver/base.rb +12 -0
- data/lib/tree_haver/node.rb +14 -10
- data/lib/tree_haver/rspec/dependency_tags.rb +9 -5
- data/lib/tree_haver/tree.rb +4 -5
- data/lib/tree_haver/version.rb +2 -2
- data/lib/tree_haver.rb +30 -18
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
- data/lib/tree_haver/backends/commonmarker.rb +0 -516
- data/lib/tree_haver/backends/markly.rb +0 -590
|
@@ -41,10 +41,13 @@ module TreeHaver
|
|
|
41
41
|
@load_attempted = true # rubocop:disable ThreadSafety/ClassInstanceVariable
|
|
42
42
|
begin
|
|
43
43
|
require "prism"
|
|
44
|
-
|
|
45
44
|
@loaded = true # rubocop:disable ThreadSafety/ClassInstanceVariable
|
|
46
45
|
rescue LoadError
|
|
47
46
|
@loaded = false # rubocop:disable ThreadSafety/ClassInstanceVariable
|
|
47
|
+
rescue StandardError
|
|
48
|
+
# :nocov: defensive code - StandardError during require is extremely rare
|
|
49
|
+
@loaded = false # rubocop:disable ThreadSafety/ClassInstanceVariable
|
|
50
|
+
# :nocov:
|
|
48
51
|
end
|
|
49
52
|
@loaded # rubocop:disable ThreadSafety/ClassInstanceVariable
|
|
50
53
|
end
|
|
@@ -87,58 +90,30 @@ module TreeHaver
|
|
|
87
90
|
# @example
|
|
88
91
|
# language = TreeHaver::Backends::Prism::Language.ruby
|
|
89
92
|
# parser.language = language
|
|
90
|
-
class Language
|
|
91
|
-
include Comparable
|
|
92
|
-
|
|
93
|
-
# The language name (always :ruby for Prism)
|
|
94
|
-
# @return [Symbol]
|
|
95
|
-
attr_reader :name
|
|
96
|
-
alias_method :language_name, :name
|
|
97
|
-
|
|
98
|
-
# The backend this language is for
|
|
99
|
-
# @return [Symbol]
|
|
100
|
-
attr_reader :backend
|
|
101
|
-
|
|
102
|
-
# Prism parsing options
|
|
103
|
-
# @return [Hash]
|
|
104
|
-
attr_reader :options
|
|
105
|
-
|
|
93
|
+
class Language < TreeHaver::Base::Language
|
|
106
94
|
# @param name [Symbol] language name (should be :ruby)
|
|
107
95
|
# @param options [Hash] Prism parsing options (e.g., frozen_string_literal, version)
|
|
108
96
|
def initialize(name = :ruby, options: {})
|
|
109
|
-
|
|
110
|
-
@backend = :prism
|
|
111
|
-
@options = options
|
|
97
|
+
super(name, backend: :prism, options: options)
|
|
112
98
|
|
|
113
|
-
unless
|
|
99
|
+
unless self.name == :ruby
|
|
114
100
|
raise TreeHaver::NotAvailable,
|
|
115
101
|
"Prism only supports Ruby parsing. " \
|
|
116
102
|
"Got language: #{name.inspect}"
|
|
117
103
|
end
|
|
118
104
|
end
|
|
119
105
|
|
|
120
|
-
# Compare languages for equality
|
|
121
|
-
#
|
|
122
|
-
# Prism languages are equal if they have the same backend and options.
|
|
106
|
+
# Compare languages for equality by options (since name is always :ruby)
|
|
123
107
|
#
|
|
124
108
|
# @param other [Object] object to compare with
|
|
125
109
|
# @return [Integer, nil] -1, 0, 1, or nil if not comparable
|
|
126
110
|
def <=>(other)
|
|
127
|
-
return unless other.is_a?(Language)
|
|
128
|
-
return unless other.backend ==
|
|
111
|
+
return unless other.is_a?(TreeHaver::Base::Language)
|
|
112
|
+
return unless other.backend == backend
|
|
129
113
|
|
|
130
|
-
|
|
114
|
+
options.to_a.sort <=> other.options.to_a.sort
|
|
131
115
|
end
|
|
132
116
|
|
|
133
|
-
# Hash value for this language (for use in Sets/Hashes)
|
|
134
|
-
# @return [Integer]
|
|
135
|
-
def hash
|
|
136
|
-
[@backend, @name, @options.to_a.sort].hash
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Alias eql? to ==
|
|
140
|
-
alias_method :eql?, :==
|
|
141
|
-
|
|
142
117
|
class << self
|
|
143
118
|
# Create a Ruby language instance (convenience method)
|
|
144
119
|
#
|
|
@@ -157,17 +132,14 @@ module TreeHaver
|
|
|
157
132
|
# Load language from library path (API compatibility)
|
|
158
133
|
#
|
|
159
134
|
# Prism only supports Ruby, so path and symbol parameters are ignored.
|
|
160
|
-
# This method exists for API consistency with tree-sitter backends,
|
|
161
|
-
# allowing `TreeHaver.parser_for(:ruby)` to work regardless of backend.
|
|
162
135
|
#
|
|
163
136
|
# @param _path [String] Ignored - Prism doesn't load external grammars
|
|
164
|
-
# @param symbol [String, nil] Ignored
|
|
137
|
+
# @param symbol [String, nil] Ignored - Prism only supports Ruby
|
|
165
138
|
# @param name [String, nil] Language name hint (defaults to :ruby)
|
|
166
139
|
# @return [Language] Ruby language
|
|
167
140
|
# @raise [TreeHaver::NotAvailable] if requested language is not Ruby
|
|
168
141
|
def from_library(_path = nil, symbol: nil, name: nil)
|
|
169
|
-
|
|
170
|
-
lang_name = name || symbol&.to_s&.sub(/^tree_sitter_/, "")&.to_sym || :ruby
|
|
142
|
+
lang_name = name || :ruby
|
|
171
143
|
|
|
172
144
|
unless lang_name == :ruby
|
|
173
145
|
raise TreeHaver::NotAvailable,
|
|
@@ -185,13 +157,13 @@ module TreeHaver
|
|
|
185
157
|
# Prism parser wrapper
|
|
186
158
|
#
|
|
187
159
|
# Wraps Prism to provide a tree-sitter-like API for parsing Ruby code.
|
|
188
|
-
class Parser
|
|
160
|
+
class Parser < TreeHaver::Base::Parser
|
|
189
161
|
# Create a new Prism parser instance
|
|
190
162
|
#
|
|
191
163
|
# @raise [TreeHaver::NotAvailable] if prism is not available
|
|
192
164
|
def initialize
|
|
165
|
+
super
|
|
193
166
|
raise TreeHaver::NotAvailable, "prism not available" unless Prism.available?
|
|
194
|
-
@language = nil
|
|
195
167
|
@options = {}
|
|
196
168
|
end
|
|
197
169
|
|
|
@@ -251,23 +223,20 @@ module TreeHaver
|
|
|
251
223
|
# Wraps a Prism::ParseResult to provide tree-sitter-compatible API.
|
|
252
224
|
#
|
|
253
225
|
# @api private
|
|
254
|
-
class Tree
|
|
226
|
+
class Tree < TreeHaver::Base::Tree
|
|
255
227
|
# @return [::Prism::ParseResult] the underlying Prism parse result
|
|
256
228
|
attr_reader :parse_result
|
|
257
229
|
|
|
258
|
-
# @return [String] the source code
|
|
259
|
-
attr_reader :source
|
|
260
|
-
|
|
261
230
|
def initialize(parse_result, source)
|
|
231
|
+
super(parse_result, source: source)
|
|
262
232
|
@parse_result = parse_result
|
|
263
|
-
@source = source
|
|
264
233
|
end
|
|
265
234
|
|
|
266
235
|
# Get the root node of the parse tree
|
|
267
236
|
#
|
|
268
237
|
# @return [Node] wrapped root node
|
|
269
238
|
def root_node
|
|
270
|
-
Node.new(@parse_result.value,
|
|
239
|
+
Node.new(@parse_result.value, source)
|
|
271
240
|
end
|
|
272
241
|
|
|
273
242
|
# Check if the parse had errors
|
|
@@ -311,13 +280,6 @@ module TreeHaver
|
|
|
311
280
|
def data_loc
|
|
312
281
|
@parse_result.data_loc
|
|
313
282
|
end
|
|
314
|
-
|
|
315
|
-
# Access the underlying Prism result (passthrough)
|
|
316
|
-
#
|
|
317
|
-
# @return [::Prism::ParseResult]
|
|
318
|
-
def inner_tree
|
|
319
|
-
@parse_result
|
|
320
|
-
end
|
|
321
283
|
end
|
|
322
284
|
|
|
323
285
|
# Prism node wrapper
|
|
@@ -331,18 +293,9 @@ module TreeHaver
|
|
|
331
293
|
# - Various node-specific accessors
|
|
332
294
|
#
|
|
333
295
|
# @api private
|
|
334
|
-
class Node
|
|
335
|
-
include Enumerable
|
|
336
|
-
|
|
337
|
-
# @return [::Prism::Node] the underlying Prism node
|
|
338
|
-
attr_reader :inner_node
|
|
339
|
-
|
|
340
|
-
# @return [String] the source code
|
|
341
|
-
attr_reader :source
|
|
342
|
-
|
|
296
|
+
class Node < TreeHaver::Base::Node
|
|
343
297
|
def initialize(node, source)
|
|
344
|
-
|
|
345
|
-
@source = source
|
|
298
|
+
super(node, source: source)
|
|
346
299
|
end
|
|
347
300
|
|
|
348
301
|
# Get node type from Prism class name
|
|
@@ -352,23 +305,25 @@ module TreeHaver
|
|
|
352
305
|
#
|
|
353
306
|
# @return [String] node type in snake_case
|
|
354
307
|
def type
|
|
355
|
-
return "nil" if
|
|
308
|
+
return "nil" if inner_node.nil?
|
|
356
309
|
|
|
357
310
|
# Convert class name to snake_case type
|
|
358
|
-
|
|
359
|
-
class_name = @inner_node.class.name.split("::").last
|
|
311
|
+
class_name = inner_node.class.name.split("::").last
|
|
360
312
|
class_name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "")
|
|
361
313
|
end
|
|
362
314
|
|
|
363
|
-
# Alias for
|
|
364
|
-
|
|
315
|
+
# Alias for type (API compatibility)
|
|
316
|
+
# @return [String] node type
|
|
317
|
+
def kind
|
|
318
|
+
type
|
|
319
|
+
end
|
|
365
320
|
|
|
366
321
|
# Get byte offset where the node starts
|
|
367
322
|
#
|
|
368
323
|
# @return [Integer]
|
|
369
324
|
def start_byte
|
|
370
|
-
return 0 if
|
|
371
|
-
loc =
|
|
325
|
+
return 0 if inner_node.nil? || !inner_node.respond_to?(:location)
|
|
326
|
+
loc = inner_node.location
|
|
372
327
|
loc&.start_offset || 0
|
|
373
328
|
end
|
|
374
329
|
|
|
@@ -376,227 +331,100 @@ module TreeHaver
|
|
|
376
331
|
#
|
|
377
332
|
# @return [Integer]
|
|
378
333
|
def end_byte
|
|
379
|
-
return 0 if
|
|
380
|
-
loc =
|
|
334
|
+
return 0 if inner_node.nil? || !inner_node.respond_to?(:location)
|
|
335
|
+
loc = inner_node.location
|
|
381
336
|
loc&.end_offset || 0
|
|
382
337
|
end
|
|
383
338
|
|
|
384
|
-
# Get the start position as row/column
|
|
339
|
+
# Get the start position as row/column (0-based)
|
|
385
340
|
#
|
|
386
|
-
# @return [Hash{Symbol => Integer}]
|
|
341
|
+
# @return [Hash{Symbol => Integer}]
|
|
387
342
|
def start_point
|
|
388
|
-
return {row: 0, column: 0} if
|
|
389
|
-
loc =
|
|
343
|
+
return {row: 0, column: 0} if inner_node.nil? || !inner_node.respond_to?(:location)
|
|
344
|
+
loc = inner_node.location
|
|
390
345
|
return {row: 0, column: 0} unless loc
|
|
391
346
|
|
|
392
|
-
# Prism uses 1-based lines internally but we need 0-based for tree-sitter compat
|
|
393
347
|
{row: (loc.start_line - 1), column: loc.start_column}
|
|
394
348
|
end
|
|
395
349
|
|
|
396
|
-
# Get the end position as row/column
|
|
350
|
+
# Get the end position as row/column (0-based)
|
|
397
351
|
#
|
|
398
|
-
# @return [Hash{Symbol => Integer}]
|
|
352
|
+
# @return [Hash{Symbol => Integer}]
|
|
399
353
|
def end_point
|
|
400
|
-
return {row: 0, column: 0} if
|
|
401
|
-
loc =
|
|
354
|
+
return {row: 0, column: 0} if inner_node.nil? || !inner_node.respond_to?(:location)
|
|
355
|
+
loc = inner_node.location
|
|
402
356
|
return {row: 0, column: 0} unless loc
|
|
403
357
|
|
|
404
|
-
# Prism uses 1-based lines internally but we need 0-based for tree-sitter compat
|
|
405
358
|
{row: (loc.end_line - 1), column: loc.end_column}
|
|
406
359
|
end
|
|
407
360
|
|
|
408
|
-
# Get
|
|
409
|
-
#
|
|
410
|
-
# @return [Integer] 1-based line number
|
|
411
|
-
def start_line
|
|
412
|
-
return 1 if @inner_node.nil? || !@inner_node.respond_to?(:location)
|
|
413
|
-
loc = @inner_node.location
|
|
414
|
-
loc&.start_line || 1
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
# Get the 1-based line number where this node ends
|
|
418
|
-
#
|
|
419
|
-
# @return [Integer] 1-based line number
|
|
420
|
-
def end_line
|
|
421
|
-
return 1 if @inner_node.nil? || !@inner_node.respond_to?(:location)
|
|
422
|
-
loc = @inner_node.location
|
|
423
|
-
loc&.end_line || 1
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
# Get position information as a hash
|
|
427
|
-
#
|
|
428
|
-
# Returns a hash with 1-based line numbers and 0-based columns.
|
|
429
|
-
# Compatible with *-merge gems' FileAnalysisBase.
|
|
361
|
+
# Get all child nodes
|
|
430
362
|
#
|
|
431
|
-
# @return [
|
|
432
|
-
def
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
end_line: end_line,
|
|
436
|
-
start_column: start_point[:column],
|
|
437
|
-
end_column: end_point[:column],
|
|
438
|
-
}
|
|
439
|
-
end
|
|
363
|
+
# @return [Array<Node>] array of wrapped child nodes
|
|
364
|
+
def children
|
|
365
|
+
return [] if inner_node.nil?
|
|
366
|
+
return [] unless inner_node.respond_to?(:child_nodes)
|
|
440
367
|
|
|
441
|
-
|
|
442
|
-
#
|
|
443
|
-
# @return [Node, nil] First child or nil
|
|
444
|
-
def first_child
|
|
445
|
-
child(0)
|
|
368
|
+
inner_node.child_nodes.compact.map { |n| Node.new(n, source) }
|
|
446
369
|
end
|
|
447
370
|
|
|
448
371
|
# Get the text content of this node
|
|
449
372
|
#
|
|
450
373
|
# @return [String]
|
|
451
374
|
def text
|
|
452
|
-
return "" if
|
|
375
|
+
return "" if inner_node.nil?
|
|
453
376
|
|
|
454
|
-
if
|
|
455
|
-
|
|
456
|
-
elsif @source
|
|
457
|
-
@source[start_byte...end_byte] || ""
|
|
377
|
+
if inner_node.respond_to?(:slice)
|
|
378
|
+
inner_node.slice
|
|
458
379
|
else
|
|
459
|
-
|
|
380
|
+
super
|
|
460
381
|
end
|
|
461
382
|
end
|
|
462
383
|
|
|
463
384
|
# Alias for Prism compatibility
|
|
464
385
|
alias_method :slice, :text
|
|
465
386
|
|
|
466
|
-
# Get the number of child nodes
|
|
467
|
-
#
|
|
468
|
-
# @return [Integer]
|
|
469
|
-
def child_count
|
|
470
|
-
return 0 if @inner_node.nil?
|
|
471
|
-
return 0 unless @inner_node.respond_to?(:child_nodes)
|
|
472
|
-
@inner_node.child_nodes.compact.size
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
# Get a child node by index
|
|
476
|
-
#
|
|
477
|
-
# @param index [Integer] child index
|
|
478
|
-
# @return [Node, nil] wrapped child node
|
|
479
|
-
def child(index)
|
|
480
|
-
return if @inner_node.nil?
|
|
481
|
-
return unless @inner_node.respond_to?(:child_nodes)
|
|
482
|
-
|
|
483
|
-
children_array = @inner_node.child_nodes.compact
|
|
484
|
-
return if index >= children_array.size
|
|
485
|
-
|
|
486
|
-
Node.new(children_array[index], @source)
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
# Get all child nodes
|
|
490
|
-
#
|
|
491
|
-
# @return [Array<Node>] array of wrapped child nodes
|
|
492
|
-
def children
|
|
493
|
-
return [] if @inner_node.nil?
|
|
494
|
-
return [] unless @inner_node.respond_to?(:child_nodes)
|
|
495
|
-
|
|
496
|
-
@inner_node.child_nodes.compact.map { |n| Node.new(n, @source) }
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
# Iterate over child nodes
|
|
500
|
-
#
|
|
501
|
-
# @yield [Node] each child node
|
|
502
|
-
# @return [Enumerator, nil]
|
|
503
|
-
def each(&block)
|
|
504
|
-
return to_enum(__method__) unless block_given?
|
|
505
|
-
children.each(&block)
|
|
506
|
-
end
|
|
507
|
-
|
|
508
387
|
# Check if this node has errors
|
|
509
388
|
#
|
|
510
389
|
# @return [Boolean]
|
|
511
390
|
def has_error?
|
|
512
|
-
return false if
|
|
391
|
+
return false if inner_node.nil?
|
|
513
392
|
|
|
514
393
|
# Check if this is an error node type
|
|
515
394
|
return true if type.include?("missing") || type.include?("error")
|
|
516
395
|
|
|
517
396
|
# Check children recursively (Prism error nodes are usually children)
|
|
518
|
-
return false unless
|
|
519
|
-
|
|
397
|
+
return false unless inner_node.respond_to?(:child_nodes)
|
|
398
|
+
inner_node.child_nodes.compact.any? { |n| n.class.name.to_s.include?("Missing") }
|
|
520
399
|
end
|
|
521
400
|
|
|
522
401
|
# Check if this node is a "missing" node (error recovery)
|
|
523
402
|
#
|
|
524
403
|
# @return [Boolean]
|
|
525
404
|
def missing?
|
|
526
|
-
return false if
|
|
405
|
+
return false if inner_node.nil?
|
|
527
406
|
type.include?("missing")
|
|
528
407
|
end
|
|
529
408
|
|
|
530
|
-
# Check if this is a "named" node (structural vs punctuation)
|
|
531
|
-
#
|
|
532
|
-
# In Prism, all nodes are "named" in tree-sitter terminology
|
|
533
|
-
# (there's no distinction between named and anonymous nodes).
|
|
534
|
-
#
|
|
535
|
-
# @return [Boolean]
|
|
536
|
-
def named?
|
|
537
|
-
true
|
|
538
|
-
end
|
|
539
|
-
|
|
540
|
-
# Check if this is a structural node
|
|
541
|
-
#
|
|
542
|
-
# @return [Boolean]
|
|
543
|
-
def structural?
|
|
544
|
-
true
|
|
545
|
-
end
|
|
546
|
-
|
|
547
409
|
# Get a child by field name (Prism node accessor)
|
|
548
410
|
#
|
|
549
411
|
# Prism nodes have specific accessors for their children.
|
|
550
|
-
# This method tries to call that accessor.
|
|
551
412
|
#
|
|
552
413
|
# @param name [String, Symbol] field/accessor name
|
|
553
414
|
# @return [Node, nil] wrapped child node
|
|
554
415
|
def child_by_field_name(name)
|
|
555
|
-
return if
|
|
556
|
-
return unless
|
|
416
|
+
return if inner_node.nil?
|
|
417
|
+
return unless inner_node.respond_to?(name)
|
|
557
418
|
|
|
558
|
-
result =
|
|
419
|
+
result = inner_node.public_send(name)
|
|
559
420
|
return if result.nil?
|
|
560
421
|
|
|
561
|
-
# Wrap if it's a node
|
|
562
|
-
|
|
563
|
-
Node.new(result, @source)
|
|
564
|
-
end
|
|
422
|
+
# Wrap if it's a node
|
|
423
|
+
result.is_a?(::Prism::Node) ? Node.new(result, source) : nil
|
|
565
424
|
end
|
|
566
425
|
|
|
567
426
|
alias_method :field, :child_by_field_name
|
|
568
427
|
|
|
569
|
-
# Get the parent node
|
|
570
|
-
#
|
|
571
|
-
# @raise [NotImplementedError] Prism nodes don't have parent references
|
|
572
|
-
# @return [void]
|
|
573
|
-
def parent
|
|
574
|
-
raise NotImplementedError, "Prism backend does not support parent navigation"
|
|
575
|
-
end
|
|
576
|
-
|
|
577
|
-
# Get next sibling
|
|
578
|
-
#
|
|
579
|
-
# @raise [NotImplementedError] Prism nodes don't have sibling references
|
|
580
|
-
# @return [void]
|
|
581
|
-
def next_sibling
|
|
582
|
-
raise NotImplementedError, "Prism backend does not support sibling navigation"
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
# Get previous sibling
|
|
586
|
-
#
|
|
587
|
-
# @raise [NotImplementedError] Prism nodes don't have sibling references
|
|
588
|
-
# @return [void]
|
|
589
|
-
def prev_sibling
|
|
590
|
-
raise NotImplementedError, "Prism backend does not support sibling navigation"
|
|
591
|
-
end
|
|
592
|
-
|
|
593
|
-
# String representation for debugging
|
|
594
|
-
#
|
|
595
|
-
# @return [String]
|
|
596
|
-
def inspect
|
|
597
|
-
"#<#{self.class} type=#{type} bytes=#{start_byte}..#{end_byte}>"
|
|
598
|
-
end
|
|
599
|
-
|
|
600
428
|
# String representation
|
|
601
429
|
#
|
|
602
430
|
# @return [String]
|
|
@@ -610,8 +438,8 @@ module TreeHaver
|
|
|
610
438
|
# @param include_private [Boolean] include private methods
|
|
611
439
|
# @return [Boolean]
|
|
612
440
|
def respond_to_missing?(method_name, include_private = false)
|
|
613
|
-
return false if
|
|
614
|
-
|
|
441
|
+
return false if inner_node.nil?
|
|
442
|
+
inner_node.respond_to?(method_name, include_private) || super
|
|
615
443
|
end
|
|
616
444
|
|
|
617
445
|
# Delegate unknown methods to the underlying Prism node
|
|
@@ -625,13 +453,18 @@ module TreeHaver
|
|
|
625
453
|
# @param block [Proc] block to pass
|
|
626
454
|
# @return [Object] result from the underlying node
|
|
627
455
|
def method_missing(method_name, *args, **kwargs, &block)
|
|
628
|
-
if
|
|
629
|
-
|
|
456
|
+
if inner_node&.respond_to?(method_name)
|
|
457
|
+
inner_node.public_send(method_name, *args, **kwargs, &block)
|
|
630
458
|
else
|
|
631
459
|
super
|
|
632
460
|
end
|
|
633
461
|
end
|
|
634
462
|
end
|
|
463
|
+
|
|
464
|
+
# Register availability checker for RSpec dependency tags
|
|
465
|
+
TreeHaver::BackendRegistry.register_availability_checker(:prism) do
|
|
466
|
+
available?
|
|
467
|
+
end
|
|
635
468
|
end
|
|
636
469
|
end
|
|
637
470
|
end
|