mirror of
https://github.com/RGBCube/cstree
synced 2025-07-27 09:07:44 +00:00
refactor red tree iterators into own module and forward more features of the underlying iters
This commit is contained in:
parent
3982732d42
commit
1fbb7453f2
7 changed files with 182 additions and 101 deletions
|
@ -51,7 +51,7 @@ mod green;
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
mod syntax;
|
mod syntax;
|
||||||
|
|
||||||
#[cfg(feature = "serde1")]
|
#[cfg(feature = "serialize")]
|
||||||
mod serde_impls;
|
mod serde_impls;
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
mod utility_types;
|
mod utility_types;
|
||||||
|
|
164
src/syntax/iter.rs
Normal file
164
src/syntax/iter.rs
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
//! Red tree iterators.
|
||||||
|
|
||||||
|
use std::iter::FusedIterator;
|
||||||
|
|
||||||
|
use text_size::TextSize;
|
||||||
|
|
||||||
|
use crate::{green::GreenElementRef, GreenNodeChildren, Language, SyntaxElementRef, SyntaxNode};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Iter<'n> {
|
||||||
|
green: GreenNodeChildren<'n>,
|
||||||
|
offset: TextSize,
|
||||||
|
index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> Iter<'n> {
|
||||||
|
fn new<L: Language, D>(parent: &'n SyntaxNode<L, D>) -> Self {
|
||||||
|
let offset = parent.text_range().start();
|
||||||
|
let green: GreenNodeChildren<'_> = parent.green().children();
|
||||||
|
Iter {
|
||||||
|
green,
|
||||||
|
offset,
|
||||||
|
index: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> Iterator for Iter<'n> {
|
||||||
|
type Item = (GreenElementRef<'n>, usize, TextSize);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.green.next().map(|element| {
|
||||||
|
let offset = self.offset;
|
||||||
|
let index = self.index;
|
||||||
|
self.offset += element.text_len();
|
||||||
|
self.index += 1;
|
||||||
|
(element, index, offset)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.green.size_hint()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn count(self) -> usize
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.green.count()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> ExactSizeIterator for Iter<'n> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.green.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n> FusedIterator for Iter<'n> {}
|
||||||
|
|
||||||
|
/// An iterator over the child nodes of a [`SyntaxNode`].
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SyntaxNodeChildren<'n, L: Language, D: 'static = ()> {
|
||||||
|
inner: Iter<'n>,
|
||||||
|
parent: &'n SyntaxNode<L, D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> SyntaxNodeChildren<'n, L, D> {
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn new(parent: &'n SyntaxNode<L, D>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Iter::new(parent),
|
||||||
|
parent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> Iterator for SyntaxNodeChildren<'n, L, D> {
|
||||||
|
type Item = &'n SyntaxNode<L, D>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
for (element, index, offset) in &mut self.inner {
|
||||||
|
if let Some(&node) = element.as_node() {
|
||||||
|
return Some(self.parent.get_or_add_node(node, index, offset).as_node().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.inner.size_hint()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn count(self) -> usize
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.inner.count()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> ExactSizeIterator for SyntaxNodeChildren<'n, L, D> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.inner.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, L: Language, D> FusedIterator for SyntaxNodeChildren<'n, L, D> {}
|
||||||
|
|
||||||
|
/// An iterator over the children of a [`SyntaxNode`].
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SyntaxElementChildren<'n, L: Language, D: 'static = ()> {
|
||||||
|
inner: Iter<'n>,
|
||||||
|
parent: &'n SyntaxNode<L, D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> SyntaxElementChildren<'n, L, D> {
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn new(parent: &'n SyntaxNode<L, D>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Iter::new(parent),
|
||||||
|
parent,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> Iterator for SyntaxElementChildren<'n, L, D> {
|
||||||
|
type Item = SyntaxElementRef<'n, L, D>;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let parent = self.parent;
|
||||||
|
self.inner
|
||||||
|
.next()
|
||||||
|
.map(|(green, index, offset)| parent.get_or_add_element(green, index, offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.inner.size_hint()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn count(self) -> usize
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.inner.count()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, L: Language, D> ExactSizeIterator for SyntaxElementChildren<'n, L, D> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.inner.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, L: Language, D> FusedIterator for SyntaxElementChildren<'n, L, D> {}
|
|
@ -8,11 +8,13 @@
|
||||||
mod element;
|
mod element;
|
||||||
pub use element::{SyntaxElement, SyntaxElementRef};
|
pub use element::{SyntaxElement, SyntaxElementRef};
|
||||||
mod node;
|
mod node;
|
||||||
pub use node::{SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren};
|
pub use node::SyntaxNode;
|
||||||
mod token;
|
mod token;
|
||||||
pub use token::SyntaxToken;
|
pub use token::SyntaxToken;
|
||||||
mod resolved;
|
mod resolved;
|
||||||
pub use resolved::{ResolvedElement, ResolvedElementRef, ResolvedNode, ResolvedToken};
|
pub use resolved::{ResolvedElement, ResolvedElementRef, ResolvedNode, ResolvedToken};
|
||||||
|
mod iter;
|
||||||
|
pub use iter::{SyntaxElementChildren, SyntaxNodeChildren};
|
||||||
|
|
||||||
mod text;
|
mod text;
|
||||||
pub use text::SyntaxText;
|
pub use text::SyntaxText;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(feature = "serde1")]
|
#[cfg(feature = "serialize")]
|
||||||
use crate::serde_impls::{SerializeWithData, SerializeWithResolver};
|
use crate::serde_impls::{SerializeWithData, SerializeWithResolver};
|
||||||
use crate::{
|
use crate::{
|
||||||
green::{GreenElementRef, SyntaxKind},
|
green::{GreenElementRef, SyntaxKind},
|
||||||
|
@ -507,7 +507,12 @@ impl<L: Language, D> SyntaxNode<L, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_or_add_node(&self, node: &GreenNode, index: usize, offset: TextSize) -> SyntaxElementRef<'_, L, D> {
|
pub(super) fn get_or_add_node(
|
||||||
|
&self,
|
||||||
|
node: &GreenNode,
|
||||||
|
index: usize,
|
||||||
|
offset: TextSize,
|
||||||
|
) -> SyntaxElementRef<'_, L, D> {
|
||||||
if let Some(elem) = self.read(index) {
|
if let Some(elem) = self.read(index) {
|
||||||
debug_assert_eq!(elem.text_range().start(), offset);
|
debug_assert_eq!(elem.text_range().start(), offset);
|
||||||
return elem;
|
return elem;
|
||||||
|
@ -520,7 +525,7 @@ impl<L: Language, D> SyntaxNode<L, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_or_add_element(
|
pub(super) fn get_or_add_element(
|
||||||
&self,
|
&self,
|
||||||
element: GreenElementRef<'_>,
|
element: GreenElementRef<'_>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -946,7 +951,7 @@ impl<L: Language, D> SyntaxNode<L, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde1")]
|
#[cfg(feature = "serialize")]
|
||||||
impl<L, D> SyntaxNode<L, D>
|
impl<L, D> SyntaxNode<L, D>
|
||||||
where
|
where
|
||||||
L: Language,
|
L: Language,
|
||||||
|
@ -973,96 +978,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
struct Iter<'n> {
|
|
||||||
green: GreenNodeChildren<'n>,
|
|
||||||
offset: TextSize,
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n> Iter<'n> {
|
|
||||||
fn new<L: Language, D>(parent: &'n SyntaxNode<L, D>) -> Self {
|
|
||||||
let offset = parent.text_range().start();
|
|
||||||
let green: GreenNodeChildren<'_> = parent.green().children();
|
|
||||||
Iter {
|
|
||||||
green,
|
|
||||||
offset,
|
|
||||||
index: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next(&mut self) -> Option<(GreenElementRef, usize, TextSize)> {
|
|
||||||
self.green.next().map(|element| {
|
|
||||||
let offset = self.offset;
|
|
||||||
let index = self.index;
|
|
||||||
self.offset += element.text_len();
|
|
||||||
self.index += 1;
|
|
||||||
(element, index, offset)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An iterator over the child nodes of a [`SyntaxNode`].
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct SyntaxNodeChildren<'n, L: Language, D: 'static = ()> {
|
|
||||||
inner: Iter<'n>,
|
|
||||||
parent: &'n SyntaxNode<L, D>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n, L: Language, D> SyntaxNodeChildren<'n, L, D> {
|
|
||||||
#[inline]
|
|
||||||
fn new(parent: &'n SyntaxNode<L, D>) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Iter::new(parent),
|
|
||||||
parent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n, L: Language, D> Iterator for SyntaxNodeChildren<'n, L, D> {
|
|
||||||
type Item = &'n SyntaxNode<L, D>;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
while let Some((element, index, offset)) = self.inner.next() {
|
|
||||||
if let Some(&node) = element.as_node() {
|
|
||||||
return Some(self.parent.get_or_add_node(node, index, offset).as_node().unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An iterator over the children of a [`SyntaxNode`].
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct SyntaxElementChildren<'n, L: Language, D: 'static = ()> {
|
|
||||||
inner: Iter<'n>,
|
|
||||||
parent: &'n SyntaxNode<L, D>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n, L: Language, D> SyntaxElementChildren<'n, L, D> {
|
|
||||||
#[inline]
|
|
||||||
fn new(parent: &'n SyntaxNode<L, D>) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Iter::new(parent),
|
|
||||||
parent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n, L: Language, D> Iterator for SyntaxElementChildren<'n, L, D> {
|
|
||||||
type Item = SyntaxElementRef<'n, L, D>;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let parent = self.parent;
|
|
||||||
self.inner
|
|
||||||
.next()
|
|
||||||
.map(|(green, index, offset)| parent.get_or_add_element(green, index, offset))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GreenNode {
|
impl GreenNode {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn children_from(
|
fn children_from(
|
||||||
|
|
|
@ -214,7 +214,7 @@ impl<L: Language, D> fmt::Display for ResolvedToken<L, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde1")]
|
#[cfg(feature = "serialize")]
|
||||||
impl<L, D> ResolvedNode<L, D>
|
impl<L, D> ResolvedNode<L, D>
|
||||||
where
|
where
|
||||||
L: Language,
|
L: Language,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod basic;
|
mod basic;
|
||||||
mod regressions;
|
mod regressions;
|
||||||
mod sendsync;
|
mod sendsync;
|
||||||
#[cfg(feature = "serde1")]
|
#[cfg(feature = "serialize")]
|
||||||
mod serde;
|
mod serde;
|
||||||
|
|
||||||
use cstree::{GreenNode, GreenNodeBuilder, Language, NodeCache, SyntaxKind};
|
use cstree::{GreenNode, GreenNodeBuilder, Language, NodeCache, SyntaxKind};
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{build_recursive, build_tree_with_cache, ResolvedNode};
|
||||||
|
|
||||||
use super::{Element, SyntaxNode};
|
use super::{Element, SyntaxNode};
|
||||||
use cstree::{
|
use cstree::{
|
||||||
interning::{IntoResolver, Rodeo},
|
interning::{new_interner, IntoResolver},
|
||||||
GreenNodeBuilder, NodeCache, NodeOrToken,
|
GreenNodeBuilder, NodeCache, NodeOrToken,
|
||||||
};
|
};
|
||||||
use serde_test::Token;
|
use serde_test::Token;
|
||||||
|
@ -238,7 +238,7 @@ fn attach_data(node: &SyntaxNode<String>) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_tree_with_data_with_resolver() {
|
fn serialize_tree_with_data_with_resolver() {
|
||||||
let mut interner = Rodeo::with_hasher(Default::default());
|
let mut interner = new_interner();
|
||||||
let mut cache = NodeCache::with_interner(&mut interner);
|
let mut cache = NodeCache::with_interner(&mut interner);
|
||||||
|
|
||||||
let root = three_level_tree();
|
let root = three_level_tree();
|
||||||
|
@ -256,7 +256,7 @@ fn serialize_tree_with_data_with_resolver() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_tree_with_resolver() {
|
fn serialize_tree_with_resolver() {
|
||||||
let mut interner = Rodeo::with_hasher(Default::default());
|
let mut interner = new_interner();
|
||||||
let mut cache = NodeCache::with_interner(&mut interner);
|
let mut cache = NodeCache::with_interner(&mut interner);
|
||||||
|
|
||||||
let root = three_level_tree();
|
let root = three_level_tree();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue