lady_deirdre/syntax/node.rs
1////////////////////////////////////////////////////////////////////////////////
2// This file is part of "Lady Deirdre", a compiler front-end foundation //
3// technology. //
4// //
5// This work is proprietary software with source-available code. //
6// //
7// To copy, use, distribute, or contribute to this work, you must agree to //
8// the terms of the General License Agreement: //
9// //
10// https://github.com/Eliah-Lakhin/lady-deirdre/blob/master/EULA.md //
11// //
12// The agreement grants a Basic Commercial License, allowing you to use //
13// this work in non-commercial and limited commercial products with a total //
14// gross revenue cap. To remove this commercial limit for one of your //
15// products, you must acquire a Full Commercial License. //
16// //
17// If you contribute to the source code, documentation, or related materials, //
18// you must grant me an exclusive license to these contributions. //
19// Contributions are governed by the "Contributions" section of the General //
20// License Agreement. //
21// //
22// Copying the work in parts is strictly forbidden, except as permitted //
23// under the General License Agreement. //
24// //
25// If you do not or cannot agree to the terms of this Agreement, //
26// do not use this work. //
27// //
28// This work is provided "as is", without any warranties, express or implied, //
29// except where such disclaimers are legally invalid. //
30// //
31// Copyright (c) 2024 Ilya Lakhin (Илья Александрович Лахин). //
32// All rights reserved. //
33////////////////////////////////////////////////////////////////////////////////
34
35extern crate lady_deirdre_derive;
36
37use std::fmt::{Debug, Formatter};
38
39pub use lady_deirdre_derive::Node;
40
41use crate::{
42 arena::{Entry, Id, Identifiable, SubId},
43 lexis::{Site, SiteSpan, SourceCode, Token, TokenBuffer, TokenRef, NIL_TOKEN_REF},
44 syntax::{
45 Capture,
46 CapturesIter,
47 ChildrenIter,
48 DebugObserver,
49 ImmutableSyntaxTree,
50 Key,
51 NodeRule,
52 PolyRef,
53 PolyVariant,
54 RefKind,
55 SyntaxSession,
56 SyntaxTree,
57 NON_RULE,
58 },
59 units::CompilationUnit,
60};
61
62/// A [NodeRef] reference that does not point to any node.
63///
64/// The value of this static equals to the [NodeRef::nil] value.
65pub static NIL_NODE_REF: NodeRef = NodeRef::nil();
66
67/// A type of the syntax tree node.
68///
69/// Typically, this trait should be implemented on enum types, where each enum
70/// variant represents an individual node kind. The variant fields would
71/// include references to the parent and children nodes.
72///
73/// The interface provides language-agnostic functions to reveal
74/// node's structure, such as [children_iter](AbstractNode::children_iter)
75/// to iterate through all children of the node instance, or
76/// [name](AbstractNode::name) to get the node's variant name.
77///
78/// The [Node::parse] function serves as the syntax parser of the programming
79/// language and the constructor of the node instance.
80///
81/// Essentially, this interface defines the syntax component of the programming
82/// language grammar.
83///
84/// The node interface is split into the [Node] trait, which includes
85/// object-unsafe API, and its super-trait [AbstractNode] which includes
86/// object-safe API.
87///
88/// You are encouraged to use the companion [Node](lady_deirdre_derive::Node)
89/// derive macro to implement all required components on enum types in terms
90/// of the LL(1) grammar.
91pub trait Node: AbstractNode + Sized {
92 /// Specifies the lexical structure of the language.
93 ///
94 /// This associated type is required because the syntax grammar of the
95 /// language includes the lexical grammar as well.
96 ///
97 /// When using the derive macro, this type is specified through the
98 /// `#[token(...)]` attribute:
99 ///
100 /// ```ignore
101 /// #[derive(Node)]
102 /// #[token(MyToken)]
103 /// struct MyNode {
104 /// //...
105 /// }
106 /// ```
107 type Token: Token;
108
109 /// Parses the programming language syntax tree node.
110 ///
111 /// The `session` parameter of type [SyntaxSession] provides access
112 /// to the token stream that needs to be parsed and offers an API to descend
113 /// into the sub-rules as needed.
114 ///
115 /// The `rule` is a numeric index of the syntax parse rule that needs to be
116 /// parsed.
117 ///
118 /// The exact set of valid values for the `rule` argument, and the mapping
119 /// between these values and the Node types, is language-specific.
120 ///
121 /// The calling side doesn't need to know this mapping upfront,
122 /// except for the following `rule` cases:
123 ///
124 /// - [ROOT_RULE](crate::syntax::ROOT_RULE) parses the root rule of the
125 /// syntax tree. The parse function should always be able to parse
126 /// at least this rule.
127 /// - [NON_RULE] does not represent any parsing rule within any
128 /// programming language. This function should never be called with this
129 /// rule value.
130 ///
131 /// If the `rule` value is within the valid set of the programming language
132 /// rule set, **the function is infallible** regardless of the input token
133 /// stream.
134 ///
135 /// In the event of syntax errors in the input stream, the function attempts
136 /// to recover from these errors, and it **always consumes at least one token**
137 /// from the input token stream (if the stream is not empty).
138 ///
139 /// Finally, the underlying parsing algorithm is deterministic
140 /// and context-free: the parse function always returns the same result
141 /// from the same set of input tokens and requested `rule`, and the
142 /// function always returns the same kind of syntax tree nodes for
143 /// the same `rule` value.
144 ///
145 /// Typically, you don't need to call this function manually. It is the
146 /// responsibility of the compilation unit manager
147 /// (e.g., [Document](crate::units::Document)) to decide when to call this
148 /// function.
149 ///
150 /// To debug the parser, use the [Node::debug] function.
151 ///
152 /// For a detailed specification of the syntax parsing process,
153 /// refer to the [SyntaxSession] documentation.
154 ///
155 /// **Safety**
156 ///
157 /// This function **is safe**. Violations of any of the above rules is an
158 /// implementation bug, not undefined behavior.
159 ///
160 /// **Panic**
161 ///
162 /// The function may panic if the `rule` parameter value is not valid for
163 /// this programming language.
164 fn parse<'code>(session: &mut impl SyntaxSession<'code, Node = Self>, rule: NodeRule) -> Self;
165
166 /// Debugs the syntax parsing algorithm for this node type.
167 ///
168 /// This function runs the parsing algorithm on the `text` source code
169 /// and prints parsing steps to the terminal (stdout).
170 fn debug(text: impl AsRef<str>) {
171 let tokens = TokenBuffer::<Self::Token>::from(text);
172
173 ImmutableSyntaxTree::<Self>::parse_with_id_and_observer(
174 SubId::fork(tokens.id()),
175 tokens.cursor(..),
176 &mut DebugObserver::default(),
177 );
178 }
179}
180
181/// An object-safe part of the syntax tree node interface.
182///
183/// This trait is a super-trait of the [Node] trait, which is not object-safe.
184///
185/// The entire interface is separated into two traits so that an API user
186/// can use most parts of the whole interface from the object-safe trait.
187///
188/// The AbstractNode trait consists of language-agnostic functions to
189/// read individual syntax tree node structure, whereas the Node trait provides
190/// node's parser, essentially the node constructor.
191pub trait AbstractNode: Send + Sync + 'static {
192 /// A syntax parse rule that parses this kind of node.
193 ///
194 /// When using the [Node](lady_deirdre_derive::Node) macro, this value
195 /// is either generated by the macro program or overridden through the
196 /// `#[denote(...)]` attribute:
197 ///
198 /// ```ignore
199 /// #[derive(Node)]
200 /// enum MyNode {
201 /// #[denote(100)] // self.rule() == 100
202 /// #[rule()]
203 /// Variant1 {},
204 ///
205 /// #[denote(V2)] // self.rule() == Self::V2
206 /// #[rule()]
207 /// Variant2 {},
208 ///
209 /// #[denote(V3, 300)] // self.rule() == Self::V3 && Self::V3 == 300
210 /// #[rule()]
211 /// Variant3 {},
212 ///
213 /// #[rule()] // self.rule() value generated by the macro
214 /// Variant4 {},
215 /// }
216 /// ```
217 fn rule(&self) -> NodeRule;
218
219 /// A debug name of this node.
220 ///
221 /// Returns None if this feature is disabled for this node instance.
222 ///
223 /// When using the [Node](lady_deirdre_derive::Node) macro, this function
224 /// returns the stringified variant's name:
225 ///
226 /// ```ignore
227 /// #[derive(Node)]
228 /// enum MyNode {
229 /// #[rule()]
230 /// Variant {}, // self.name() == Some("Variant")
231 ///
232 /// NonParsable {}, // self.name() == None
233 /// }
234 /// ```
235 fn name(&self) -> Option<&'static str>;
236
237 /// An end-user display description of this node.
238 ///
239 /// Returns None if this feature is disabled for this node instance.
240 ///
241 /// This function is intended to be used for the syntax errors formatting.
242 ///
243 /// When using the [Node](lady_deirdre_derive::Node) macro, this function
244 /// returns what you have specified with the `#[describe(...)]` attribute:
245 ///
246 /// ```ignore
247 /// #[derive(Node)]
248 /// enum MyNode {
249 /// // self.describe(false) == Some("short")
250 /// // self.describe(true) == Some("verbose")
251 /// #[rule()]
252 /// #[describe("short", "verbose")]
253 /// Variant {},
254 ///
255 /// NonParsable {}, // self.name() == None
256 /// }
257 /// ```
258 ///
259 /// The difference between the short (`verbose` is false) and verbose
260 /// (verbose is `true`) descriptions is that the short version represents
261 /// a "class" of the node, while the verbose version provides a more
262 /// detailed text specific to this particular node.
263 ///
264 /// For example, a short description of the Sum and Mul binary operators
265 /// would simply be "operator", whereas, for verbose versions
266 /// this function might returns something like "<a + b>" and "<a * b>".
267 fn describe(&self, verbose: bool) -> Option<&'static str>;
268
269 /// Returns a [NodeRef] reference of this node.
270 ///
271 /// The returning value resolves to self when borrowing a node from
272 /// the [SyntaxTree].
273 ///
274 /// This function may return [nil](NodeRef::nil) reference, if the feature
275 /// is disabled for this node instance.
276 ///
277 /// When using the [Node](lady_deirdre_derive::Node) macro, this function
278 /// returns what you have annotated with the `#[node(...)]` attribute:
279 ///
280 /// ```ignore
281 /// #[derive(Node)]
282 /// enum MyNode {
283 /// // self.node_ref() returns `node` value
284 /// #[rule()]
285 /// Variant {
286 /// #[node]
287 /// node: NodeRef,
288 /// },
289 ///
290 /// // self.node_ref() returns NodeRef::nil()
291 /// #[rule()]
292 /// VariantWithoutNodeRef {
293 /// // #[node]
294 /// node: NodeRef,
295 /// },
296 /// }
297 /// ```
298 fn node_ref(&self) -> NodeRef;
299
300 /// Returns a [NodeRef] reference of the parent node of this node.
301 ///
302 /// The returning value resolves to the parent node when borrowing a node
303 /// from the [SyntaxTree].
304 ///
305 /// This function may return [nil](NodeRef::nil) reference, if the feature
306 /// is disabled for this node instance.
307 ///
308 /// When using the [Node](lady_deirdre_derive::Node) macro, this function
309 /// returns what you have annotated with the `#[parent(...)]` attribute:
310 ///
311 /// ```ignore
312 /// #[derive(Node)]
313 /// enum MyNode {
314 /// // self.parent_ref() returns `parent` value
315 /// #[rule()]
316 /// Variant {
317 /// #[parent]
318 /// parent: NodeRef,
319 /// },
320 ///
321 /// // self.parent_ref() returns NodeRef::nil()
322 /// #[rule()]
323 /// VariantWithoutParentRef {
324 /// // #[parent]
325 /// parent: NodeRef,
326 /// },
327 /// }
328 /// ```
329 fn parent_ref(&self) -> NodeRef;
330
331 /// Updates the parent node reference of this node.
332 ///
333 /// This function updates the value returned by the
334 /// [parent_ref](Self::parent_ref) function.
335 ///
336 /// The compilation unit managers
337 /// (e.g., mutable [Document](crate::units::Document)) may use this function
338 /// to "transplant" the syntax tree branch to another branch.
339 ///
340 /// This function could ignore the provided [NodeRef] reference
341 /// if the "parent_ref" feature is not available for this node instance.
342 fn set_parent_ref(&mut self, parent_ref: NodeRef);
343
344 /// Returns a set of children of this node associated with the specified
345 /// `key`.
346 ///
347 /// When using the [Node](lady_deirdre_derive::Node) macro, this function
348 /// returns what you have annotated with the `#[child]` attribute.
349 ///
350 /// The string `key` denotes the field name, and the numeric `key`
351 /// denotes the index of the `#[child]` attribute in order.
352 ///
353 /// The function returns None if there is no capture associated
354 /// with specified key.
355 ///
356 /// ```ignore
357 /// #[derive(Node)]
358 /// enum MyNode {
359 /// #[rule()]
360 /// Variant {
361 /// #[child] // self.capture(Key::Index(0))
362 /// capture_1: NodeRef,
363 ///
364 /// #[child] // self.capture(Key::Name("capture_2"))
365 /// capture_2: Vec<NodeRef>,
366 ///
367 /// #[child] // self.capture(Key::Index(2))
368 /// capture_3: TokenRef,
369 /// },
370 /// }
371 /// ```
372 fn capture(&self, key: Key) -> Option<Capture>;
373
374 /// Returns the first set of children of this node.
375 ///
376 /// Returns None if there are no known captures in this node instance.
377 #[inline(always)]
378 fn first_capture(&self) -> Option<Capture> {
379 self.capture(Key::Index(0))
380 }
381
382 /// Returns the last set of children of this node.
383 ///
384 /// Returns None if there are no known captures in this node instance.
385 #[inline(always)]
386 fn last_capture(&self) -> Option<Capture> {
387 self.capture(Key::Index(self.captures_len().checked_sub(1)?))
388 }
389
390 /// Returns all valid [capture](Self::capture) keys.
391 ///
392 /// The keys in the returning array come in order such as the index of the
393 /// [Key] in this array corresponds to the [Key::Index] with this index.
394 ///
395 /// However the function prefers to return an array of [Key::Name] so that
396 /// the calling side gains both the capture number and the capture name
397 /// metadata.
398 fn capture_keys(&self) -> &'static [Key<'static>];
399
400 /// Returns a total number of [captures](Self::capture) of this node instance.
401 #[inline(always)]
402 fn captures_len(&self) -> usize {
403 self.capture_keys().len()
404 }
405
406 /// Returns an iterator over all capture values.
407 #[inline(always)]
408 fn captures_iter(&self) -> CapturesIter<Self>
409 where
410 Self: Sized,
411 {
412 CapturesIter::new(self)
413 }
414
415 /// Returns an iterator over all children of this node.
416 ///
417 /// This is a version of the [captures_iter](Self::captures_iter) that
418 /// subsequently iterates each child inside the [Capture] and flattens
419 /// the result.
420 #[inline(always)]
421 fn children_iter(&self) -> ChildrenIter<Self>
422 where
423 Self: Sized,
424 {
425 ChildrenIter::new(self)
426 }
427
428 /// Returns a [NodeRef] reference of a child node that precedes
429 /// the `current` child node.
430 ///
431 /// Returns None if the `current` node is the first child, or if
432 /// the `current` is not a reference to a child node.
433 fn prev_child_node(&self, current: &NodeRef) -> Option<&NodeRef>
434 where
435 Self: Sized,
436 {
437 let mut nodes = self
438 .children_iter()
439 .rev()
440 .filter(|child| child.kind().is_node())
441 .map(|child| child.as_node_ref());
442
443 loop {
444 let probe = nodes.next()?;
445
446 if probe == current {
447 return nodes.next();
448 }
449 }
450 }
451
452 /// Returns a [NodeRef] reference of a child node that follows after
453 /// the `current` child node.
454 ///
455 /// Returns None if the `current` node is the last child, or if
456 /// the `current` is not a reference to a child node.
457 fn next_child_node(&self, current: &NodeRef) -> Option<&NodeRef>
458 where
459 Self: Sized,
460 {
461 let mut nodes = self
462 .children_iter()
463 .filter(|child| child.kind().is_node())
464 .map(|child| child.as_node_ref());
465
466 loop {
467 let probe = nodes.next()?;
468
469 if probe == current {
470 return nodes.next();
471 }
472 }
473 }
474
475 /// Infers the [site span](SiteSpan) of this node.
476 ///
477 /// The underlying algorithm infers the span based on the leftmost captured
478 /// token (or the leftmost token of the leftmost descendant node)
479 /// start site, and the rightmost token end site correspondingly.
480 ///
481 /// If the underlying syntax captures the leftmost and the rightmost tokens
482 /// of the corresponding parse rules, this span matches the parsed segment
483 /// span.
484 ///
485 /// Returns None if the span cannot be inferred based on the node captures
486 /// (e.g., if the syntax does not have [TokenRef] captures).
487 ///
488 /// The `unit` parameter is the compilation unit
489 /// (e.g., [Document](crate::units::Document)) to which this Node instance
490 /// belongs.
491 fn span(&self, unit: &impl CompilationUnit) -> Option<SiteSpan>
492 where
493 Self: Sized,
494 {
495 let start = self.start(unit)?;
496 let end = self.end(unit)?;
497
498 Some(start..end)
499 }
500
501 /// Infers the start [site](Site) of this node.
502 ///
503 /// The underlying algorithm infers the site based on the leftmost captured
504 /// token (or the leftmost token of the leftmost descendant node)
505 /// start site.
506 ///
507 /// If the underlying syntax captures the leftmost tokens of
508 /// the corresponding parse rules, this span matches the parsed segment
509 /// start site.
510 ///
511 /// Returns None if the site cannot be inferred based on the node captures
512 /// (e.g., if the syntax does not have [TokenRef] captures).
513 ///
514 /// The `unit` parameter is the compilation unit
515 /// (e.g., [Document](crate::units::Document)) to which this Node instance
516 /// belongs.
517 fn start(&self, unit: &impl CompilationUnit) -> Option<Site>
518 where
519 Self: Sized,
520 {
521 for child in self.captures_iter() {
522 match child.start(unit) {
523 None => continue,
524 Some(site) => return Some(site),
525 }
526 }
527
528 None
529 }
530
531 /// Infers the end [site](Site) of this node.
532 ///
533 /// The underlying algorithm infers the site based on the rightmost captured
534 /// token (or the rightmost token of the rightmost descendant node)
535 /// end site.
536 ///
537 /// If the underlying syntax captures the rightmost tokens of
538 /// the corresponding parse rules, this span matches the parsed segment
539 /// end site.
540 ///
541 /// Returns None if the site cannot be inferred based on the node captures
542 /// (e.g., if the syntax does not have [TokenRef] captures).
543 ///
544 /// The `unit` parameter is the compilation unit
545 /// (e.g., [Document](crate::units::Document)) to which this Node instance
546 /// belongs.
547 fn end(&self, unit: &impl CompilationUnit) -> Option<Site>
548 where
549 Self: Sized,
550 {
551 for child in self.captures_iter().rev() {
552 match child.end(unit) {
553 None => continue,
554 Some(site) => return Some(site),
555 }
556 }
557
558 None
559 }
560
561 /// A debug name of the parse rule.
562 ///
563 /// The returning value is the same as `self.name(self.rule())`.
564 ///
565 /// See [name](Self::name) for details.
566 fn rule_name(rule: NodeRule) -> Option<&'static str>
567 where
568 Self: Sized;
569
570 /// An end-user display description of the parse rule.
571 ///
572 /// The returning value is the same as `self.describe(self.rule(), verbose)`.
573 ///
574 /// See [describe](Self::describe) for details.
575 fn rule_description(rule: NodeRule, verbose: bool) -> Option<&'static str>
576 where
577 Self: Sized;
578}
579
580/// A globally unique reference of the [node](Node) in the syntax tree.
581///
582/// Each [syntax tree](crate::syntax::SyntaxTree) node could be uniquely
583/// addressed within a pair of the [Id] and [Entry], where the identifier
584/// uniquely addresses a specific compilation unit instance (syntax tree), and
585/// the entry part addresses a node within this tree.
586///
587/// Essentially, NodeRef is a composite index.
588///
589/// Both components of this index form a unique pair
590/// (within the current process), because each compilation unit has a unique
591/// identifier, and the nodes within the syntax tree always receive unique
592/// [Entry] indices within the syntax tree.
593///
594/// If the node instance has been removed from the syntax tree over time,
595/// new nodes within this syntax tree will never occupy the same NodeRef object,
596/// but the NodeRef referred to the removed Node would become _invalid_.
597///
598/// The [nil](NodeRef::nil) NodeRefs are special references that are considered
599/// to be always invalid (they intentionally don't refer to any node within
600/// any syntax tree).
601///
602/// Two distinct instances of the nil NodeRef are always equal.
603#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
604pub struct NodeRef {
605 /// An identifier of the syntax tree.
606 pub id: Id,
607
608 /// A versioned index of the node instance within the syntax tree.
609 pub entry: Entry,
610}
611
612impl Debug for NodeRef {
613 #[inline]
614 fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
615 match self.is_nil() {
616 false => formatter.write_fmt(format_args!(
617 "NodeRef(id: {:?}, entry: {:?})",
618 self.id, self.entry,
619 )),
620 true => formatter.write_str("NodeRef(Nil)"),
621 }
622 }
623}
624
625impl Identifiable for NodeRef {
626 #[inline(always)]
627 fn id(&self) -> Id {
628 self.id
629 }
630}
631
632impl Default for NodeRef {
633 #[inline(always)]
634 fn default() -> Self {
635 Self::nil()
636 }
637}
638
639impl PolyRef for NodeRef {
640 #[inline(always)]
641 fn kind(&self) -> RefKind {
642 RefKind::Node
643 }
644
645 #[inline(always)]
646 fn is_nil(&self) -> bool {
647 self.id.is_nil() || self.entry.is_nil()
648 }
649
650 #[inline(always)]
651 fn as_variant(&self) -> PolyVariant {
652 PolyVariant::Node(*self)
653 }
654
655 #[inline(always)]
656 fn as_token_ref(&self) -> &TokenRef {
657 &NIL_TOKEN_REF
658 }
659
660 #[inline(always)]
661 fn as_node_ref(&self) -> &NodeRef {
662 self
663 }
664
665 #[inline(always)]
666 fn span(&self, unit: &impl CompilationUnit) -> Option<SiteSpan> {
667 self.deref(unit)?.span(unit)
668 }
669}
670
671impl NodeRef {
672 /// Returns a NodeRef that intentionally does not refer to any node within
673 /// any syntax tree.
674 ///
675 /// If you need just a static reference to the nil NodeRef, use
676 /// the predefined [NIL_NODE_REF] static.
677 #[inline(always)]
678 pub const fn nil() -> Self {
679 Self {
680 id: Id::nil(),
681 entry: Entry::nil(),
682 }
683 }
684
685 /// Immutably borrows a syntax tree node referred to by this NodeRef.
686 ///
687 /// Returns None if this NodeRef is not valid for the specified `tree`.
688 #[inline(always)]
689 pub fn deref<'tree, N: Node>(
690 &self,
691 tree: &'tree impl SyntaxTree<Node = N>,
692 ) -> Option<&'tree N> {
693 if self.id != tree.id() {
694 return None;
695 }
696
697 tree.get_node(&self.entry)
698 }
699
700 /// Mutably borrows a syntax tree node referred to by this NodeRef.
701 ///
702 /// Returns None if this NodeRef is not valid for the specified `tree`.
703 #[inline(always)]
704 pub fn deref_mut<'tree, N: Node>(
705 &self,
706 tree: &'tree mut impl SyntaxTree<Node = N>,
707 ) -> Option<&'tree mut N> {
708 if self.id != tree.id() {
709 return None;
710 }
711
712 tree.get_node_mut(&self.entry)
713 }
714
715 /// Returns a syntax parse rule that parses referred node.
716 ///
717 /// Returns [NON_RULE] if this NodeRef is not valid for the specified `tree`.
718 ///
719 /// See [AbstractNode::rule] for details.
720 #[inline(always)]
721 pub fn rule(&self, tree: &impl SyntaxTree) -> NodeRule {
722 self.deref(tree).map(AbstractNode::rule).unwrap_or(NON_RULE)
723 }
724
725 /// Returns a debug name of the referred node.
726 ///
727 /// Returns None if this NodeRef is not valid for the specified `tree`,
728 /// or if the node instance does not have a name.
729 ///
730 /// See [AbstractNode::name] for details.
731 #[inline(always)]
732 pub fn name<N: Node>(&self, tree: &impl SyntaxTree<Node = N>) -> Option<&'static str> {
733 self.deref(tree).map(AbstractNode::name).flatten()
734 }
735
736 /// Returns an end-user display description of the referred node.
737 ///
738 /// Returns None if this NodeRef is not valid for the specified `tree`,
739 /// or if the node instance does not have a description.
740 ///
741 /// See [AbstractNode::describe] for details.
742 #[inline(always)]
743 pub fn describe<N: Node>(
744 &self,
745 tree: &impl SyntaxTree<Node = N>,
746 verbose: bool,
747 ) -> Option<&'static str> {
748 self.deref(tree)
749 .map(|node| node.describe(verbose))
750 .flatten()
751 }
752
753 /// Returns a reference of the parent node of the referred node.
754 ///
755 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
756 /// the specified `tree`, or if the node instance does not have a parent.
757 ///
758 /// See [AbstractNode::parent_ref] for details.
759 #[inline(always)]
760 pub fn parent(&self, tree: &impl SyntaxTree) -> NodeRef {
761 let Some(node) = self.deref(tree) else {
762 return NodeRef::nil();
763 };
764
765 node.parent_ref()
766 }
767
768 /// Returns a reference to the first child node of the referred node.
769 ///
770 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
771 /// the specified `tree`, or if the node instance does not have child nodes.
772 pub fn first_child(&self, tree: &impl SyntaxTree) -> NodeRef {
773 let Some(node) = self.deref(tree) else {
774 return NodeRef::nil();
775 };
776
777 node.children_iter()
778 .filter(|child| child.kind().is_node())
779 .map(|child| child.as_node_ref())
780 .next()
781 .copied()
782 .unwrap_or_default()
783 }
784
785 /// Returns a reference to the last child node of the referred node.
786 ///
787 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
788 /// the specified `tree`, or if the node instance does not have child nodes.
789 pub fn last_child(&self, tree: &impl SyntaxTree) -> NodeRef {
790 let Some(node) = self.deref(tree) else {
791 return NodeRef::nil();
792 };
793
794 node.children_iter()
795 .rev()
796 .filter(|child| child.kind().is_node())
797 .map(|child| child.as_node_ref())
798 .next()
799 .copied()
800 .unwrap_or_default()
801 }
802
803 /// Returns a child node by the capture `key`.
804 ///
805 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
806 /// the specified `tree`, or if the specified `key` parameter does not
807 /// address a NodeRef capture.
808 ///
809 /// If the capture referred to by the `key` parameter addresses multiple
810 /// nodes, the function returns the first one.
811 ///
812 /// See [AbstractNode::capture] for details.
813 pub fn get_child<'a>(&self, tree: &impl SyntaxTree, key: impl Into<Key<'a>>) -> NodeRef {
814 let Some(node) = self.deref(tree) else {
815 return NodeRef::nil();
816 };
817
818 let Some(child) = node.capture(key.into()) else {
819 return NodeRef::nil();
820 };
821
822 let Some(first) = child.first() else {
823 return NodeRef::nil();
824 };
825
826 *first.as_node_ref()
827 }
828
829 /// Returns a child token by the capture `key`.
830 ///
831 /// Returns [nil](TokenRef::nil) if this NodeRef is not valid for
832 /// the specified `tree`, or if the specified `key` parameter does not
833 /// address a [TokenRef] capture.
834 ///
835 /// If the capture referred to by the `key` parameter addresses multiple
836 /// tokens, the function returns the first one.
837 ///
838 /// See [AbstractNode::capture] for details.
839 pub fn get_token(&self, tree: &impl SyntaxTree, key: &'static str) -> TokenRef {
840 let Some(node) = self.deref(tree) else {
841 return TokenRef::nil();
842 };
843
844 let Some(child) = node.capture(key.into()) else {
845 return TokenRef::nil();
846 };
847
848 let Some(first) = child.first() else {
849 return TokenRef::nil();
850 };
851
852 *first.as_token_ref()
853 }
854
855 /// Returns a previous sibling node of the node referred to by this NodeRef
856 /// within the node's parent.
857 ///
858 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
859 /// the specified `tree`, or if the referred node does not have a preceded
860 /// sibling.
861 pub fn prev_sibling(&self, tree: &impl SyntaxTree) -> NodeRef {
862 let Some(node) = self.deref(tree) else {
863 return NodeRef::nil();
864 };
865
866 let Some(parent) = node.parent_ref().deref(tree) else {
867 return NodeRef::nil();
868 };
869
870 let Some(sibling) = parent.prev_child_node(self) else {
871 return NodeRef::nil();
872 };
873
874 *sibling
875 }
876
877 /// Returns a next sibling node of the node referred to by this NodeRef
878 /// within the node's parent.
879 ///
880 /// Returns [nil](NodeRef::nil) if this NodeRef is not valid for
881 /// the specified `tree`, or if the referred node does not have a successive
882 /// sibling.
883 pub fn next_sibling(&self, tree: &impl SyntaxTree) -> NodeRef {
884 let Some(node) = self.deref(tree) else {
885 return NodeRef::nil();
886 };
887
888 let Some(parent) = node.parent_ref().deref(tree) else {
889 return NodeRef::nil();
890 };
891
892 let Some(sibling) = parent.next_child_node(self) else {
893 return NodeRef::nil();
894 };
895
896 *sibling
897 }
898
899 /// Returns true if the node referred to by this NodeRef exists in the specified
900 /// `tree`.
901 #[inline(always)]
902 pub fn is_valid_ref(&self, tree: &impl SyntaxTree) -> bool {
903 if self.id != tree.id() {
904 return false;
905 }
906
907 tree.has_node(&self.entry)
908 }
909}