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)]
|
||||
mod syntax;
|
||||
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serialize")]
|
||||
mod serde_impls;
|
||||
#[allow(missing_docs)]
|
||||
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;
|
||||
pub use element::{SyntaxElement, SyntaxElementRef};
|
||||
mod node;
|
||||
pub use node::{SyntaxElementChildren, SyntaxNode, SyntaxNodeChildren};
|
||||
pub use node::SyntaxNode;
|
||||
mod token;
|
||||
pub use token::SyntaxToken;
|
||||
mod resolved;
|
||||
pub use resolved::{ResolvedElement, ResolvedElementRef, ResolvedNode, ResolvedToken};
|
||||
mod iter;
|
||||
pub use iter::{SyntaxElementChildren, SyntaxNodeChildren};
|
||||
|
||||
mod text;
|
||||
pub use text::SyntaxText;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::*;
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serialize")]
|
||||
use crate::serde_impls::{SerializeWithData, SerializeWithResolver};
|
||||
use crate::{
|
||||
green::{GreenElementRef, SyntaxKind},
|
||||
|
@ -507,7 +507,12 @@ impl<L: Language, D> SyntaxNode<L, D> {
|
|||
}
|
||||
|
||||
#[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) {
|
||||
debug_assert_eq!(elem.text_range().start(), offset);
|
||||
return elem;
|
||||
|
@ -520,7 +525,7 @@ impl<L: Language, D> SyntaxNode<L, D> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_or_add_element(
|
||||
pub(super) fn get_or_add_element(
|
||||
&self,
|
||||
element: GreenElementRef<'_>,
|
||||
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>
|
||||
where
|
||||
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 {
|
||||
#[inline(always)]
|
||||
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>
|
||||
where
|
||||
L: Language,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
mod basic;
|
||||
mod regressions;
|
||||
mod sendsync;
|
||||
#[cfg(feature = "serde1")]
|
||||
#[cfg(feature = "serialize")]
|
||||
mod serde;
|
||||
|
||||
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 cstree::{
|
||||
interning::{IntoResolver, Rodeo},
|
||||
interning::{new_interner, IntoResolver},
|
||||
GreenNodeBuilder, NodeCache, NodeOrToken,
|
||||
};
|
||||
use serde_test::Token;
|
||||
|
@ -238,7 +238,7 @@ fn attach_data(node: &SyntaxNode<String>) {
|
|||
|
||||
#[test]
|
||||
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 root = three_level_tree();
|
||||
|
@ -256,7 +256,7 @@ fn serialize_tree_with_data_with_resolver() {
|
|||
|
||||
#[test]
|
||||
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 root = three_level_tree();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue