tree_haver 3.0.0 → 3.1.1

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.
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TreeHaver RSpec Integration
4
+ #
5
+ # This file provides RSpec helpers and configuration for testing
6
+ # code that uses TreeHaver. Require this in your spec_helper.rb:
7
+ #
8
+ # require "tree_haver/rspec"
9
+ #
10
+ # This will load:
11
+ # - Dependency tags for conditional test execution
12
+ # - (Future) Additional test helpers as needed
13
+ #
14
+ # @example spec_helper.rb
15
+ # require "tree_haver/rspec"
16
+ #
17
+ # RSpec.configure do |config|
18
+ # # Your additional configuration...
19
+ # end
20
+ #
21
+ # @see TreeHaver::RSpec::DependencyTags
22
+
23
+ require_relative "rspec/dependency_tags"
@@ -156,7 +156,7 @@ module TreeHaver
156
156
  raise unless e.name == :edit || e.message.include?("edit")
157
157
  raise TreeHaver::NotAvailable,
158
158
  "Incremental parsing not supported by current backend. " \
159
- "Use MRI (ruby_tree_sitter), Rust (tree_stump), or Java (java-tree-sitter) backend."
159
+ "Use MRI (ruby_tree_sitter), Rust (tree_stump), or Java (java-tree-sitter / jtreesitter) backend."
160
160
  end
161
161
 
162
162
  private
@@ -10,7 +10,7 @@ module TreeHaver
10
10
  # Current version of the tree_haver gem
11
11
  #
12
12
  # @return [String] the version string (e.g., "3.0.0")
13
- VERSION = "3.0.0"
13
+ VERSION = "3.1.1"
14
14
  end
15
15
 
16
16
  # Traditional location for VERSION constant
data/lib/tree_haver.rb CHANGED
@@ -10,12 +10,17 @@ require "set"
10
10
  require_relative "tree_haver/version"
11
11
  require_relative "tree_haver/language_registry"
12
12
 
13
- # TreeHaver is a cross-Ruby adapter for the tree-sitter parsing library.
13
+ # TreeHaver is a cross-Ruby adapter for code parsing with 10 backends.
14
14
  #
15
- # It provides a unified API for parsing source code using tree-sitter grammars,
16
- # working seamlessly across MRI Ruby, JRuby, and TruffleRuby.
15
+ # Provides a unified API for parsing source code across MRI Ruby, JRuby, and TruffleRuby
16
+ # using tree-sitter grammars or language-specific native parsers.
17
17
  #
18
- # @example Basic usage with TOML
18
+ # Supports 10 backends:
19
+ # - Tree-sitter: MRI (C), Rust, FFI, Java
20
+ # - Native parsers: Prism (Ruby), Psych (YAML), Commonmarker (Markdown), Markly (GFM)
21
+ # - Pure Ruby: Citrus (portable fallback)
22
+ #
23
+ # @example Basic usage with tree-sitter
19
24
  # # Load a language grammar
20
25
  # language = TreeHaver::Language.from_library(
21
26
  # "/usr/local/lib/libtree-sitter-toml.so",
@@ -30,8 +35,28 @@ require_relative "tree_haver/language_registry"
30
35
  # tree = parser.parse("[package]\nname = \"my-app\"")
31
36
  # root = tree.root_node
32
37
  #
33
- # # Traverse the AST
34
- # root.each { |child| puts child.type }
38
+ # # Use unified Position API (works across all backends)
39
+ # puts root.start_line # => 1 (1-based)
40
+ # puts root.source_position # => {start_line:, end_line:, start_column:, end_column:}
41
+ #
42
+ # @example Using language-specific backends
43
+ # # Parse Ruby with Prism
44
+ # TreeHaver.backend = :prism
45
+ # parser = TreeHaver::Parser.new
46
+ # parser.language = TreeHaver::Backends::Prism::Language.ruby
47
+ # tree = parser.parse("class Example; end")
48
+ #
49
+ # # Parse YAML with Psych
50
+ # TreeHaver.backend = :psych
51
+ # parser = TreeHaver::Parser.new
52
+ # parser.language = TreeHaver::Backends::Psych::Language.yaml
53
+ # tree = parser.parse("key: value")
54
+ #
55
+ # # Parse Markdown with Commonmarker
56
+ # TreeHaver.backend = :commonmarker
57
+ # parser = TreeHaver::Parser.new
58
+ # parser.language = TreeHaver::Backends::Commonmarker::Language.markdown
59
+ # tree = parser.parse("# Heading\nParagraph")
35
60
  #
36
61
  # @example Using language registration
37
62
  # TreeHaver.register_language(:toml, path: "/usr/local/lib/libtree-sitter-toml.so")
@@ -43,22 +68,21 @@ require_relative "tree_haver/language_registry"
43
68
  # finder.register! if finder.available?
44
69
  # language = TreeHaver::Language.toml
45
70
  #
46
- # @example Using GrammarFinder in a *-merge gem
47
- # # Each merge gem (toml-merge, json-merge, bash-merge) uses the same pattern
48
- # finder = TreeHaver::GrammarFinder.new(:toml) # or :json, :bash, etc.
49
- # if finder.available?
50
- # finder.register!
51
- # else
52
- # warn finder.not_found_message
53
- # end
54
- #
55
71
  # @example Selecting a backend
56
- # TreeHaver.backend = :ffi # Force FFI backend
57
- # TreeHaver.backend = :mri # Force MRI backend
58
- # TreeHaver.backend = :auto # Auto-select (default)
72
+ # TreeHaver.backend = :mri # Force MRI (ruby_tree_sitter)
73
+ # TreeHaver.backend = :rust # Force Rust (tree_stump)
74
+ # TreeHaver.backend = :ffi # Force FFI
75
+ # TreeHaver.backend = :java # Force Java (JRuby)
76
+ # TreeHaver.backend = :prism # Force Prism (Ruby)
77
+ # TreeHaver.backend = :psych # Force Psych (YAML)
78
+ # TreeHaver.backend = :commonmarker # Force Commonmarker (Markdown)
79
+ # TreeHaver.backend = :markly # Force Markly (GFM)
80
+ # TreeHaver.backend = :citrus # Force Citrus (pure Ruby)
81
+ # TreeHaver.backend = :auto # Auto-select (default)
59
82
  #
60
83
  # @see https://tree-sitter.github.io/tree-sitter/ tree-sitter documentation
61
84
  # @see GrammarFinder For automatic grammar library discovery
85
+ # @see Backends For available parsing backends
62
86
  module TreeHaver
63
87
  # Base error class for TreeHaver exceptions
64
88
  # @see https://github.com/Faveod/ruby-tree-sitter/pull/83 for inherit from Exception reasoning
@@ -115,12 +139,17 @@ module TreeHaver
115
139
  # - {Backends::FFI} - Uses Ruby FFI to call libtree-sitter directly
116
140
  # - {Backends::Java} - Uses JRuby's Java integration
117
141
  # - {Backends::Citrus} - Uses Citrus PEG parser (pure Ruby, portable)
142
+ # - {Backends::Prism} - Uses Ruby's built-in Prism parser (Ruby-only, stdlib in 3.4+)
118
143
  module Backends
119
144
  autoload :MRI, File.join(__dir__, "tree_haver", "backends", "mri")
120
145
  autoload :Rust, File.join(__dir__, "tree_haver", "backends", "rust")
121
146
  autoload :FFI, File.join(__dir__, "tree_haver", "backends", "ffi")
122
147
  autoload :Java, File.join(__dir__, "tree_haver", "backends", "java")
123
148
  autoload :Citrus, File.join(__dir__, "tree_haver", "backends", "citrus")
149
+ autoload :Prism, File.join(__dir__, "tree_haver", "backends", "prism")
150
+ autoload :Psych, File.join(__dir__, "tree_haver", "backends", "psych")
151
+ autoload :Commonmarker, File.join(__dir__, "tree_haver", "backends", "commonmarker")
152
+ autoload :Markly, File.join(__dir__, "tree_haver", "backends", "markly")
124
153
 
125
154
  # Known backend conflicts
126
155
  #
@@ -135,6 +164,10 @@ module TreeHaver
135
164
  ffi: [:mri], # FFI segfaults if MRI (ruby_tree_sitter) has been loaded
136
165
  java: [],
137
166
  citrus: [],
167
+ prism: [], # Prism has no conflicts with other backends
168
+ psych: [], # Psych has no conflicts with other backends
169
+ commonmarker: [], # Commonmarker has no conflicts with other backends
170
+ markly: [], # Markly has no conflicts with other backends
138
171
  }.freeze
139
172
  end
140
173
 
@@ -179,6 +212,9 @@ module TreeHaver
179
212
  # @see CitrusGrammarFinder
180
213
  autoload :CitrusGrammarFinder, File.join(__dir__, "tree_haver", "citrus_grammar_finder")
181
214
 
215
+ # Point class for position information (row, column)
216
+ autoload :Point, File.join(__dir__, "tree_haver", "point")
217
+
182
218
  # Unified Node wrapper providing consistent API across backends
183
219
  autoload :Node, File.join(__dir__, "tree_haver", "node")
184
220
 
@@ -201,7 +237,10 @@ module TreeHaver
201
237
  # @return [Boolean]
202
238
  # @example Disable protection for testing
203
239
  # TreeHaver.backend_protect = false
204
- attr_writer :backend_protect
240
+ def backend_protect=(value)
241
+ @backend_protect_mutex ||= Mutex.new
242
+ @backend_protect_mutex.synchronize { @backend_protect = value }
243
+ end
205
244
 
206
245
  # Check if backend conflict protection is enabled
207
246
  #
@@ -267,6 +306,10 @@ module TreeHaver
267
306
  when "ffi" then :ffi
268
307
  when "java" then :java
269
308
  when "citrus" then :citrus
309
+ when "prism" then :prism
310
+ when "psych" then :psych
311
+ when "commonmarker" then :commonmarker
312
+ when "markly" then :markly
270
313
  else :auto
271
314
  end
272
315
  end
@@ -463,6 +506,14 @@ module TreeHaver
463
506
  Backends::Java
464
507
  when :citrus
465
508
  Backends::Citrus
509
+ when :prism
510
+ Backends::Prism
511
+ when :psych
512
+ Backends::Psych
513
+ when :commonmarker
514
+ Backends::Commonmarker
515
+ when :markly
516
+ Backends::Markly
466
517
  when :auto
467
518
  backend_module # Fall back to normal resolution for :auto
468
519
  else
@@ -519,6 +570,14 @@ module TreeHaver
519
570
  Backends::Java
520
571
  when :citrus
521
572
  Backends::Citrus
573
+ when :prism
574
+ Backends::Prism
575
+ when :psych
576
+ Backends::Psych
577
+ when :commonmarker
578
+ Backends::Commonmarker
579
+ when :markly
580
+ Backends::Markly
522
581
  else
523
582
  # auto-select: prefer native/fast backends, fall back to pure Ruby (Citrus)
524
583
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby" && Backends::Java.available?
@@ -669,6 +728,111 @@ module TreeHaver
669
728
  def registered_language(name)
670
729
  LanguageRegistry.registered(name)
671
730
  end
731
+
732
+ # Create a parser configured for a specific language
733
+ #
734
+ # This is the recommended high-level API for creating a parser. It handles:
735
+ # 1. Checking if the language is already registered
736
+ # 2. Auto-discovering tree-sitter grammar via GrammarFinder
737
+ # 3. Falling back to Citrus grammar if tree-sitter is unavailable
738
+ # 4. Creating and configuring the parser
739
+ #
740
+ # @param language_name [Symbol, String] the language to parse (e.g., :toml, :json, :bash)
741
+ # @param library_path [String, nil] optional explicit path to tree-sitter grammar library
742
+ # @param symbol [String, nil] optional tree-sitter symbol name (defaults to "tree_sitter_<name>")
743
+ # @param citrus_config [Hash, nil] optional Citrus fallback configuration
744
+ # @option citrus_config [String] :gem_name gem name for the Citrus grammar
745
+ # @option citrus_config [String] :grammar_const fully qualified constant name for grammar module
746
+ # @return [TreeHaver::Parser] configured parser with language set
747
+ # @raise [TreeHaver::NotAvailable] if no parser backend is available for the language
748
+ #
749
+ # @example Basic usage (auto-discovers grammar)
750
+ # parser = TreeHaver.parser_for(:toml)
751
+ # tree = parser.parse("[package]\nname = \"my-app\"")
752
+ #
753
+ # @example With explicit library path
754
+ # parser = TreeHaver.parser_for(:toml, library_path: "/custom/path/libtree-sitter-toml.so")
755
+ #
756
+ # @example With Citrus fallback configuration
757
+ # parser = TreeHaver.parser_for(:toml,
758
+ # citrus_config: { gem_name: "toml-rb", grammar_const: "TomlRB::Document" }
759
+ # )
760
+ def parser_for(language_name, library_path: nil, symbol: nil, citrus_config: nil)
761
+ name = language_name.to_sym
762
+ symbol ||= "tree_sitter_#{name}"
763
+
764
+ # Step 1: Try to get the language (may already be registered)
765
+ language = begin
766
+ # Check if already registered and loadable
767
+ if registered_language(name)
768
+ Language.public_send(name, path: library_path, symbol: symbol)
769
+ end
770
+ rescue NotAvailable, ArgumentError, LoadError
771
+ nil
772
+ end
773
+
774
+ # Step 2: If not registered, try GrammarFinder for tree-sitter
775
+ unless language
776
+ # Principle of Least Surprise: If user provides an explicit path,
777
+ # it MUST exist. Don't silently fall back to auto-discovery.
778
+ if library_path && !library_path.empty?
779
+ unless File.exist?(library_path)
780
+ raise NotAvailable,
781
+ "Specified parser path does not exist: #{library_path}"
782
+ end
783
+ begin
784
+ register_language(name, path: library_path, symbol: symbol)
785
+ language = Language.public_send(name)
786
+ rescue NotAvailable, ArgumentError, LoadError => e
787
+ # Re-raise with more context since user explicitly provided this path
788
+ raise NotAvailable,
789
+ "Failed to load parser from specified path #{library_path}: #{e.message}"
790
+ end
791
+ else
792
+ # Auto-discover via GrammarFinder (no explicit path provided)
793
+ begin
794
+ finder = GrammarFinder.new(name)
795
+ if finder.available?
796
+ finder.register!
797
+ language = Language.public_send(name)
798
+ end
799
+ rescue NotAvailable, ArgumentError, LoadError
800
+ language = nil
801
+ end
802
+ end
803
+ end
804
+
805
+ # Step 3: Try Citrus fallback if tree-sitter failed
806
+ unless language
807
+ citrus_config ||= {}
808
+ begin
809
+ citrus_finder = CitrusGrammarFinder.new(
810
+ language: name,
811
+ gem_name: citrus_config[:gem_name],
812
+ grammar_const: citrus_config[:grammar_const],
813
+ )
814
+ if citrus_finder.available?
815
+ citrus_finder.register!
816
+ language = Language.public_send(name)
817
+ end
818
+ rescue NotAvailable, ArgumentError, LoadError, NameError
819
+ language = nil
820
+ end
821
+ end
822
+
823
+ # Step 4: Raise if nothing worked
824
+ unless language
825
+ raise NotAvailable,
826
+ "No parser available for #{name}. " \
827
+ "Install tree-sitter-#{name} or the appropriate Ruby gem. " \
828
+ "Set TREE_SITTER_#{name.to_s.upcase}_PATH for custom grammar location."
829
+ end
830
+
831
+ # Step 5: Create and configure parser
832
+ parser = Parser.new
833
+ parser.language = language
834
+ parser
835
+ end
672
836
  end
673
837
 
674
838
  # Represents a tree-sitter language grammar
@@ -827,7 +991,8 @@ module TreeHaver
827
991
  "Registered backends: #{all_backends.keys.inspect}"
828
992
  end
829
993
 
830
- # For tree-sitter backends, use the path
994
+ # For tree-sitter backends, try to load from path
995
+ # If that fails, fall back to Citrus if available
831
996
  if reg && reg[:path]
832
997
  path = kwargs[:path] || args.first || reg[:path]
833
998
  # Symbol priority: kwargs override > registration > derive from method_name
@@ -842,7 +1007,30 @@ module TreeHaver
842
1007
  # Using symbol-derived name ensures ruby_tree_sitter gets the correct language name
843
1008
  # e.g., "toml" not "toml_both" when symbol is "tree_sitter_toml"
844
1009
  name = kwargs[:name] || symbol&.sub(/\Atree_sitter_/, "")
845
- return from_library(path, symbol: symbol, name: name)
1010
+
1011
+ begin
1012
+ return from_library(path, symbol: symbol, name: name)
1013
+ rescue NotAvailable, ArgumentError, LoadError, FFI::NotFoundError => _e
1014
+ # Tree-sitter failed to load - check for Citrus fallback
1015
+ # This handles cases where:
1016
+ # - The .so file doesn't exist or can't be loaded (NotAvailable, LoadError)
1017
+ # - FFI can't find required symbols like ts_parser_new (FFI::NotFoundError)
1018
+ # - Invalid arguments were provided (ArgumentError)
1019
+ citrus_reg = all_backends[:citrus]
1020
+ if citrus_reg && citrus_reg[:grammar_module]
1021
+ return Backends::Citrus::Language.new(citrus_reg[:grammar_module])
1022
+ end
1023
+ # No Citrus fallback available, re-raise the original error
1024
+ raise
1025
+ end
1026
+ end
1027
+
1028
+ # No tree-sitter path registered - check for Citrus fallback
1029
+ # This enables auto-fallback when tree-sitter grammar is not installed
1030
+ # but a Citrus grammar (pure Ruby) is available
1031
+ citrus_reg = all_backends[:citrus]
1032
+ if citrus_reg && citrus_reg[:grammar_module]
1033
+ return Backends::Citrus::Language.new(citrus_reg[:grammar_module])
846
1034
  end
847
1035
 
848
1036
  # No appropriate registration found
@@ -913,8 +1101,28 @@ module TreeHaver
913
1101
  end
914
1102
  end
915
1103
 
916
- @impl = mod::Parser.new
917
- @explicit_backend = backend # Remember for introspection (always a Symbol or nil)
1104
+ # Try to create the parser, with fallback to Citrus if tree-sitter fails
1105
+ # This enables auto-fallback when tree-sitter runtime isn't available
1106
+ begin
1107
+ @impl = mod::Parser.new
1108
+ @explicit_backend = backend # Remember for introspection (always a Symbol or nil)
1109
+ rescue NoMethodError, FFI::NotFoundError, LoadError => e
1110
+ # Tree-sitter backend failed (likely missing runtime library)
1111
+ # Try Citrus as fallback if we weren't explicitly asked for a specific backend
1112
+ if backend.nil? || backend == :auto
1113
+ if Backends::Citrus.available?
1114
+ @impl = Backends::Citrus::Parser.new
1115
+ @explicit_backend = :citrus
1116
+ else
1117
+ # No fallback available, re-raise original error
1118
+ raise NotAvailable, "Tree-sitter backend failed: #{e.message}. " \
1119
+ "Citrus fallback not available. Install tree-sitter runtime or citrus gem."
1120
+ end
1121
+ else
1122
+ # Explicit backend was requested, don't fallback
1123
+ raise
1124
+ end
1125
+ end
918
1126
  end
919
1127
 
920
1128
  # Get the backend this parser is using (for introspection)
@@ -952,12 +1160,23 @@ module TreeHaver
952
1160
  # @example
953
1161
  # parser.language = TreeHaver::Language.from_library("/path/to/grammar.so")
954
1162
  def language=(lang)
1163
+ # Check if this is a Citrus language - if so, we need a Citrus parser
1164
+ # This enables automatic backend switching when tree-sitter fails and
1165
+ # falls back to Citrus
1166
+ if lang.is_a?(Backends::Citrus::Language)
1167
+ unless @impl.is_a?(Backends::Citrus::Parser)
1168
+ # Switch to Citrus parser to match the Citrus language
1169
+ @impl = Backends::Citrus::Parser.new
1170
+ @explicit_backend = :citrus
1171
+ end
1172
+ end
1173
+
955
1174
  # Unwrap the language before passing to backend
956
1175
  # Backends receive raw language objects, never TreeHaver wrappers
957
1176
  inner_lang = unwrap_language(lang)
958
1177
  @impl.language = inner_lang
959
1178
  # Return the original (possibly wrapped) language for consistency
960
- lang
1179
+ lang # rubocop:disable Lint/Void (intentional return value)
961
1180
  end
962
1181
 
963
1182
  private
@@ -1028,6 +1247,14 @@ module TreeHaver
1028
1247
  return lang.impl if lang.respond_to?(:impl)
1029
1248
  when :citrus
1030
1249
  return lang.grammar_module if lang.respond_to?(:grammar_module)
1250
+ when :prism
1251
+ return lang # Prism backend expects the Language wrapper
1252
+ when :psych
1253
+ return lang # Psych backend expects the Language wrapper
1254
+ when :commonmarker
1255
+ return lang # Commonmarker backend expects the Language wrapper
1256
+ when :markly
1257
+ return lang # Markly backend expects the Language wrapper
1031
1258
  else
1032
1259
  # Unknown backend (e.g., test backend)
1033
1260
  # Try generic unwrapping methods for flexibility in testing
data/sig/tree_haver.rbs CHANGED
@@ -1,6 +1,9 @@
1
1
  # Type definitions for TreeHaver
2
2
  #
3
- # TreeHaver is a cross-Ruby adapter for the tree-sitter parsing library
3
+ # TreeHaver is a cross-Ruby adapter for code parsing with 10 backends:
4
+ # - Tree-sitter: MRI, Rust, FFI, Java
5
+ # - Native parsers: Prism (Ruby), Psych (YAML), Commonmarker (Markdown), Markly (GFM)
6
+ # - Pure Ruby: Citrus
4
7
 
5
8
  module TreeHaver
6
9
  VERSION: String
@@ -134,6 +137,20 @@ module TreeHaver
134
137
  # Get the end point (row, column)
135
138
  def end_point: () -> Point
136
139
 
140
+ # Position API - consistent across all backends
141
+ # Get 1-based line number where node starts
142
+ def start_line: () -> Integer
143
+
144
+ # Get 1-based line number where node ends
145
+ def end_line: () -> Integer
146
+
147
+ # Get complete position information as hash
148
+ # Returns {start_line:, end_line:, start_column:, end_column:}
149
+ def source_position: () -> Hash[Symbol, Integer]
150
+
151
+ # Get first child node (convenience method)
152
+ def first_child: () -> Node?
153
+
137
154
  # Get the number of child nodes
138
155
  def child_count: () -> Integer
139
156
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tree_haver
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -133,6 +133,26 @@ dependencies:
133
133
  - - "~>"
134
134
  - !ruby/object:Gem::Version
135
135
  version: '3.0'
136
+ - !ruby/object:Gem::Dependency
137
+ name: kettle-soup-cover
138
+ requirement: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '1.1'
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 1.1.1
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.1'
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: 1.1.1
136
156
  - !ruby/object:Gem::Dependency
137
157
  name: kettle-test
138
158
  requirement: !ruby/object:Gem::Requirement
@@ -241,9 +261,13 @@ files:
241
261
  - SECURITY.md
242
262
  - lib/tree_haver.rb
243
263
  - lib/tree_haver/backends/citrus.rb
264
+ - lib/tree_haver/backends/commonmarker.rb
244
265
  - lib/tree_haver/backends/ffi.rb
245
266
  - lib/tree_haver/backends/java.rb
267
+ - lib/tree_haver/backends/markly.rb
246
268
  - lib/tree_haver/backends/mri.rb
269
+ - lib/tree_haver/backends/prism.rb
270
+ - lib/tree_haver/backends/psych.rb
247
271
  - lib/tree_haver/backends/rust.rb
248
272
  - lib/tree_haver/citrus_grammar_finder.rb
249
273
  - lib/tree_haver/compat.rb
@@ -251,6 +275,9 @@ files:
251
275
  - lib/tree_haver/language_registry.rb
252
276
  - lib/tree_haver/node.rb
253
277
  - lib/tree_haver/path_validator.rb
278
+ - lib/tree_haver/point.rb
279
+ - lib/tree_haver/rspec.rb
280
+ - lib/tree_haver/rspec/dependency_tags.rb
254
281
  - lib/tree_haver/tree.rb
255
282
  - lib/tree_haver/version.rb
256
283
  - sig/tree_haver.rbs
@@ -262,10 +289,10 @@ licenses:
262
289
  - MIT
263
290
  metadata:
264
291
  homepage_uri: https://tree-haver.galtzo.com/
265
- source_code_uri: https://github.com/kettle-rb/tree_haver/tree/v3.0.0
266
- changelog_uri: https://github.com/kettle-rb/tree_haver/blob/v3.0.0/CHANGELOG.md
292
+ source_code_uri: https://github.com/kettle-rb/tree_haver/tree/v3.1.1
293
+ changelog_uri: https://github.com/kettle-rb/tree_haver/blob/v3.1.1/CHANGELOG.md
267
294
  bug_tracker_uri: https://github.com/kettle-rb/tree_haver/issues
268
- documentation_uri: https://www.rubydoc.info/gems/tree_haver/3.0.0
295
+ documentation_uri: https://www.rubydoc.info/gems/tree_haver/3.1.1
269
296
  funding_uri: https://github.com/sponsors/pboling
270
297
  wiki_uri: https://github.com/kettle-rb/tree_haver/wiki
271
298
  news_uri: https://www.railsbling.com/tags/tree_haver
@@ -295,7 +322,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
322
  - !ruby/object:Gem::Version
296
323
  version: '0'
297
324
  requirements: []
298
- rubygems_version: 4.0.1
325
+ rubygems_version: 4.0.3
299
326
  specification_version: 4
300
327
  summary: "\U0001F334 Cross-Ruby adapter for tree-sitter parsing that works on MRI,
301
328
  JRuby, and TruffleRuby"
metadata.gz.sig CHANGED
Binary file