1
Fork 0
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:
Domenic Quirl 2021-09-17 17:10:05 +02:00
parent 3982732d42
commit 1fbb7453f2
7 changed files with 182 additions and 101 deletions

View file

@ -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
View 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> {}

View file

@ -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;

View file

@ -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(

View file

@ -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,

View file

@ -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};

View file

@ -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();