ruby_tree_sitter 1.6.0-x86_64-darwin
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 +7 -0
 - data/LICENSE +22 -0
 - data/README.md +213 -0
 - data/ext/tree_sitter/encoding.c +29 -0
 - data/ext/tree_sitter/extconf.rb +149 -0
 - data/ext/tree_sitter/input.c +127 -0
 - data/ext/tree_sitter/input_edit.c +42 -0
 - data/ext/tree_sitter/language.c +219 -0
 - data/ext/tree_sitter/logger.c +228 -0
 - data/ext/tree_sitter/macros.h +163 -0
 - data/ext/tree_sitter/node.c +623 -0
 - data/ext/tree_sitter/parser.c +398 -0
 - data/ext/tree_sitter/point.c +26 -0
 - data/ext/tree_sitter/quantifier.c +43 -0
 - data/ext/tree_sitter/query.c +289 -0
 - data/ext/tree_sitter/query_capture.c +28 -0
 - data/ext/tree_sitter/query_cursor.c +231 -0
 - data/ext/tree_sitter/query_error.c +41 -0
 - data/ext/tree_sitter/query_match.c +44 -0
 - data/ext/tree_sitter/query_predicate_step.c +83 -0
 - data/ext/tree_sitter/range.c +35 -0
 - data/ext/tree_sitter/repo.rb +128 -0
 - data/ext/tree_sitter/symbol_type.c +46 -0
 - data/ext/tree_sitter/tree.c +234 -0
 - data/ext/tree_sitter/tree_cursor.c +269 -0
 - data/ext/tree_sitter/tree_sitter.c +44 -0
 - data/ext/tree_sitter/tree_sitter.h +107 -0
 - data/lib/tree_sitter/3.0/tree_sitter.bundle +0 -0
 - data/lib/tree_sitter/3.1/tree_sitter.bundle +0 -0
 - data/lib/tree_sitter/3.2/tree_sitter.bundle +0 -0
 - data/lib/tree_sitter/3.3/tree_sitter.bundle +0 -0
 - data/lib/tree_sitter/helpers.rb +23 -0
 - data/lib/tree_sitter/mixins/language.rb +167 -0
 - data/lib/tree_sitter/node.rb +167 -0
 - data/lib/tree_sitter/query.rb +191 -0
 - data/lib/tree_sitter/query_captures.rb +30 -0
 - data/lib/tree_sitter/query_cursor.rb +27 -0
 - data/lib/tree_sitter/query_match.rb +100 -0
 - data/lib/tree_sitter/query_matches.rb +39 -0
 - data/lib/tree_sitter/query_predicate.rb +14 -0
 - data/lib/tree_sitter/text_predicate_capture.rb +37 -0
 - data/lib/tree_sitter/version.rb +8 -0
 - data/lib/tree_sitter.rb +34 -0
 - data/lib/tree_stand/ast_modifier.rb +30 -0
 - data/lib/tree_stand/breadth_first_visitor.rb +54 -0
 - data/lib/tree_stand/config.rb +19 -0
 - data/lib/tree_stand/node.rb +351 -0
 - data/lib/tree_stand/parser.rb +87 -0
 - data/lib/tree_stand/range.rb +55 -0
 - data/lib/tree_stand/tree.rb +123 -0
 - data/lib/tree_stand/utils/printer.rb +73 -0
 - data/lib/tree_stand/version.rb +7 -0
 - data/lib/tree_stand/visitor.rb +127 -0
 - data/lib/tree_stand/visitors/tree_walker.rb +37 -0
 - data/lib/tree_stand.rb +48 -0
 - data/tree_sitter.gemspec +34 -0
 - metadata +135 -0
 
| 
         @@ -0,0 +1,219 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "tree_sitter.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
            #include <dlfcn.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <stdint.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            typedef TSLanguage *(tree_sitter_lang)(void);
         
     | 
| 
      
 7 
     | 
    
         
            +
            const char *tree_sitter_prefix = "tree_sitter_";
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            extern VALUE mTreeSitter;
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            VALUE cLanguage;
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            DATA_TYPE(TSLanguage *, language)
         
     | 
| 
      
 14 
     | 
    
         
            +
            DATA_FREE(language)
         
     | 
| 
      
 15 
     | 
    
         
            +
            DATA_MEMSIZE(language)
         
     | 
| 
      
 16 
     | 
    
         
            +
            DATA_DECLARE_DATA_TYPE(language)
         
     | 
| 
      
 17 
     | 
    
         
            +
            DATA_ALLOCATE(language)
         
     | 
| 
      
 18 
     | 
    
         
            +
            DATA_UNWRAP(language)
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            TSLanguage *value_to_language(VALUE self) { return SELF; }
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            VALUE new_language(const TSLanguage *language) {
         
     | 
| 
      
 23 
     | 
    
         
            +
              VALUE res = language_allocate(cLanguage);
         
     | 
| 
      
 24 
     | 
    
         
            +
              unwrap(res)->data = (TSLanguage *)language;
         
     | 
| 
      
 25 
     | 
    
         
            +
              return res;
         
     | 
| 
      
 26 
     | 
    
         
            +
            }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            /**
         
     | 
| 
      
 29 
     | 
    
         
            +
             * Load a language parser from disk.
         
     | 
| 
      
 30 
     | 
    
         
            +
             *
         
     | 
| 
      
 31 
     | 
    
         
            +
             * @raise [RuntimeError] if the parser was not found, or if it's incompatible
         
     | 
| 
      
 32 
     | 
    
         
            +
             * with this gem.
         
     | 
| 
      
 33 
     | 
    
         
            +
             *
         
     | 
| 
      
 34 
     | 
    
         
            +
             * @param name [String] the parser's name.
         
     | 
| 
      
 35 
     | 
    
         
            +
             * @param path [String, Pathname] the parser's shared library (so, dylib) path on disk.
         
     | 
| 
      
 36 
     | 
    
         
            +
             *
         
     | 
| 
      
 37 
     | 
    
         
            +
             * @return [Language]
         
     | 
| 
      
 38 
     | 
    
         
            +
             */
         
     | 
| 
      
 39 
     | 
    
         
            +
            static VALUE language_load(VALUE self, VALUE name, VALUE path) {
         
     | 
| 
      
 40 
     | 
    
         
            +
              VALUE path_s = rb_funcall(path, rb_intern("to_s"), 0);
         
     | 
| 
      
 41 
     | 
    
         
            +
              char *path_cstr = StringValueCStr(path_s);
         
     | 
| 
      
 42 
     | 
    
         
            +
              void *lib = dlopen(path_cstr, RTLD_NOW);
         
     | 
| 
      
 43 
     | 
    
         
            +
              const char *err = dlerror();
         
     | 
| 
      
 44 
     | 
    
         
            +
              if (err != NULL) {
         
     | 
| 
      
 45 
     | 
    
         
            +
                rb_raise(rb_eRuntimeError,
         
     | 
| 
      
 46 
     | 
    
         
            +
                         "Could not load shared library `%s'.\nReason: %s", path_cstr, err);
         
     | 
| 
      
 47 
     | 
    
         
            +
              }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              char buf[256];
         
     | 
| 
      
 50 
     | 
    
         
            +
              snprintf(buf, sizeof(buf), "tree_sitter_%s", StringValueCStr(name));
         
     | 
| 
      
 51 
     | 
    
         
            +
              tree_sitter_lang *make_ts_language = dlsym(lib, buf);
         
     | 
| 
      
 52 
     | 
    
         
            +
              err = dlerror();
         
     | 
| 
      
 53 
     | 
    
         
            +
              if (err != NULL) {
         
     | 
| 
      
 54 
     | 
    
         
            +
                dlclose(lib);
         
     | 
| 
      
 55 
     | 
    
         
            +
                rb_raise(rb_eRuntimeError,
         
     | 
| 
      
 56 
     | 
    
         
            +
                         "Could not load symbol `%s' from library `%s'.\nReason:%s",
         
     | 
| 
      
 57 
     | 
    
         
            +
                         StringValueCStr(name), path_cstr, err);
         
     | 
| 
      
 58 
     | 
    
         
            +
              }
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              TSLanguage *lang = make_ts_language();
         
     | 
| 
      
 61 
     | 
    
         
            +
              if (lang == NULL) {
         
     | 
| 
      
 62 
     | 
    
         
            +
                dlclose(lib);
         
     | 
| 
      
 63 
     | 
    
         
            +
                rb_raise(rb_eRuntimeError,
         
     | 
| 
      
 64 
     | 
    
         
            +
                         "TSLanguage = NULL for language `%s' in library `%s'.\nCall your "
         
     | 
| 
      
 65 
     | 
    
         
            +
                         "local TSLanguage supplier.",
         
     | 
| 
      
 66 
     | 
    
         
            +
                         StringValueCStr(name), path_cstr);
         
     | 
| 
      
 67 
     | 
    
         
            +
              }
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              uint32_t version = ts_language_version(lang);
         
     | 
| 
      
 70 
     | 
    
         
            +
              if (version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION) {
         
     | 
| 
      
 71 
     | 
    
         
            +
                rb_raise(rb_eRuntimeError,
         
     | 
| 
      
 72 
     | 
    
         
            +
                         "Language %s (v%d) from `%s' is old.\nMinimum supported ABI: "
         
     | 
| 
      
 73 
     | 
    
         
            +
                         "v%d.\nCurrent ABI: v%d.",
         
     | 
| 
      
 74 
     | 
    
         
            +
                         StringValueCStr(name), version, path_cstr,
         
     | 
| 
      
 75 
     | 
    
         
            +
                         TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION,
         
     | 
| 
      
 76 
     | 
    
         
            +
                         TREE_SITTER_LANGUAGE_VERSION);
         
     | 
| 
      
 77 
     | 
    
         
            +
              }
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              return new_language(lang);
         
     | 
| 
      
 80 
     | 
    
         
            +
            }
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            static VALUE language_equal(VALUE self, VALUE other) {
         
     | 
| 
      
 83 
     | 
    
         
            +
              TSLanguage *this = SELF;
         
     | 
| 
      
 84 
     | 
    
         
            +
              TSLanguage *that = unwrap(other)->data;
         
     | 
| 
      
 85 
     | 
    
         
            +
              return this == that ? Qtrue : Qfalse;
         
     | 
| 
      
 86 
     | 
    
         
            +
            }
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            /**
         
     | 
| 
      
 89 
     | 
    
         
            +
             * Get the number of distinct field names in the language.
         
     | 
| 
      
 90 
     | 
    
         
            +
             *
         
     | 
| 
      
 91 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 92 
     | 
    
         
            +
             */
         
     | 
| 
      
 93 
     | 
    
         
            +
            static VALUE language_field_count(VALUE self) {
         
     | 
| 
      
 94 
     | 
    
         
            +
              return UINT2NUM(ts_language_field_count(SELF));
         
     | 
| 
      
 95 
     | 
    
         
            +
            }
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            /**
         
     | 
| 
      
 98 
     | 
    
         
            +
             * Get the numerical id for the given field name string.
         
     | 
| 
      
 99 
     | 
    
         
            +
             *
         
     | 
| 
      
 100 
     | 
    
         
            +
             * @param name [String]
         
     | 
| 
      
 101 
     | 
    
         
            +
             *
         
     | 
| 
      
 102 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 103 
     | 
    
         
            +
             */
         
     | 
| 
      
 104 
     | 
    
         
            +
            static VALUE language_field_id_for_name(VALUE self, VALUE name) {
         
     | 
| 
      
 105 
     | 
    
         
            +
              TSLanguage *language = SELF;
         
     | 
| 
      
 106 
     | 
    
         
            +
              const char *str = StringValuePtr(name);
         
     | 
| 
      
 107 
     | 
    
         
            +
              uint32_t length = (uint32_t)RSTRING_LEN(name);
         
     | 
| 
      
 108 
     | 
    
         
            +
              return UINT2NUM(ts_language_field_id_for_name(language, str, length));
         
     | 
| 
      
 109 
     | 
    
         
            +
            }
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            /**
         
     | 
| 
      
 112 
     | 
    
         
            +
             * Get the field name string for the given numerical id.
         
     | 
| 
      
 113 
     | 
    
         
            +
             *
         
     | 
| 
      
 114 
     | 
    
         
            +
             * @param field_id [Integer]
         
     | 
| 
      
 115 
     | 
    
         
            +
             *
         
     | 
| 
      
 116 
     | 
    
         
            +
             * @return [String]
         
     | 
| 
      
 117 
     | 
    
         
            +
             */
         
     | 
| 
      
 118 
     | 
    
         
            +
            static VALUE language_field_name_for_id(VALUE self, VALUE field_id) {
         
     | 
| 
      
 119 
     | 
    
         
            +
              return safe_str(ts_language_field_name_for_id(SELF, NUM2UINT(field_id)));
         
     | 
| 
      
 120 
     | 
    
         
            +
            }
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            /**
         
     | 
| 
      
 123 
     | 
    
         
            +
             * Get the next parse state. Combine this with lookahead iterators to generate
         
     | 
| 
      
 124 
     | 
    
         
            +
             * completion suggestions or valid symbols in error nodes. Use
         
     | 
| 
      
 125 
     | 
    
         
            +
             * {Node#grammar_symbol} for valid symbols.
         
     | 
| 
      
 126 
     | 
    
         
            +
             */
         
     | 
| 
      
 127 
     | 
    
         
            +
            static VALUE language_next_state(VALUE self, VALUE state, VALUE symbol) {
         
     | 
| 
      
 128 
     | 
    
         
            +
              uint16_t sta = (uint16_t)NUM2UINT(state);
         
     | 
| 
      
 129 
     | 
    
         
            +
              uint16_t sym = (uint16_t)NUM2UINT(symbol);
         
     | 
| 
      
 130 
     | 
    
         
            +
              return UINT2NUM(ts_language_next_state(SELF, sta, sym));
         
     | 
| 
      
 131 
     | 
    
         
            +
            }
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            /**
         
     | 
| 
      
 134 
     | 
    
         
            +
             * Get the number of distinct node types in the language.
         
     | 
| 
      
 135 
     | 
    
         
            +
             *
         
     | 
| 
      
 136 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 137 
     | 
    
         
            +
             */
         
     | 
| 
      
 138 
     | 
    
         
            +
            static VALUE language_symbol_count(VALUE self) {
         
     | 
| 
      
 139 
     | 
    
         
            +
              return UINT2NUM(ts_language_symbol_count(SELF));
         
     | 
| 
      
 140 
     | 
    
         
            +
            }
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            /**
         
     | 
| 
      
 143 
     | 
    
         
            +
             * Get a node type string for the given numerical id.
         
     | 
| 
      
 144 
     | 
    
         
            +
             *
         
     | 
| 
      
 145 
     | 
    
         
            +
             * @param symbol [Integer]
         
     | 
| 
      
 146 
     | 
    
         
            +
             *
         
     | 
| 
      
 147 
     | 
    
         
            +
             * @return [String]
         
     | 
| 
      
 148 
     | 
    
         
            +
             */
         
     | 
| 
      
 149 
     | 
    
         
            +
            static VALUE language_symbol_name(VALUE self, VALUE symbol) {
         
     | 
| 
      
 150 
     | 
    
         
            +
              return safe_str(ts_language_symbol_name(SELF, NUM2UINT(symbol)));
         
     | 
| 
      
 151 
     | 
    
         
            +
            }
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            /**
         
     | 
| 
      
 154 
     | 
    
         
            +
             * Get the numerical id for the given node type string.
         
     | 
| 
      
 155 
     | 
    
         
            +
             *
         
     | 
| 
      
 156 
     | 
    
         
            +
             * @param string   [Symbol]
         
     | 
| 
      
 157 
     | 
    
         
            +
             * @param is_named [Boolean]
         
     | 
| 
      
 158 
     | 
    
         
            +
             *
         
     | 
| 
      
 159 
     | 
    
         
            +
             * @return [Integer]
         
     | 
| 
      
 160 
     | 
    
         
            +
             */
         
     | 
| 
      
 161 
     | 
    
         
            +
            static VALUE language_symbol_for_name(VALUE self, VALUE string,
         
     | 
| 
      
 162 
     | 
    
         
            +
                                                  VALUE is_named) {
         
     | 
| 
      
 163 
     | 
    
         
            +
              const char *str = rb_id2name(SYM2ID(string));
         
     | 
| 
      
 164 
     | 
    
         
            +
              uint32_t length = (uint32_t)strlen(str);
         
     | 
| 
      
 165 
     | 
    
         
            +
              bool named = RTEST(is_named);
         
     | 
| 
      
 166 
     | 
    
         
            +
              return UINT2NUM(ts_language_symbol_for_name(SELF, str, length, named));
         
     | 
| 
      
 167 
     | 
    
         
            +
            }
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            /**
         
     | 
| 
      
 170 
     | 
    
         
            +
             * Check whether the given node type id belongs to named nodes, anonymous nodes,
         
     | 
| 
      
 171 
     | 
    
         
            +
             * or a hidden nodes.
         
     | 
| 
      
 172 
     | 
    
         
            +
             *
         
     | 
| 
      
 173 
     | 
    
         
            +
             * Hidden nodes are never returned from the API.
         
     | 
| 
      
 174 
     | 
    
         
            +
             *
         
     | 
| 
      
 175 
     | 
    
         
            +
             * @see Node#named?
         
     | 
| 
      
 176 
     | 
    
         
            +
             *
         
     | 
| 
      
 177 
     | 
    
         
            +
             * @param symbol [Integer]
         
     | 
| 
      
 178 
     | 
    
         
            +
             *
         
     | 
| 
      
 179 
     | 
    
         
            +
             * @return [SymbolType]
         
     | 
| 
      
 180 
     | 
    
         
            +
             */
         
     | 
| 
      
 181 
     | 
    
         
            +
            static VALUE language_symbol_type(VALUE self, VALUE symbol) {
         
     | 
| 
      
 182 
     | 
    
         
            +
              return new_symbol_type(ts_language_symbol_type(SELF, NUM2UINT(symbol)));
         
     | 
| 
      
 183 
     | 
    
         
            +
            }
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            /**
         
     | 
| 
      
 186 
     | 
    
         
            +
             * Get the ABI version number for this language. This version number is used
         
     | 
| 
      
 187 
     | 
    
         
            +
             * to ensure that languages were generated by a compatible version of
         
     | 
| 
      
 188 
     | 
    
         
            +
             * Tree-sitter.
         
     | 
| 
      
 189 
     | 
    
         
            +
             *
         
     | 
| 
      
 190 
     | 
    
         
            +
             * @see Parser#language=
         
     | 
| 
      
 191 
     | 
    
         
            +
             */
         
     | 
| 
      
 192 
     | 
    
         
            +
            static VALUE language_version(VALUE self) {
         
     | 
| 
      
 193 
     | 
    
         
            +
              return UINT2NUM(ts_language_version(SELF));
         
     | 
| 
      
 194 
     | 
    
         
            +
            }
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            void init_language(void) {
         
     | 
| 
      
 197 
     | 
    
         
            +
              cLanguage = rb_define_class_under(mTreeSitter, "Language", rb_cObject);
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
              rb_define_alloc_func(cLanguage, language_allocate);
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
              /* Module methods */
         
     | 
| 
      
 202 
     | 
    
         
            +
              rb_define_module_function(cLanguage, "load", language_load, 2);
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
              /* Operators */
         
     | 
| 
      
 205 
     | 
    
         
            +
              rb_define_method(cLanguage, "==", language_equal, 1);
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
              /* Class methods */
         
     | 
| 
      
 208 
     | 
    
         
            +
              rb_define_method(cLanguage, "field_count", language_field_count, 0);
         
     | 
| 
      
 209 
     | 
    
         
            +
              rb_define_method(cLanguage, "field_id_for_name", language_field_id_for_name,
         
     | 
| 
      
 210 
     | 
    
         
            +
                               1);
         
     | 
| 
      
 211 
     | 
    
         
            +
              rb_define_method(cLanguage, "field_name_for_id", language_field_name_for_id,
         
     | 
| 
      
 212 
     | 
    
         
            +
                               1);
         
     | 
| 
      
 213 
     | 
    
         
            +
              rb_define_method(cLanguage, "next_state", language_next_state, 2);
         
     | 
| 
      
 214 
     | 
    
         
            +
              rb_define_method(cLanguage, "symbol_count", language_symbol_count, 0);
         
     | 
| 
      
 215 
     | 
    
         
            +
              rb_define_method(cLanguage, "symbol_for_name", language_symbol_for_name, 2);
         
     | 
| 
      
 216 
     | 
    
         
            +
              rb_define_method(cLanguage, "symbol_name", language_symbol_name, 1);
         
     | 
| 
      
 217 
     | 
    
         
            +
              rb_define_method(cLanguage, "symbol_type", language_symbol_type, 1);
         
     | 
| 
      
 218 
     | 
    
         
            +
              rb_define_method(cLanguage, "version", language_version, 0);
         
     | 
| 
      
 219 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,228 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "tree_sitter.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            extern VALUE mTreeSitter;
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            VALUE cLogger;
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            // This type is layed out in the DATA_* style.
         
     | 
| 
      
 8 
     | 
    
         
            +
            // data: the TSLogger object
         
     | 
| 
      
 9 
     | 
    
         
            +
            // payload: what will be used in TSLogger.log()
         
     | 
| 
      
 10 
     | 
    
         
            +
            //          therefore: data.payload = payload
         
     | 
| 
      
 11 
     | 
    
         
            +
            // format: optional formatting string. Passed to "printf" if it exists
         
     | 
| 
      
 12 
     | 
    
         
            +
            typedef struct {
         
     | 
| 
      
 13 
     | 
    
         
            +
              TSLogger data;
         
     | 
| 
      
 14 
     | 
    
         
            +
              VALUE payload;
         
     | 
| 
      
 15 
     | 
    
         
            +
              VALUE format;
         
     | 
| 
      
 16 
     | 
    
         
            +
            } logger_t;
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            static const char *logger_log_type_str(TSLogType log_type) {
         
     | 
| 
      
 19 
     | 
    
         
            +
              switch (log_type) {
         
     | 
| 
      
 20 
     | 
    
         
            +
              case TSLogTypeParse:
         
     | 
| 
      
 21 
     | 
    
         
            +
                return "Parse:";
         
     | 
| 
      
 22 
     | 
    
         
            +
              case TSLogTypeLex:
         
     | 
| 
      
 23 
     | 
    
         
            +
                return "Lex  :";
         
     | 
| 
      
 24 
     | 
    
         
            +
              default:
         
     | 
| 
      
 25 
     | 
    
         
            +
                return "?????:";
         
     | 
| 
      
 26 
     | 
    
         
            +
              }
         
     | 
| 
      
 27 
     | 
    
         
            +
            }
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            static void logger_log_printf(void *ptr, TSLogType log_type,
         
     | 
| 
      
 30 
     | 
    
         
            +
                                          const char *message) {
         
     | 
| 
      
 31 
     | 
    
         
            +
              logger_t *logger = (logger_t *)ptr;
         
     | 
| 
      
 32 
     | 
    
         
            +
              VALUE type = safe_str(logger_log_type_str(log_type));
         
     | 
| 
      
 33 
     | 
    
         
            +
              VALUE msg = safe_str(message);
         
     | 
| 
      
 34 
     | 
    
         
            +
              rb_funcall(logger->payload, rb_intern("printf"), 3, logger->format, type,
         
     | 
| 
      
 35 
     | 
    
         
            +
                         msg);
         
     | 
| 
      
 36 
     | 
    
         
            +
            }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            static void logger_log_puts(void *ptr, TSLogType log_type,
         
     | 
| 
      
 39 
     | 
    
         
            +
                                        const char *message) {
         
     | 
| 
      
 40 
     | 
    
         
            +
              logger_t *logger = (logger_t *)ptr;
         
     | 
| 
      
 41 
     | 
    
         
            +
              const char *format =
         
     | 
| 
      
 42 
     | 
    
         
            +
                  NIL_P(logger->format) ? "%s %s" : StringValueCStr(logger->format);
         
     | 
| 
      
 43 
     | 
    
         
            +
              VALUE str = rb_sprintf(format, logger_log_type_str(log_type), message);
         
     | 
| 
      
 44 
     | 
    
         
            +
              rb_funcall(logger->payload, rb_intern("puts"), 1, str);
         
     | 
| 
      
 45 
     | 
    
         
            +
            }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            static void logger_log_write(void *ptr, TSLogType log_type,
         
     | 
| 
      
 48 
     | 
    
         
            +
                                         const char *message) {
         
     | 
| 
      
 49 
     | 
    
         
            +
              logger_t *logger = (logger_t *)ptr;
         
     | 
| 
      
 50 
     | 
    
         
            +
              const char *format =
         
     | 
| 
      
 51 
     | 
    
         
            +
                  NIL_P(logger->format) ? "%s %s\n" : StringValueCStr(logger->format);
         
     | 
| 
      
 52 
     | 
    
         
            +
              VALUE str = rb_sprintf(format, logger_log_type_str(log_type), message);
         
     | 
| 
      
 53 
     | 
    
         
            +
              rb_funcall(logger->payload, rb_intern("write"), 1, str);
         
     | 
| 
      
 54 
     | 
    
         
            +
            }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            static void logger_payload_set(logger_t *logger, VALUE value) {
         
     | 
| 
      
 57 
     | 
    
         
            +
              logger->payload = value;
         
     | 
| 
      
 58 
     | 
    
         
            +
              logger->data.payload = (void *)logger;
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              if (!NIL_P(logger->format) && !NIL_P(logger->payload)) {
         
     | 
| 
      
 61 
     | 
    
         
            +
                if (rb_respond_to(logger->payload, rb_intern("printf"))) {
         
     | 
| 
      
 62 
     | 
    
         
            +
                  logger->data.log = logger_log_printf;
         
     | 
| 
      
 63 
     | 
    
         
            +
                } else if (rb_respond_to(logger->payload, rb_intern("puts"))) {
         
     | 
| 
      
 64 
     | 
    
         
            +
                  logger->data.log = logger_log_puts;
         
     | 
| 
      
 65 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 66 
     | 
    
         
            +
                  logger->data.log = logger_log_write;
         
     | 
| 
      
 67 
     | 
    
         
            +
                }
         
     | 
| 
      
 68 
     | 
    
         
            +
              } else if (!NIL_P(logger->payload)) {
         
     | 
| 
      
 69 
     | 
    
         
            +
                logger->data.log = logger_log_write;
         
     | 
| 
      
 70 
     | 
    
         
            +
              }
         
     | 
| 
      
 71 
     | 
    
         
            +
            }
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            static void logger_free(void *ptr) { xfree(ptr); }
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            static size_t logger_memsize(const void *ptr) {
         
     | 
| 
      
 76 
     | 
    
         
            +
              logger_t *type = (logger_t *)ptr;
         
     | 
| 
      
 77 
     | 
    
         
            +
              return sizeof(type);
         
     | 
| 
      
 78 
     | 
    
         
            +
            }
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            static void logger_mark(void *ptr) {
         
     | 
| 
      
 81 
     | 
    
         
            +
              logger_t *logger = (logger_t *)ptr;
         
     | 
| 
      
 82 
     | 
    
         
            +
              rb_gc_mark_movable(logger->payload);
         
     | 
| 
      
 83 
     | 
    
         
            +
              // we don't want format to move because its reference will be
         
     | 
| 
      
 84 
     | 
    
         
            +
              // consumed by the parser.
         
     | 
| 
      
 85 
     | 
    
         
            +
              //
         
     | 
| 
      
 86 
     | 
    
         
            +
              // No funny things please.
         
     | 
| 
      
 87 
     | 
    
         
            +
              rb_gc_mark(logger->format);
         
     | 
| 
      
 88 
     | 
    
         
            +
            }
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            static void logger_compact(void *ptr) {
         
     | 
| 
      
 91 
     | 
    
         
            +
              logger_t *logger = (logger_t *)ptr;
         
     | 
| 
      
 92 
     | 
    
         
            +
              logger->payload = rb_gc_location(logger->payload);
         
     | 
| 
      
 93 
     | 
    
         
            +
            }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            const rb_data_type_t logger_data_type = {
         
     | 
| 
      
 96 
     | 
    
         
            +
                .wrap_struct_name = "logger",
         
     | 
| 
      
 97 
     | 
    
         
            +
                .function =
         
     | 
| 
      
 98 
     | 
    
         
            +
                    {
         
     | 
| 
      
 99 
     | 
    
         
            +
                        .dmark = logger_mark,
         
     | 
| 
      
 100 
     | 
    
         
            +
                        .dfree = logger_free,
         
     | 
| 
      
 101 
     | 
    
         
            +
                        .dsize = logger_memsize,
         
     | 
| 
      
 102 
     | 
    
         
            +
                        .dcompact = logger_compact,
         
     | 
| 
      
 103 
     | 
    
         
            +
                    },
         
     | 
| 
      
 104 
     | 
    
         
            +
                .flags = RUBY_TYPED_FREE_IMMEDIATELY,
         
     | 
| 
      
 105 
     | 
    
         
            +
            };
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            DATA_UNWRAP(logger)
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            static VALUE logger_allocate(VALUE klass) {
         
     | 
| 
      
 110 
     | 
    
         
            +
              logger_t *logger;
         
     | 
| 
      
 111 
     | 
    
         
            +
              return TypedData_Make_Struct(klass, logger_t, &logger_data_type, logger);
         
     | 
| 
      
 112 
     | 
    
         
            +
            }
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            VALUE new_logger(const TSLogger *ptr) {
         
     | 
| 
      
 115 
     | 
    
         
            +
              if (ptr != NULL) {
         
     | 
| 
      
 116 
     | 
    
         
            +
                VALUE res = logger_allocate(cLogger);
         
     | 
| 
      
 117 
     | 
    
         
            +
                logger_t *logger = unwrap(res);
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                logger->data.payload = logger;
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                VALUE payload = Qnil;
         
     | 
| 
      
 122 
     | 
    
         
            +
                VALUE format = Qnil;
         
     | 
| 
      
 123 
     | 
    
         
            +
                if (ptr->payload != NULL) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                  logger_t *old_logger = (logger_t *)ptr->payload;
         
     | 
| 
      
 125 
     | 
    
         
            +
                  payload = old_logger->payload;
         
     | 
| 
      
 126 
     | 
    
         
            +
                  format = old_logger->format;
         
     | 
| 
      
 127 
     | 
    
         
            +
                }
         
     | 
| 
      
 128 
     | 
    
         
            +
                logger_payload_set(logger, payload);
         
     | 
| 
      
 129 
     | 
    
         
            +
                logger->format = format;
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                return res;
         
     | 
| 
      
 132 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 133 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 134 
     | 
    
         
            +
              }
         
     | 
| 
      
 135 
     | 
    
         
            +
            }
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            VALUE new_logger_by_val(TSLogger val) { return new_logger(&val); }
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            TSLogger value_to_logger(VALUE self) { return SELF; }
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            static void logger_initialize_stderr(logger_t *logger) {
         
     | 
| 
      
 142 
     | 
    
         
            +
              VALUE stderr = rb_gv_get("$stderr");
         
     | 
| 
      
 143 
     | 
    
         
            +
              if (!NIL_P(stderr)) {
         
     | 
| 
      
 144 
     | 
    
         
            +
                logger_payload_set(logger, stderr);
         
     | 
| 
      
 145 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 146 
     | 
    
         
            +
                logger_payload_set(logger, Qnil);
         
     | 
| 
      
 147 
     | 
    
         
            +
              }
         
     | 
| 
      
 148 
     | 
    
         
            +
            }
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            /**
         
     | 
| 
      
 151 
     | 
    
         
            +
             * Create a new logger.
         
     | 
| 
      
 152 
     | 
    
         
            +
             *
         
     | 
| 
      
 153 
     | 
    
         
            +
             * By default, it logs to stderr.
         
     | 
| 
      
 154 
     | 
    
         
            +
             *
         
     | 
| 
      
 155 
     | 
    
         
            +
             * You can provide your proper backend. You have to make sure that it
         
     | 
| 
      
 156 
     | 
    
         
            +
             * exposes a +printf+, +puts+, or +write+ (lookup is done in that specific
         
     | 
| 
      
 157 
     | 
    
         
            +
             * order). {::StringIO} is a perfect candidate.
         
     | 
| 
      
 158 
     | 
    
         
            +
             *
         
     | 
| 
      
 159 
     | 
    
         
            +
             * You can also provide a format ({::String}) if your backend supports a +printf+.
         
     | 
| 
      
 160 
     | 
    
         
            +
             *
         
     | 
| 
      
 161 
     | 
    
         
            +
             * @example
         
     | 
| 
      
 162 
     | 
    
         
            +
             *   backend = StringIO.new
         
     | 
| 
      
 163 
     | 
    
         
            +
             *   parser.logger = TreeSitter::Logger.new(backend)
         
     | 
| 
      
 164 
     | 
    
         
            +
             *
         
     | 
| 
      
 165 
     | 
    
         
            +
             * @param args [Array] The first argument is always a backend. The second
         
     | 
| 
      
 166 
     | 
    
         
            +
             *                     argument is the format.
         
     | 
| 
      
 167 
     | 
    
         
            +
             */
         
     | 
| 
      
 168 
     | 
    
         
            +
            static VALUE logger_initialize(int argc, VALUE *argv, VALUE self) {
         
     | 
| 
      
 169 
     | 
    
         
            +
              // TODO:
         
     | 
| 
      
 170 
     | 
    
         
            +
              // For now, we only take:
         
     | 
| 
      
 171 
     | 
    
         
            +
              //   argv[0] = stream
         
     | 
| 
      
 172 
     | 
    
         
            +
              //   argv[1] = format : String
         
     | 
| 
      
 173 
     | 
    
         
            +
              // We need to add support for argv[1] : lambda/block
         
     | 
| 
      
 174 
     | 
    
         
            +
              //   case argv[1]
         
     | 
| 
      
 175 
     | 
    
         
            +
              //   in lambda => lambda
         
     | 
| 
      
 176 
     | 
    
         
            +
              //   in String => puts || printf || write
         
     | 
| 
      
 177 
     | 
    
         
            +
              //   else      => write
         
     | 
| 
      
 178 
     | 
    
         
            +
              //   end
         
     | 
| 
      
 179 
     | 
    
         
            +
              logger_t *logger = unwrap(self);
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
              VALUE payload;
         
     | 
| 
      
 182 
     | 
    
         
            +
              VALUE format;
         
     | 
| 
      
 183 
     | 
    
         
            +
              rb_scan_args(argc, argv, "02", &payload, &format);
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
              logger->format = format;
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
              if (argc == 0) {
         
     | 
| 
      
 188 
     | 
    
         
            +
                logger_initialize_stderr(logger);
         
     | 
| 
      
 189 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 190 
     | 
    
         
            +
                logger_payload_set(logger, payload);
         
     | 
| 
      
 191 
     | 
    
         
            +
              }
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
              return self;
         
     | 
| 
      
 194 
     | 
    
         
            +
            }
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            static VALUE logger_inspect(VALUE self) {
         
     | 
| 
      
 197 
     | 
    
         
            +
              logger_t *logger = unwrap(self);
         
     | 
| 
      
 198 
     | 
    
         
            +
              return rb_sprintf("{payload=%+" PRIsVALUE ", format=%+" PRIsVALUE "}",
         
     | 
| 
      
 199 
     | 
    
         
            +
                                logger->payload, logger->format);
         
     | 
| 
      
 200 
     | 
    
         
            +
            }
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            DATA_FAST_FORWARD_FNV(logger, write, payload)
         
     | 
| 
      
 203 
     | 
    
         
            +
            DATA_FAST_FORWARD_FNV(logger, puts, payload)
         
     | 
| 
      
 204 
     | 
    
         
            +
            DATA_FAST_FORWARD_FNV(logger, printf, payload)
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
            DEFINE_ACCESSOR(logger, format)
         
     | 
| 
      
 207 
     | 
    
         
            +
            DEFINE_GETTER(logger, payload)
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
            static VALUE logger_set_payload(VALUE self, VALUE payload) {
         
     | 
| 
      
 210 
     | 
    
         
            +
              logger_payload_set(unwrap(self), payload);
         
     | 
| 
      
 211 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 212 
     | 
    
         
            +
            }
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
            void init_logger(void) {
         
     | 
| 
      
 215 
     | 
    
         
            +
              cLogger = rb_define_class_under(mTreeSitter, "Logger", rb_cObject);
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
              rb_define_alloc_func(cLogger, logger_allocate);
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
              /* Class methods */
         
     | 
| 
      
 220 
     | 
    
         
            +
              rb_define_method(cLogger, "initialize", logger_initialize, -1);
         
     | 
| 
      
 221 
     | 
    
         
            +
              DECLARE_ACCESSOR(cLogger, logger, format)
         
     | 
| 
      
 222 
     | 
    
         
            +
              DECLARE_ACCESSOR(cLogger, logger, payload)
         
     | 
| 
      
 223 
     | 
    
         
            +
              rb_define_method(cLogger, "write", logger_write, -1);
         
     | 
| 
      
 224 
     | 
    
         
            +
              rb_define_method(cLogger, "puts", logger_puts, -1);
         
     | 
| 
      
 225 
     | 
    
         
            +
              rb_define_method(cLogger, "printf", logger_printf, -1);
         
     | 
| 
      
 226 
     | 
    
         
            +
              rb_define_method(cLogger, "inspect", logger_inspect, 0);
         
     | 
| 
      
 227 
     | 
    
         
            +
              rb_define_method(cLogger, "to_s", logger_inspect, 0);
         
     | 
| 
      
 228 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,163 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef _RB_TREE_SITTER_MACROS_H
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define _RB_TREE_SITTER_MACROS_H
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #define DECLARE_GETTER(klass, type, field)                                     \
         
     | 
| 
      
 5 
     | 
    
         
            +
              rb_define_method(klass, #field, type##_get_##field, 0);
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            #define DECLARE_SETTER(klass, type, field)                                     \
         
     | 
| 
      
 8 
     | 
    
         
            +
              rb_define_method(klass, #field "=", type##_set_##field, 1);
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            #define DECLARE_ACCESSOR(klass, type, field)                                   \
         
     | 
| 
      
 11 
     | 
    
         
            +
              DECLARE_GETTER(klass, type, field)                                           \
         
     | 
| 
      
 12 
     | 
    
         
            +
              DECLARE_SETTER(klass, type, field)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            // Plain DEFINE_GETTER/DEFINE_SETTER/etc are for TypedData structs, reaching
         
     | 
| 
      
 15 
     | 
    
         
            +
            // their top-level fields, and are of type VALUE
         
     | 
| 
      
 16 
     | 
    
         
            +
            //
         
     | 
| 
      
 17 
     | 
    
         
            +
            // DATA_* are for TypeData structs, raching their data field
         
     | 
| 
      
 18 
     | 
    
         
            +
            // which can be of an arbitraty tuype.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            #define DEFINE_GETTER(type, field)                                             \
         
     | 
| 
      
 21 
     | 
    
         
            +
              static VALUE type##_get_##field(VALUE self) { return (unwrap(self))->field; }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            #define DEFINE_SETTER(type, field)                                             \
         
     | 
| 
      
 24 
     | 
    
         
            +
              static VALUE type##_set_##field(VALUE self, VALUE val) {                     \
         
     | 
| 
      
 25 
     | 
    
         
            +
                unwrap(self)->field = val;                                                 \
         
     | 
| 
      
 26 
     | 
    
         
            +
                return Qnil;                                                               \
         
     | 
| 
      
 27 
     | 
    
         
            +
              }
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            #define DEFINE_ACCESSOR(type, field)                                           \
         
     | 
| 
      
 30 
     | 
    
         
            +
              DEFINE_GETTER(type, field)                                                   \
         
     | 
| 
      
 31 
     | 
    
         
            +
              DEFINE_SETTER(type, field)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #define DATA_WRAP(base, type)                                                  \
         
     | 
| 
      
 34 
     | 
    
         
            +
              DATA_TYPE(TS##base, type)                                                    \
         
     | 
| 
      
 35 
     | 
    
         
            +
              DATA_FREE(type)                                                              \
         
     | 
| 
      
 36 
     | 
    
         
            +
              DATA_MEMSIZE(type)                                                           \
         
     | 
| 
      
 37 
     | 
    
         
            +
              DATA_DECLARE_DATA_TYPE(type)                                                 \
         
     | 
| 
      
 38 
     | 
    
         
            +
              DATA_ALLOCATE(type)                                                          \
         
     | 
| 
      
 39 
     | 
    
         
            +
              DATA_UNWRAP(type)                                                            \
         
     | 
| 
      
 40 
     | 
    
         
            +
              DATA_NEW(c##base, TS##base, type)                                            \
         
     | 
| 
      
 41 
     | 
    
         
            +
              DATA_FROM_VALUE(TS##base, type)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            #define DATA_PTR_WRAP(base, type)                                              \
         
     | 
| 
      
 44 
     | 
    
         
            +
              DATA_TYPE(TS##base *, type)                                                  \
         
     | 
| 
      
 45 
     | 
    
         
            +
              DATA_FREE_PTR(type)                                                          \
         
     | 
| 
      
 46 
     | 
    
         
            +
              DATA_MEMSIZE(type)                                                           \
         
     | 
| 
      
 47 
     | 
    
         
            +
              DATA_DECLARE_DATA_TYPE(type)                                                 \
         
     | 
| 
      
 48 
     | 
    
         
            +
              DATA_ALLOCATE(type)                                                          \
         
     | 
| 
      
 49 
     | 
    
         
            +
              DATA_UNWRAP(type)                                                            \
         
     | 
| 
      
 50 
     | 
    
         
            +
              DATA_PTR_NEW(c##base, TS##base, type)                                        \
         
     | 
| 
      
 51 
     | 
    
         
            +
              DATA_FROM_VALUE(TS##base *, type)
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            #define DATA_TYPE(klass, type)                                                 \
         
     | 
| 
      
 54 
     | 
    
         
            +
              typedef struct {                                                             \
         
     | 
| 
      
 55 
     | 
    
         
            +
                klass data;                                                                \
         
     | 
| 
      
 56 
     | 
    
         
            +
              } type##_t;
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            #define DATA_FREE(type)                                                        \
         
     | 
| 
      
 59 
     | 
    
         
            +
              static void type##_free(void *ptr) { xfree(ptr); }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            #define DATA_FREE_PTR(type)                                                    \
         
     | 
| 
      
 62 
     | 
    
         
            +
              static void type##_free(void *ptr) {                                         \
         
     | 
| 
      
 63 
     | 
    
         
            +
                type##_t *type = (type##_t *)ptr;                                          \
         
     | 
| 
      
 64 
     | 
    
         
            +
                if (type->data != NULL) {                                                  \
         
     | 
| 
      
 65 
     | 
    
         
            +
                  ts_##type##_delete(type->data);                                          \
         
     | 
| 
      
 66 
     | 
    
         
            +
                }                                                                          \
         
     | 
| 
      
 67 
     | 
    
         
            +
                xfree(ptr);                                                                \
         
     | 
| 
      
 68 
     | 
    
         
            +
              }
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            #define DATA_MEMSIZE(type)                                                     \
         
     | 
| 
      
 71 
     | 
    
         
            +
              static size_t type##_memsize(const void *ptr) {                              \
         
     | 
| 
      
 72 
     | 
    
         
            +
                type##_t *type = (type##_t *)ptr;                                          \
         
     | 
| 
      
 73 
     | 
    
         
            +
                return sizeof(type);                                                       \
         
     | 
| 
      
 74 
     | 
    
         
            +
              }
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            #define DATA_DECLARE_DATA_TYPE(type)                                           \
         
     | 
| 
      
 77 
     | 
    
         
            +
              const rb_data_type_t type##_data_type = {                                    \
         
     | 
| 
      
 78 
     | 
    
         
            +
                  .wrap_struct_name = #type "",                                            \
         
     | 
| 
      
 79 
     | 
    
         
            +
                  .function =                                                              \
         
     | 
| 
      
 80 
     | 
    
         
            +
                      {                                                                    \
         
     | 
| 
      
 81 
     | 
    
         
            +
                          .dmark = NULL,                                                   \
         
     | 
| 
      
 82 
     | 
    
         
            +
                          .dfree = type##_free,                                            \
         
     | 
| 
      
 83 
     | 
    
         
            +
                          .dsize = type##_memsize,                                         \
         
     | 
| 
      
 84 
     | 
    
         
            +
                          .dcompact = NULL,                                                \
         
     | 
| 
      
 85 
     | 
    
         
            +
                      },                                                                   \
         
     | 
| 
      
 86 
     | 
    
         
            +
                  .flags = RUBY_TYPED_FREE_IMMEDIATELY,                                    \
         
     | 
| 
      
 87 
     | 
    
         
            +
              };
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            #define DATA_ALLOCATE(type)                                                    \
         
     | 
| 
      
 90 
     | 
    
         
            +
              static VALUE type##_allocate(VALUE klass) {                                  \
         
     | 
| 
      
 91 
     | 
    
         
            +
                type##_t *type;                                                            \
         
     | 
| 
      
 92 
     | 
    
         
            +
                return TypedData_Make_Struct(klass, type##_t, &type##_data_type, type);    \
         
     | 
| 
      
 93 
     | 
    
         
            +
              }
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            #define DATA_UNWRAP(type)                                                      \
         
     | 
| 
      
 96 
     | 
    
         
            +
              static type##_t *unwrap(VALUE self) {                                        \
         
     | 
| 
      
 97 
     | 
    
         
            +
                type##_t *type;                                                            \
         
     | 
| 
      
 98 
     | 
    
         
            +
                TypedData_Get_Struct(self, type##_t, &type##_data_type, type);             \
         
     | 
| 
      
 99 
     | 
    
         
            +
                return type;                                                               \
         
     | 
| 
      
 100 
     | 
    
         
            +
              }
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            #define SELF unwrap(self)->data
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            #define DATA_NEW(klass, struct, type)                                          \
         
     | 
| 
      
 105 
     | 
    
         
            +
              VALUE new_##type(const struct *ptr) {                                        \
         
     | 
| 
      
 106 
     | 
    
         
            +
                if (ptr == NULL) {                                                         \
         
     | 
| 
      
 107 
     | 
    
         
            +
                  return Qnil;                                                             \
         
     | 
| 
      
 108 
     | 
    
         
            +
                }                                                                          \
         
     | 
| 
      
 109 
     | 
    
         
            +
                VALUE res = type##_allocate(klass);                                        \
         
     | 
| 
      
 110 
     | 
    
         
            +
                type##_t *type = unwrap(res);                                              \
         
     | 
| 
      
 111 
     | 
    
         
            +
                type->data = *ptr;                                                         \
         
     | 
| 
      
 112 
     | 
    
         
            +
                return res;                                                                \
         
     | 
| 
      
 113 
     | 
    
         
            +
              }                                                                            \
         
     | 
| 
      
 114 
     | 
    
         
            +
              VALUE new_##type##_by_val(struct ptr) {                                      \
         
     | 
| 
      
 115 
     | 
    
         
            +
                VALUE res = type##_allocate(klass);                                        \
         
     | 
| 
      
 116 
     | 
    
         
            +
                type##_t *type = unwrap(res);                                              \
         
     | 
| 
      
 117 
     | 
    
         
            +
                type->data = ptr;                                                          \
         
     | 
| 
      
 118 
     | 
    
         
            +
                return res;                                                                \
         
     | 
| 
      
 119 
     | 
    
         
            +
              }
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            #define DATA_FROM_VALUE(struct, type)                                          \
         
     | 
| 
      
 122 
     | 
    
         
            +
              struct value_to_##type(VALUE self) {                                         \
         
     | 
| 
      
 123 
     | 
    
         
            +
                return (unwrap(self))->data;                                               \
         
     | 
| 
      
 124 
     | 
    
         
            +
              }
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            #define DATA_PTR_NEW(klass, struct, type)                                      \
         
     | 
| 
      
 127 
     | 
    
         
            +
              VALUE new_##type(struct *ptr) {                                              \
         
     | 
| 
      
 128 
     | 
    
         
            +
                if (ptr == NULL) {                                                         \
         
     | 
| 
      
 129 
     | 
    
         
            +
                  return Qnil;                                                             \
         
     | 
| 
      
 130 
     | 
    
         
            +
                }                                                                          \
         
     | 
| 
      
 131 
     | 
    
         
            +
                VALUE res = type##_allocate(klass);                                        \
         
     | 
| 
      
 132 
     | 
    
         
            +
                type##_t *type = unwrap(res);                                              \
         
     | 
| 
      
 133 
     | 
    
         
            +
                type->data = ptr;                                                          \
         
     | 
| 
      
 134 
     | 
    
         
            +
                return res;                                                                \
         
     | 
| 
      
 135 
     | 
    
         
            +
              }
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            #define DATA_DEFINE_GETTER(type, field, cast)                                  \
         
     | 
| 
      
 138 
     | 
    
         
            +
              static VALUE type##_get_##field(VALUE self) {                                \
         
     | 
| 
      
 139 
     | 
    
         
            +
                return cast((unwrap(self))->data.field);                                   \
         
     | 
| 
      
 140 
     | 
    
         
            +
              }
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            #define DATA_DEFINE_SETTER(type, field, cast)                                  \
         
     | 
| 
      
 143 
     | 
    
         
            +
              static VALUE type##_set_##field(VALUE self, VALUE val) {                     \
         
     | 
| 
      
 144 
     | 
    
         
            +
                type##_t *type = unwrap(self);                                             \
         
     | 
| 
      
 145 
     | 
    
         
            +
                type->data.field = cast(val);                                              \
         
     | 
| 
      
 146 
     | 
    
         
            +
                return Qnil;                                                               \
         
     | 
| 
      
 147 
     | 
    
         
            +
              }
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            #define DATA_DEFINE_ACCESSOR(type, field, cast_get, cast_set)                  \
         
     | 
| 
      
 150 
     | 
    
         
            +
              DATA_DEFINE_GETTER(type, field, cast_get)                                    \
         
     | 
| 
      
 151 
     | 
    
         
            +
              DATA_DEFINE_SETTER(type, field, cast_set)
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            #define DATA_FAST_FORWARD_FNV(type, fn, field)                                 \
         
     | 
| 
      
 154 
     | 
    
         
            +
              static VALUE type##_##fn(int argc, VALUE *argv, VALUE self) {                \
         
     | 
| 
      
 155 
     | 
    
         
            +
                type##_t *type = unwrap(self);                                             \
         
     | 
| 
      
 156 
     | 
    
         
            +
                if (!NIL_P(type->field)) {                                                 \
         
     | 
| 
      
 157 
     | 
    
         
            +
                  return rb_funcallv(type->field, rb_intern(#fn ""), argc, argv);          \
         
     | 
| 
      
 158 
     | 
    
         
            +
                } else {                                                                   \
         
     | 
| 
      
 159 
     | 
    
         
            +
                  return Qnil;                                                             \
         
     | 
| 
      
 160 
     | 
    
         
            +
                }                                                                          \
         
     | 
| 
      
 161 
     | 
    
         
            +
              }
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            #endif
         
     |