├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── tasks.json ├── LICENSE ├── README.md ├── csharp-tree-sitter.csproj ├── src └── binding.cs ├── tests └── test.cs └── tree-sitter ├── Makefile ├── README.md ├── tree-sitter-cpp.def ├── tree-sitter.def └── tree-sitter.vcxproj /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | 3 | **/.chunks* 4 | **/.cache 5 | **/.tokens 6 | **/.archive 7 | **/obj 8 | **/bin 9 | **/src/obj 10 | **/src/bin 11 | **/_* 12 | 13 | 14 | *_ 15 | *~ 16 | \#*\# 17 | *.obj 18 | *.pdb 19 | *.lib 20 | *.exp 21 | *.dll -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tree-sitter/tree-sitter"] 2 | path = tree-sitter/tree-sitter 3 | url = https://github.com/tree-sitter/tree-sitter.git 4 | [submodule "tree-sitter/tree-sitter-cpp"] 5 | path = tree-sitter/tree-sitter-cpp 6 | url = https://github.com/DennySun2100/tree-sitter-cpp.git 7 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "test", 9 | "stopAtEntry": false, 10 | "type": "coreclr", 11 | "request": "launch", 12 | "preLaunchTask": "build", 13 | "console": "integratedTerminal", 14 | "program": "${workspaceFolder}/bin/Debug/net7.0/csharp-tree-sitter.dll", 15 | "cwd": "${workspaceFolder}", 16 | "args": [ 17 | "-files", 18 | "path" 19 | ], 20 | }, 21 | ] 22 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/csharp-tree-sitter.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/csharp-tree-sitter.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "--project", 36 | "${workspaceFolder}/csharp-tree-sitter.csproj" 37 | ], 38 | "problemMatcher": "$msCompile" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # csharp-tree-sitter 2 | ================== 3 | 4 | ## Introduction 5 | This module provides C# bindings to the [tree-sitter](https://github.com/tree-sitter/tree-sitter) parsing library, which can enable c# developers be able to invoke the tree-sitter libraries through P/Invoke from their c# code. 6 | 7 | ## Cloning 8 | 9 | This repo includes the needed tree-sitter repos as submodules. Remember to use the `--recursive` option with git clone. 10 | 11 | ```cmd 12 | git clone https://github.com/tree-sitter/csharp-tree-sitter.git --recursive 13 | ``` 14 | 15 | ## Building 16 | 17 | Requirements: 18 | - Windows-only (the Makefile in the `tree-sitter` has OS-specific stuff in it so far) 19 | - .NET 7 20 | 21 | We'll first need to build the dependencies, and then the C# project. 22 | 23 | - get dependencies built 24 | - `cd tree-sitter` 25 | - `nmake` 26 | - `cd ..` 27 | - `dotnet build csharp-tree-sitter.csproj` 28 | 29 | ## Testing 30 | 31 | A good demo is the following, it is a test written in c# which walks the AST tree in post order by calling `tree-sitter-cpp` parser with these bindings. 32 | 33 | Assuming you're in VS Code: 34 | - navigate to a C++ file to be parsed 35 | - press `F5` to run with the default 'launch' configuration 36 | 37 | Otherwise, you may manually run with: 38 | 39 | ```cmd 40 | csharp-tree-sitter.exe -files [your test cpp files] 41 | ``` 42 | 43 | TODO: continue here 44 | 45 | ## Contributing 46 | 47 | TODO: Explain how other users and developers can contribute to make your code better. 48 | -------------------------------------------------------------------------------- /csharp-tree-sitter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net7.0 6 | disable 7 | disable 8 | x64 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/binding.cs: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Module Name: 4 | // binding.cs 5 | // 6 | // Abstract: 7 | // Wrapper for GitHub Tree-Sitter Library. 8 | // 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Diagnostics; 12 | using System.Runtime.InteropServices; 13 | 14 | namespace GitHub.TreeSitter 15 | { 16 | public enum TSInputEncoding { 17 | TSInputEncodingUTF8, 18 | TSInputEncodingUTF16 19 | } 20 | 21 | public enum TSSymbolType { 22 | TSSymbolTypeRegular, 23 | TSSymbolTypeAnonymous, 24 | TSSymbolTypeAuxiliary, 25 | } 26 | 27 | public enum TSLogType { 28 | TSLogTypeParse, 29 | TSLogTypeLex, 30 | } 31 | 32 | public enum TSQuantifier { 33 | TSQuantifierZero = 0, // must match the array initialization value 34 | TSQuantifierZeroOrOne, 35 | TSQuantifierZeroOrMore, 36 | TSQuantifierOne, 37 | TSQuantifierOneOrMore, 38 | } 39 | 40 | public enum TSQueryPredicateStepType { 41 | TSQueryPredicateStepTypeDone, 42 | TSQueryPredicateStepTypeCapture, 43 | TSQueryPredicateStepTypeString, 44 | } 45 | 46 | public enum TSQueryError { 47 | TSQueryErrorNone = 0, 48 | TSQueryErrorSyntax, 49 | TSQueryErrorNodeType, 50 | TSQueryErrorField, 51 | TSQueryErrorCapture, 52 | TSQueryErrorStructure, 53 | TSQueryErrorLanguage, 54 | } 55 | 56 | [StructLayout(LayoutKind.Sequential)] 57 | public struct TSPoint 58 | { 59 | public uint row; 60 | public uint column; 61 | 62 | public TSPoint(uint row, uint column) 63 | { 64 | this.row = row; 65 | this.column = column; 66 | } 67 | } 68 | 69 | [StructLayout(LayoutKind.Sequential)] 70 | public struct TSRange 71 | { 72 | public TSPoint start_point; 73 | public TSPoint end_point; 74 | public uint start_byte; 75 | public uint end_byte; 76 | } 77 | 78 | [StructLayout(LayoutKind.Sequential)] 79 | public struct TSInputEdit 80 | { 81 | public uint start_byte; 82 | public uint old_end_byte; 83 | public uint new_end_byte; 84 | public TSPoint start_point; 85 | public TSPoint old_end_point; 86 | public TSPoint new_end_point; 87 | } 88 | 89 | [StructLayout(LayoutKind.Sequential)] 90 | public struct TSQueryCapture 91 | { 92 | public TSNode node; 93 | public uint index; 94 | } 95 | 96 | [StructLayout(LayoutKind.Sequential)] 97 | public struct TSQueryMatch 98 | { 99 | public uint id; 100 | public ushort pattern_index; 101 | public ushort capture_count; 102 | public IntPtr captures; 103 | } 104 | 105 | [StructLayout(LayoutKind.Sequential)] 106 | public struct TSQueryPredicateStep 107 | { 108 | public TSQueryPredicateStepType type; 109 | public uint value_id; 110 | } 111 | 112 | public delegate void TSLogger(TSLogType logType, string message); 113 | 114 | /********************/ 115 | /* Section - Parser */ 116 | /********************/ 117 | 118 | public sealed class TSParser : IDisposable 119 | { 120 | private IntPtr Ptr { get; set; } 121 | 122 | public TSParser() 123 | { 124 | Ptr = ts_parser_new(); 125 | } 126 | 127 | public void Dispose() 128 | { 129 | if (Ptr != IntPtr.Zero) { 130 | ts_parser_delete(Ptr); 131 | Ptr = IntPtr.Zero; 132 | } 133 | } 134 | 135 | public bool set_language(TSLanguage language) { return ts_parser_set_language(Ptr, language.Ptr); } 136 | 137 | public TSLanguage language() { 138 | var ptr = ts_parser_language(Ptr); 139 | return ptr != IntPtr.Zero ? new TSLanguage(ptr) : null; 140 | } 141 | 142 | public bool set_included_ranges(TSRange[] ranges) { 143 | return ts_parser_set_included_ranges(Ptr, ranges, (uint)ranges.Length); 144 | } 145 | public TSRange[] included_ranges() { 146 | uint length; 147 | return ts_parser_included_ranges(Ptr, out length); 148 | } 149 | 150 | public TSTree parse_string(TSTree oldTree, string input) { 151 | var ptr = ts_parser_parse_string_encoding(Ptr, oldTree != null ? oldTree.Ptr : IntPtr.Zero, 152 | input, (uint)input.Length * 2, TSInputEncoding.TSInputEncodingUTF16); 153 | return ptr != IntPtr.Zero ? new TSTree(ptr) : null; 154 | } 155 | 156 | public void reset() { ts_parser_reset(Ptr); } 157 | public void set_timeout_micros(ulong timeout) { ts_parser_set_timeout_micros(Ptr,timeout); } 158 | public ulong timeout_micros() { return ts_parser_timeout_micros(Ptr); } 159 | public void set_logger(TSLogger logger) { 160 | var code = new _TSLoggerCode(logger); 161 | var data = new _TSLoggerData { Log = logger != null ? new TSLogCallback(code.LogCallback) : null }; 162 | ts_parser_set_logger(Ptr, data); 163 | } 164 | 165 | [StructLayout(LayoutKind.Sequential)] 166 | private struct _TSLoggerData 167 | { 168 | private IntPtr Payload; 169 | internal TSLogCallback Log; 170 | } 171 | 172 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 173 | private delegate void TSLogCallback(IntPtr payload, TSLogType logType, [MarshalAs(UnmanagedType.LPUTF8Str)] string message); 174 | 175 | private class _TSLoggerCode 176 | { 177 | private TSLogger logger; 178 | 179 | internal _TSLoggerCode(TSLogger logger) 180 | { 181 | this.logger = logger; 182 | } 183 | 184 | internal void LogCallback(IntPtr payload, TSLogType logType, string message) 185 | { 186 | logger(logType, message); 187 | } 188 | } 189 | 190 | #region PInvoke 191 | [DllImport("tree-sitter-cpp.dll", CallingConvention = CallingConvention.Cdecl)] 192 | private static extern IntPtr tree_sitter_cpp(); 193 | 194 | [DllImport("tree-sitter-c-sharp.dll", CallingConvention = CallingConvention.Cdecl)] 195 | private static extern IntPtr tree_sitter_c_sharp(); 196 | 197 | [DllImport("tree-sitter-rust.dll", CallingConvention = CallingConvention.Cdecl)] 198 | private static extern IntPtr tree_sitter_rust(); 199 | 200 | 201 | /** 202 | * Create a new parser. 203 | */ 204 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 205 | private static extern IntPtr ts_parser_new(); 206 | 207 | /** 208 | * Delete the parser, freeing all of the memory that it used. 209 | */ 210 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 211 | private static extern void ts_parser_delete(IntPtr parser); 212 | 213 | /** 214 | * Set the language that the parser should use for parsing. 215 | * 216 | * Returns a boolean indicating whether or not the language was successfully 217 | * assigned. True means assignment succeeded. False means there was a version 218 | * mismatch: the language was generated with an incompatible version of the 219 | * Tree-sitter CLI. Check the language's version using `ts_language_version` 220 | * and compare it to this library's `TREE_SITTER_LANGUAGE_VERSION` and 221 | * `TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION` constants. 222 | */ 223 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 224 | [return: MarshalAs(UnmanagedType.I1)] 225 | private static extern bool ts_parser_set_language(IntPtr parser, IntPtr language); 226 | 227 | /** 228 | * Get the parser's current language. 229 | */ 230 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 231 | private static extern IntPtr ts_parser_language(IntPtr parser); 232 | 233 | /** 234 | * Set the ranges of text that the parser should include when parsing. 235 | * 236 | * By default, the parser will always include entire documents. This function 237 | * allows you to parse only a *portion* of a document but still return a syntax 238 | * tree whose ranges match up with the document as a whole. You can also pass 239 | * multiple disjoint ranges. 240 | * 241 | * The second and third parameters specify the location and length of an array 242 | * of ranges. The parser does *not* take ownership of these ranges; it copies 243 | * the data, so it doesn't matter how these ranges are allocated. 244 | * 245 | * If `length` is zero, then the entire document will be parsed. Otherwise, 246 | * the given ranges must be ordered from earliest to latest in the document, 247 | * and they must not overlap. That is, the following must hold for all 248 | * `i` < `length - 1`: ranges[i].end_byte <= ranges[i + 1].start_byte 249 | * 250 | * If this requirement is not satisfied, the operation will fail, the ranges 251 | * will not be assigned, and this function will return `false`. On success, 252 | * this function returns `true` 253 | */ 254 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 255 | //[return: MarshalAs(UnmanagedType.I1)] 256 | private static extern bool ts_parser_set_included_ranges(IntPtr parser, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] TSRange[] ranges, uint length); 257 | 258 | /** 259 | * Get the ranges of text that the parser will include when parsing. 260 | * 261 | * The returned pointer is owned by the parser. The caller should not free it 262 | * or write to it. The length of the array will be written to the given 263 | * `length` pointer. 264 | */ 265 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 266 | [return: MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] 267 | private static extern TSRange[] ts_parser_included_ranges(IntPtr parser, out uint length); 268 | 269 | /** 270 | * Use the parser to parse some source code stored in one contiguous buffer. 271 | * The first two parameters are the same as in the `ts_parser_parse` function 272 | * above. The second two parameters indicate the location of the buffer and its 273 | * length in bytes. 274 | */ 275 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 276 | private static extern IntPtr ts_parser_parse_string(IntPtr parser, IntPtr oldTree, [MarshalAs(UnmanagedType.LPUTF8Str)] string input, uint length); 277 | 278 | /** 279 | * Use the parser to parse some source code stored in one contiguous buffer. 280 | * The first two parameters are the same as in the `ts_parser_parse` function 281 | * above. The second two parameters indicate the location of the buffer and its 282 | * length in bytes. 283 | */ 284 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 285 | //private static extern IntPtr ts_parser_parse_string_encoding(IntPtr parser, IntPtr oldTree, [MarshalAs(UnmanagedType.LPUTF8Str)] string input, uint length, TSInputEncoding encoding); 286 | private static extern IntPtr ts_parser_parse_string_encoding(IntPtr parser, IntPtr oldTree, [MarshalAs(UnmanagedType.LPWStr)] string input, uint length, TSInputEncoding encoding); 287 | 288 | /** 289 | * Instruct the parser to start the next parse from the beginning. 290 | * 291 | * If the parser previously failed because of a timeout or a cancellation, then 292 | * by default, it will resume where it left off on the next call to 293 | * `ts_parser_parse` or other parsing functions. If you don't want to resume, 294 | * and instead intend to use this parser to parse some other document, you must 295 | * call `ts_parser_reset` first. 296 | */ 297 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 298 | private static extern void ts_parser_reset(IntPtr parser); 299 | 300 | /** 301 | * Set the maximum duration in microseconds that parsing should be allowed to 302 | * take before halting. 303 | * 304 | * If parsing takes longer than this, it will halt early, returning NULL. 305 | * See `ts_parser_parse` for more information. 306 | */ 307 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 308 | private static extern void ts_parser_set_timeout_micros(IntPtr parser, ulong timeout); 309 | 310 | /** 311 | * Get the duration in microseconds that parsing is allowed to take. 312 | */ 313 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 314 | private static extern ulong ts_parser_timeout_micros(IntPtr parser); 315 | 316 | /** 317 | * Set the parser's current cancellation flag pointer. 318 | * 319 | * If a non-null pointer is assigned, then the parser will periodically read 320 | * from this pointer during parsing. If it reads a non-zero value, it will 321 | * halt early, returning NULL. See `ts_parser_parse` for more information. 322 | */ 323 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 324 | private static extern void ts_parser_set_cancellation_flag(IntPtr parser, ref IntPtr flag); 325 | 326 | /** 327 | * Get the parser's current cancellation flag pointer. 328 | */ 329 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 330 | private static extern IntPtr ts_parser_cancellation_flag(IntPtr parser); 331 | 332 | /** 333 | * Set the logger that a parser should use during parsing. 334 | * 335 | * The parser does not take ownership over the logger payload. If a logger was 336 | * previously assigned, the caller is responsible for releasing any memory 337 | * owned by the previous logger. 338 | */ 339 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 340 | private static extern void ts_parser_set_logger(IntPtr parser, _TSLoggerData logger); 341 | #endregion 342 | } 343 | 344 | /******************/ 345 | /* Section - Tree */ 346 | /******************/ 347 | 348 | public sealed class TSTree : IDisposable 349 | { 350 | internal IntPtr Ptr { get; private set; } 351 | 352 | public TSTree(IntPtr ptr) 353 | { 354 | Ptr = ptr; 355 | } 356 | 357 | public void Dispose() 358 | { 359 | if (Ptr != IntPtr.Zero) { 360 | ts_tree_delete(Ptr); 361 | Ptr = IntPtr.Zero; 362 | } 363 | } 364 | 365 | public TSTree copy() { 366 | var ptr = ts_tree_copy(Ptr); 367 | return ptr != IntPtr.Zero ? new TSTree(ptr) : null; 368 | } 369 | public TSNode root_node() { return ts_tree_root_node(Ptr); } 370 | public TSNode root_node_with_offset(uint offsetBytes, TSPoint offsetPoint) { return ts_tree_root_node_with_offset(Ptr, offsetBytes, offsetPoint); } 371 | public TSLanguage language() { 372 | var ptr = ts_tree_language(Ptr); 373 | return ptr != IntPtr.Zero ? new TSLanguage(ptr) : null; 374 | } 375 | public void edit(TSInputEdit edit) { ts_tree_edit(Ptr, ref edit); } 376 | #region PInvoke 377 | /** 378 | * Create a shallow copy of the syntax tree. This is very fast. 379 | * 380 | * You need to copy a syntax tree in order to use it on more than one thread at 381 | * a time, as syntax trees are not thread safe. 382 | */ 383 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 384 | private static extern IntPtr ts_tree_copy(IntPtr tree); 385 | 386 | /** 387 | * Delete the syntax tree, freeing all of the memory that it used. 388 | */ 389 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 390 | private static extern void ts_tree_delete(IntPtr tree); 391 | 392 | /** 393 | * Get the root node of the syntax tree. 394 | */ 395 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 396 | private static extern TSNode ts_tree_root_node(IntPtr tree); 397 | 398 | /** 399 | * Get the root node of the syntax tree, but with its position 400 | * shifted forward by the given offset. 401 | */ 402 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 403 | private static extern TSNode ts_tree_root_node_with_offset(IntPtr tree, uint offsetBytes, TSPoint offsetPoint); 404 | 405 | /** 406 | * Get the language that was used to parse the syntax tree. 407 | */ 408 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 409 | private static extern IntPtr ts_tree_language(IntPtr tree); 410 | 411 | /** 412 | * Get the array of included ranges that was used to parse the syntax tree. 413 | * 414 | * The returned pointer must be freed by the caller. 415 | */ 416 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 417 | private static extern IntPtr ts_tree_included_ranges(IntPtr tree, out uint length); 418 | 419 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 420 | private static extern void ts_tree_included_ranges_free(IntPtr ranges); 421 | 422 | /** 423 | * Edit the syntax tree to keep it in sync with source code that has been 424 | * edited. 425 | * 426 | * You must describe the edit both in terms of byte offsets and in terms of 427 | * (row, column) coordinates. 428 | */ 429 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 430 | private static extern void ts_tree_edit(IntPtr tree, ref TSInputEdit edit); 431 | 432 | /** 433 | * Compare an old edited syntax tree to a new syntax tree representing the same 434 | * document, returning an array of ranges whose syntactic structure has changed. 435 | * 436 | * For this to work correctly, the old syntax tree must have been edited such 437 | * that its ranges match up to the new tree. Generally, you'll want to call 438 | * this function right after calling one of the `ts_parser_parse` functions. 439 | * You need to pass the old tree that was passed to parse, as well as the new 440 | * tree that was returned from that function. 441 | * 442 | * The returned array is allocated using `malloc` and the caller is responsible 443 | * for freeing it using `free`. The length of the array will be written to the 444 | * given `length` pointer. 445 | */ 446 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 447 | private static extern IntPtr ts_tree_get_changed_ranges(IntPtr old_tree, IntPtr new_tree, out uint length); 448 | #endregion 449 | } 450 | 451 | /******************/ 452 | /* Section - Node */ 453 | /******************/ 454 | [StructLayout(LayoutKind.Sequential)] 455 | public struct TSNode 456 | { 457 | private uint context0; 458 | private uint context1; 459 | private uint context2; 460 | private uint context3; 461 | public IntPtr id; 462 | private IntPtr tree; 463 | 464 | public void clear() { id = IntPtr.Zero; tree = IntPtr.Zero; } 465 | public bool is_zero() { return (id == IntPtr.Zero && tree == IntPtr.Zero); } 466 | public string type() { return Marshal.PtrToStringAnsi(ts_node_type(this)); } 467 | public string type(TSLanguage lang) { return lang.symbol_name(symbol());} 468 | public ushort symbol() { return ts_node_symbol(this); } 469 | public uint start_offset() { return ts_node_start_byte(this) / sizeof(ushort); } 470 | public TSPoint start_point() { var pt = ts_node_start_point(this); return new TSPoint(pt.row, pt.column / sizeof(ushort)); } 471 | public uint end_offset() { return ts_node_end_byte(this) / sizeof(ushort); } 472 | public TSPoint end_point() { var pt = ts_node_end_point(this); return new TSPoint(pt.row, pt.column / sizeof(ushort)); } 473 | public string to_string() { var dat = ts_node_string(this); var str = Marshal.PtrToStringAnsi(dat); ts_node_string_free(dat); return str; } 474 | public bool is_null() { return ts_node_is_null(this); } 475 | public bool is_named() { return ts_node_is_named(this); } 476 | public bool is_missing() { return ts_node_is_missing(this); } 477 | public bool is_extra() { return ts_node_is_extra(this); } 478 | public bool has_changes() { return ts_node_has_changes(this); } 479 | public bool has_error() { return ts_node_has_error(this); } 480 | public TSNode parent() { return ts_node_parent(this); } 481 | public TSNode child(uint index) { return ts_node_child(this, index); } 482 | public IntPtr field_name_for_child(uint index) { return ts_node_field_name_for_child(this, index); } 483 | public uint child_count() { return ts_node_child_count(this); } 484 | public TSNode named_child(uint index) { return ts_node_named_child(this, index); } 485 | public uint named_child_count() { return ts_node_named_child_count(this); } 486 | public TSNode child_by_field_name(string field_name) { return ts_node_child_by_field_name(this, field_name, (uint)field_name.Length); } 487 | public TSNode child_by_field_id(ushort fieldId) { return ts_node_child_by_field_id(this, fieldId); } 488 | public TSNode next_sibling() { return ts_node_next_sibling(this); } 489 | public TSNode prev_sibling() { return ts_node_prev_sibling(this); } 490 | public TSNode next_named_sibling() { return ts_node_next_named_sibling(this); } 491 | public TSNode prev_named_sibling() { return ts_node_prev_named_sibling(this); } 492 | public TSNode first_child_for_offset(uint offset) { return ts_node_first_child_for_byte(this, offset * sizeof(ushort)); } 493 | public TSNode first_named_child_for_offset(uint offset) { return ts_node_first_named_child_for_byte(this, offset * sizeof(ushort)); } 494 | public TSNode descendant_for_offset_range(uint start, uint end) { return ts_node_descendant_for_byte_range(this, start * sizeof(ushort), end * sizeof(ushort)); } 495 | public TSNode descendant_for_point_range(TSPoint start, TSPoint end) { return ts_node_descendant_for_point_range(this, start, end); } 496 | public TSNode named_descendant_for_offset_range(uint start, uint end) { return ts_node_named_descendant_for_byte_range(this, start * sizeof(ushort), end * sizeof(ushort)); } 497 | public TSNode named_descendant_for_point_range(TSPoint start, TSPoint end) { return ts_node_named_descendant_for_point_range(this, start, end); } 498 | public bool eq(TSNode other) { return ts_node_eq(this, other); } 499 | 500 | public string text(string data) { 501 | uint beg = start_offset(); 502 | uint end = end_offset(); 503 | return data.Substring((int)beg, (int)(end - beg)); 504 | } 505 | 506 | #region PInvoke 507 | /** 508 | * Get the node's type as a null-terminated string. 509 | */ 510 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 511 | private static extern IntPtr ts_node_type(TSNode node); 512 | 513 | /** 514 | * Get the node's type as a numerical id. 515 | */ 516 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 517 | private static extern ushort ts_node_symbol(TSNode node); 518 | 519 | /** 520 | * Get the node's start byte. 521 | */ 522 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 523 | private static extern uint ts_node_start_byte(TSNode node); 524 | 525 | /** 526 | * Get the node's start position in terms of rows and columns. 527 | */ 528 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 529 | private static extern TSPoint ts_node_start_point(TSNode node); 530 | 531 | /** 532 | * Get the node's end byte. 533 | */ 534 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 535 | private static extern uint ts_node_end_byte(TSNode node); 536 | 537 | /** 538 | * Get the node's end position in terms of rows and columns. 539 | */ 540 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 541 | private static extern TSPoint ts_node_end_point(TSNode node); 542 | 543 | /** 544 | * Get an S-expression representing the node as a string. 545 | * 546 | * This string is allocated with `malloc` and the caller is responsible for 547 | * freeing it using `free`. 548 | */ 549 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 550 | private static extern IntPtr ts_node_string(TSNode node); 551 | 552 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 553 | private static extern void ts_node_string_free(IntPtr str); 554 | 555 | /** 556 | * Check if the node is null. Functions like `ts_node_child` and 557 | * `ts_node_next_sibling` will return a null node to indicate that no such node 558 | * was found. 559 | */ 560 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 561 | private static extern bool ts_node_is_null(TSNode node); 562 | 563 | /** 564 | * Check if the node is *named*. Named nodes correspond to named rules in the 565 | * grammar, whereas *anonymous* nodes correspond to string literals in the 566 | * grammar. 567 | */ 568 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 569 | private static extern bool ts_node_is_named(TSNode node); 570 | 571 | /** 572 | * Check if the node is *missing*. Missing nodes are inserted by the parser in 573 | * order to recover from certain kinds of syntax errors. 574 | */ 575 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 576 | private static extern bool ts_node_is_missing(TSNode node); 577 | 578 | /** 579 | * Check if the node is *extra*. Extra nodes represent things like comments, 580 | * which are not required the grammar, but can appear anywhere. 581 | */ 582 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 583 | private static extern bool ts_node_is_extra(TSNode node); 584 | 585 | /** 586 | * Check if a syntax node has been edited. 587 | */ 588 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 589 | private static extern bool ts_node_has_changes(TSNode node); 590 | 591 | /** 592 | * Check if the node is a syntax error or contains any syntax errors. 593 | */ 594 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 595 | private static extern bool ts_node_has_error(TSNode node); 596 | 597 | /** 598 | * Get the node's immediate parent. 599 | */ 600 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 601 | private static extern TSNode ts_node_parent(TSNode node); 602 | 603 | /** 604 | * Get the node's child at the given index, where zero represents the first 605 | * child. 606 | */ 607 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 608 | private static extern TSNode ts_node_child(TSNode node, uint index); 609 | 610 | /** 611 | * Get the field name for node's child at the given index, where zero represents 612 | * the first child. Returns NULL, if no field is found. 613 | */ 614 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 615 | private static extern IntPtr ts_node_field_name_for_child(TSNode node, uint index); 616 | 617 | /** 618 | * Get the node's number of children. 619 | */ 620 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 621 | private static extern uint ts_node_child_count(TSNode node); 622 | 623 | /** 624 | * Get the node's number of *named* children. 625 | * 626 | * See also `ts_node_is_named`. 627 | */ 628 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 629 | private static extern TSNode ts_node_named_child(TSNode node, uint index); 630 | 631 | /** 632 | * Get the node's number of *named* children. 633 | * 634 | * See also `ts_node_is_named`. 635 | */ 636 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 637 | private static extern uint ts_node_named_child_count(TSNode node); 638 | 639 | /** 640 | * Get the node's child with the given numerical field id. 641 | * 642 | * You can convert a field name to an id using the 643 | * `ts_language_field_id_for_name` function. 644 | */ 645 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 646 | private static extern TSNode ts_node_child_by_field_name(TSNode self, [MarshalAs(UnmanagedType.LPUTF8Str)] string field_name, uint field_name_length); 647 | 648 | /** 649 | * Get the node's child with the given numerical field id. 650 | * 651 | * You can convert a field name to an id using the 652 | * `ts_language_field_id_for_name` function. 653 | */ 654 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 655 | private static extern TSNode ts_node_child_by_field_id(TSNode self, ushort fieldId); 656 | 657 | /** 658 | * Get the node's next / previous sibling. 659 | */ 660 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 661 | private static extern TSNode ts_node_next_sibling(TSNode self); 662 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 663 | private static extern TSNode ts_node_prev_sibling(TSNode self); 664 | 665 | /** 666 | * Get the node's next / previous *named* sibling. 667 | */ 668 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 669 | private static extern TSNode ts_node_next_named_sibling(TSNode self); 670 | 671 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 672 | private static extern TSNode ts_node_prev_named_sibling(TSNode self); 673 | 674 | /** 675 | * Get the node's first child that extends beyond the given byte offset. 676 | */ 677 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 678 | private static extern TSNode ts_node_first_child_for_byte(TSNode self, uint byteOffset); 679 | 680 | /** 681 | * Get the node's first named child that extends beyond the given byte offset. 682 | */ 683 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 684 | private static extern TSNode ts_node_first_named_child_for_byte(TSNode self, uint byteOffset); 685 | 686 | /** 687 | * Get the smallest node within this node that spans the given range of bytes 688 | * or (row, column) positions. 689 | */ 690 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 691 | private static extern TSNode ts_node_descendant_for_byte_range(TSNode self, uint startByte, uint endByte); 692 | 693 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 694 | private static extern TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint startPoint, TSPoint endPoint); 695 | 696 | /** 697 | * Get the smallest named node within this node that spans the given range of 698 | * bytes or (row, column) positions. 699 | */ 700 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 701 | private static extern TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint startByte, uint endByte); 702 | 703 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 704 | private static extern TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint startPoint, TSPoint endPoint); 705 | 706 | /** 707 | * Check if two nodes are identical. 708 | */ 709 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 710 | private static extern bool ts_node_eq(TSNode node1, TSNode node2); 711 | #endregion 712 | } 713 | 714 | /************************/ 715 | /* Section - TreeCursor */ 716 | /************************/ 717 | 718 | public sealed class TSCursor : IDisposable 719 | { 720 | [StructLayout(LayoutKind.Sequential)] 721 | public struct TSTreeCursor 722 | { 723 | private IntPtr Tree; 724 | private IntPtr Id; 725 | private uint Context0; 726 | private uint Context1; 727 | } 728 | 729 | 730 | private IntPtr Ptr; 731 | private TSTreeCursor cursor; 732 | public TSLanguage lang { get; private set;} 733 | 734 | public TSCursor(TSTreeCursor cursor, TSLanguage lang) 735 | { 736 | this.cursor = cursor; 737 | this.lang = lang; 738 | Ptr = new IntPtr(1); 739 | } 740 | 741 | public TSCursor(TSNode node, TSLanguage lang) 742 | { 743 | this.cursor = ts_tree_cursor_new(node); 744 | this.lang = lang; 745 | Ptr = new IntPtr(1); 746 | } 747 | 748 | public void Dispose() 749 | { 750 | if (Ptr != IntPtr.Zero) { 751 | ts_tree_cursor_delete(ref cursor); 752 | Ptr = IntPtr.Zero; 753 | } 754 | } 755 | 756 | public void reset(TSNode node) { ts_tree_cursor_reset(ref cursor, node); } 757 | public TSNode current_node() { return ts_tree_cursor_current_node(ref cursor); } 758 | public string current_field() { return lang.fields[current_field_id()]; } 759 | public string current_symbol() { 760 | ushort symbol = ts_tree_cursor_current_node(ref cursor).symbol(); 761 | return (symbol != UInt16.MaxValue) ? lang.symbols[symbol] : "ERROR"; 762 | } 763 | public ushort current_field_id() { return ts_tree_cursor_current_field_id(ref cursor); } 764 | public bool goto_parent() { return ts_tree_cursor_goto_parent(ref cursor); } 765 | public bool goto_next_sibling() { return ts_tree_cursor_goto_next_sibling(ref cursor); } 766 | public bool goto_first_child() { return ts_tree_cursor_goto_first_child(ref cursor); } 767 | public long goto_first_child_for_offset(uint offset) { return ts_tree_cursor_goto_first_child_for_byte(ref cursor, offset * sizeof(ushort)); } 768 | public long goto_first_child_for_point(TSPoint point) { return ts_tree_cursor_goto_first_child_for_point(ref cursor, point); } 769 | public TSCursor copy() { return new TSCursor(ts_tree_cursor_copy(ref cursor), lang); } 770 | 771 | #region PInvoke 772 | /** 773 | * Create a new tree cursor starting from the given node. 774 | * 775 | * A tree cursor allows you to walk a syntax tree more efficiently than is 776 | * possible using the `TSNode` functions. It is a mutable object that is always 777 | * on a certain syntax node, and can be moved imperatively to different nodes. 778 | */ 779 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 780 | private static extern TSTreeCursor ts_tree_cursor_new(TSNode node); 781 | 782 | /** 783 | * Delete a tree cursor, freeing all of the memory that it used. 784 | */ 785 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 786 | private static extern void ts_tree_cursor_delete(ref TSTreeCursor cursor); 787 | 788 | /** 789 | * Re-initialize a tree cursor to start at a different node. 790 | */ 791 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 792 | private static extern void ts_tree_cursor_reset(ref TSTreeCursor cursor, TSNode node); 793 | 794 | /** 795 | * Get the tree cursor's current node. 796 | */ 797 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 798 | private static extern TSNode ts_tree_cursor_current_node(ref TSTreeCursor cursor); 799 | 800 | /** 801 | * Get the field name of the tree cursor's current node. 802 | * 803 | * This returns `NULL` if the current node doesn't have a field. 804 | * See also `ts_node_child_by_field_name`. 805 | */ 806 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 807 | private static extern IntPtr ts_tree_cursor_current_field_name(ref TSTreeCursor cursor); 808 | 809 | /** 810 | * Get the field id of the tree cursor's current node. 811 | * 812 | * This returns zero if the current node doesn't have a field. 813 | * See also `ts_node_child_by_field_id`, `ts_language_field_id_for_name`. 814 | */ 815 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 816 | private static extern ushort ts_tree_cursor_current_field_id(ref TSTreeCursor cursor); 817 | 818 | /** 819 | * Move the cursor to the parent of its current node. 820 | * 821 | * This returns `true` if the cursor successfully moved, and returns `false` 822 | * if there was no parent node (the cursor was already on the root node). 823 | */ 824 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 825 | private static extern bool ts_tree_cursor_goto_parent(ref TSTreeCursor cursor); 826 | 827 | /** 828 | * Move the cursor to the next sibling of its current node. 829 | * 830 | * This returns `true` if the cursor successfully moved, and returns `false` 831 | * if there was no next sibling node. 832 | */ 833 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 834 | private static extern bool ts_tree_cursor_goto_next_sibling(ref TSTreeCursor cursor); 835 | 836 | /** 837 | * Move the cursor to the first child of its current node. 838 | * 839 | * This returns `true` if the cursor successfully moved, and returns `false` 840 | * if there were no children. 841 | */ 842 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 843 | private static extern bool ts_tree_cursor_goto_first_child(ref TSTreeCursor cursor); 844 | 845 | /** 846 | * Move the cursor to the first child of its current node that extends beyond 847 | * the given byte offset or point. 848 | * 849 | * This returns the index of the child node if one was found, and returns -1 850 | * if no such child was found. 851 | */ 852 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 853 | private static extern long ts_tree_cursor_goto_first_child_for_byte(ref TSTreeCursor cursor, uint byteOffset); 854 | 855 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 856 | private static extern long ts_tree_cursor_goto_first_child_for_point(ref TSTreeCursor cursor, TSPoint point); 857 | 858 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 859 | private static extern TSTreeCursor ts_tree_cursor_copy(ref TSTreeCursor cursor); 860 | #endregion 861 | } 862 | 863 | /*******************/ 864 | /* Section - Query */ 865 | /*******************/ 866 | 867 | public sealed class TSQuery : IDisposable 868 | { 869 | internal IntPtr Ptr { get; private set; } 870 | 871 | public TSQuery(IntPtr ptr) 872 | { 873 | Ptr = ptr; 874 | } 875 | 876 | public void Dispose() 877 | { 878 | if (Ptr != IntPtr.Zero) { 879 | ts_query_delete(Ptr); 880 | Ptr = IntPtr.Zero; 881 | } 882 | } 883 | 884 | public uint pattern_count() { return ts_query_pattern_count(Ptr); } 885 | public uint capture_count() { return ts_query_capture_count(Ptr); } 886 | public uint string_count() { return ts_query_string_count(Ptr); } 887 | public uint start_offset_for_pattern(uint patternIndex) { return ts_query_start_byte_for_pattern(Ptr, patternIndex) / sizeof(ushort); } 888 | public IntPtr predicates_for_pattern(uint patternIndex, out uint length) { return ts_query_predicates_for_pattern(Ptr, patternIndex, out length); } 889 | public bool is_pattern_rooted(uint patternIndex) { return ts_query_is_pattern_rooted(Ptr, patternIndex); } 890 | public bool is_pattern_non_local(uint patternIndex) { return ts_query_is_pattern_non_local(Ptr, patternIndex); } 891 | public bool is_pattern_guaranteed_at_offset(uint offset) { return ts_query_is_pattern_guaranteed_at_step(Ptr, offset / sizeof(ushort)); } 892 | public string capture_name_for_id(uint id, out uint length) { return Marshal.PtrToStringAnsi(ts_query_capture_name_for_id(Ptr, id, out length)); } 893 | public TSQuantifier capture_quantifier_for_id(uint patternId, uint captureId) { return ts_query_capture_quantifier_for_id(Ptr, patternId, captureId); } 894 | public string string_value_for_id(uint id, out uint length) { return Marshal.PtrToStringAnsi(ts_query_string_value_for_id(Ptr, id, out length)); } 895 | public void disable_capture(string captureName) { ts_query_disable_capture(Ptr, captureName, (uint)captureName.Length); } 896 | public void disable_pattern(uint patternIndex) { ts_query_disable_pattern(Ptr, patternIndex); } 897 | 898 | #region PInvoke 899 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 900 | private static extern void ts_query_delete(IntPtr query); 901 | 902 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 903 | private static extern uint ts_query_pattern_count(IntPtr query); 904 | 905 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 906 | private static extern uint ts_query_capture_count(IntPtr query); 907 | 908 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 909 | private static extern uint ts_query_string_count(IntPtr query); 910 | 911 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 912 | private static extern uint ts_query_start_byte_for_pattern(IntPtr query, uint patternIndex); 913 | 914 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 915 | private static extern IntPtr ts_query_predicates_for_pattern(IntPtr query, uint patternIndex, out uint length); 916 | 917 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 918 | private static extern bool ts_query_is_pattern_rooted(IntPtr query, uint patternIndex); 919 | 920 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 921 | private static extern bool ts_query_is_pattern_non_local(IntPtr query, uint patternIndex); 922 | 923 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 924 | private static extern bool ts_query_is_pattern_guaranteed_at_step(IntPtr query, uint byteOffset); 925 | 926 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 927 | private static extern IntPtr ts_query_capture_name_for_id(IntPtr query, uint id, out uint length); 928 | 929 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 930 | private static extern TSQuantifier ts_query_capture_quantifier_for_id(IntPtr query, uint patternId, uint captureId); 931 | 932 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 933 | private static extern IntPtr ts_query_string_value_for_id(IntPtr query, uint id, out uint length); 934 | 935 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 936 | private static extern void ts_query_disable_capture(IntPtr query, [MarshalAs(UnmanagedType.LPUTF8Str)] string captureName, uint captureNameLength); 937 | 938 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 939 | private static extern void ts_query_disable_pattern(IntPtr query, uint patternIndex); 940 | #endregion 941 | } 942 | 943 | public sealed class TSQueryCursor : IDisposable 944 | { 945 | private IntPtr Ptr { get; set; } 946 | 947 | private TSQueryCursor(IntPtr ptr) 948 | { 949 | Ptr = ptr; 950 | } 951 | 952 | public TSQueryCursor() 953 | { 954 | Ptr = ts_query_cursor_new(); 955 | } 956 | 957 | public void Dispose() 958 | { 959 | if (Ptr != IntPtr.Zero) { 960 | ts_query_cursor_delete(Ptr); 961 | Ptr = IntPtr.Zero; 962 | } 963 | } 964 | 965 | public void exec(TSQuery query, TSNode node) { ts_query_cursor_exec(Ptr, query.Ptr, node); } 966 | public bool did_exceed_match_limit() { return ts_query_cursor_did_exceed_match_limit(Ptr); } 967 | public uint match_limit() { return ts_query_cursor_match_limit(Ptr); } 968 | public void set_match_limit(uint limit) { ts_query_cursor_set_match_limit(Ptr, limit); } 969 | public void set_range(uint start, uint end) { ts_query_cursor_set_byte_range(Ptr, start * sizeof(ushort), end * sizeof(ushort)); } 970 | public void set_point_range(TSPoint start,TSPoint end) { ts_query_cursor_set_point_range(Ptr, start, end); } 971 | public bool next_match(out TSQueryMatch match, out TSQueryCapture[] captures) { 972 | captures = null; 973 | if (ts_query_cursor_next_match(Ptr, out match)) { 974 | if (match.capture_count > 0) { 975 | captures = new TSQueryCapture [match.capture_count]; 976 | for (ushort i = 0; i < match.capture_count; i++) { 977 | var intPtr = match.captures + Marshal.SizeOf(typeof(TSQueryCapture)) * i; 978 | captures[i] = Marshal.PtrToStructure(intPtr); 979 | } 980 | } 981 | return true; 982 | } 983 | return false; 984 | } 985 | public void remove_match(uint id) { ts_query_cursor_remove_match(Ptr, id); } 986 | public bool next_capture(out TSQueryMatch match,out uint index) { return ts_query_cursor_next_capture(Ptr, out match, out index); } 987 | 988 | #region PInvoke 989 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 990 | private static extern IntPtr ts_query_cursor_new(); 991 | 992 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 993 | private static extern void ts_query_cursor_delete(IntPtr cursor); 994 | 995 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 996 | private static extern void ts_query_cursor_exec(IntPtr cursor,IntPtr query,TSNode node); 997 | 998 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 999 | private static extern bool ts_query_cursor_did_exceed_match_limit(IntPtr cursor); 1000 | 1001 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1002 | private static extern uint ts_query_cursor_match_limit(IntPtr cursor); 1003 | 1004 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1005 | private static extern void ts_query_cursor_set_match_limit(IntPtr cursor, uint limit); 1006 | 1007 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1008 | private static extern void ts_query_cursor_set_byte_range(IntPtr cursor,uint start_byte,uint end_byte); 1009 | 1010 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1011 | private static extern void ts_query_cursor_set_point_range(IntPtr cursor,TSPoint start_point,TSPoint end_point); 1012 | 1013 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1014 | private static extern bool ts_query_cursor_next_match(IntPtr cursor,out TSQueryMatch match); 1015 | 1016 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1017 | private static extern void ts_query_cursor_remove_match(IntPtr cursor,uint id); 1018 | 1019 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1020 | private static extern bool ts_query_cursor_next_capture(IntPtr cursor,out TSQueryMatch match,out uint capture_index); 1021 | #endregion 1022 | } 1023 | 1024 | 1025 | /**********************/ 1026 | /* Section - Language */ 1027 | /**********************/ 1028 | 1029 | public sealed class TSLanguage : IDisposable 1030 | { 1031 | internal IntPtr Ptr { get; private set; } 1032 | 1033 | public TSLanguage(IntPtr ptr) 1034 | { 1035 | Ptr = ptr; 1036 | 1037 | symbols = new String[symbol_count()+1]; 1038 | for (ushort i = 0; i < symbols.Length; i++) { 1039 | symbols[i] = Marshal.PtrToStringAnsi(ts_language_symbol_name(Ptr, i)); 1040 | } 1041 | 1042 | fields = new String[field_count()+1]; 1043 | fieldIds = new Dictionary((int)field_count()+1); 1044 | 1045 | for (ushort i = 0; i < fields.Length; i++) { 1046 | fields[i] = Marshal.PtrToStringAnsi(ts_language_field_name_for_id(Ptr, i)); 1047 | if (fields[i] != null) { 1048 | fieldIds.Add(fields[i], i); // TODO: check for dupes, and throw if found 1049 | } 1050 | } 1051 | 1052 | #if false 1053 | for (int i = 0; i < symbols.Length; i++) { 1054 | for (int j = 0; j < i; j++) { 1055 | Debug.Assert(symbols[i] != symbols[j]); 1056 | } 1057 | } 1058 | 1059 | for (int i = 0; i < fields.Length; i++) { 1060 | for (int j = 0; j < i; j++) { 1061 | Debug.Assert(fields[i] != fields[j]); 1062 | } 1063 | } 1064 | #endif 1065 | } 1066 | 1067 | public void Dispose() 1068 | { 1069 | if (Ptr != IntPtr.Zero) { 1070 | //ts_query_cursor_delete(Ptr); 1071 | Ptr = IntPtr.Zero; 1072 | } 1073 | } 1074 | 1075 | public TSQuery query_new(string source, out uint error_offset, out TSQueryError error_type) { 1076 | var ptr = ts_query_new(Ptr, source, (uint)source.Length, out error_offset, out error_type); 1077 | return ptr != IntPtr.Zero ? new TSQuery(ptr) : null; 1078 | } 1079 | 1080 | public String[] symbols; 1081 | public String[] fields; 1082 | public Dictionary fieldIds; 1083 | 1084 | public uint symbol_count() { return ts_language_symbol_count(Ptr); } 1085 | public string symbol_name(ushort symbol) { return (symbol != UInt16.MaxValue) ? symbols[symbol] : "ERROR"; } 1086 | public ushort symbol_for_name(string str, bool is_named) { return ts_language_symbol_for_name(Ptr, str, (uint)str.Length, is_named); } 1087 | public uint field_count() { return ts_language_field_count(Ptr); } 1088 | public string field_name_for_id(ushort fieldId) { return fields[fieldId]; } 1089 | public ushort field_id_for_name(string str) { return ts_language_field_id_for_name(Ptr, str, (uint)str.Length); } 1090 | public TSSymbolType symbol_type(ushort symbol) { return ts_language_symbol_type(Ptr, symbol); } 1091 | 1092 | #region PInvoke 1093 | /** 1094 | * Create a new query from a string containing one or more S-expression 1095 | * patterns. The query is associated with a particular language, and can 1096 | * only be run on syntax nodes parsed with that language. 1097 | * 1098 | * If all of the given patterns are valid, this returns a `TSQuery`. 1099 | * If a pattern is invalid, this returns `NULL`, and provides two pieces 1100 | * of information about the problem: 1101 | * 1. The byte offset of the error is written to the `error_offset` parameter. 1102 | * 2. The type of error is written to the `error_type` parameter. 1103 | */ 1104 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1105 | private static extern IntPtr ts_query_new(IntPtr language, [MarshalAs(UnmanagedType.LPUTF8Str)] string source, uint source_len, out uint error_offset, out TSQueryError error_type); 1106 | 1107 | /** 1108 | * Get the number of distinct node types in the language. 1109 | */ 1110 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1111 | private static extern uint ts_language_symbol_count(IntPtr language); 1112 | 1113 | /** 1114 | * Get a node type string for the given numerical id. 1115 | */ 1116 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1117 | private static extern IntPtr ts_language_symbol_name(IntPtr language, ushort symbol); 1118 | 1119 | /** 1120 | * Get the numerical id for the given node type string. 1121 | */ 1122 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1123 | private static extern ushort ts_language_symbol_for_name(IntPtr language, [MarshalAs(UnmanagedType.LPUTF8Str)] string str, uint length, bool is_named); 1124 | 1125 | /** 1126 | * Get the number of distinct field names in the language. 1127 | */ 1128 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1129 | private static extern uint ts_language_field_count(IntPtr language); 1130 | 1131 | /** 1132 | * Get the field name string for the given numerical id. 1133 | */ 1134 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1135 | private static extern IntPtr ts_language_field_name_for_id(IntPtr language, ushort fieldId); 1136 | 1137 | /** 1138 | * Get the numerical id for the given field name string. 1139 | */ 1140 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1141 | private static extern ushort ts_language_field_id_for_name(IntPtr language, [MarshalAs(UnmanagedType.LPUTF8Str)] string str, uint length); 1142 | 1143 | /** 1144 | * Check whether the given node type id belongs to named nodes, anonymous nodes, 1145 | * or a hidden nodes. 1146 | * 1147 | * See also `ts_node_is_named`. Hidden nodes are never returned from the API. 1148 | */ 1149 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1150 | private static extern TSSymbolType ts_language_symbol_type(IntPtr language, ushort symbol); 1151 | 1152 | /** 1153 | * Get the ABI version number for this language. This version number is used 1154 | * to ensure that languages were generated by a compatible version of 1155 | * Tree-sitter. 1156 | * 1157 | * See also `ts_parser_set_language`. 1158 | */ 1159 | [DllImport("tree-sitter.dll", CallingConvention = CallingConvention.Cdecl)] 1160 | private static extern uint ts_language_version(IntPtr language); 1161 | #endregion 1162 | } 1163 | } 1164 | -------------------------------------------------------------------------------- /tests/test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using GitHub.TreeSitter; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace TreeSitterTest 8 | { 9 | // A class to test the TreeSitter methods 10 | public class TestTreeSitterCPP 11 | { 12 | public static TSLanguage lang = new TSLanguage(tree_sitter_cpp()); 13 | 14 | [DllImport("tree-sitter-cpp.dll", CallingConvention = CallingConvention.Cdecl)] 15 | private static extern IntPtr tree_sitter_cpp(); 16 | 17 | public static void PostOrderTraverse(string path, String filetext, TSCursor cursor) 18 | { 19 | var rootCursor = cursor; 20 | 21 | for (;;) { 22 | int so = (int)cursor.current_node().start_offset(); 23 | int eo = (int)cursor.current_node().end_offset(); 24 | int sl = (int)cursor.current_node().start_point().row + 1; 25 | var field = cursor.current_field(); 26 | var type = cursor.current_symbol(); 27 | bool hasChildren = cursor.goto_first_child(); 28 | 29 | var span = filetext.AsSpan(so, eo - so); 30 | 31 | if (hasChildren) { 32 | continue; 33 | } 34 | 35 | Console.Error.WriteLine("The node type is {0}, symbol is {1}", type, span.ToString()); 36 | 37 | if (cursor.goto_next_sibling()) { 38 | continue; 39 | } 40 | 41 | do { 42 | cursor.goto_parent(); 43 | int so_p = (int)cursor.current_node().start_offset(); 44 | int eo_p = (int)cursor.current_node().end_offset(); 45 | var type_p = cursor.current_symbol(); 46 | var span_p = filetext.AsSpan(so_p, eo_p - so_p); 47 | 48 | Console.Error.WriteLine("The node type is {0}, symbol is {1}", type_p, span_p.ToString()); 49 | 50 | if (rootCursor == cursor) { 51 | Console.Error.WriteLine("done!"); 52 | return; 53 | } 54 | } while (!cursor.goto_next_sibling()); 55 | } 56 | } 57 | 58 | public static bool ParseTree(string path, string filetext, TSParser parser) 59 | { 60 | parser.set_language(TestTreeSitterCPP.lang); 61 | 62 | using var tree = parser.parse_string(null, filetext); 63 | if (tree == null) { 64 | return false; 65 | } 66 | 67 | using var cursor = new TSCursor(tree.root_node(), lang); 68 | 69 | PostOrderTraverse(path, filetext, cursor); 70 | return true; 71 | } 72 | 73 | public static bool TraverseTree(string filename, string filetext) 74 | { 75 | using var parser = new TSParser(); 76 | return ParseTree(filename, filetext, parser); 77 | } 78 | 79 | public static bool PrintTree(List paths) 80 | { 81 | bool good = true; 82 | foreach (var path in paths) { 83 | var filetext = File.ReadAllText(path); 84 | if (!TraverseTree(path, filetext)) { 85 | good = false; 86 | } 87 | } 88 | return good; 89 | } 90 | 91 | public static void PrintErrorAt(string path, string error, params Object[] args) 92 | { 93 | Console.ForegroundColor = ConsoleColor.Red; 94 | if (Console.CursorLeft != 0) { 95 | Console.Error.WriteLine(); 96 | } 97 | 98 | Console.Error.WriteLine("{0}(): error {1}", path, String.Format(error, args)); 99 | Console.ForegroundColor = Console.ForegroundColor; 100 | } 101 | 102 | public static List ArgsToPaths(ref int pos, string[] args) 103 | { 104 | if (++pos >= args.Length) { 105 | PrintErrorAt("", "XR0100: No input files to process."); 106 | return null; 107 | } 108 | 109 | var files = new List(); 110 | var used = new HashSet(); 111 | var options = new EnumerationOptions(); 112 | options.RecurseSubdirectories = false; 113 | options.ReturnSpecialDirectories = false; 114 | options.MatchCasing = MatchCasing.CaseInsensitive; 115 | options.MatchType = MatchType.Simple; 116 | options.IgnoreInaccessible = false; 117 | 118 | for (; pos < args.Length; pos++) { 119 | var arg = args[pos]; 120 | 121 | if (arg[0] == '-') { 122 | pos--; 123 | break; 124 | } 125 | 126 | if (Directory.Exists(arg)) { 127 | PrintErrorAt(arg, "XR0101: Path is a directory, not a file spec."); 128 | return null; 129 | } 130 | 131 | string directory = System.IO.Path.GetDirectoryName(arg); 132 | string pattern = System.IO.Path.GetFileName(arg); 133 | if (directory == String.Empty) { 134 | directory = "."; 135 | } 136 | if (directory == null || String.IsNullOrEmpty(pattern)) { 137 | PrintErrorAt(arg, "XR0102: Path is anot a valid file spec."); 138 | return null; 139 | } 140 | 141 | if (!Directory.Exists(directory)) { 142 | PrintErrorAt(directory, "XR0103: Couldn't find direvtory."); 143 | return null; 144 | } 145 | 146 | int cnt = 0; 147 | foreach (var filepath in Directory.EnumerateFiles(directory, pattern, options)) { 148 | cnt++; 149 | if (!used.Contains(filepath)) { 150 | files.Add(filepath); 151 | used.Add(filepath); 152 | } 153 | } 154 | } 155 | 156 | return files; 157 | } 158 | 159 | public static void Main(string[] args) 160 | { 161 | var files = (List)null; 162 | int a = 0; 163 | 164 | // Check if the args have at least two elements and the first one is "-files" 165 | if (args.Length < 2 || args[0] != "-files") 166 | { 167 | Console.WriteLine("Invalid arguments. Please use -files followed by one or more file paths."); 168 | return; 169 | } 170 | 171 | if ((files = ArgsToPaths(ref a, args)) != null) { 172 | PrintTree(files); 173 | } 174 | } 175 | } 176 | } 177 | 178 | 179 | -------------------------------------------------------------------------------- /tree-sitter/Makefile: -------------------------------------------------------------------------------- 1 | ######## 2 | # 3 | # Tree-Sitter Base and Common Language Parsers 4 | # 5 | 6 | CFLAGS=/nologo /FC /Od /Z7 /Gy /diagnostics:column /Itree-sitter/lib/include 7 | LFLAGS=/def:$(@B).def /incremental:no /debug 8 | 9 | BIN=..\bin\debug\net7.0 10 | 11 | DLLS=\ 12 | $(BIN)/tree-sitter.dll \ 13 | $(BIN)/tree-sitter-cpp.dll \ 14 | 15 | all: dirs $(DLLS) 16 | 17 | dirs: 18 | @if not exist tree-sitter\lib\src\alloc.c echo. 19 | @if not exist tree-sitter\lib\src\alloc.c echo *** Error: Missing tree-sitter sources. Did you use --recursive with git clone? 20 | @if not exist tree-sitter\lib\src\alloc.c echo. 21 | @if not exist $(BIN)\nul mkdir $(BIN) 22 | 23 | ######## 24 | # 25 | # Tree-Sitter Base Library 26 | # 27 | $(BIN)/tree-sitter.obj: \ 28 | tree-sitter/lib/src/alloc.c \ 29 | tree-sitter/lib/src/get_changed_ranges.c \ 30 | tree-sitter/lib/src/language.c \ 31 | tree-sitter/lib/src/lexer.c \ 32 | tree-sitter/lib/src/lib.c \ 33 | tree-sitter/lib/src/node.c \ 34 | tree-sitter/lib/src/parser.c \ 35 | tree-sitter/lib/src/query.c \ 36 | tree-sitter/lib/src/stack.c \ 37 | tree-sitter/lib/src/subtree.c \ 38 | tree-sitter/lib/src/tree.c \ 39 | tree-sitter/lib/src/tree_cursor.c 40 | cl $(CFLAGS) /Fo:$@ \ 41 | /Itree-sitter/lib/src /Itree-sitter/lib/src/unicode \ 42 | /c tree-sitter/lib/src/lib.c 43 | 44 | $(BIN)/tree-sitter.dll: $(BIN)/tree-sitter.obj 45 | cl /LD $(CFLAGS) /Fe:$@ $** /link $(LFLAGS) 46 | 47 | 48 | ######## 49 | # 50 | # C++ 51 | # 52 | $(BIN)/tree-sitter-cpp-parser.obj: tree-sitter-cpp/src/parser.c 53 | cl $(CFLAGS) /Fo:$@ /Itree-sitter-cpp/src/include /c $** 54 | 55 | $(BIN)/tree-sitter-cpp-scanner.obj: tree-sitter-cpp/src/scanner.c 56 | cl $(CFLAGS) /Fo:$@ /Itree-sitter-cpp/src/include /c $** 57 | 58 | $(BIN)/tree-sitter-cpp.dll: $(BIN)/tree-sitter-cpp-parser.obj $(BIN)/tree-sitter-cpp-scanner.obj 59 | cl /LD $(CFLAGS) /Fe:$@ $** /link $(LFLAGS) 60 | 61 | ######## 62 | # 63 | # Clean 64 | # 65 | clean: 66 | -del *.obj $(BIN)\*.obj 2>nul 67 | -del $(BIN)\tree-sitter*.dll $(BIN)\tree-sitter*.exp $(BIN)\tree-sitter*.lib $(BIN)\tree-sitter*.pdb 2>nul 68 | -del tree-sitter*.dll tree-sitter*.exp tree-sitter*.lib tree-sitter*.pdb 2>nul 69 | -del $(BIN)\xred.* $(BIN)\test.exe $(BIN)\test.exp $(BIN)\test.pdb $(BIN)\test.lib 2>nul 70 | -del *~ 2>nul 71 | @-echo. 72 | @-echo. 73 | 74 | ######## 75 | # 76 | # 77 | # 78 | 79 | xt: 80 | xred -tree xpdb.cs > xpdb.tree && emacs xpdb.tree 81 | xred -tree vm_devices_net_netvsp_src_lib.rs > lib.tree && emacs lib.tree 82 | xred -tree minkernel_fs_ntfs_create.c > create.tree && emacs create.tree 83 | xred -tree dpx.cpp > dpx.tree && emacs dpx.tree 84 | 85 | # End of File. 86 | -------------------------------------------------------------------------------- /tree-sitter/README.md: -------------------------------------------------------------------------------- 1 | # Update the submodules 2 | 3 | To update the tree-sitter submodules when there is any update on language grammars or tree-sitter tools, you need to run: 4 | ```cmd 5 | git pull 6 | git submodule update --remote 7 | ``` 8 | -------------------------------------------------------------------------------- /tree-sitter/tree-sitter-cpp.def: -------------------------------------------------------------------------------- 1 | LIBRARY TREE-SITTER-CPP 2 | EXPORTS 3 | tree_sitter_cpp 4 | -------------------------------------------------------------------------------- /tree-sitter/tree-sitter.def: -------------------------------------------------------------------------------- 1 | LIBRARY TREE-SITTER 2 | EXPORTS 3 | ts_parser_new 4 | ts_parser_delete 5 | ts_parser_set_language 6 | ts_parser_language 7 | ts_parser_set_included_ranges 8 | ts_parser_included_ranges 9 | ts_parser_parse_string 10 | ts_parser_parse_string_encoding 11 | ts_parser_reset 12 | ts_parser_set_timeout_micros 13 | ts_parser_timeout_micros 14 | ts_parser_set_cancellation_flag 15 | ts_parser_cancellation_flag 16 | ts_tree_copy 17 | ts_tree_delete 18 | ts_tree_root_node 19 | ts_tree_root_node_with_offset 20 | ts_tree_language 21 | ts_tree_included_ranges 22 | ts_tree_get_changed_ranges 23 | ts_node_type 24 | ts_node_symbol 25 | ts_node_start_byte 26 | ts_node_start_point 27 | ts_node_end_byte 28 | ts_node_end_point 29 | ts_node_string 30 | ts_node_is_null 31 | ts_node_is_named 32 | ts_node_is_missing 33 | ts_node_is_extra 34 | ts_node_has_changes 35 | ts_node_has_error 36 | ts_node_parent 37 | ts_node_child 38 | ts_node_field_name_for_child 39 | ts_node_child_count 40 | ts_node_named_child 41 | ts_node_named_child_count 42 | ts_node_child_by_field_name 43 | ts_node_child_by_field_id 44 | ts_node_next_sibling 45 | ts_node_prev_sibling 46 | ts_node_next_named_sibling 47 | ts_node_prev_named_sibling 48 | ts_node_first_child_for_byte 49 | ts_node_first_named_child_for_byte 50 | ts_node_descendant_for_byte_range 51 | ts_node_descendant_for_point_range 52 | ts_node_named_descendant_for_byte_range 53 | ts_node_named_descendant_for_point_range 54 | ts_node_eq 55 | ts_tree_cursor_new 56 | ts_tree_cursor_delete 57 | ts_tree_cursor_reset 58 | ts_tree_cursor_current_node 59 | ts_tree_cursor_current_field_name 60 | ts_tree_cursor_current_field_id 61 | ts_tree_cursor_goto_parent 62 | ts_tree_cursor_goto_next_sibling 63 | ts_tree_cursor_goto_first_child 64 | ts_tree_cursor_goto_first_child_for_byte 65 | ts_tree_cursor_goto_first_child_for_point 66 | ts_tree_cursor_copy 67 | ts_query_new 68 | ts_query_delete 69 | ts_query_pattern_count 70 | ts_query_capture_count 71 | ts_query_string_count 72 | ts_query_start_byte_for_pattern 73 | ts_query_is_pattern_rooted 74 | ts_query_is_pattern_non_local 75 | ts_query_is_pattern_guaranteed_at_step 76 | ts_query_capture_name_for_id 77 | ts_query_capture_quantifier_for_id 78 | ts_query_string_value_for_id 79 | ts_query_disable_capture 80 | ts_query_disable_pattern 81 | ts_query_cursor_new 82 | ts_query_cursor_delete 83 | ts_query_cursor_exec 84 | ts_query_cursor_did_exceed_match_limit 85 | ts_query_cursor_match_limit 86 | ts_query_cursor_set_match_limit 87 | ts_query_cursor_set_byte_range 88 | ts_query_cursor_set_point_range 89 | ts_query_cursor_next_match 90 | ts_query_cursor_remove_match 91 | ts_query_cursor_next_capture 92 | ts_language_symbol_count 93 | ts_language_symbol_name 94 | ts_language_symbol_for_name 95 | ts_language_field_count 96 | ts_language_field_name_for_id 97 | ts_language_field_id_for_name 98 | ts_language_symbol_type 99 | ts_language_version 100 | ts_parser_set_logger 101 | ts_parser_logger 102 | 103 | ts_tree_get_changed_ranges_free = free 104 | ts_node_string_free = free 105 | -------------------------------------------------------------------------------- /tree-sitter/tree-sitter.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {1F2609F5-0FE8-4C78-BBAF-612F429A21D3} 15 | MyProject 16 | Win32Proj 17 | 10.0 18 | 19 | 20 | 21 | Application 22 | true 23 | 24 | 25 | Application 26 | false 27 | 28 | 29 | 30 | 31 | NotUsing 32 | Level3 33 | Disabled 34 | 35 | 36 | Console 37 | 38 | 39 | 40 | 41 | NotUsing 42 | Level3 43 | Full 44 | 45 | 46 | Console 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | --------------------------------------------------------------------------------