From 1f4e083cf9b93ed77be74fba071322ef929a2700 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Thu, 14 Dec 2023 22:51:57 +0100 Subject: [PATCH] Don't store node names as cursor state --- crates/codegen/parser/runtime/src/cst.rs | 2 +- crates/codegen/parser/runtime/src/cursor.rs | 61 +++++++++++-------- .../parser/runtime/src/napi/napi_cursor.rs | 2 +- .../runtime/src/support/choice_helper.rs | 2 +- .../runtime/src/support/parser_function.rs | 2 +- .../runtime/src/support/parser_result.rs | 4 +- .../outputs/cargo/crate/src/generated/cst.rs | 2 +- .../cargo/crate/src/generated/cursor.rs | 61 +++++++++++-------- .../crate/src/generated/napi/napi_cursor.rs | 2 +- .../src/generated/support/choice_helper.rs | 2 +- .../src/generated/support/parser_function.rs | 2 +- .../src/generated/support/parser_result.rs | 4 +- .../tests/src/doc_examples/cursor_api.rs | 8 +-- .../outputs/npm/crate/src/generated/cst.rs | 2 +- .../outputs/npm/crate/src/generated/cursor.rs | 61 +++++++++++-------- .../crate/src/generated/napi/napi_cursor.rs | 2 +- .../src/generated/support/choice_helper.rs | 2 +- .../src/generated/support/parser_function.rs | 2 +- .../src/generated/support/parser_result.rs | 4 +- .../testing/utils/src/cst_snapshots/mod.rs | 7 ++- .../testing/utils/src/version_pragmas/mod.rs | 2 +- 21 files changed, 132 insertions(+), 104 deletions(-) diff --git a/crates/codegen/parser/runtime/src/cst.rs b/crates/codegen/parser/runtime/src/cst.rs index 57fd5a479e..8c210a3016 100644 --- a/crates/codegen/parser/runtime/src/cst.rs +++ b/crates/codegen/parser/runtime/src/cst.rs @@ -131,7 +131,7 @@ impl RuleNode { let acc = String::with_capacity(self.text_len.utf8); self.cursor_with_offset(TextIndex::ZERO) - .filter_map(|(_, node)| node.into_token()) + .filter_map(|node| node.into_token()) .fold(acc, |mut acc, token| { acc.push_str(&token.text); acc diff --git a/crates/codegen/parser/runtime/src/cursor.rs b/crates/codegen/parser/runtime/src/cursor.rs index 2546f0b84a..481ab18079 100644 --- a/crates/codegen/parser/runtime/src/cursor.rs +++ b/crates/codegen/parser/runtime/src/cursor.rs @@ -2,14 +2,14 @@ use std::rc::Rc; -use crate::cst::{NamedNode, Node, RuleNode}; +use crate::cst::{Node, RuleNode}; use crate::kinds::{RuleKind, TokenKind}; use crate::text_index::{TextIndex, TextRange}; /// A [`PathNode`] that points to a [`RuleNode`]. #[derive(Clone, Debug, PartialEq, Eq)] struct PathRuleNode { - rule_node: (String, Rc), + rule_node: Rc, child_number: usize, text_offset: TextIndex, } @@ -17,7 +17,7 @@ struct PathRuleNode { impl PathRuleNode { fn into_path_node(self) -> PathNode { PathNode { - node: (self.rule_node.0, Node::Rule(self.rule_node.1)), + node: Node::Rule(self.rule_node), child_number: self.child_number, text_offset: self.text_offset, } @@ -28,7 +28,7 @@ impl PathRuleNode { #[derive(Clone, Debug, PartialEq, Eq)] struct PathNode { /// The node the cursor is currently pointing to. - node: NamedNode, + node: Node, /// The index of the current child node in the parent's children. // Required to go to the next/previous sibling. child_number: usize, @@ -39,14 +39,14 @@ struct PathNode { impl PathNode { fn text_range(&self) -> TextRange { let start = self.text_offset; - let end = start + self.node.1.text_len(); + let end = start + self.node.text_len(); start..end } fn to_path_rule_node(&self) -> Option { - if let (name, Node::Rule(rule_node)) = &self.node { + if let Node::Rule(rule_node) = &self.node { Some(PathRuleNode { - rule_node: (name.clone(), rule_node.clone()), + rule_node: rule_node.clone(), child_number: self.child_number, text_offset: self.text_offset, }) @@ -71,7 +71,7 @@ pub struct Cursor { } impl Iterator for Cursor { - type Item = NamedNode; + type Item = Node; fn next(&mut self) -> Option { if self.is_completed { @@ -79,6 +79,7 @@ impl Iterator for Cursor { } else { let cur = self.node(); self.go_to_next(); + Some(cur) } } @@ -89,7 +90,7 @@ impl Cursor { Self { path: vec![], current: PathNode { - node: (String::new(), node), + node, child_number: 0, text_offset, }, @@ -129,10 +130,20 @@ impl Cursor { } /// Returns the currently pointed to [`Node`]. - pub fn node(&self) -> NamedNode { + pub fn node(&self) -> Node { self.current.node.clone() } + pub fn node_name(&self) -> String { + if let Some(parent) = self.path.last() { + parent.rule_node.children[self.current.child_number] + .0 + .clone() + } else { + String::new() + } + } + /// Returns the text offset that corresponds to the beginning of the currently pointed to node. pub fn text_offset(&self) -> TextIndex { self.current.text_offset @@ -150,7 +161,7 @@ impl Cursor { /// Returns an iterator over the current node's ancestors, starting from the cursor root node. pub fn ancestors(&self) -> impl Iterator> { - self.path.iter().map(|elem| &elem.rule_node.1) + self.path.iter().map(|elem| &elem.rule_node) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. @@ -225,7 +236,7 @@ impl Cursor { // If the current cursor is a node and it has children, go to first children if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.first().cloned() { + if let Some((_, child_node)) = parent.rule_node.children.first().cloned() { self.current = PathNode { node: child_node, text_offset: parent.text_offset, @@ -250,11 +261,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - let child_number = parent.rule_node.1.children.len() - 1; - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + let child_number = parent.rule_node.children.len() - 1; + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // This is cheaper than summing up the length of the children let text_offset = - parent.text_offset + parent.rule_node.1.text_len - child_node.1.text_len(); + parent.text_offset + parent.rule_node.text_len - child_node.text_len(); self.path.push(parent); @@ -280,11 +291,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // Sum up the length of the children before this child // TODO: it might sometimes be quicker to start from the end (like `go_to_last_child`) let text_offset = parent.text_offset - + parent.rule_node.1.children[..child_number] + + parent.rule_node.children[..child_number] .iter() .map(|(_name, node)| node.text_len()) .sum(); @@ -313,15 +324,12 @@ impl Cursor { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number + 1; - if let Some(new_child) = parent_path_element - .rule_node - .1 - .children - .get(new_child_number) + if let Some((_, new_child)) = + parent_path_element.rule_node.children.get(new_child_number) { self.current = PathNode { node: new_child.clone(), - text_offset: self.current.text_offset + self.current.node.1.text_len(), + text_offset: self.current.text_offset + self.current.node.text_len(), child_number: new_child_number, }; @@ -343,11 +351,12 @@ impl Cursor { if self.current.child_number > 0 { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number - 1; - let new_child = parent_path_element.rule_node.1.children[new_child_number].clone(); + let (_, new_child) = + parent_path_element.rule_node.children[new_child_number].clone(); self.current = PathNode { node: new_child, - text_offset: self.current.text_offset - self.current.node.1.text_len(), + text_offset: self.current.text_offset - self.current.node.text_len(), child_number: new_child_number, }; return true; @@ -391,7 +400,7 @@ impl Cursor { fn go_to_next_matching(&mut self, pred: impl Fn(&Node) -> bool) -> bool { while self.go_to_next() { - if pred(&self.current.node.1) { + if pred(&self.current.node) { return true; } } diff --git a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs index 80f45e17dc..9124b3a447 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs @@ -54,7 +54,7 @@ impl Cursor { #[napi(ts_return_type = "cst.Node", catch_unwind)] pub fn node(&self, env: Env) -> JsObject { - self.0.node().1.to_js(&env) + self.0.node().to_js(&env) } #[napi(getter, ts_return_type = "text_index.TextIndex", catch_unwind)] diff --git a/crates/codegen/parser/runtime/src/support/choice_helper.rs b/crates/codegen/parser/runtime/src/support/choice_helper.rs index d6af7fa2a4..07e35c3941 100644 --- a/crates/codegen/parser/runtime/src/support/choice_helper.rs +++ b/crates/codegen/parser/runtime/src/support/choice_helper.rs @@ -136,7 +136,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .filter_map(|(_name, node)| match node { + .filter_map(|node| match node { cst::Node::Token(token) if token.kind != TokenKind::SKIPPED => Some(token.text.len()), _ => None, }) diff --git a/crates/codegen/parser/runtime/src/support/parser_function.rs b/crates/codegen/parser/runtime/src/support/parser_function.rs index 481c907f46..4b493bdafa 100644 --- a/crates/codegen/parser/runtime/src/support/parser_function.rs +++ b/crates/codegen/parser/runtime/src/support/parser_function.rs @@ -98,7 +98,7 @@ where errors.is_empty(), parse_tree .cursor_with_offset(TextIndex::ZERO) - .all(|(_, n)| n.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) ); ParseOutput { parse_tree, errors } diff --git a/crates/codegen/parser/runtime/src/support/parser_result.rs b/crates/codegen/parser/runtime/src/support/parser_result.rs index 7201a02d71..d8a519db15 100644 --- a/crates/codegen/parser/runtime/src/support/parser_result.rs +++ b/crates/codegen/parser/runtime/src/support/parser_result.rs @@ -136,8 +136,8 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .all(|(_name, node)| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .flat_map(|(_, node)| node.cursor_with_offset(TextIndex::ZERO)) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs index 0d14788559..f2c0be1b76 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs @@ -133,7 +133,7 @@ impl RuleNode { let acc = String::with_capacity(self.text_len.utf8); self.cursor_with_offset(TextIndex::ZERO) - .filter_map(|(_, node)| node.into_token()) + .filter_map(|node| node.into_token()) .fold(acc, |mut acc, token| { acc.push_str(&token.text); acc diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs index 21f2abf9fc..bd67e0a8dc 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs @@ -4,14 +4,14 @@ use std::rc::Rc; -use crate::cst::{NamedNode, Node, RuleNode}; +use crate::cst::{Node, RuleNode}; use crate::kinds::{RuleKind, TokenKind}; use crate::text_index::{TextIndex, TextRange}; /// A [`PathNode`] that points to a [`RuleNode`]. #[derive(Clone, Debug, PartialEq, Eq)] struct PathRuleNode { - rule_node: (String, Rc), + rule_node: Rc, child_number: usize, text_offset: TextIndex, } @@ -19,7 +19,7 @@ struct PathRuleNode { impl PathRuleNode { fn into_path_node(self) -> PathNode { PathNode { - node: (self.rule_node.0, Node::Rule(self.rule_node.1)), + node: Node::Rule(self.rule_node), child_number: self.child_number, text_offset: self.text_offset, } @@ -30,7 +30,7 @@ impl PathRuleNode { #[derive(Clone, Debug, PartialEq, Eq)] struct PathNode { /// The node the cursor is currently pointing to. - node: NamedNode, + node: Node, /// The index of the current child node in the parent's children. // Required to go to the next/previous sibling. child_number: usize, @@ -41,14 +41,14 @@ struct PathNode { impl PathNode { fn text_range(&self) -> TextRange { let start = self.text_offset; - let end = start + self.node.1.text_len(); + let end = start + self.node.text_len(); start..end } fn to_path_rule_node(&self) -> Option { - if let (name, Node::Rule(rule_node)) = &self.node { + if let Node::Rule(rule_node) = &self.node { Some(PathRuleNode { - rule_node: (name.clone(), rule_node.clone()), + rule_node: rule_node.clone(), child_number: self.child_number, text_offset: self.text_offset, }) @@ -73,7 +73,7 @@ pub struct Cursor { } impl Iterator for Cursor { - type Item = NamedNode; + type Item = Node; fn next(&mut self) -> Option { if self.is_completed { @@ -81,6 +81,7 @@ impl Iterator for Cursor { } else { let cur = self.node(); self.go_to_next(); + Some(cur) } } @@ -91,7 +92,7 @@ impl Cursor { Self { path: vec![], current: PathNode { - node: (String::new(), node), + node, child_number: 0, text_offset, }, @@ -131,10 +132,20 @@ impl Cursor { } /// Returns the currently pointed to [`Node`]. - pub fn node(&self) -> NamedNode { + pub fn node(&self) -> Node { self.current.node.clone() } + pub fn node_name(&self) -> String { + if let Some(parent) = self.path.last() { + parent.rule_node.children[self.current.child_number] + .0 + .clone() + } else { + String::new() + } + } + /// Returns the text offset that corresponds to the beginning of the currently pointed to node. pub fn text_offset(&self) -> TextIndex { self.current.text_offset @@ -152,7 +163,7 @@ impl Cursor { /// Returns an iterator over the current node's ancestors, starting from the cursor root node. pub fn ancestors(&self) -> impl Iterator> { - self.path.iter().map(|elem| &elem.rule_node.1) + self.path.iter().map(|elem| &elem.rule_node) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. @@ -227,7 +238,7 @@ impl Cursor { // If the current cursor is a node and it has children, go to first children if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.first().cloned() { + if let Some((_, child_node)) = parent.rule_node.children.first().cloned() { self.current = PathNode { node: child_node, text_offset: parent.text_offset, @@ -252,11 +263,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - let child_number = parent.rule_node.1.children.len() - 1; - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + let child_number = parent.rule_node.children.len() - 1; + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // This is cheaper than summing up the length of the children let text_offset = - parent.text_offset + parent.rule_node.1.text_len - child_node.1.text_len(); + parent.text_offset + parent.rule_node.text_len - child_node.text_len(); self.path.push(parent); @@ -282,11 +293,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // Sum up the length of the children before this child // TODO: it might sometimes be quicker to start from the end (like `go_to_last_child`) let text_offset = parent.text_offset - + parent.rule_node.1.children[..child_number] + + parent.rule_node.children[..child_number] .iter() .map(|(_name, node)| node.text_len()) .sum(); @@ -315,15 +326,12 @@ impl Cursor { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number + 1; - if let Some(new_child) = parent_path_element - .rule_node - .1 - .children - .get(new_child_number) + if let Some((_, new_child)) = + parent_path_element.rule_node.children.get(new_child_number) { self.current = PathNode { node: new_child.clone(), - text_offset: self.current.text_offset + self.current.node.1.text_len(), + text_offset: self.current.text_offset + self.current.node.text_len(), child_number: new_child_number, }; @@ -345,11 +353,12 @@ impl Cursor { if self.current.child_number > 0 { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number - 1; - let new_child = parent_path_element.rule_node.1.children[new_child_number].clone(); + let (_, new_child) = + parent_path_element.rule_node.children[new_child_number].clone(); self.current = PathNode { node: new_child, - text_offset: self.current.text_offset - self.current.node.1.text_len(), + text_offset: self.current.text_offset - self.current.node.text_len(), child_number: new_child_number, }; return true; @@ -393,7 +402,7 @@ impl Cursor { fn go_to_next_matching(&mut self, pred: impl Fn(&Node) -> bool) -> bool { while self.go_to_next() { - if pred(&self.current.node.1) { + if pred(&self.current.node) { return true; } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cursor.rs index e8f964c902..ae10a5f831 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cursor.rs @@ -56,7 +56,7 @@ impl Cursor { #[napi(ts_return_type = "cst.Node", catch_unwind)] pub fn node(&self, env: Env) -> JsObject { - self.0.node().1.to_js(&env) + self.0.node().to_js(&env) } #[napi(getter, ts_return_type = "text_index.TextIndex", catch_unwind)] diff --git a/crates/solidity/outputs/cargo/crate/src/generated/support/choice_helper.rs b/crates/solidity/outputs/cargo/crate/src/generated/support/choice_helper.rs index 3ca13177a7..f4b54a3316 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/support/choice_helper.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/support/choice_helper.rs @@ -138,7 +138,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .filter_map(|(_name, node)| match node { + .filter_map(|node| match node { cst::Node::Token(token) if token.kind != TokenKind::SKIPPED => Some(token.text.len()), _ => None, }) diff --git a/crates/solidity/outputs/cargo/crate/src/generated/support/parser_function.rs b/crates/solidity/outputs/cargo/crate/src/generated/support/parser_function.rs index 3afb612395..9aa5e6806a 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/support/parser_function.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/support/parser_function.rs @@ -100,7 +100,7 @@ where errors.is_empty(), parse_tree .cursor_with_offset(TextIndex::ZERO) - .all(|(_, n)| n.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) ); ParseOutput { parse_tree, errors } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/support/parser_result.rs b/crates/solidity/outputs/cargo/crate/src/generated/support/parser_result.rs index fd6573d388..df5f3eb895 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/support/parser_result.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/support/parser_result.rs @@ -138,8 +138,8 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .all(|(_name, node)| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .flat_map(|(_, node)| node.cursor_with_offset(TextIndex::ZERO)) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/solidity/outputs/cargo/tests/src/doc_examples/cursor_api.rs b/crates/solidity/outputs/cargo/tests/src/doc_examples/cursor_api.rs index c1b2763a7c..24462f9cb4 100644 --- a/crates/solidity/outputs/cargo/tests/src/doc_examples/cursor_api.rs +++ b/crates/solidity/outputs/cargo/tests/src/doc_examples/cursor_api.rs @@ -22,7 +22,7 @@ fn using_cursor_api() -> Result<()> { assert!(cursor.go_to_first_child()); assert!(cursor.go_to_next_token_with_kinds(&[TokenKind::Identifier])); - let token_node = cursor.node().1; + let token_node = cursor.node(); contract_names.push(token_node.as_token().unwrap().text.clone()); assert!(cursor.go_to_parent()); @@ -48,7 +48,7 @@ fn using_spawn() -> Result<()> { let mut child_cursor = cursor.spawn(); assert!(child_cursor.go_to_next_token_with_kinds(&[TokenKind::Identifier])); - let token_node = child_cursor.node().1; + let token_node = child_cursor.node(); contract_names.push(token_node.as_token().unwrap().text.clone()); } @@ -65,7 +65,7 @@ fn using_iter() -> Result<()> { let mut cursor = parse_output.create_tree_cursor(); while cursor.go_to_next_rule_with_kinds(&[RuleKind::ContractDefinition]) { - let rule_node = cursor.node().1; + let rule_node = cursor.node(); if let Some(token_node) = rule_node .as_rule() .unwrap() @@ -88,7 +88,7 @@ fn using_iter_combinators() -> Result<()> { let contract_names: Vec<_> = parse_output .create_tree_cursor() - .filter_map(|(_name, node)| { + .filter_map(|node| { let node = node.as_rule_with_kind(&[RuleKind::ContractDefinition])?; let contract_name = node .children diff --git a/crates/solidity/outputs/npm/crate/src/generated/cst.rs b/crates/solidity/outputs/npm/crate/src/generated/cst.rs index 0d14788559..f2c0be1b76 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cst.rs @@ -133,7 +133,7 @@ impl RuleNode { let acc = String::with_capacity(self.text_len.utf8); self.cursor_with_offset(TextIndex::ZERO) - .filter_map(|(_, node)| node.into_token()) + .filter_map(|node| node.into_token()) .fold(acc, |mut acc, token| { acc.push_str(&token.text); acc diff --git a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs index 21f2abf9fc..bd67e0a8dc 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs @@ -4,14 +4,14 @@ use std::rc::Rc; -use crate::cst::{NamedNode, Node, RuleNode}; +use crate::cst::{Node, RuleNode}; use crate::kinds::{RuleKind, TokenKind}; use crate::text_index::{TextIndex, TextRange}; /// A [`PathNode`] that points to a [`RuleNode`]. #[derive(Clone, Debug, PartialEq, Eq)] struct PathRuleNode { - rule_node: (String, Rc), + rule_node: Rc, child_number: usize, text_offset: TextIndex, } @@ -19,7 +19,7 @@ struct PathRuleNode { impl PathRuleNode { fn into_path_node(self) -> PathNode { PathNode { - node: (self.rule_node.0, Node::Rule(self.rule_node.1)), + node: Node::Rule(self.rule_node), child_number: self.child_number, text_offset: self.text_offset, } @@ -30,7 +30,7 @@ impl PathRuleNode { #[derive(Clone, Debug, PartialEq, Eq)] struct PathNode { /// The node the cursor is currently pointing to. - node: NamedNode, + node: Node, /// The index of the current child node in the parent's children. // Required to go to the next/previous sibling. child_number: usize, @@ -41,14 +41,14 @@ struct PathNode { impl PathNode { fn text_range(&self) -> TextRange { let start = self.text_offset; - let end = start + self.node.1.text_len(); + let end = start + self.node.text_len(); start..end } fn to_path_rule_node(&self) -> Option { - if let (name, Node::Rule(rule_node)) = &self.node { + if let Node::Rule(rule_node) = &self.node { Some(PathRuleNode { - rule_node: (name.clone(), rule_node.clone()), + rule_node: rule_node.clone(), child_number: self.child_number, text_offset: self.text_offset, }) @@ -73,7 +73,7 @@ pub struct Cursor { } impl Iterator for Cursor { - type Item = NamedNode; + type Item = Node; fn next(&mut self) -> Option { if self.is_completed { @@ -81,6 +81,7 @@ impl Iterator for Cursor { } else { let cur = self.node(); self.go_to_next(); + Some(cur) } } @@ -91,7 +92,7 @@ impl Cursor { Self { path: vec![], current: PathNode { - node: (String::new(), node), + node, child_number: 0, text_offset, }, @@ -131,10 +132,20 @@ impl Cursor { } /// Returns the currently pointed to [`Node`]. - pub fn node(&self) -> NamedNode { + pub fn node(&self) -> Node { self.current.node.clone() } + pub fn node_name(&self) -> String { + if let Some(parent) = self.path.last() { + parent.rule_node.children[self.current.child_number] + .0 + .clone() + } else { + String::new() + } + } + /// Returns the text offset that corresponds to the beginning of the currently pointed to node. pub fn text_offset(&self) -> TextIndex { self.current.text_offset @@ -152,7 +163,7 @@ impl Cursor { /// Returns an iterator over the current node's ancestors, starting from the cursor root node. pub fn ancestors(&self) -> impl Iterator> { - self.path.iter().map(|elem| &elem.rule_node.1) + self.path.iter().map(|elem| &elem.rule_node) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. @@ -227,7 +238,7 @@ impl Cursor { // If the current cursor is a node and it has children, go to first children if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.first().cloned() { + if let Some((_, child_node)) = parent.rule_node.children.first().cloned() { self.current = PathNode { node: child_node, text_offset: parent.text_offset, @@ -252,11 +263,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - let child_number = parent.rule_node.1.children.len() - 1; - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + let child_number = parent.rule_node.children.len() - 1; + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // This is cheaper than summing up the length of the children let text_offset = - parent.text_offset + parent.rule_node.1.text_len - child_node.1.text_len(); + parent.text_offset + parent.rule_node.text_len - child_node.text_len(); self.path.push(parent); @@ -282,11 +293,11 @@ impl Cursor { } if let Some(parent) = self.current.to_path_rule_node() { - if let Some(child_node) = parent.rule_node.1.children.get(child_number).cloned() { + if let Some((_, child_node)) = parent.rule_node.children.get(child_number).cloned() { // Sum up the length of the children before this child // TODO: it might sometimes be quicker to start from the end (like `go_to_last_child`) let text_offset = parent.text_offset - + parent.rule_node.1.children[..child_number] + + parent.rule_node.children[..child_number] .iter() .map(|(_name, node)| node.text_len()) .sum(); @@ -315,15 +326,12 @@ impl Cursor { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number + 1; - if let Some(new_child) = parent_path_element - .rule_node - .1 - .children - .get(new_child_number) + if let Some((_, new_child)) = + parent_path_element.rule_node.children.get(new_child_number) { self.current = PathNode { node: new_child.clone(), - text_offset: self.current.text_offset + self.current.node.1.text_len(), + text_offset: self.current.text_offset + self.current.node.text_len(), child_number: new_child_number, }; @@ -345,11 +353,12 @@ impl Cursor { if self.current.child_number > 0 { if let Some(parent_path_element) = self.path.last() { let new_child_number = self.current.child_number - 1; - let new_child = parent_path_element.rule_node.1.children[new_child_number].clone(); + let (_, new_child) = + parent_path_element.rule_node.children[new_child_number].clone(); self.current = PathNode { node: new_child, - text_offset: self.current.text_offset - self.current.node.1.text_len(), + text_offset: self.current.text_offset - self.current.node.text_len(), child_number: new_child_number, }; return true; @@ -393,7 +402,7 @@ impl Cursor { fn go_to_next_matching(&mut self, pred: impl Fn(&Node) -> bool) -> bool { while self.go_to_next() { - if pred(&self.current.node.1) { + if pred(&self.current.node) { return true; } } diff --git a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cursor.rs index e8f964c902..ae10a5f831 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cursor.rs @@ -56,7 +56,7 @@ impl Cursor { #[napi(ts_return_type = "cst.Node", catch_unwind)] pub fn node(&self, env: Env) -> JsObject { - self.0.node().1.to_js(&env) + self.0.node().to_js(&env) } #[napi(getter, ts_return_type = "text_index.TextIndex", catch_unwind)] diff --git a/crates/solidity/outputs/npm/crate/src/generated/support/choice_helper.rs b/crates/solidity/outputs/npm/crate/src/generated/support/choice_helper.rs index 3ca13177a7..f4b54a3316 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/support/choice_helper.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/support/choice_helper.rs @@ -138,7 +138,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .filter_map(|(_name, node)| match node { + .filter_map(|node| match node { cst::Node::Token(token) if token.kind != TokenKind::SKIPPED => Some(token.text.len()), _ => None, }) diff --git a/crates/solidity/outputs/npm/crate/src/generated/support/parser_function.rs b/crates/solidity/outputs/npm/crate/src/generated/support/parser_function.rs index 3afb612395..9aa5e6806a 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/support/parser_function.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/support/parser_function.rs @@ -100,7 +100,7 @@ where errors.is_empty(), parse_tree .cursor_with_offset(TextIndex::ZERO) - .all(|(_, n)| n.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) ); ParseOutput { parse_tree, errors } diff --git a/crates/solidity/outputs/npm/crate/src/generated/support/parser_result.rs b/crates/solidity/outputs/npm/crate/src/generated/support/parser_result.rs index fd6573d388..df5f3eb895 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/support/parser_result.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/support/parser_result.rs @@ -138,8 +138,8 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(|(_name, node)| node.cursor_with_offset(TextIndex::ZERO)) - .all(|(_name, node)| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) + .flat_map(|(_, node)| node.cursor_with_offset(TextIndex::ZERO)) + .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs index 012eae0517..999c8a8cd2 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs @@ -91,10 +91,11 @@ fn write_tree(w: &mut W, mut cursor: Cursor, source: &str) -> Result<( let significant_nodes_with_range = std::iter::from_fn(|| loop { let (depth, range) = (cursor.depth(), cursor.text_range()); + let node_name = cursor.node_name(); // Skip whitespace and trivia rules containing only those tokens match cursor.next() { - Some((_, cst::Node::Rule(rule))) + Some(cst::Node::Rule(rule)) if rule.is_trivia() && rule.children.iter().all(|(_name, node)| { node.as_token().map_or(false, |t| is_whitespace(t.kind)) @@ -102,8 +103,8 @@ fn write_tree(w: &mut W, mut cursor: Cursor, source: &str) -> Result<( { continue } - Some((_, cst::Node::Token(token))) if is_whitespace(token.kind) => continue, - next => break next.map(|item| (item, depth, range)), + Some(cst::Node::Token(token)) if is_whitespace(token.kind) => continue, + next => break next.map(|item| ((node_name, item), depth, range)), } }); diff --git a/crates/solidity/testing/utils/src/version_pragmas/mod.rs b/crates/solidity/testing/utils/src/version_pragmas/mod.rs index b0a8c4094b..fcb8ed4505 100644 --- a/crates/solidity/testing/utils/src/version_pragmas/mod.rs +++ b/crates/solidity/testing/utils/src/version_pragmas/mod.rs @@ -22,7 +22,7 @@ pub fn extract_version_pragmas( let mut cursor = output.create_tree_cursor(); while !cursor.is_completed() { - let node = &cursor.node().1; + let node = &cursor.node(); if matches!(node, Node::Rule(rule) if rule.kind == RuleKind::VersionPragmaExpression) { pragmas.push(extract_pragma(node).with_context(|| {