web_tree_sitter_sg/
lib.rs

1#![allow(clippy::unused_unit)]
2
3// FIXME: Double check we construct object properties in order.
4
5use core::cell::RefCell;
6use js_sys::{Array, Error, Function, JsString, Object, Promise, Reflect, Uint8Array};
7use wasm_bindgen::{prelude::*, JsCast};
8use wasm_bindgen_futures::JsFuture;
9
10trait JsValueExt {
11    type Value;
12    fn lift_error(self) -> Result<Self::Value, JsError>;
13}
14
15impl<T> JsValueExt for Result<T, JsValue> {
16    type Value = T;
17
18    fn lift_error(self) -> Result<Self::Value, JsError> {
19        self.map_err(|err| {
20            let message = match err.dyn_into::<Error>() {
21                Ok(error) => error.message(),
22                Err(value) => JsString::from(value),
23            };
24            JsError::new(&String::from(message))
25        })
26    }
27}
28
29#[cfg(feature = "node")]
30#[wasm_bindgen]
31extern {
32    #[wasm_bindgen(js_name = "global")]
33    static GLOBAL: Object;
34}
35
36#[cfg(feature = "node")]
37#[wasm_bindgen(module = "web-tree-sitter-wasm-bindgen")]
38extern {
39    fn initialize_tree_sitter() -> Promise;
40}
41
42thread_local! {
43    // Ensure `web-tree-sitter` is only initialized once
44    static TREE_SITTER_INITIALIZED: RefCell<bool> = RefCell::new(false);
45}
46
47pub struct TreeSitter;
48
49impl TreeSitter {
50    #[cfg(feature = "node")]
51    pub async fn init() -> Result<(), JsError> {
52        #![allow(non_snake_case)]
53
54        // Exit early if `web-tree-sitter` is already initialized
55        if TREE_SITTER_INITIALIZED.with(|cell| *cell.borrow()) {
56            return Ok(());
57        }
58
59        JsFuture::from(initialize_tree_sitter()).await.lift_error()?;
60
61        // Set `web-tree-sitter` to initialized
62        TREE_SITTER_INITIALIZED.with(|cell| cell.replace(true));
63
64        Ok(())
65    }
66
67    #[cfg(feature = "web")]
68    pub async fn init() -> Result<(), JsError> {
69        #![allow(non_snake_case)]
70
71        // Exit early if `web-tree-sitter` is already initialized
72        if TREE_SITTER_INITIALIZED.with(|cell| *cell.borrow()) {
73            return Ok(());
74        }
75
76        let scope = &web_sys::window().unwrap_throw();
77
78        let tree_sitter = Reflect::get(&scope, &"TreeSitter".into()).and_then(|property| {
79            if property.is_undefined() {
80                let message = "window.TreeSitter is not defined; load the tree-sitter javascript module first";
81                Err(JsError::new(message).into())
82            } else {
83                Ok(property)
84            }
85        })?;
86
87        // Call `init` from `web-tree-sitter` to initialize emscripten
88        let init = Reflect::get(&tree_sitter, &"init".into())
89            .lift_error()?
90            .unchecked_into::<Function>();
91        JsFuture::from(
92            init.call0(&JsValue::UNDEFINED)
93                .lift_error()?
94                .unchecked_into::<Promise>(),
95        )
96        .await
97        .lift_error()?;
98
99        let Language = Reflect::get(&tree_sitter, &"Language".into()).lift_error()?;
100        let Parser = tree_sitter;
101
102        // Manually define `Parser` and `Language` in a fashion that works with wasm-bindgen
103        Reflect::set(scope, &"Parser".into(), &Parser).lift_error()?;
104        Reflect::set(scope, &"Language".into(), &Language).lift_error()?;
105
106        // Set `web-tree-sitter` to initialized
107        TREE_SITTER_INITIALIZED.with(|cell| cell.replace(true));
108
109        Ok(())
110    }
111
112    fn init_guard() {
113        if !TREE_SITTER_INITIALIZED.with(|cell| *cell.borrow()) {
114            wasm_bindgen::throw_str("TreeSitter::init must be called to initialize the library");
115        }
116    }
117}
118
119#[wasm_bindgen]
120extern {
121    #[derive(Clone, Debug, Eq, PartialEq)]
122    #[wasm_bindgen(extends = Object)]
123    pub type Edit;
124
125    // Instance Properties
126
127    #[wasm_bindgen(method, getter, js_name = newEndIndex)]
128    pub fn new_end_index(this: &Edit) -> u32;
129
130    #[wasm_bindgen(method, getter, js_name = newEndPosition)]
131    pub fn new_end_position(this: &Edit) -> Point;
132
133    #[wasm_bindgen(method, getter, js_name = oldEndIndex)]
134    pub fn old_end_index(this: &Edit) -> u32;
135
136    #[wasm_bindgen(method, getter, js_name = oldEndPosition)]
137    pub fn old_end_position(this: &Edit) -> Point;
138
139    #[wasm_bindgen(method, getter, js_name = startIndex)]
140    pub fn start_index(this: &Edit) -> u32;
141
142    #[wasm_bindgen(method, getter, js_name = startPosition)]
143    pub fn start_position(this: &Edit) -> Point;
144}
145
146impl Edit {
147    pub fn new(
148        start_index: u32,
149        old_end_index: u32,
150        new_end_index: u32,
151        start_position: &Point,
152        old_end_position: &Point,
153        new_end_position: &Point,
154    ) -> Self {
155        let obj = Object::new();
156        Reflect::set(&obj, &"startIndex".into(), &start_index.into()).unwrap();
157        Reflect::set(&obj, &"oldEndIndex".into(), &old_end_index.into()).unwrap();
158        Reflect::set(&obj, &"newEndIndex".into(), &new_end_index.into()).unwrap();
159        Reflect::set(&obj, &"startPosition".into(), &start_position.into()).unwrap();
160        Reflect::set(&obj, &"oldEndPosition".into(), &old_end_position.into()).unwrap();
161        Reflect::set(&obj, &"newEndPosition".into(), &new_end_position.into()).unwrap();
162        JsCast::unchecked_into(obj)
163    }
164}
165
166impl Default for Edit {
167    fn default() -> Self {
168        let start_index = Default::default();
169        let old_end_index = Default::default();
170        let new_end_index = Default::default();
171        let start_position = &Default::default();
172        let old_end_position = &Default::default();
173        let new_end_position = &Default::default();
174        Self::new(
175            start_index,
176            old_end_index,
177            new_end_index,
178            start_position,
179            old_end_position,
180            new_end_position,
181        )
182    }
183}
184
185pub type Input = Function;
186
187pub type InputClosureType = dyn FnMut(u32, Option<Point>, Option<u32>) -> Option<JsString>;
188
189pub type Logger = Function;
190
191pub type LoggerClosureType = dyn FnMut(JsString, LoggerParams, JsString);
192
193#[wasm_bindgen]
194extern {
195    #[derive(Clone, Debug, Eq, PartialEq)]
196    #[wasm_bindgen(extends = Object)]
197    pub type LoggerParams;
198
199    #[wasm_bindgen(method, indexing_getter)]
200    fn get(this: &LoggerParams, key: &JsString) -> JsString;
201
202    #[wasm_bindgen(method, indexing_setter)]
203    fn set(this: &LoggerParams, val: &JsString);
204
205    #[wasm_bindgen(method, indexing_deleter)]
206    fn delete(this: &LoggerParams, val: &JsString);
207}
208
209#[wasm_bindgen]
210extern {
211    #[derive(Clone, Debug, PartialEq)]
212    pub type Language;
213
214    // Static Methods
215
216    #[wasm_bindgen(static_method_of = Language, js_name = load)]
217    fn __load_bytes(bytes: &Uint8Array) -> Promise;
218
219    #[wasm_bindgen(static_method_of = Language, js_name = load)]
220    fn __load_path(path: &str) -> Promise;
221
222    // Instance Properties
223
224    #[wasm_bindgen(method, getter)]
225    pub fn version(this: &Language) -> u32;
226
227    #[wasm_bindgen(method, getter, js_name = fieldCount)]
228    pub fn field_count(this: &Language) -> u16;
229
230    #[wasm_bindgen(method, getter, js_name = nodeTypeCount)]
231    pub fn node_kind_count(this: &Language) -> u16;
232
233    // Instance Methods
234
235    #[wasm_bindgen(method, js_name = fieldNameForId)]
236    pub fn field_name_for_id(this: &Language, field_id: u16) -> Option<String>;
237
238    #[wasm_bindgen(method, js_name = fieldIdForName)]
239    pub fn field_id_for_name(this: &Language, field_name: &str) -> Option<u16>;
240
241    #[wasm_bindgen(method, js_name = idForNodeType)]
242    pub fn id_for_node_kind(this: &Language, kind: &str, named: bool) -> u16;
243
244    #[wasm_bindgen(method, js_name = nodeTypeForId)]
245    pub fn node_kind_for_id(this: &Language, kind_id: u16) -> Option<String>;
246
247    #[wasm_bindgen(method, js_name = nodeTypeIsNamed)]
248    pub fn node_kind_is_named(this: &Language, kind_id: u16) -> bool;
249
250    #[wasm_bindgen(method, js_name = nodeTypeIsVisible)]
251    pub fn node_kind_is_visible(this: &Language, kind_id: u16) -> bool;
252
253    #[wasm_bindgen(catch, method)]
254    pub fn query(this: &Language, source: &JsString) -> Result<Query, QueryError>;
255}
256
257impl Language {
258    pub async fn load_bytes(bytes: &Uint8Array) -> Result<Language, LanguageError> {
259        TreeSitter::init_guard();
260        JsFuture::from(Language::__load_bytes(bytes))
261            .await
262            .map(JsCast::unchecked_into)
263            .map_err(JsCast::unchecked_into)
264    }
265
266    pub async fn load_path(path: &str) -> Result<Language, LanguageError> {
267        TreeSitter::init_guard();
268        JsFuture::from(Language::__load_path(path))
269            .await
270            .map(JsCast::unchecked_into)
271            .map_err(JsCast::unchecked_into)
272    }
273}
274
275#[wasm_bindgen]
276extern {
277    #[derive(Clone, Debug, Eq, PartialEq)]
278    #[wasm_bindgen(extends = Error)]
279    pub type LanguageError;
280}
281
282#[wasm_bindgen]
283extern {
284    #[derive(Clone, Debug, Eq, PartialEq)]
285    #[wasm_bindgen(extends = Object)]
286    pub type ParseOptions;
287
288    // Instance Properties
289
290    // -> Range[]
291    #[wasm_bindgen(method, getter, js_name = includedRanges)]
292    pub fn included_ranges(this: &ParseOptions) -> Option<Array>;
293}
294
295impl ParseOptions {
296    pub fn new(included_ranges: Option<&Array>) -> Self {
297        let obj = Object::new();
298        Reflect::set(&obj, &"includedRanges".into(), &included_ranges.into()).unwrap();
299        JsCast::unchecked_into(obj)
300    }
301}
302
303impl Default for ParseOptions {
304    fn default() -> Self {
305        let included_ranges = Default::default();
306        Self::new(included_ranges)
307    }
308}
309
310#[wasm_bindgen]
311extern {
312    #[derive(Clone, Debug)]
313    #[wasm_bindgen(extends = Object)]
314    pub type Point;
315
316    // Instance Properties
317
318    #[wasm_bindgen(method, getter)]
319    pub fn column(this: &Point) -> u32;
320
321    #[wasm_bindgen(method, getter)]
322    pub fn row(this: &Point) -> u32;
323}
324
325impl Point {
326    pub fn new(row: u32, column: u32) -> Self {
327        let obj = Object::new();
328        Reflect::set(&obj, &"row".into(), &row.into()).unwrap();
329        Reflect::set(&obj, &"column".into(), &column.into()).unwrap();
330        JsCast::unchecked_into(obj)
331    }
332
333    #[inline(always)]
334    fn spread(&self) -> (u32, u32) {
335        (self.row(), self.column())
336    }
337}
338
339impl Default for Point {
340    fn default() -> Self {
341        let row = Default::default();
342        let column = Default::default();
343        Self::new(row, column)
344    }
345}
346
347impl Eq for Point {
348}
349
350impl std::hash::Hash for Point {
351    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
352        let this = self.spread();
353        this.hash(state);
354    }
355}
356
357impl Ord for Point {
358    fn cmp(&self, that: &Self) -> std::cmp::Ordering {
359        let this = self.spread();
360        let that = that.spread();
361        this.cmp(&that)
362    }
363}
364
365impl PartialEq for Point {
366    fn eq(&self, that: &Self) -> bool {
367        let this = self.spread();
368        let that = that.spread();
369        this.eq(&that)
370    }
371}
372
373impl PartialOrd for Point {
374    fn partial_cmp(&self, that: &Point) -> Option<std::cmp::Ordering> {
375        let this = self.spread();
376        let that = that.spread();
377        this.partial_cmp(&that)
378    }
379}
380
381#[wasm_bindgen]
382extern {
383    #[derive(Clone, Debug, Eq, PartialEq)]
384    #[wasm_bindgen(extends = Object)]
385    pub type PredicateOperand;
386
387    // Instance Properties
388
389    #[wasm_bindgen(method, getter)]
390    pub fn name(this: &PredicateOperand) -> JsString;
391
392    #[wasm_bindgen(method, getter)]
393    pub fn type_(this: &PredicateOperand) -> JsString;
394}
395
396impl PredicateOperand {
397    pub fn new(type_: &JsString, name: &JsString) -> Self {
398        let obj = Object::new();
399        Reflect::set(&obj, &"type".into(), &type_.into()).unwrap();
400        Reflect::set(&obj, &"name".into(), &name.into()).unwrap();
401        JsCast::unchecked_into(obj)
402    }
403}
404
405impl Default for PredicateOperand {
406    fn default() -> Self {
407        let name = &<String as Default>::default().into();
408        let type_ = &<String as Default>::default().into();
409        Self::new(name, type_)
410    }
411}
412
413#[wasm_bindgen]
414extern {
415    #[derive(Clone, Debug, Eq, PartialEq)]
416    #[wasm_bindgen(extends = Object)]
417    pub type PredicateResult;
418
419    // Instance Properties
420
421    #[wasm_bindgen(method, getter)]
422    pub fn operator(this: &PredicateResult) -> JsString;
423
424    // -> PredicateOperand[]
425    #[wasm_bindgen(method, getter)]
426    pub fn operands(this: &PredicateResult) -> Box<[JsValue]>;
427}
428
429impl PredicateResult {
430    pub fn new(operator: &JsString, operands: &Array) -> Self {
431        let obj = Object::new();
432        Reflect::set(&obj, &"operator".into(), &operator.into()).unwrap();
433        Reflect::set(&obj, &"operands".into(), &operands.into()).unwrap();
434        JsCast::unchecked_into(obj)
435    }
436}
437
438impl Default for PredicateResult {
439    fn default() -> Self {
440        let operator = &<String as Default>::default().into();
441        let operands = &<Vec<JsValue> as Default>::default().into_iter().collect();
442        Self::new(operator, operands)
443    }
444}
445
446#[wasm_bindgen]
447extern {
448    #[derive(Clone, Debug)]
449    pub type Query;
450
451    // Instance Properties
452
453    // -> JsString[]
454    #[wasm_bindgen(method, getter, js_name = captureNames)]
455    pub fn capture_names(this: &Query) -> Box<[JsValue]>;
456
457    // Instance Methods
458
459    #[wasm_bindgen(method)]
460    pub fn delete(this: &Query);
461
462    // -> QueryMatch[]
463    #[wasm_bindgen(method)]
464    pub fn matches(
465        this: &Query,
466        node: &SyntaxNode,
467        start_position: Option<&Point>,
468        end_position: Option<&Point>,
469    ) -> Box<[JsValue]>;
470
471    // -> QueryCapture[]
472    #[wasm_bindgen(method)]
473    pub fn captures(
474        this: &Query,
475        node: &SyntaxNode,
476        start_position: Option<&Point>,
477        end_position: Option<&Point>,
478    ) -> Box<[JsValue]>;
479
480    // -> PredicateResult[]
481    #[wasm_bindgen(method, js_name = predicatesForPattern)]
482    pub fn predicates_for_pattern(this: &Query, pattern_index: u32) -> Box<[JsValue]>;
483}
484
485#[wasm_bindgen]
486extern {
487    #[derive(Clone, Debug, Eq, PartialEq)]
488    #[wasm_bindgen(extends = Object)]
489    pub type QueryCapture;
490
491    // Instance Properties
492
493    #[wasm_bindgen(method, getter)]
494    pub fn name(this: &QueryCapture) -> JsString;
495
496    #[wasm_bindgen(method, getter)]
497    pub fn node(this: &QueryCapture) -> SyntaxNode;
498}
499
500impl QueryCapture {
501    pub fn new(name: &JsString, node: &SyntaxNode) -> Self {
502        let obj = Object::new();
503        Reflect::set(&obj, &"name".into(), &name.into()).unwrap();
504        Reflect::set(&obj, &"node".into(), &node.into()).unwrap();
505        JsCast::unchecked_into(obj)
506    }
507}
508
509#[wasm_bindgen]
510extern {
511    #[derive(Clone, Debug, Eq, PartialEq)]
512    #[wasm_bindgen(extends = Error)]
513    pub type QueryError;
514}
515
516#[wasm_bindgen]
517extern {
518    #[derive(Clone, Debug, Eq, PartialEq)]
519    #[wasm_bindgen(extends = Object)]
520    pub type QueryMatch;
521
522    // Instance Properties
523
524    #[wasm_bindgen(method, getter)]
525    pub fn pattern(this: &QueryMatch) -> u32;
526
527    // -> QueryCapture[]
528    #[wasm_bindgen(method, getter)]
529    pub fn captures(this: &QueryMatch) -> Box<[JsValue]>;
530}
531
532impl QueryMatch {
533    pub fn new(pattern: u32, captures: &Array) -> Self {
534        let obj = Object::new();
535        Reflect::set(&obj, &"pattern".into(), &pattern.into()).unwrap();
536        Reflect::set(&obj, &"captures".into(), &captures.into()).unwrap();
537        JsCast::unchecked_into(obj)
538    }
539}
540
541#[wasm_bindgen]
542extern {
543    #[derive(Clone, Debug)]
544    #[wasm_bindgen(extends = Object)]
545    pub type Range;
546
547    // Instance Properties
548
549    #[wasm_bindgen(method, getter, js_name = endIndex)]
550    pub fn end_index(this: &Range) -> u32;
551
552    #[wasm_bindgen(method, getter, js_name = endPosition)]
553    pub fn end_position(this: &Range) -> Point;
554
555    #[wasm_bindgen(method, getter, js_name = startIndex)]
556    pub fn start_index(this: &Range) -> u32;
557
558    #[wasm_bindgen(method, getter, js_name = startPosition)]
559    pub fn start_position(this: &Range) -> Point;
560}
561
562impl Range {
563    pub fn new(start_position: &Point, end_position: &Point, start_index: u32, end_index: u32) -> Self {
564        let obj = Object::new();
565        Reflect::set(&obj, &"startPosition".into(), &start_position.into()).unwrap();
566        Reflect::set(&obj, &"endPosition".into(), &end_position.into()).unwrap();
567        Reflect::set(&obj, &"startIndex".into(), &start_index.into()).unwrap();
568        Reflect::set(&obj, &"endIndex".into(), &end_index.into()).unwrap();
569        JsCast::unchecked_into(obj)
570    }
571
572    #[inline(always)]
573    fn spread(&self) -> (u32, u32, Point, Point) {
574        (
575            self.start_index(),
576            self.end_index(),
577            self.start_position(),
578            self.end_position(),
579        )
580    }
581}
582
583impl Default for Range {
584    fn default() -> Range {
585        let start_position = Default::default();
586        let end_position = Default::default();
587        let start_index = Default::default();
588        let end_index = Default::default();
589        Self::new(&start_position, &end_position, start_index, end_index)
590    }
591}
592
593impl Eq for Range {
594}
595
596impl std::hash::Hash for Range {
597    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
598        let this = self.spread();
599        this.hash(state)
600    }
601}
602
603impl Ord for Range {
604    fn cmp(&self, that: &Self) -> std::cmp::Ordering {
605        let this = self.spread();
606        let that = that.spread();
607        this.cmp(&that)
608    }
609}
610
611impl PartialEq<Range> for Range {
612    fn eq(&self, that: &Self) -> bool {
613        let this = self.spread();
614        let that = that.spread();
615        this.eq(&that)
616    }
617}
618
619impl PartialOrd<Range> for Range {
620    fn partial_cmp(&self, that: &Self) -> Option<std::cmp::Ordering> {
621        let this = self.spread();
622        let that = that.spread();
623        this.partial_cmp(&that)
624    }
625}
626
627#[wasm_bindgen]
628extern {
629    #[derive(Clone, Debug)]
630    pub type SyntaxNode;
631
632    // Instance Properties
633
634    #[wasm_bindgen(method, getter, js_name = childCount)]
635    pub fn child_count(this: &SyntaxNode) -> u32;
636
637    #[wasm_bindgen(method, getter)]
638    pub fn children(this: &SyntaxNode) -> Box<[JsValue]>;
639
640    #[wasm_bindgen(method, getter, js_name = endIndex)]
641    pub fn end_index(this: &SyntaxNode) -> u32;
642
643    #[wasm_bindgen(method, getter, js_name = endPosition)]
644    pub fn end_position(this: &SyntaxNode) -> Point;
645
646    #[wasm_bindgen(method, getter, js_name = firstChild)]
647    pub fn first_child(this: &SyntaxNode) -> Option<SyntaxNode>;
648
649    #[wasm_bindgen(method, getter, js_name = firstNamedChild)]
650    pub fn first_named_child(this: &SyntaxNode) -> Option<SyntaxNode>;
651
652    #[wasm_bindgen(method, getter)]
653    pub fn id(this: &SyntaxNode) -> u32;
654
655    #[wasm_bindgen(method, getter, js_name = lastChild)]
656    pub fn last_child(this: &SyntaxNode) -> Option<SyntaxNode>;
657
658    #[wasm_bindgen(method, getter, js_name = lastNamedChild)]
659    pub fn last_named_child(this: &SyntaxNode) -> Option<SyntaxNode>;
660
661    #[wasm_bindgen(method, getter, js_name = namedChildCount)]
662    pub fn named_child_count(this: &SyntaxNode) -> u32;
663
664    #[wasm_bindgen(method, getter, js_name = namedChildren)]
665    pub fn named_children(this: &SyntaxNode) -> Box<[JsValue]>;
666
667    #[wasm_bindgen(method, getter, js_name = nextNamedSibling)]
668    pub fn next_named_sibling(this: &SyntaxNode) -> Option<SyntaxNode>;
669
670    #[wasm_bindgen(method, getter, js_name = nextSibling)]
671    pub fn next_sibling(this: &SyntaxNode) -> Option<SyntaxNode>;
672
673    #[wasm_bindgen(method, getter)]
674    pub fn parent(this: &SyntaxNode) -> Option<SyntaxNode>;
675
676    #[wasm_bindgen(method, getter, js_name = previousNamedSibling)]
677    pub fn previous_named_sibling(this: &SyntaxNode) -> Option<SyntaxNode>;
678
679    #[wasm_bindgen(method, getter, js_name = previousSibling)]
680    pub fn previous_sibling(this: &SyntaxNode) -> Option<SyntaxNode>;
681
682    #[wasm_bindgen(method, getter, js_name = startIndex)]
683    pub fn start_index(this: &SyntaxNode) -> u32;
684
685    #[wasm_bindgen(method, getter, js_name = startPosition)]
686    pub fn start_position(this: &SyntaxNode) -> Point;
687
688    #[wasm_bindgen(method, getter)]
689    pub fn text(this: &SyntaxNode) -> JsString;
690
691    #[wasm_bindgen(method, getter)]
692    pub fn tree(this: &SyntaxNode) -> Tree;
693
694    #[wasm_bindgen(method, getter, js_name = type)]
695    pub fn type_(this: &SyntaxNode) -> JsString;
696
697    #[wasm_bindgen(method, getter, js_name = typeId)]
698    pub fn type_id(this: &SyntaxNode) -> u16;
699
700    // Instance Methods
701
702    #[wasm_bindgen(method)]
703    pub fn child(this: &SyntaxNode, index: u32) -> Option<SyntaxNode>;
704
705    #[wasm_bindgen(method, js_name = childForFieldId)]
706    pub fn child_for_field_id(this: &SyntaxNode, field_id: u16) -> Option<SyntaxNode>;
707
708    #[wasm_bindgen(method, js_name = childForFieldName)]
709    pub fn child_for_field_name(this: &SyntaxNode, field_name: &str) -> Option<SyntaxNode>;
710
711    #[wasm_bindgen(method, js_name = descendantForIndex)]
712    pub fn descendant_for_index(this: &SyntaxNode, index: u32) -> Option<SyntaxNode>;
713
714    #[wasm_bindgen(method, js_name = descendantForIndex)]
715    pub fn descendant_for_index_range(this: &SyntaxNode, start_index: u32, end_index: u32) -> Option<SyntaxNode>;
716
717    #[wasm_bindgen(method, js_name = descendantForPosition)]
718    pub fn descendant_for_position(this: &SyntaxNode, position: &Point) -> Option<SyntaxNode>;
719
720    #[wasm_bindgen(method, js_name = descendantForPosition)]
721    pub fn descendant_for_position_range(
722        this: &SyntaxNode,
723        start_position: &Point,
724        end_position: &Point,
725    ) -> Option<SyntaxNode>;
726
727    #[wasm_bindgen(method, js_name = descendantsOfType)]
728    pub fn descendants_of_type_array(
729        this: &SyntaxNode,
730        type_: Box<[JsValue]>,
731        start_position: Option<&Point>,
732        end_position: Option<&Point>,
733    ) -> Box<[JsValue]>;
734
735    // -> SyntaxNode[]
736    #[wasm_bindgen(method, js_name = descendantsOfType)]
737    pub fn descendants_of_type_string(
738        this: &SyntaxNode,
739        type_: &str,
740        start_position: Option<&Point>,
741        end_position: Option<&Point>,
742    ) -> Box<[JsValue]>;
743
744    #[wasm_bindgen(method)]
745    pub fn equals(this: &SyntaxNode, other: &SyntaxNode) -> bool;
746
747    #[wasm_bindgen(method, js_name = hasChanges)]
748    pub fn has_changes(this: &SyntaxNode) -> bool;
749
750    #[wasm_bindgen(method, js_name = hasError)]
751    pub fn has_error(this: &SyntaxNode) -> bool;
752
753    #[wasm_bindgen(method, js_name = isMissing)]
754    pub fn is_missing(this: &SyntaxNode) -> bool;
755
756    #[wasm_bindgen(method, js_name = isNamed)]
757    pub fn is_named(this: &SyntaxNode) -> bool;
758
759    #[wasm_bindgen(method, js_name = namedChild)]
760    pub fn named_child(this: &SyntaxNode, index: u32) -> Option<SyntaxNode>;
761
762    #[wasm_bindgen(method, js_name = namedDescendantForIndex)]
763    pub fn named_descendant_for_index(this: &SyntaxNode, index: u32) -> Option<SyntaxNode>;
764
765    #[wasm_bindgen(method, js_name = namedDescendantForIndex)]
766    pub fn named_descendant_for_index_range(this: &SyntaxNode, start_index: u32, end_index: u32) -> Option<SyntaxNode>;
767
768    #[wasm_bindgen(method, js_name = namedDescendantForPosition)]
769    pub fn named_descendant_for_position(this: &SyntaxNode, position: &Point) -> Option<SyntaxNode>;
770
771    #[wasm_bindgen(method, js_name = namedDescendantForPosition)]
772    pub fn named_descendant_for_position_range(
773        this: &SyntaxNode,
774        start_position: &Point,
775        end_position: &Point,
776    ) -> Option<SyntaxNode>;
777
778    #[wasm_bindgen(method, js_name = toString)]
779    pub fn to_string(this: &SyntaxNode) -> JsString;
780
781    #[wasm_bindgen(method)]
782    pub fn walk(this: &SyntaxNode) -> TreeCursor;
783}
784
785impl PartialEq<SyntaxNode> for SyntaxNode {
786    fn eq(&self, other: &SyntaxNode) -> bool {
787        self.equals(other)
788    }
789}
790
791impl Eq for SyntaxNode {
792}
793
794impl std::hash::Hash for SyntaxNode {
795    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
796        self.id().hash(state);
797    }
798}
799
800#[wasm_bindgen]
801extern {
802    #[derive(Debug)]
803    pub type Tree;
804
805    // Instance Properties
806
807    #[wasm_bindgen(method, getter, js_name = rootNode)]
808    pub fn root_node(this: &Tree) -> SyntaxNode;
809
810    // Instance Methods
811
812    #[wasm_bindgen(method)]
813    pub fn copy(this: &Tree) -> Tree;
814
815    #[wasm_bindgen(method)]
816    pub fn delete(this: &Tree);
817
818    #[wasm_bindgen(method)]
819    pub fn edit(this: &Tree, delta: &Edit) -> Tree;
820
821    #[wasm_bindgen(method)]
822    pub fn walk(this: &Tree) -> TreeCursor;
823
824    // -> Range[]
825    #[wasm_bindgen(method, js_name = getChangedRanges)]
826    pub fn get_changed_ranges(this: &Tree, other: &Tree) -> Box<[JsValue]>;
827
828    #[wasm_bindgen(method, js_name = getLanguage)]
829    pub fn get_language(this: &Tree) -> Language;
830}
831
832impl Clone for Tree {
833    fn clone(&self) -> Tree {
834        self.copy()
835    }
836}
837
838#[wasm_bindgen]
839extern {
840    #[derive(Clone, Debug)]
841    pub type TreeCursor;
842
843    // Instance Properties
844
845    #[wasm_bindgen(method, getter, js_name = endIndex)]
846    pub fn end_index(this: &TreeCursor) -> u32;
847
848    #[wasm_bindgen(method, getter, js_name = endPosition)]
849    pub fn end_position(this: &TreeCursor) -> Point;
850
851    #[wasm_bindgen(method, getter, js_name = nodeIsNamed)]
852    pub fn node_is_named(this: &TreeCursor) -> bool;
853
854    #[wasm_bindgen(method, getter, js_name = nodeText)]
855    pub fn node_text(this: &TreeCursor) -> JsString;
856
857    #[wasm_bindgen(method, getter, js_name = nodeType)]
858    pub fn node_type(this: &TreeCursor) -> JsString;
859
860    #[wasm_bindgen(method, getter, js_name = startIndex)]
861    pub fn start_index(this: &TreeCursor) -> u32;
862
863    #[wasm_bindgen(method, getter, js_name = startPosition)]
864    pub fn start_position(this: &TreeCursor) -> Point;
865
866    // Instance Methods
867
868    #[wasm_bindgen(method, js_name = currentFieldId)]
869    pub fn current_field_id(this: &TreeCursor) -> Option<u16>;
870
871    #[wasm_bindgen(method, js_name = currentFieldName)]
872    pub fn current_field_name(this: &TreeCursor) -> Option<JsString>;
873
874    #[wasm_bindgen(method, js_name = currentNode)]
875    pub fn current_node(this: &TreeCursor) -> SyntaxNode;
876
877    #[wasm_bindgen(method)]
878    pub fn delete(this: &TreeCursor);
879
880    #[wasm_bindgen(method, js_name = gotoFirstChild)]
881    pub fn goto_first_child(this: &TreeCursor) -> bool;
882
883    #[wasm_bindgen(method, js_name = gotoNextSibling)]
884    pub fn goto_next_sibling(this: &TreeCursor) -> bool;
885
886    #[wasm_bindgen(method, js_name = gotoParent)]
887    pub fn goto_parent(this: &TreeCursor) -> bool;
888
889    #[wasm_bindgen(method)]
890    pub fn reset(this: &TreeCursor, node: &SyntaxNode);
891}
892
893#[wasm_bindgen]
894extern {
895    #[derive(Clone, Debug)]
896    pub type Parser;
897
898    // Static Methods
899
900    // Constructor
901
902    #[wasm_bindgen(catch, constructor)]
903    fn __new() -> Result<Parser, ParserError>;
904
905    // Instance Methods
906
907    #[wasm_bindgen(method)]
908    pub fn delete(this: &Parser);
909
910    #[wasm_bindgen(method, js_name = getLanguage)]
911    pub fn get_language(this: &Parser) -> Option<Language>;
912
913    #[wasm_bindgen(method, js_name = getLogger)]
914    pub fn get_logger(this: &Parser) -> Option<Logger>;
915
916    #[wasm_bindgen(method, js_name = getTimeoutMicros)]
917    pub fn get_timeout_micros(this: &Parser) -> f64;
918
919    #[wasm_bindgen(catch, method, js_name = parse)]
920    pub fn parse_with_function(
921        this: &Parser,
922        input: &Input,
923        previous_tree: Option<&Tree>,
924        options: Option<&ParseOptions>,
925    ) -> Result<Option<Tree>, ParserError>;
926
927    #[wasm_bindgen(catch, method, js_name = parse)]
928    pub fn parse_with_string(
929        this: &Parser,
930        input: &JsString,
931        previous_tree: Option<&Tree>,
932        options: Option<&ParseOptions>,
933    ) -> Result<Option<Tree>, ParserError>;
934
935    #[wasm_bindgen(method)]
936    pub fn reset(this: &Parser);
937
938    #[wasm_bindgen(catch, method, js_name = setLanguage)]
939    pub fn set_language(this: &Parser, language: Option<&Language>) -> Result<(), LanguageError>;
940
941    #[wasm_bindgen(method, js_name = setLogger)]
942    pub fn set_logger(this: &Parser, logger: Option<&Logger>);
943
944    #[wasm_bindgen(method, js_name = setTimeoutMicros)]
945    pub fn set_timeout_micros(this: &Parser, timeout_micros: f64);
946}
947
948impl Parser {
949    pub fn new() -> Result<Parser, ParserError> {
950        TreeSitter::init_guard();
951        let result = Parser::__new()?;
952        Ok(result)
953    }
954}
955
956#[wasm_bindgen]
957extern {
958    #[derive(Clone, Debug, Eq, PartialEq)]
959    #[wasm_bindgen(extends = Error)]
960    pub type ParserError;
961}