Skip to content

Commit

Permalink
chore: implement Grit node bindings (#2697)
Browse files Browse the repository at this point in the history
  • Loading branch information
arendjr authored May 3, 2024
1 parent ef8abbe commit 9db5f0e
Showing 1 changed file with 111 additions and 21 deletions.
132 changes: 111 additions & 21 deletions crates/biome_grit_patterns/src/grit_node.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::util::TextRangeGritExt;
use biome_grit_syntax::GritSyntaxNode;
use grit_util::{AstCursor, AstNode as GritAstNode, ByteRange, CodeRange};
use std::{borrow::Cow, ops::Deref, str::Utf8Error};
Expand Down Expand Up @@ -27,84 +28,173 @@ impl From<&GritSyntaxNode> for GritNode {

impl GritAstNode for GritNode {
fn ancestors(&self) -> impl Iterator<Item = Self> {
TodoIterator
AncestorIterator::new(self)
}

fn children(&self) -> impl Iterator<Item = Self> {
TodoIterator
ChildrenIterator::new(self)
}

fn parent(&self) -> Option<Self> {
todo!()
self.0.parent().map(Into::into)
}

fn next_named_node(&self) -> Option<Self> {
todo!()
let mut current_node = Cow::Borrowed(&self.0);
loop {
if let Some(sibling) = current_node.next_sibling() {
return Some(sibling.into());
}
current_node = Cow::Owned(current_node.parent()?);
}
}

fn previous_named_node(&self) -> Option<Self> {
todo!()
let mut current_node = Cow::Borrowed(&self.0);
loop {
if let Some(sibling) = current_node.prev_sibling() {
return Some(sibling.into());
}
current_node = Cow::Owned(current_node.parent()?);
}
}

fn next_sibling(&self) -> Option<Self> {
todo!()
self.0.next_sibling().map(Into::into)
}

fn previous_sibling(&self) -> Option<Self> {
todo!()
self.0.prev_sibling().map(Into::into)
}

fn text(&self) -> Result<Cow<str>, Utf8Error> {
todo!()
Ok(Cow::Owned(self.0.text_trimmed().to_string()))
}

fn byte_range(&self) -> ByteRange {
todo!()
self.0.text_trimmed_range().to_byte_range()
}

fn code_range(&self) -> CodeRange {
todo!()
let range = self.0.text_trimmed_range();
CodeRange {
start: range.start().into(),
end: range.end().into(),
// Code ranges contain an address so they can quickly check whether
// a particular binding belongs to a given range or not.
address: self
.0
.first_token()
.map(|token| token.text().as_ptr() as usize)
.unwrap_or_default(),
}
}

fn full_source(&self) -> &str {
todo!()
// This should not be a problem anytime soon, though we may want to
// reconsider when we implement rewrites.
unimplemented!("Full source of file not available")
}

fn walk(&self) -> impl AstCursor<Node = Self> {
TodoCursor
GritNodeCursor::new(self)
}
}

#[derive(Clone)]
struct TodoIterator;
pub struct AncestorIterator {
node: Option<GritNode>,
}

impl Iterator for TodoIterator {
impl AncestorIterator {
fn new(node: &GritNode) -> Self {
Self {
node: Some(node.clone()),
}
}
}

impl Iterator for AncestorIterator {
type Item = GritNode;

fn next(&mut self) -> Option<Self::Item> {
todo!()
let node = self.node.as_ref().cloned()?;
self.node = node.parent();
Some(node)
}
}

pub struct ChildrenIterator {
cursor: Option<GritNodeCursor>,
}

impl ChildrenIterator {
fn new(node: &GritNode) -> Self {
let mut cursor = GritNodeCursor::new(node);
Self {
cursor: cursor.goto_first_child().then_some(cursor),
}
}
}

impl Iterator for ChildrenIterator {
type Item = GritNode;

fn next(&mut self) -> Option<Self::Item> {
let c = self.cursor.as_mut()?;
let node = c.node();
if !c.goto_next_sibling() {
self.cursor = None;
}
Some(node)
}
}

#[derive(Clone)]
struct TodoCursor;
struct GritNodeCursor {
node: GritNode,
}

impl GritNodeCursor {
fn new(node: &GritNode) -> Self {
Self { node: node.clone() }
}
}

impl AstCursor for TodoCursor {
impl AstCursor for GritNodeCursor {
type Node = GritNode;

fn goto_first_child(&mut self) -> bool {
todo!()
match self.node.first_child() {
Some(child) => {
self.node = child.into();
true
}
None => false,
}
}

fn goto_parent(&mut self) -> bool {
todo!()
match self.node.parent() {
Some(parent) => {
self.node = parent;
true
}
None => false,
}
}

fn goto_next_sibling(&mut self) -> bool {
todo!()
match self.node.next_sibling() {
Some(sibling) => {
self.node = sibling;
true
}
None => false,
}
}

fn node(&self) -> Self::Node {
todo!()
self.node.clone()
}
}

0 comments on commit 9db5f0e

Please sign in to comment.