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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 771611c72bcd18fedf2bdbc8bf89a966e20a2dfdef1318dcf9bd660197028356
4
+ data.tar.gz: '08ddfca6d434e570e910eae6f3d57ae372aaaf44005d85a6c3b5aff8c85bc2bb'
5
+ SHA512:
6
+ metadata.gz: be8d857a1bc1491a639d9978c64aeb1a6e1b5e602ac1339e7a28f3c20db2638450842e5ded9f61fb5b6fcb609809f05f94e843809a3ae6bb1b317be524507871
7
+ data.tar.gz: dc3eadf9136739d502738552fb5bb17f5fbd712d7f802faf30f1b0ff3b9fa7e84569a100caa995e810899055522eacd616fe949f86581246896379bc772a9fac
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022-present, Faveod SAS.
4
+ Copyright (c) 2022-present, Shopify Inc.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,199 @@
1
+ # Ruby tree-sitter bindings
2
+
3
+ [![ci](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/ci.yml/badge.svg)](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/ci.yml) [![valgrind](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/valgrind.yml/badge.svg)](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/valgrind.yml) [![asan/ubsan](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/asan.yml/badge.svg)](https://github.com/Faveod/ruby-tree-sitter/actions/workflows/asan.yml)
4
+
5
+ Ruby bindings for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
6
+
7
+ The [official bindings](https://github.com/tree-sitter/ruby-tree-sitter) are
8
+ very old, unmaintained, and don't work with modern `tree-sitter` APIs.
9
+
10
+
11
+ ## Usage
12
+
13
+ ### TreeSitter API
14
+
15
+ The TreeSitter API is a low-level Ruby binding for tree-sitter.
16
+
17
+ ``` ruby
18
+ require 'tree_sitter'
19
+
20
+ parser = TreeSitter::Parser.new
21
+ language = TreeSitter::Language.load('javascript', 'path/to/libtree-sitter-javascript.{so,dylib}')
22
+
23
+ src = "[1, null]"
24
+
25
+ parser.language = language
26
+
27
+ tree = parser.parse_string(nil, src)
28
+ root = tree.root_node
29
+
30
+ root.each do |child|
31
+ # ...
32
+ end
33
+ ```
34
+
35
+ The main philosophy behind the TreeSitter bindings is to do a 1:1 mapping between
36
+ tree-sitter's `C` API and `Ruby`, which makes it easier to experiment and port
37
+ ideas from different languages/bindings.
38
+
39
+ But it feels like writing some managed `C` with `Ruby`, and that's why we provide
40
+ a high-level API ([TreeStand](#treestand-api)) as well.
41
+
42
+ ### TreeStand API
43
+
44
+ The TreeStand API is a high-level Ruby wrapper for the [TreeSitter](#treesitter-api) bindings. It
45
+ makes it easier to configure the parsers, and work with the underlying syntax tree.
46
+ ```ruby
47
+ require 'tree_stand'
48
+
49
+ TreeStand.configure do
50
+ config.parser_path = "path/to/parser/folder/"
51
+ end
52
+
53
+ sql_parser = TreeStand::Parser.new("sql")
54
+ ruby_parser = TreeStand::Parser.new("ruby")
55
+ ```
56
+
57
+ TreeStand provides an idiomatic Ruby interface to work with tree-sitter parsers.
58
+
59
+ ## Dependencies
60
+
61
+ This gem is a binding for `tree-sitter`. It doesn't have a version of
62
+ `tree-sitter` baked in it by default.
63
+
64
+ You must install `tree-sitter` and make sure that their dynamic library is
65
+ accessible from `$PATH`, or build the gem with `--disable-sys-libs`, which will
66
+ download the latest tagged `tree-sitter` and build against it (see [Build from
67
+ source](docs/Contributing.md#build-from-source) .)
68
+
69
+ You can either install `tree-sitter` from source or through your go-to package manager.
70
+
71
+ ### Linux
72
+
73
+ `ubuntu >= 22.04`
74
+
75
+ ```console
76
+ sudo apt install libtree-sitter-dev
77
+ ```
78
+
79
+ `arch`
80
+
81
+ ```console
82
+ sudo pacman -S tree-sitter
83
+ ```
84
+
85
+ ### MacOS
86
+
87
+ ```console
88
+ sudo port install tree-sitter
89
+ ```
90
+
91
+ or
92
+
93
+ ```console
94
+ brew install tree-sitter
95
+ ```
96
+
97
+ ## Install
98
+
99
+ From [rubygems](https://rubygems.org/gems/ruby_tree_sitter), in your `Gemfile`:
100
+
101
+ ```ruby
102
+ gem 'ruby_tree_sitter', '~> 1.0'
103
+ ```
104
+
105
+ Or manually:
106
+
107
+ ```sh
108
+ gem install ruby_tree_sitter
109
+ ```
110
+
111
+ Or from `git` sources, which will compile on installation:
112
+
113
+ ```ruby
114
+ gem 'ruby_tree_sitter', git: 'https://github.com/Faveod/ruby-tree-sitter'
115
+ ```
116
+
117
+ ### Disable system libraries
118
+
119
+ To install with `--disable-sys-lib`, you can either:
120
+
121
+ ```sh
122
+ gem install ruby_tree_sitter -- --disable-sys-libs
123
+ ```
124
+
125
+ Or via bundle:
126
+
127
+ ```sh
128
+ bundle config set build.ruby_tree_sitter --disable-sys-libs
129
+ ```
130
+
131
+ ### No compilation
132
+
133
+ If you don't want to install from `rubygems`, `git`, or if you don't want to
134
+ compile on install, then download a native gem from this repository's
135
+ [releases](https://github.com/Faveod/ruby-tree-sitter/releases), or you can
136
+ compile it yourself (see [Build from
137
+ source](docs/Contributing.md#build-from-source) .)
138
+
139
+ In that case, you'd have to point your `Gemfile` to the `gem` as such:
140
+
141
+ ``` ruby
142
+ gem 'tree_sitter', path: 'path/to/native/tree_sitter.gem'
143
+ ```
144
+
145
+ ⚠️ We're currently missing a lot of platforms and architectures. Cross-build
146
+ will come back in the near future.
147
+
148
+ ### Parsers
149
+
150
+ You will have to install parsers yourself, either by:
151
+
152
+ 1. Downloading and building from source.
153
+ 1. Downloading from your package manager, if available.
154
+ 1. Downloading a pre-built binary from
155
+ [Faveod/tree-sitter-parsers](https://github.com/Faveod/tree-sitter-parsers)
156
+ which supports numerous architectures.
157
+
158
+ ### A note on static vs dynamic linking
159
+
160
+ This extension will statically link against a downloaded version of
161
+ `tree-sitter` when you use the `--disable-sys-lib`. So any installed version of
162
+ `tree-sitter` will not be loaded.
163
+
164
+ The native gems are also statically linked.
165
+
166
+ All other methods will dynamically link against the installed `tree-sitter`.
167
+
168
+ ## Examples
169
+
170
+ See `examples` directory.
171
+
172
+ ## Development
173
+
174
+ See [`docs/README.md`](docs/Contributing.md).
175
+
176
+ ## 🚧 👷‍♀️ Notes 👷 🚧
177
+
178
+ Since we're doing a 1:1 mapping between the `tree-sitter` API and the bindings,
179
+ you need to be extra-careful when playing with the provided objects. Some of
180
+ them have their underlying `C` data-structure automatically freed, so you might
181
+ get yourself in undesirable situations if you don't pay attention to what you're
182
+ doing.
183
+
184
+ We're only talking about `Tree`, `TreeCursor`, `Query`, and `QueryCursor`. Just
185
+ don't copy them left and right, and then expect them to work without
186
+ `SEGFAULT`ing and creating a black-hole in your living-room. Assume that you
187
+ have to work locally with them. If you get a `SEGFAULT`, you can debug the
188
+ native `C` code using `gdb`. You can read more on `SEGFAULT`s
189
+ [here](docs/SIGSEGV.md), and debugging [here](docs/Contributing.md#Debugging).
190
+
191
+ That said, we do aim at providing an idiomatic `Ruby` interface. It should also
192
+ provide a _safer_ interface, where you don't have to worry about when and how
193
+ resources are freed.
194
+
195
+ To See a full list of the ruby-specific APIs, see [here](lib/README.md).
196
+
197
+ ## Sponsors
198
+
199
+ <img src="img/faveod.jpg" width="75%">
@@ -0,0 +1,29 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE mEncoding;
6
+
7
+ const char *utf8 = "utf8";
8
+ const char *utf16 = "utf16";
9
+
10
+ TSInputEncoding value_to_encoding(VALUE encoding) {
11
+ VALUE enc = SYM2ID(encoding);
12
+ /* VALUE u8 = rb_const_get_at(mEncoding, rb_intern(utf8)); */
13
+ VALUE u16 = SYM2ID(rb_const_get_at(mEncoding, rb_intern("UTF16")));
14
+
15
+ // NOTE: should we emit a warning instead of defaulting to UTF8?
16
+ if (enc == u16) {
17
+ return TSInputEncodingUTF16;
18
+ } else {
19
+ return TSInputEncodingUTF8;
20
+ }
21
+ }
22
+
23
+ void init_encoding(void) {
24
+ mEncoding = rb_define_module_under(mTreeSitter, "Encoding");
25
+
26
+ /* Constants */
27
+ rb_define_const(mEncoding, "UTF8", ID2SYM(rb_intern(utf8)));
28
+ rb_define_const(mEncoding, "UTF16", ID2SYM(rb_intern(utf16)));
29
+ }
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+ require 'pathname'
5
+
6
+ require_relative 'repo'
7
+
8
+ # ################################## #
9
+ # Some helpers #
10
+ # ################################## #
11
+
12
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
13
+
14
+ cflags = []
15
+ ldflags = []
16
+
17
+ def system_tree_sitter?
18
+ enable_config('sys-libs', true)
19
+ end
20
+
21
+ def env_var_on?(var)
22
+ %w[1 on true t yes y].include?(ENV.fetch(var, '').downcase)
23
+ end
24
+
25
+ # ################################## #
26
+ # System lib vs Downloaded lib #
27
+ # ################################## #
28
+
29
+ dir_include, dir_lib =
30
+ if system_tree_sitter?
31
+ [
32
+ %w[/opt/include /opt/local/include /usr/include /usr/local/include],
33
+ %w[/opt/lib /opt/local/lib /usr/lib /usr/local/lib],
34
+ ]
35
+ else
36
+ repo = TreeSitter::Repo.new
37
+ if !repo.download
38
+ msg = <<~MSG
39
+
40
+ Could not fetch tree-sitter sources:
41
+
42
+ #{repo.exe.map { |k, v| "#{k}: #{v}" }.join("\n")}
43
+
44
+ MSG
45
+ abort(msg)
46
+ end
47
+
48
+ # We need to make sure we're selecting the proper toolchain.
49
+ # Especially needed for corss-compilation.
50
+ ENV.store('CC', RbConfig::CONFIG['CC'])
51
+ repo.compile
52
+ repo.keep_static_lib
53
+ repo.include_and_lib_dirs
54
+ end
55
+
56
+ # ################################## #
57
+ # Generate Makefile #
58
+ # ################################## #
59
+
60
+ header = find_header('tree_sitter/api.h', *dir_include)
61
+ library = find_library('tree-sitter', # libtree-sitter
62
+ 'ts_parser_new', # a symbol
63
+ *dir_lib)
64
+
65
+ if !header || !library
66
+ abort <<~MSG
67
+
68
+ * Missing header : #{header ? 'no' : 'yes'}
69
+ * Missing lib : #{library ? 'no' : 'yes'}
70
+ * Use system tree-sitter : #{system_tree_sitter?}
71
+
72
+ Try to install tree-sitter from source, or through your package manager,
73
+ or even try one of the following options to extconf.rb/rake compile:
74
+
75
+ --with-tree-sitter-dir=/path/to/tree-sitter
76
+ --with-tree-sitter-lib=/path/to/tree-sitter/lib
77
+ --with-tree-sitter-include=/path/to/tree-sitter/include
78
+
79
+ MSG
80
+ end
81
+
82
+ cflags << '-Werror' if env_var_on?('TREE_SITTER_PEDANTIC')
83
+
84
+ if env_var_on?('DEBUG')
85
+ cflags << '-fbounds-check'
86
+ CONFIG['optflags'].gsub!(/-O\d/, '-O0')
87
+ else
88
+ cflags << '-DNDEBUG'
89
+ CONFIG['optflags'].gsub!(/-O\d/, '-O3')
90
+ end
91
+
92
+ sanitizers = ENV.fetch('SANITIZE', nil)
93
+
94
+ if sanitizers =~ /memory/
95
+ puts <<~MSG
96
+
97
+ We do not support memory sanitizers as of yet.
98
+ It requires building ruby with the same sanitizer, and maybe its dependencies.
99
+
100
+ exiting…
101
+
102
+ MSG
103
+ exit 1
104
+ end
105
+
106
+ if sanitizers
107
+ # NOTE: when sanitizing, the default generated warning flags emit a lot of …
108
+ # warnings.
109
+ #
110
+ # I couldn't make mkmf understand it's running with clang and not gcc, so
111
+ # I'm omitting the warning generating warnings.
112
+ #
113
+ # It should be harmless, since sanitization is meant for CI and dev builds.
114
+ %w[
115
+ -Wduplicated-cond
116
+ -Wimplicit-fallthrough=\d+
117
+ -Wno-cast-function-type
118
+ -Wno-packed-bitfield-compat
119
+ -Wsuggest-attribute=\w+
120
+ ].each do |r|
121
+ $warnflags.gsub!(/#{r}/, '')
122
+ end
123
+
124
+ cflags.concat %W[
125
+ -fms-extensions
126
+ -fdeclspec
127
+ -fsanitize=#{sanitizers}
128
+ -fsanitize-blacklist=../../../../.asanignore
129
+ -fsanitize-recover=#{sanitizers}
130
+ -fno-sanitize-recover=all
131
+ -fno-sanitize=null
132
+ -fno-sanitize=alignment
133
+ -fno-omit-frame-pointer
134
+ ]
135
+
136
+ ldflags.concat %W[
137
+ -fsanitize=#{sanitizers}
138
+ -dynamic-libasan
139
+ ]
140
+ end
141
+
142
+ cflags.concat %w[-std=c99 -fPIC -Wall]
143
+
144
+ append_cflags(cflags)
145
+ append_ldflags(ldflags)
146
+
147
+ dir_config('tree-sitter')
148
+ create_header
149
+ create_makefile('tree_sitter/tree_sitter')
@@ -0,0 +1,127 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cInput;
6
+
7
+ typedef struct {
8
+ TSInput data;
9
+ VALUE payload;
10
+ VALUE last_result;
11
+ } input_t;
12
+
13
+ const char *input_read(void *payload, uint32_t byte_index, TSPoint position,
14
+ uint32_t *bytes_read) {
15
+ input_t *input = (input_t *)payload;
16
+ VALUE read = rb_funcall(input->payload, rb_intern("read"), 2,
17
+ UINT2NUM(byte_index), new_point(&position));
18
+ if (NIL_P(read)) {
19
+ *bytes_read = 0;
20
+ input->last_result = Qnil;
21
+ return NULL;
22
+ }
23
+
24
+ VALUE size = rb_funcall(read, rb_intern("bytesize"), 0);
25
+ *bytes_read = NUM2UINT(size);
26
+ input->last_result = rb_funcall(read, rb_intern("to_str"), 0);
27
+
28
+ return StringValueCStr(input->last_result);
29
+ }
30
+
31
+ static void input_payload_set(input_t *input, VALUE value) {
32
+ input->payload = value;
33
+ input->last_result = Qnil;
34
+ input->data.payload = (void *)input;
35
+ input->data.read = input_read;
36
+ }
37
+
38
+ static void input_free(void *ptr) { xfree(ptr); }
39
+
40
+ static size_t input_memsize(const void *ptr) {
41
+ input_t *type = (input_t *)ptr;
42
+ return sizeof(type);
43
+ }
44
+
45
+ static void input_mark(void *ptr) {
46
+ input_t *input = (input_t *)ptr;
47
+ rb_gc_mark_movable(input->payload);
48
+ // we don't want last_result to move because its const char* content will be
49
+ // consumed by the parser.
50
+ //
51
+ // No funny things please.
52
+ rb_gc_mark(input->last_result);
53
+ }
54
+
55
+ static void input_compact(void *ptr) {
56
+ input_t *input = (input_t *)ptr;
57
+ input->payload = rb_gc_location(input->payload);
58
+ }
59
+
60
+ const rb_data_type_t input_data_type = {
61
+ .wrap_struct_name = "input",
62
+ .function =
63
+ {
64
+ .dmark = input_mark,
65
+ .dfree = input_free,
66
+ .dsize = input_memsize,
67
+ .dcompact = input_compact,
68
+ },
69
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
70
+ };
71
+
72
+ DATA_UNWRAP(input)
73
+
74
+ static VALUE input_allocate(VALUE klass) {
75
+ input_t *input;
76
+ return TypedData_Make_Struct(klass, input_t, &input_data_type, input);
77
+ }
78
+
79
+ TSInput value_to_input(VALUE self) { return SELF; }
80
+
81
+ VALUE new_input(const TSInput *ptr) {
82
+ if (ptr != NULL) {
83
+ VALUE res = input_allocate(cInput);
84
+ input_t *input = unwrap(res);
85
+ VALUE payload = Qnil;
86
+ if (ptr->payload != NULL) {
87
+ input_t *old_input = (input_t *)ptr->payload;
88
+ payload = old_input->payload;
89
+ }
90
+ input_payload_set(input, payload);
91
+ return res;
92
+ } else {
93
+ return Qnil;
94
+ }
95
+ }
96
+
97
+ static VALUE input_initialize(int argc, VALUE *argv, VALUE self) {
98
+ input_t *input = unwrap(self);
99
+ VALUE payload;
100
+ rb_scan_args(argc, argv, "01", &payload);
101
+ input_payload_set(input, payload);
102
+ return self;
103
+ }
104
+
105
+ static VALUE input_inspect(VALUE self) {
106
+ return rb_sprintf("{payload=%+" PRIsVALUE "}", unwrap(self)->payload);
107
+ }
108
+
109
+ DEFINE_GETTER(input, payload)
110
+
111
+ static VALUE input_set_payload(VALUE self, VALUE payload) {
112
+ input_payload_set(unwrap(self), payload);
113
+ return Qnil;
114
+ }
115
+
116
+ // FIXME: Missing encoding and read!
117
+ void init_input(void) {
118
+ cInput = rb_define_class_under(mTreeSitter, "Input", rb_cObject);
119
+
120
+ rb_define_alloc_func(cInput, input_allocate);
121
+
122
+ /* Class methods */
123
+ DECLARE_ACCESSOR(cInput, input, payload)
124
+ rb_define_method(cInput, "initialize", input_initialize, -1);
125
+ rb_define_method(cInput, "inspect", input_inspect, 0);
126
+ rb_define_method(cInput, "to_s", input_inspect, 0);
127
+ }
@@ -0,0 +1,42 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cInputEdit;
6
+
7
+ DATA_WRAP(InputEdit, input_edit)
8
+ DATA_DEFINE_ACCESSOR(input_edit, start_byte, UINT2NUM, NUM2UINT)
9
+ DATA_DEFINE_ACCESSOR(input_edit, old_end_byte, UINT2NUM, NUM2UINT)
10
+ DATA_DEFINE_ACCESSOR(input_edit, new_end_byte, UINT2NUM, NUM2UINT)
11
+ DATA_DEFINE_ACCESSOR(input_edit, start_point, new_point_by_val, value_to_point)
12
+ DATA_DEFINE_ACCESSOR(input_edit, old_end_point, new_point_by_val, value_to_point)
13
+ DATA_DEFINE_ACCESSOR(input_edit, new_end_point, new_point_by_val, value_to_point)
14
+
15
+ static VALUE input_edit_inspect(VALUE self) {
16
+ input_edit_t *input_edit = unwrap(self);
17
+ return rb_sprintf("{start_byte=%i, old_end_byte=%i , new_end_byte=%i, "
18
+ "start_point=%+" PRIsVALUE ", old_end_point=%+" PRIsVALUE
19
+ ", new_end_point=%+" PRIsVALUE "}",
20
+ input_edit->data.start_byte, input_edit->data.old_end_byte,
21
+ input_edit->data.new_end_byte,
22
+ new_point_by_val(input_edit->data.start_point),
23
+ new_point_by_val(input_edit->data.old_end_point),
24
+ new_point_by_val(input_edit->data.new_end_point));
25
+ }
26
+
27
+ void init_input_edit(void) {
28
+ cInputEdit = rb_define_class_under(mTreeSitter, "InputEdit", rb_cObject);
29
+
30
+ rb_define_alloc_func(cInputEdit, input_edit_allocate);
31
+
32
+ /* Class methods */
33
+ DECLARE_ACCESSOR(cInputEdit, input_edit, start_byte)
34
+ DECLARE_ACCESSOR(cInputEdit, input_edit, old_end_byte)
35
+ DECLARE_ACCESSOR(cInputEdit, input_edit, new_end_byte)
36
+ DECLARE_ACCESSOR(cInputEdit, input_edit, start_point)
37
+ DECLARE_ACCESSOR(cInputEdit, input_edit, old_end_point)
38
+ DECLARE_ACCESSOR(cInputEdit, input_edit, new_end_point)
39
+
40
+ rb_define_method(cInputEdit, "inspect", input_edit_inspect, 0);
41
+ rb_define_method(cInputEdit, "to_s", input_edit_inspect, 0);
42
+ }