diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:25:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:25:56 +0000 |
commit | 018c4950b9406055dec02ef0fb52f132e2bb1e2c (patch) | |
tree | a835ebdf2088ef88fa681f8fad45f09922c1ae9a /vendor/rowan/src/ast.rs | |
parent | Adding debian version 1.75.0+dfsg1-5. (diff) | |
download | rustc-018c4950b9406055dec02ef0fb52f132e2bb1e2c.tar.xz rustc-018c4950b9406055dec02ef0fb52f132e2bb1e2c.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rowan/src/ast.rs')
-rw-r--r-- | vendor/rowan/src/ast.rs | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/vendor/rowan/src/ast.rs b/vendor/rowan/src/ast.rs index ea848e08a..856a9f63c 100644 --- a/vendor/rowan/src/ast.rs +++ b/vendor/rowan/src/ast.rs @@ -55,7 +55,7 @@ pub trait AstNode { } /// A "pointer" to a [`SyntaxNode`], via location in the source code. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct SyntaxNodePtr<L: Language> { kind: L::Kind, range: TextRange, @@ -67,24 +67,30 @@ impl<L: Language> SyntaxNodePtr<L> { Self { kind: node.kind(), range: node.text_range() } } + /// Like [`Self::try_to_node`] but panics instead of returning `None` on + /// failure. + pub fn to_node(&self, root: &SyntaxNode<L>) -> SyntaxNode<L> { + self.try_to_node(root).unwrap_or_else(|| panic!("can't resolve {self:?} with {root:?}")) + } + /// "Dereferences" the pointer to get the [`SyntaxNode`] it points to. /// - /// Panics if node is not found, so make sure that `root` syntax tree is - /// equivalent (is build from the same text) to the tree which was - /// originally used to get this [`SyntaxNodePtr`]. + /// Returns `None` if the node is not found, so make sure that the `root` + /// syntax tree is equivalent to (i.e. is build from the same text from) the + /// tree which was originally used to get this [`SyntaxNodePtr`]. /// - /// Also panics if `root` is not actually a root (i.e. it has a parent). + /// Also returns `None` if `root` is not actually a root (i.e. it has a + /// parent). /// /// The complexity is linear in the depth of the tree and logarithmic in /// tree width. As most trees are shallow, thinking about this as /// `O(log(N))` in the size of the tree is not too wrong! - pub fn to_node(&self, root: &SyntaxNode<L>) -> SyntaxNode<L> { - assert!(root.parent().is_none()); - successors(Some(root.clone()), |node| { - node.child_or_token_at_range(self.range).and_then(|it| it.into_node()) - }) - .find(|it| it.text_range() == self.range && it.kind() == self.kind) - .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) + pub fn try_to_node(&self, root: &SyntaxNode<L>) -> Option<SyntaxNode<L>> { + if root.parent().is_some() { + return None; + } + successors(Some(root.clone()), |node| node.child_or_token_at_range(self.range)?.into_node()) + .find(|it| it.text_range() == self.range && it.kind() == self.kind) } /// Casts this to an [`AstPtr`] to the given node type if possible. @@ -117,10 +123,15 @@ impl<N: AstNode> AstPtr<N> { Self { raw: SyntaxNodePtr::new(node.syntax()) } } - /// Given the root node containing the node `n` that `self` is a pointer to, - /// returns `n`. See [`SyntaxNodePtr::to_node`]. + /// Like `Self::try_to_node` but panics on failure. pub fn to_node(&self, root: &SyntaxNode<N::Language>) -> N { - N::cast(self.raw.to_node(root)).unwrap() + self.try_to_node(root).unwrap_or_else(|| panic!("can't resolve {self:?} with {root:?}")) + } + + /// Given the root node containing the node `n` that `self` is a pointer to, + /// returns `n` if possible. See [`SyntaxNodePtr::try_to_node`]. + pub fn try_to_node(&self, root: &SyntaxNode<N::Language>) -> Option<N> { + N::cast(self.raw.try_to_node(root)?) } /// Returns the underlying [`SyntaxNodePtr`]. |