ruby_tree_sitter 1.1.0-arm64-darwin-22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +199 -0
  4. data/ext/tree_sitter/encoding.c +29 -0
  5. data/ext/tree_sitter/extconf.rb +149 -0
  6. data/ext/tree_sitter/input.c +127 -0
  7. data/ext/tree_sitter/input_edit.c +42 -0
  8. data/ext/tree_sitter/language.c +219 -0
  9. data/ext/tree_sitter/logger.c +228 -0
  10. data/ext/tree_sitter/macros.h +163 -0
  11. data/ext/tree_sitter/node.c +618 -0
  12. data/ext/tree_sitter/parser.c +398 -0
  13. data/ext/tree_sitter/point.c +26 -0
  14. data/ext/tree_sitter/quantifier.c +43 -0
  15. data/ext/tree_sitter/query.c +282 -0
  16. data/ext/tree_sitter/query_capture.c +28 -0
  17. data/ext/tree_sitter/query_cursor.c +215 -0
  18. data/ext/tree_sitter/query_error.c +41 -0
  19. data/ext/tree_sitter/query_match.c +44 -0
  20. data/ext/tree_sitter/query_predicate_step.c +83 -0
  21. data/ext/tree_sitter/range.c +35 -0
  22. data/ext/tree_sitter/repo.rb +121 -0
  23. data/ext/tree_sitter/symbol_type.c +46 -0
  24. data/ext/tree_sitter/tree.c +234 -0
  25. data/ext/tree_sitter/tree_cursor.c +269 -0
  26. data/ext/tree_sitter/tree_sitter.c +44 -0
  27. data/ext/tree_sitter/tree_sitter.h +107 -0
  28. data/lib/tree_sitter/node.rb +197 -0
  29. data/lib/tree_sitter/tree_sitter.bundle +0 -0
  30. data/lib/tree_sitter/version.rb +8 -0
  31. data/lib/tree_sitter.rb +14 -0
  32. data/lib/tree_stand/ast_modifier.rb +30 -0
  33. data/lib/tree_stand/breadth_first_visitor.rb +54 -0
  34. data/lib/tree_stand/config.rb +13 -0
  35. data/lib/tree_stand/node.rb +224 -0
  36. data/lib/tree_stand/parser.rb +67 -0
  37. data/lib/tree_stand/range.rb +55 -0
  38. data/lib/tree_stand/tree.rb +123 -0
  39. data/lib/tree_stand/utils/printer.rb +73 -0
  40. data/lib/tree_stand/version.rb +7 -0
  41. data/lib/tree_stand/visitor.rb +127 -0
  42. data/lib/tree_stand/visitors/tree_walker.rb +37 -0
  43. data/lib/tree_stand.rb +48 -0
  44. data/tree_sitter.gemspec +35 -0
  45. metadata +124 -0
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # Wrapper around the TreeSitter parser. It looks up the parser by filename in
6
+ # the configured parsers directory.
7
+ # @example
8
+ # TreeStand.configure do
9
+ # config.parser_path = "path/to/parser/folder/"
10
+ # end
11
+ #
12
+ # # Looks for a parser in `path/to/parser/folder/sql.{so,dylib}`
13
+ # sql_parser = TreeStand::Parser.new("sql")
14
+ #
15
+ # # Looks for a parser in `path/to/parser/folder/ruby.{so,dylib}`
16
+ # ruby_parser = TreeStand::Parser.new("ruby")
17
+ class Parser
18
+ extend T::Sig
19
+
20
+ sig { returns(TreeSitter::Language) }
21
+ attr_reader :ts_language
22
+
23
+ sig { returns(TreeSitter::Parser) }
24
+ attr_reader :ts_parser
25
+
26
+ # @param language [String]
27
+ sig { params(language: String).void }
28
+ def initialize(language)
29
+ @language_string = language
30
+ @ts_language = TreeSitter::Language.load(
31
+ language,
32
+ "#{TreeStand.config.parser_path}/#{language}.so",
33
+ )
34
+ @ts_parser = TreeSitter::Parser.new.tap do |parser|
35
+ parser.language = @ts_language
36
+ end
37
+ end
38
+
39
+ # Parse the provided document with the TreeSitter parser.
40
+ # @param tree [TreeStand::Tree, nil] providing the old tree will allow the
41
+ # parser to take advantage of incremental parsing and improve performance
42
+ # by re-useing nodes from the old tree.
43
+ sig { params(document: String, tree: T.nilable(TreeStand::Tree)).returns(TreeStand::Tree) }
44
+ def parse_string(document, tree: nil)
45
+ # @todo There's a bug with passing a non-nil tree
46
+ ts_tree = @ts_parser.parse_string(nil, document)
47
+ TreeStand::Tree.new(self, ts_tree, document)
48
+ end
49
+
50
+ # (see #parse_string)
51
+ # @note Like {#parse_string}, except that if the tree contains any parse
52
+ # errors, raises an {TreeStand::InvalidDocument} error.
53
+ #
54
+ # @see #parse_string
55
+ # @raise [TreeStand::InvalidDocument]
56
+ sig { params(document: String, tree: T.nilable(TreeStand::Tree)).returns(TreeStand::Tree) }
57
+ def parse_string!(document, tree: nil)
58
+ tree = parse_string(document, tree: tree)
59
+ return tree unless tree.any?(&:error?)
60
+
61
+ raise(InvalidDocument, <<~ERROR)
62
+ Encountered errors in the document. Check the tree for more details.
63
+ #{tree}
64
+ ERROR
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # Wrapper around a TreeSitter range. This is mainly used to compare ranges.
6
+ class Range
7
+ extend T::Sig
8
+
9
+ # Point is a Struct containing the row and column from a TreeSitter point.
10
+ # TreeStand uses this to compare points.
11
+ # @!attribute [rw] row
12
+ # @return [Integer]
13
+ # @!attribute [rw] column
14
+ # @return [Integer]
15
+ Point = Struct.new(:row, :column)
16
+
17
+ sig { returns(Integer) }
18
+ attr_reader :start_byte
19
+
20
+ sig { returns(Integer) }
21
+ attr_reader :end_byte
22
+
23
+ sig { returns(TreeStand::Range::Point) }
24
+ attr_reader :start_point
25
+
26
+ sig { returns(TreeStand::Range::Point) }
27
+ attr_reader :end_point
28
+
29
+ # @api private
30
+ sig do
31
+ params(
32
+ start_byte: Integer,
33
+ end_byte: Integer,
34
+ start_point: T.any(TreeStand::Range::Point, TreeSitter::Point),
35
+ end_point: T.any(TreeStand::Range::Point, TreeSitter::Point),
36
+ ).void
37
+ end
38
+ def initialize(start_byte:, end_byte:, start_point:, end_point:)
39
+ @start_byte = start_byte
40
+ @end_byte = end_byte
41
+ @start_point = Point.new(start_point.row, start_point.column)
42
+ @end_point = Point.new(end_point.row, end_point.column)
43
+ end
44
+
45
+ sig { params(other: Object).returns(T::Boolean) }
46
+ def ==(other)
47
+ return false unless other.is_a?(TreeStand::Range)
48
+
49
+ @start_byte == other.start_byte &&
50
+ @end_byte == other.end_byte &&
51
+ @start_point == other.start_point &&
52
+ @end_point == other.end_point
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # Wrapper around a TreeSitter tree.
6
+ #
7
+ # This class exposes a convient API for working with the tree. There are
8
+ # dangers in using this class. The tree is mutable and the document can be
9
+ # changed. This class does not protect against that.
10
+ #
11
+ # Some of the moetods on this class edit and re-parse the document updating
12
+ # the tree. Because the document is re-parsed, the tree will be different. Which
13
+ # means all outstanding nodes & ranges will be invalid.
14
+ #
15
+ # Methods that edit the document are suffixed with `!`, e.g. `#edit!`.
16
+ #
17
+ # It's often the case that you will want perfrom multiple edits. One such
18
+ # pattern is to call #query & #edit on all matches in a loop. It's important
19
+ # to keep the destructive nature of #edit in mind and re-issue the query
20
+ # after each edit.
21
+ #
22
+ # Another thing to keep in mind is that edits done later in the document will
23
+ # likely not affect the ranges that occur earlier in the document. This can
24
+ # be a convient property that could allow you to apply edits in a reverse order.
25
+ # This is not always possible and depends on the edits you make, beware that
26
+ # the tree will be different after each edit and this approach may cause bugs.
27
+ class Tree
28
+ extend T::Sig
29
+ extend Forwardable
30
+ include Enumerable
31
+
32
+ sig { returns(String) }
33
+ attr_reader :document
34
+
35
+ sig { returns(TreeSitter::Tree) }
36
+ attr_reader :ts_tree
37
+
38
+ sig { returns(TreeStand::Parser) }
39
+ attr_reader :parser
40
+
41
+ # @!method query(query_string)
42
+ # (see TreeStand::Node#query)
43
+ # @note This is a convenience method that calls {TreeStand::Node#query} on
44
+ # {#root_node}.
45
+ #
46
+ # @!method find_node(query_string)
47
+ # (see TreeStand::Node#find_node)
48
+ # @note This is a convenience method that calls {TreeStand::Node#find_node} on
49
+ # {#root_node}.
50
+ #
51
+ # @!method find_node!(query_string)
52
+ # (see TreeStand::Node#find_node!)
53
+ # @note This is a convenience method that calls {TreeStand::Node#find_node!} on
54
+ # {#root_node}.
55
+ #
56
+ # @!method walk(&block)
57
+ # (see TreeStand::Node#walk)
58
+ #
59
+ # @note This is a convenience method that calls {TreeStand::Node#walk} on
60
+ # {#root_node}.
61
+ #
62
+ # @example Tree includes Enumerable
63
+ # tree.any? { |node| node.type == :error }
64
+ #
65
+ # @!method text
66
+ # (see TreeStand::Node#text)
67
+ # @note This is a convenience method that calls {TreeStand::Node#text} on
68
+ # {#root_node}.
69
+ def_delegators(
70
+ :root_node,
71
+ :query,
72
+ :find_node,
73
+ :find_node!,
74
+ :walk,
75
+ :text,
76
+ )
77
+
78
+ alias_method :each, :walk
79
+
80
+ # @api private
81
+ sig { params(parser: TreeStand::Parser, tree: TreeSitter::Tree, document: String).void }
82
+ def initialize(parser, tree, document)
83
+ @parser = parser
84
+ @ts_tree = tree
85
+ @document = document
86
+ end
87
+
88
+ sig { returns(TreeStand::Node) }
89
+ def root_node
90
+ TreeStand::Node.new(self, @ts_tree.root_node)
91
+ end
92
+
93
+ # This method replaces the section of the document specified by range and
94
+ # replaces it with the provided text. Then it will reparse the document and
95
+ # update the tree!
96
+ sig { params(range: TreeStand::Range, replacement: String).void }
97
+ def edit!(range, replacement)
98
+ new_document = +''
99
+ new_document << @document[0...range.start_byte]
100
+ new_document << replacement
101
+ new_document << @document[range.end_byte..]
102
+ replace_with_new_doc(new_document)
103
+ end
104
+
105
+ # This method deletes the section of the document specified by range. Then
106
+ # it will reparse the document and update the tree!
107
+ sig { params(range: TreeStand::Range).void }
108
+ def delete!(range)
109
+ new_document = +''
110
+ new_document << @document[0...range.start_byte]
111
+ new_document << @document[range.end_byte..]
112
+ replace_with_new_doc(new_document)
113
+ end
114
+
115
+ private
116
+
117
+ def replace_with_new_doc(new_document)
118
+ @document = new_document
119
+ new_tree = @parser.parse_string(@document, tree: self)
120
+ @ts_tree = new_tree.ts_tree
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # A collection of useful methods for working with syntax trees.
6
+ module Utils
7
+ # Used to {TreeStand::Node#pretty_print pretty-print} the node.
8
+ #
9
+ # @example
10
+ # pp node
11
+ # # (expression
12
+ # # (sum
13
+ # # left: (number) | 1
14
+ # # ("+") | +
15
+ # # right: (variable))) | x
16
+ class Printer
17
+ extend T::Sig
18
+
19
+ # @param ralign the right alignment for the text column.
20
+ sig { params(ralign: Integer).void }
21
+ def initialize(ralign:)
22
+ @ralign = ralign
23
+ end
24
+
25
+ # (see TreeStand::Utils::Printer)
26
+ sig { params(node: TreeStand::Node, io: T.any(IO, StringIO, String)).returns(T.any(IO, StringIO, String)) }
27
+ def print(node, io: StringIO.new)
28
+ lines = pretty_output_lines(node)
29
+
30
+ lines.each do |line|
31
+ if line.text.empty?
32
+ io << line.sexpr << "\n"
33
+ next
34
+ end
35
+
36
+ io << "#{line.sexpr}#{' ' * [(@ralign - line.sexpr.size), 0].max}| #{line.text}\n"
37
+ end
38
+
39
+ io
40
+ end
41
+
42
+ private
43
+
44
+ Line = Struct.new(:sexpr, :text)
45
+ private_constant :Line
46
+
47
+ def pretty_output_lines(node, prefix: '', depth: 0)
48
+ indent = ' ' * depth
49
+ ts_node = node.ts_node
50
+ if indent.size + prefix.size + ts_node.to_s.size < @ralign || ts_node.child_count.zero?
51
+ return [Line.new("#{indent}#{prefix}#{ts_node}", node.text)]
52
+ end
53
+
54
+ lines = T.let([Line.new("#{indent}#{prefix}(#{ts_node.type}", '')], T::Array[Line])
55
+
56
+ node.each.with_index do |child, index|
57
+ lines += if field_name = ts_node.field_name_for_child(index)
58
+ pretty_output_lines(
59
+ child,
60
+ prefix: "#{field_name}: ",
61
+ depth: depth + 1,
62
+ )
63
+ else
64
+ pretty_output_lines(child, depth: depth + 1)
65
+ end
66
+ end
67
+
68
+ T.must(lines.last).sexpr << ')'
69
+ lines
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ # typed: strong
3
+
4
+ module TreeStand
5
+ # The current version of the gem.
6
+ VERSION = '0.2.0'
7
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # Depth-first traversal through the tree, calling hooks at each stop.
6
+ #
7
+ # Hooks are language dependent and are defined by creating methods on the
8
+ # visitor with the form `on_*` or `around_*`, where `*` is {Node#type}.
9
+ #
10
+ # - Hooks prefixed with `on_*` are called *before* visiting a node.
11
+ # - Hooks prefixed with `around_*` must `yield` to continue visiting child
12
+ # nodes.
13
+ #
14
+ # You can also define default hooks by implementing an {on} or {around}
15
+ # method to call when visiting each node.
16
+ #
17
+ # @example Create a visitor counting certain nodes
18
+ # class CountingVisitor < TreeStand::Visitor
19
+ # attr_reader :count
20
+ #
21
+ # def initialize(root, type:)
22
+ # super(root)
23
+ # @type = type
24
+ # @count = 0
25
+ # end
26
+ #
27
+ # def on_predicate(node)
28
+ # # if this node matches our search, increment the counter
29
+ # @count += 1 if node.type == @type
30
+ # end
31
+ # end
32
+ #
33
+ # # Initialize a visitor
34
+ # visitor = CountingVisitor.new(document, :predicate).visit
35
+ # # Check the result
36
+ # visitor.count
37
+ # # => 3
38
+ #
39
+ # @example A visitor using around hooks to contruct a tree
40
+ # class TreeBuilder < TreeStand::Visitor
41
+ # TreeNode = Struct.new(:name, :children)
42
+ #
43
+ # attr_reader :stack
44
+ #
45
+ # def initialize(root)
46
+ # super(root)
47
+ # @stack = []
48
+ # end
49
+ #
50
+ # def around(node)
51
+ # @stack << TreeNode.new(node.type, [])
52
+ #
53
+ # # visit all children of this node
54
+ # yield
55
+ #
56
+ # # The last node on the stack is the root of the tree.
57
+ # return if @stack.size == 1
58
+ #
59
+ # # Pop the last node off the stack and add it to the parent
60
+ # @stack[-2].children << @stack.pop
61
+ # end
62
+ # end
63
+ class Visitor
64
+ extend T::Sig
65
+
66
+ sig { params(node: TreeStand::Node).void }
67
+ def initialize(node)
68
+ @node = node
69
+ end
70
+
71
+ # Run the visitor on the document and return self. Allows chaining create and visit.
72
+ # @example
73
+ # visitor = CountingVisitor.new(node, :predicate).visit
74
+ sig { returns(T.self_type) }
75
+ def visit
76
+ visit_node(@node)
77
+ self
78
+ end
79
+
80
+ # @abstract The default implementation does nothing.
81
+ #
82
+ # @example Create callback to count all nodes in a tree.
83
+ # def on(node)
84
+ # @count += 1
85
+ # end
86
+ sig { overridable.params(node: TreeStand::Node).void }
87
+ def on(node) = nil
88
+
89
+ # @abstract The default implementation yields to visit all children.
90
+ #
91
+ # @example Use around hooks to run logic before & after visiting a node. Pairs will with a stack.
92
+ # def around(node)
93
+ # @stack << TreeNode.new(node.type, [])
94
+ #
95
+ # # visit all children of this node
96
+ # yield
97
+ #
98
+ # # The last node on the stack is the root of the tree.
99
+ # return if @stack.size == 1
100
+ #
101
+ # # Pop the last node off the stack and add it to the parent
102
+ # @stack[-2].children << @stack.pop
103
+ # end
104
+ sig { overridable.params(node: TreeStand::Node, block: T.proc.void).void }
105
+ def around(node, &block) = yield
106
+
107
+ private
108
+
109
+ def visit_node(node)
110
+ if respond_to?("on_#{node.type}")
111
+ public_send("on_#{node.type}", node)
112
+ else
113
+ on(node)
114
+ end
115
+
116
+ if respond_to?("around_#{node.type}")
117
+ public_send("around_#{node.type}", node) do
118
+ node.each { |child| visit_node(child) }
119
+ end
120
+ else
121
+ around(node) do
122
+ node.each { |child| visit_node(child) }
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module TreeStand
5
+ # A collection of useful visitors for traversing trees.
6
+ module Visitors
7
+ # Walks the tree depth-first and yields each node to the provided block.
8
+ #
9
+ # @example Create a list of all the nodes in the tree.
10
+ # list = []
11
+ # TreeStand::Visitors::TreeWalker.new(root) do |node|
12
+ # list << node
13
+ # end.visit
14
+ #
15
+ # @see TreeStand::Node#walk
16
+ # @see TreeStand::Tree#walk
17
+ class TreeWalker < Visitor
18
+ extend T::Sig
19
+
20
+ # @param block [Proc] A block that will be called for
21
+ # each node in the tree.
22
+ sig do
23
+ params(
24
+ node: TreeStand::Node,
25
+ block: T.proc.params(node: TreeStand::Node).void,
26
+ ).void
27
+ end
28
+ def initialize(node, &block)
29
+ super(node)
30
+ @block = block
31
+ end
32
+
33
+ sig { override.params(node: TreeStand::Node).void }
34
+ def on(node) = @block.call(node)
35
+ end
36
+ end
37
+ end
data/lib/tree_stand.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'forwardable'
5
+ require 'sorbet-runtime'
6
+ require 'stringio'
7
+ require 'tree_sitter'
8
+ require 'zeitwerk'
9
+
10
+ loader = Zeitwerk::Loader.for_gem
11
+ loader.ignore("#{__dir__}/tree_sitter")
12
+ loader.ignore("#{__dir__}/tree_sitter.rb")
13
+ loader.setup
14
+
15
+ # TreeStand is a high-level Ruby wrapper for {https://tree-sitter.github.io/tree-sitter tree-sitter} bindings. It makes
16
+ # it easier to configure the parsers, and work with the underlying syntax tree.
17
+ module TreeStand
18
+ # Common Ancestor for all TreeStand errors.
19
+ class Error < StandardError; end
20
+ # Raised when the parsed document contains errors.
21
+ class InvalidDocument < Error; end
22
+ # Raised when performing a search on a tree where a return value is expected,
23
+ # but no match is found.
24
+ class NodeNotFound < Error; end
25
+
26
+ class << self
27
+ extend T::Sig
28
+
29
+ # Easy configuration of the gem.
30
+ #
31
+ # @example
32
+ # TreeStand.configure do
33
+ # config.parser_path = "path/to/parser/folder/"
34
+ # end
35
+ #
36
+ # sql_parser = TreeStand::Parser.new("sql")
37
+ # ruby_parser = TreeStand::Parser.new("ruby")
38
+ sig { params(block: T.proc.void).void }
39
+ def configure(&block)
40
+ instance_eval(&block)
41
+ end
42
+
43
+ sig { returns(TreeStand::Config) }
44
+ def config
45
+ @config ||= Config.new
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) if !$LOAD_PATH.include?(lib)
5
+
6
+ require 'tree_sitter/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.required_ruby_version = '>= 3.0'
10
+
11
+ spec.authors = ['Firas al-Khalil', 'Derek Stride']
12
+ spec.email = ['firasalkhalil@gmail.com', 'derek@stride.host']
13
+ spec.homepage = 'https://www.github.com/Faveod/ruby-tree-sitter'
14
+ spec.license = 'MIT'
15
+ spec.name = 'ruby_tree_sitter'
16
+ spec.summary = 'Ruby bindings for Tree-Sitter'
17
+ spec.version = TreeSitter::VERSION
18
+
19
+ spec.metadata = {
20
+ 'allowed_push_host' => 'https://rubygems.org',
21
+ 'homepage_uri' => spec.homepage,
22
+ 'source_code_uri' => spec.homepage,
23
+ 'changelog_uri' => spec.homepage,
24
+ 'documentation_uri' => 'https://faveod.github.io/ruby-tree-sitter/',
25
+ }
26
+
27
+ spec.extensions = %(ext/tree_sitter/extconf.rb)
28
+ spec.files = %w[LICENSE README.md tree_sitter.gemspec]
29
+ spec.files += Dir.glob('ext/**/*.{c,h,rb}')
30
+ spec.files += Dir.glob('lib/**/*.rb')
31
+ spec.require_paths = ['lib']
32
+
33
+ spec.add_dependency 'sorbet-runtime'
34
+ spec.add_dependency 'zeitwerk'
35
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_tree_sitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: arm64-darwin-22
6
+ authors:
7
+ - Firas al-Khalil
8
+ - Derek Stride
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2024-05-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sorbet-runtime
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: zeitwerk
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description:
43
+ email:
44
+ - firasalkhalil@gmail.com
45
+ - derek@stride.host
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE
51
+ - README.md
52
+ - ext/tree_sitter/encoding.c
53
+ - ext/tree_sitter/extconf.rb
54
+ - ext/tree_sitter/input.c
55
+ - ext/tree_sitter/input_edit.c
56
+ - ext/tree_sitter/language.c
57
+ - ext/tree_sitter/logger.c
58
+ - ext/tree_sitter/macros.h
59
+ - ext/tree_sitter/node.c
60
+ - ext/tree_sitter/parser.c
61
+ - ext/tree_sitter/point.c
62
+ - ext/tree_sitter/quantifier.c
63
+ - ext/tree_sitter/query.c
64
+ - ext/tree_sitter/query_capture.c
65
+ - ext/tree_sitter/query_cursor.c
66
+ - ext/tree_sitter/query_error.c
67
+ - ext/tree_sitter/query_match.c
68
+ - ext/tree_sitter/query_predicate_step.c
69
+ - ext/tree_sitter/range.c
70
+ - ext/tree_sitter/repo.rb
71
+ - ext/tree_sitter/symbol_type.c
72
+ - ext/tree_sitter/tree.c
73
+ - ext/tree_sitter/tree_cursor.c
74
+ - ext/tree_sitter/tree_sitter.c
75
+ - ext/tree_sitter/tree_sitter.h
76
+ - lib/tree_sitter.rb
77
+ - lib/tree_sitter/node.rb
78
+ - lib/tree_sitter/tree_sitter.bundle
79
+ - lib/tree_sitter/version.rb
80
+ - lib/tree_stand.rb
81
+ - lib/tree_stand/ast_modifier.rb
82
+ - lib/tree_stand/breadth_first_visitor.rb
83
+ - lib/tree_stand/config.rb
84
+ - lib/tree_stand/node.rb
85
+ - lib/tree_stand/parser.rb
86
+ - lib/tree_stand/range.rb
87
+ - lib/tree_stand/tree.rb
88
+ - lib/tree_stand/utils/printer.rb
89
+ - lib/tree_stand/version.rb
90
+ - lib/tree_stand/visitor.rb
91
+ - lib/tree_stand/visitors/tree_walker.rb
92
+ - tree_sitter.gemspec
93
+ homepage: https://www.github.com/Faveod/ruby-tree-sitter
94
+ licenses:
95
+ - MIT
96
+ metadata:
97
+ allowed_push_host: https://rubygems.org
98
+ homepage_uri: https://www.github.com/Faveod/ruby-tree-sitter
99
+ source_code_uri: https://www.github.com/Faveod/ruby-tree-sitter
100
+ changelog_uri: https://www.github.com/Faveod/ruby-tree-sitter
101
+ documentation_uri: https://faveod.github.io/ruby-tree-sitter/
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '3.2'
111
+ - - "<"
112
+ - !ruby/object:Gem::Version
113
+ version: 3.3.dev
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.4.19
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Ruby bindings for Tree-Sitter
124
+ test_files: []