From c4dbf1986c2815f78352a3bf972c139d1c3039bd Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 11:15:00 +0100 Subject: [PATCH 1/9] Replace `Cursor::path_rule_nodes` with borrowing `Cursor::ancestors` ...and use the borrowing variant for the NAPI `pathRuleNodes` function to not double-allocate. The borrowing variant is more general in the Rust API; not all use cases want or should rely on previously collecting the path into a Vec of owned `Rc`s. --- crates/codegen/parser/runtime/src/cursor.rs | 8 +++----- crates/codegen/parser/runtime/src/napi/napi_cursor.rs | 3 +-- .../solidity/outputs/cargo/crate/src/generated/cursor.rs | 8 +++----- .../outputs/cargo/crate/src/generated/napi/napi_cursor.rs | 3 +-- crates/solidity/outputs/npm/crate/src/generated/cursor.rs | 8 +++----- .../outputs/npm/crate/src/generated/napi/napi_cursor.rs | 3 +-- 6 files changed, 12 insertions(+), 21 deletions(-) diff --git a/crates/codegen/parser/runtime/src/cursor.rs b/crates/codegen/parser/runtime/src/cursor.rs index 89bf585049..8bdfd75721 100644 --- a/crates/codegen/parser/runtime/src/cursor.rs +++ b/crates/codegen/parser/runtime/src/cursor.rs @@ -144,11 +144,9 @@ impl Cursor { self.current.text_range() } - pub fn path_rule_nodes(&self) -> Vec> { - self.path - .iter() - .map(|path_element| path_element.rule_node.clone()) - .collect() + /// 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) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. diff --git a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs index 33abaf9e19..153290358f 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs @@ -65,8 +65,7 @@ impl Cursor { #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 - .path_rule_nodes() - .iter() + .ancestors() .map(|rust_rule_node| rust_rule_node.to_js(&env)) .collect() } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs index b3743ec4b6..43f3ada227 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs @@ -146,11 +146,9 @@ impl Cursor { self.current.text_range() } - pub fn path_rule_nodes(&self) -> Vec> { - self.path - .iter() - .map(|path_element| path_element.rule_node.clone()) - .collect() + /// 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) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. 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 0dc62a5db8..5cc54070d1 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 @@ -67,8 +67,7 @@ impl Cursor { #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 - .path_rule_nodes() - .iter() + .ancestors() .map(|rust_rule_node| rust_rule_node.to_js(&env)) .collect() } diff --git a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs index b3743ec4b6..43f3ada227 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs @@ -146,11 +146,9 @@ impl Cursor { self.current.text_range() } - pub fn path_rule_nodes(&self) -> Vec> { - self.path - .iter() - .map(|path_element| path_element.rule_node.clone()) - .collect() + /// 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) } /// Attempts to go to current node's next one, according to the DFS pre-order traversal. 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 0dc62a5db8..5cc54070d1 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 @@ -67,8 +67,7 @@ impl Cursor { #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 - .path_rule_nodes() - .iter() + .ancestors() .map(|rust_rule_node| rust_rule_node.to_js(&env)) .collect() } From 02caa79447320c5a9dad291d1f6c762791831c5b Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 14:59:52 +0100 Subject: [PATCH 2/9] Use Cursor iterator rather than Visitor to print CST snapshot tests In preparation to remove the CST `Visitor` trait altogether. --- crates/codegen/parser/runtime/src/cst.rs | 7 ++ crates/codegen/parser/runtime/src/cursor.rs | 4 + .../outputs/cargo/crate/src/generated/cst.rs | 7 ++ .../cargo/crate/src/generated/cursor.rs | 4 + .../outputs/npm/crate/src/generated/cst.rs | 7 ++ .../outputs/npm/crate/src/generated/cursor.rs | 4 + .../everything/generated/0.4.11-failure.yml | 2 +- .../everything/generated/0.8.13-failure.yml | 2 +- .../generated/0.4.11-failure.yml | 2 +- .../testing/utils/src/cst_snapshots/mod.rs | 94 +++++++++++++------ .../utils/src/cst_snapshots/test_nodes.rs | 2 +- 11 files changed, 101 insertions(+), 34 deletions(-) diff --git a/crates/codegen/parser/runtime/src/cst.rs b/crates/codegen/parser/runtime/src/cst.rs index e3c1437a91..4f8833e876 100644 --- a/crates/codegen/parser/runtime/src/cst.rs +++ b/crates/codegen/parser/runtime/src/cst.rs @@ -46,6 +46,13 @@ impl Node { } } + pub fn children(&self) -> &[Node] { + match self { + Self::Rule(node) => &node.children, + Self::Token(_) => &[], + } + } + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { Cursor::new(self.clone(), text_offset) } diff --git a/crates/codegen/parser/runtime/src/cursor.rs b/crates/codegen/parser/runtime/src/cursor.rs index 8bdfd75721..1cb1babecd 100644 --- a/crates/codegen/parser/runtime/src/cursor.rs +++ b/crates/codegen/parser/runtime/src/cursor.rs @@ -144,6 +144,10 @@ impl Cursor { self.current.text_range() } + pub fn depth(&self) -> usize { + self.path.len() + } + /// 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) diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs index f20fe136e9..28b996b98c 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs @@ -48,6 +48,13 @@ impl Node { } } + pub fn children(&self) -> &[Node] { + match self { + Self::Rule(node) => &node.children, + Self::Token(_) => &[], + } + } + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { Cursor::new(self.clone(), text_offset) } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs index 43f3ada227..6dca60823e 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs @@ -146,6 +146,10 @@ impl Cursor { self.current.text_range() } + pub fn depth(&self) -> usize { + self.path.len() + } + /// 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) diff --git a/crates/solidity/outputs/npm/crate/src/generated/cst.rs b/crates/solidity/outputs/npm/crate/src/generated/cst.rs index f20fe136e9..28b996b98c 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cst.rs @@ -48,6 +48,13 @@ impl Node { } } + pub fn children(&self) -> &[Node] { + match self { + Self::Rule(node) => &node.children, + Self::Token(_) => &[], + } + } + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { Cursor::new(self.clone(), text_offset) } diff --git a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs index 43f3ada227..6dca60823e 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs @@ -146,6 +146,10 @@ impl Cursor { self.current.text_range() } + pub fn depth(&self) -> usize { + self.path.len() + } + /// 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) diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml index 1bd97cba98..242ab96c25 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml @@ -60,5 +60,5 @@ Tree: - PathImport (Rule): # 30..40 ' "foo.sol"' - AsciiStringLiteral (Token): '"foo.sol"' # 31..40 - Semicolon (Token): ";" # 40..41 - - EndOfFileTrivia (Rule): "\n" # 42..43 + - EndOfFileTrivia (Rule): # 42..43 "\n" - SKIPPED (Token): "using A for B;\n\ncontract C { }\n\ninterface I { }\n\nl..." # 43..243 diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml index 24a7c853a4..1e5065aae4 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml @@ -131,5 +131,5 @@ Tree: - IsKeyword (Token): "is" # 208..210 - BoolKeyword (Token): "bool" # 211..215 - Semicolon (Token): ";" # 215..216 - - EndOfFileTrivia (Rule): "\n" # 217..218 + - EndOfFileTrivia (Rule): # 217..218 "\n" - SKIPPED (Token): "event E1(uint256 value);\n" # 218..243 diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml index 147d1ee2c7..7e34a1f2e3 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml @@ -58,5 +58,5 @@ Tree: - Period (Token): "." # 52..53 - VersionPragmaValue (Token): "0" # 53..54 - Semicolon (Token): ";" # 54..55 - - EndOfFileTrivia (Rule): "\n" # 56..57 + - EndOfFileTrivia (Rule): # 56..57 "\n" - SKIPPED (Token): "using EnvelopeUtils for Envelope global;\nusing Tra..." # 57..793 diff --git a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs index e85b331b86..d8f6120d6a 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs @@ -1,11 +1,16 @@ mod test_nodes; -use std::{self, cmp::max, fmt::Write}; +use std::{cmp::max, fmt::Write}; use anyhow::Result; -use slang_solidity::{cursor::Cursor, text_index::TextRangeExtensions}; +use slang_solidity::{ + cst, + cursor::Cursor, + kinds::TokenKind, + text_index::{TextRange, TextRangeExtensions}, +}; -use crate::cst_snapshots::test_nodes::{TestNode, TestNodeKind}; +use crate::{cst_snapshots::test_nodes::TestNode, node_extensions::NodeExtensions}; pub struct CstSnapshots; @@ -83,55 +88,84 @@ fn write_errors(w: &mut W, errors: &Vec) -> Result<()> { return Ok(()); } -fn write_tree(w: &mut W, cursor: Cursor, source: &str) -> Result<()> { +fn write_tree(w: &mut W, mut cursor: Cursor, source: &str) -> Result<()> { write!(w, "Tree:")?; writeln!(w)?; - let tree = TestNode::from_cst(cursor); - write_node(w, &tree, source, 0)?; + let significant_nodes_with_range = std::iter::from_fn(|| loop { + let (depth, range) = (cursor.depth(), cursor.text_range()); + + // Skip whitespace and trivia rules containing only those tokens + match cursor.next() { + Some(cst::Node::Rule(rule)) + if rule.is_trivia() + && rule.children.iter().all(|token| { + token + .as_token_with_kind(&[TokenKind::Whitespace, TokenKind::EndOfLine]) + .is_some() + }) => + { + continue + } + Some(cst::Node::Token(token)) if token.kind == TokenKind::Whitespace => continue, + Some(cst::Node::Token(token)) if token.kind == TokenKind::EndOfLine => continue, + next => break next.map(|item| (item, depth, range)), + } + }); - return Ok(()); + for (node, depth, range) in significant_nodes_with_range { + write_node(w, &node, &range, source, depth)?; + } + + Ok(()) } fn write_node( w: &mut W, - node: &TestNode, + node: &cst::Node, + range: &TextRange, source: &str, indentation: usize, ) -> Result<()> { - let range_string = format!("{range:?}", range = node.range.utf8()); + let range_string = format!("{range:?}", range = range.utf8()); - let (node_value, node_comment) = if node.range.is_empty() { - let preview = match node.kind { - TestNodeKind::Rule(_) => " []", - TestNodeKind::Token(_) | TestNodeKind::Trivia(_) => " \"\"", + let (node_value, node_comment) = if range.is_empty() { + let preview = match node { + cst::Node::Rule(_) => " []", + cst::Node::Token(_) => " \"\"", }; + (preview.to_owned(), range_string) } else { - let preview = node.render_preview(source, &node.range)?; - if node.children.is_empty() { - ( - format!(" {preview}"), - format!("{range:?}", range = node.range.utf8()), - ) + let preview = TestNode::render_source_preview(source, &range)?; + + if node.children().is_empty() { + // "foo" # 1..2 + (format!(" {preview}"), range_string) } else { - ( - "".to_owned(), - format!("{range:?} {preview}", range = node.range.utf8()), - ) + // # 1..2 "foo" + ("".to_owned(), format!("{range_string} {preview}")) } }; + let name = match node { + cst::Node::Rule(rule) => format!("{:?} (Rule)", rule.kind), + cst::Node::Token(token) + if matches!( + token.kind, + TokenKind::SingleLineComment | TokenKind::MultilineComment + ) => + { + format!("{:?} (Trivia)", token.kind) + } + cst::Node::Token(token) => format!("{:?} (Token)", token.kind), + }; + writeln!( w, - "{indentation} - {kind}:{node_value} # {node_comment}", + "{indentation} - {name}:{node_value} # {node_comment}", indentation = " ".repeat(4 * indentation), - kind = node.kind, )?; - for child in &node.children { - write_node(w, child, source, indentation + 1)?; - } - - return Ok(()); + Ok(()) } diff --git a/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs b/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs index 429a6b249c..efc72d74ea 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs @@ -95,7 +95,7 @@ impl TestNode { return visitor.stack.remove(0).remove(0); } - pub fn render_preview(&self, source: &str, range: &TextRange) -> Result { + pub fn render_source_preview(source: &str, range: &TextRange) -> Result { let max_length = 50; let length = range.end.utf8 - range.start.utf8; From e401a11339d9a7bb2d00fb334619f9a3409927a0 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 15:13:24 +0100 Subject: [PATCH 3/9] Remove Visitor impl for TestNodeBuilder --- .../testing/utils/src/cst_snapshots/mod.rs | 72 ++++++--- .../utils/src/cst_snapshots/test_nodes.rs | 144 ------------------ 2 files changed, 54 insertions(+), 162 deletions(-) delete mode 100644 crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs diff --git a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs index d8f6120d6a..041f3550f5 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs @@ -1,5 +1,3 @@ -mod test_nodes; - use std::{cmp::max, fmt::Write}; use anyhow::Result; @@ -10,7 +8,7 @@ use slang_solidity::{ text_index::{TextRange, TextRangeExtensions}, }; -use crate::{cst_snapshots::test_nodes::TestNode, node_extensions::NodeExtensions}; +use crate::node_extensions::NodeExtensions; pub struct CstSnapshots; @@ -99,16 +97,13 @@ fn write_tree(w: &mut W, mut cursor: Cursor, source: &str) -> Result<( match cursor.next() { Some(cst::Node::Rule(rule)) if rule.is_trivia() - && rule.children.iter().all(|token| { - token - .as_token_with_kind(&[TokenKind::Whitespace, TokenKind::EndOfLine]) - .is_some() + && rule.children.iter().all(|node| { + node.as_token_matching(|t| is_whitespace(t.kind)).is_some() }) => { continue } - Some(cst::Node::Token(token)) if token.kind == TokenKind::Whitespace => continue, - Some(cst::Node::Token(token)) if token.kind == TokenKind::EndOfLine => continue, + Some(cst::Node::Token(token)) if is_whitespace(token.kind) => continue, next => break next.map(|item| (item, depth, range)), } }); @@ -137,7 +132,7 @@ fn write_node( (preview.to_owned(), range_string) } else { - let preview = TestNode::render_source_preview(source, &range)?; + let preview = render_source_preview(source, &range)?; if node.children().is_empty() { // "foo" # 1..2 @@ -150,14 +145,7 @@ fn write_node( let name = match node { cst::Node::Rule(rule) => format!("{:?} (Rule)", rule.kind), - cst::Node::Token(token) - if matches!( - token.kind, - TokenKind::SingleLineComment | TokenKind::MultilineComment - ) => - { - format!("{:?} (Trivia)", token.kind) - } + cst::Node::Token(token) if is_comment(token.kind) => format!("{:?} (Trivia)", token.kind), cst::Node::Token(token) => format!("{:?} (Token)", token.kind), }; @@ -169,3 +157,51 @@ fn write_node( Ok(()) } + +pub fn render_source_preview(source: &str, range: &TextRange) -> Result { + let max_length = 50; + let length = range.end.utf8 - range.start.utf8; + + // Trim long values: + let contents = source + .bytes() + .skip(range.start.utf8) + .take(length.clamp(0, max_length)) + .collect(); + + // Add terminator if trimmed: + let mut contents = String::from_utf8(contents)?; + if length > max_length { + contents.push_str("..."); + } + + // Escape line breaks: + let contents = contents + .replace("\t", "\\t") + .replace("\r", "\\r") + .replace("\n", "\\n"); + + // Surround by quotes for use in yaml: + let contents = { + if contents.contains("\"") { + let contents = contents.replace("'", "''"); + format!("'{contents}'") + } else { + let contents = contents.replace("\"", "\\\""); + format!("\"{contents}\"") + } + }; + + return Ok(contents); +} + +fn is_whitespace(kind: TokenKind) -> bool { + matches!(kind, TokenKind::Whitespace | TokenKind::EndOfLine) +} + +fn is_comment(kind: TokenKind) -> bool { + matches!( + kind, + TokenKind::SingleLineComment | TokenKind::MultilineComment + ) +} diff --git a/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs b/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs deleted file mode 100644 index efc72d74ea..0000000000 --- a/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs +++ /dev/null @@ -1,144 +0,0 @@ -use std::ops::ControlFlow; -use std::rc::Rc; - -use anyhow::Result; -use slang_solidity::{ - cst::RuleNode, cst::TokenNode, cursor::Cursor, kinds::RuleKind, kinds::TokenKind, - text_index::TextRange, visitor::Step, visitor::Visitor, -}; - -#[derive(Debug)] -pub enum TestNodeKind { - Rule(RuleKind), - Token(TokenKind), - Trivia(TokenKind), -} - -pub struct TestNode { - pub kind: TestNodeKind, - pub range: TextRange, - pub children: Vec, -} - -struct TestNodeBuilder { - stack: Vec>, -} - -impl Visitor<()> for TestNodeBuilder { - fn rule_enter( - &mut self, - _node: &Rc, - _cursor: &Cursor, - ) -> Result, ()> { - self.stack.push(vec![]); - Ok(ControlFlow::Continue(Step::In)) - } - - fn rule_exit(&mut self, node: &Rc, cursor: &Cursor) -> Result, ()> { - let children = self.stack.pop().unwrap(); - - if (node.kind == RuleKind::LeadingTrivia) | (node.kind == RuleKind::TrailingTrivia) { - if children.is_empty() { - return Ok(ControlFlow::Continue(())); - } - } - - let new_node = TestNode { - kind: TestNodeKind::Rule(node.kind), - range: cursor.text_range(), - children, - }; - self.stack.last_mut().unwrap().push(new_node); - - Ok(ControlFlow::Continue(())) - } - - fn token(&mut self, node: &Rc, cursor: &Cursor) -> Result, ()> { - if !Self::is_whitespace(node) { - let kind = if Self::is_comment(node) { - TestNodeKind::Trivia(node.kind) - } else { - TestNodeKind::Token(node.kind) - }; - - let new_node = TestNode { - kind, - range: cursor.text_range(), - children: vec![], - }; - self.stack.last_mut().unwrap().push(new_node); - } - - Ok(ControlFlow::Continue(())) - } -} - -impl TestNodeBuilder { - fn is_whitespace(token_node: &Rc) -> bool { - (token_node.kind == TokenKind::Whitespace) | (token_node.kind == TokenKind::EndOfLine) - } - - fn is_comment(token_node: &Rc) -> bool { - (token_node.kind == TokenKind::SingleLineComment) - | (token_node.kind == TokenKind::MultilineComment) - } -} - -impl TestNode { - pub fn from_cst(mut cursor: Cursor) -> Self { - let mut visitor = TestNodeBuilder { - stack: vec![vec![]], - }; - - cursor.drive_visitor(&mut visitor).unwrap(); - - return visitor.stack.remove(0).remove(0); - } - - pub fn render_source_preview(source: &str, range: &TextRange) -> Result { - let max_length = 50; - let length = range.end.utf8 - range.start.utf8; - - // Trim long values: - let contents = source - .bytes() - .skip(range.start.utf8) - .take(length.clamp(0, max_length)) - .collect(); - - // Add terminator if trimmed: - let mut contents = String::from_utf8(contents)?; - if length > max_length { - contents.push_str("..."); - } - - // Escape line breaks: - let contents = contents - .replace("\t", "\\t") - .replace("\r", "\\r") - .replace("\n", "\\n"); - - // Surround by quotes for use in yaml: - let contents = { - if contents.contains("\"") { - let contents = contents.replace("'", "''"); - format!("'{contents}'") - } else { - let contents = contents.replace("\"", "\\\""); - format!("\"{contents}\"") - } - }; - - return Ok(contents); - } -} - -impl std::fmt::Display for TestNodeKind { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - return match self { - TestNodeKind::Rule(kind) => write!(f, "{kind:?} (Rule)"), - TestNodeKind::Token(kind) => write!(f, "{kind:?} (Token)"), - TestNodeKind::Trivia(kind) => write!(f, "{kind:?} (Trivia)"), - }; - } -} From 22a2be4ff713cf3476538d573481e73af65da6ff Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 15:36:41 +0100 Subject: [PATCH 4/9] Add a Cursor API example using Iterator combinators --- .../tests/src/doc_examples/cursor_api.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) 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 e22290632a..76e81d2edd 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 @@ -92,6 +92,30 @@ fn cursor_api_using_iter() -> Result<()> { return Ok(()); } +#[test] +fn cursor_api_using_iter_combinators() -> Result<()> { + let language = Language::new(Version::parse("0.8.0")?)?; + let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); + + let cursor = parse_output.create_tree_cursor(); + + let contract_names: Vec<_> = cursor + .filter_map(|node| { + let node = node.as_rule_with_kind(&[RuleKind::ContractDefinition])?; + let name = node + .children + .iter() + .find_map(|node| node.as_token_with_kind(&[TokenKind::Identifier]))?; + + Some(name.text.clone()) + }) + .collect(); + + assert_eq!(contract_names, &["Foo"]); + + return Ok(()); +} + #[test] fn cursor_as_iter() -> Result<()> { let language = Language::new(Version::parse("0.8.0")?)?; From b7e986bd29b8ed37734168bc5c2062cff4cabf8f Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 15:44:53 +0100 Subject: [PATCH 5/9] Remove the CST Visitor API --- crates/codegen/parser/runtime/src/lib.rs | 1 - crates/codegen/parser/runtime/src/visitor.rs | 75 ------------------ .../cargo/crate/src/generated/visitor.rs | 77 ------------------- .../cargo/tests/src/doc_examples/mod.rs | 1 - .../tests/src/doc_examples/visitor_api.rs | 56 -------------- .../npm/crate/src/generated/visitor.rs | 77 ------------------- .../public/user-guide/cargo-crate/index.md | 16 ---- 7 files changed, 303 deletions(-) delete mode 100644 crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs diff --git a/crates/codegen/parser/runtime/src/lib.rs b/crates/codegen/parser/runtime/src/lib.rs index eb5b7b0741..8ed2f8ed55 100644 --- a/crates/codegen/parser/runtime/src/lib.rs +++ b/crates/codegen/parser/runtime/src/lib.rs @@ -10,7 +10,6 @@ pub(crate) mod lexer; pub mod parse_error; pub mod parse_output; pub mod text_index; -pub mod visitor; #[cfg(feature = "slang_napi_interfaces")] pub mod napi; diff --git a/crates/codegen/parser/runtime/src/visitor.rs b/crates/codegen/parser/runtime/src/visitor.rs index 1562bc0e59..8b13789179 100644 --- a/crates/codegen/parser/runtime/src/visitor.rs +++ b/crates/codegen/parser/runtime/src/visitor.rs @@ -1,76 +1 @@ -use std::ops::ControlFlow; -use std::rc::Rc; -use super::{cst::*, cursor::Cursor}; - -/// A Visitor pattern for traversing the CST. -/// -/// The trait supports fallible iteration, i.e. the visitor can early return an error from the visit. -pub trait Visitor { - /// Called when the [`Visitor`] enters a [`RuleNode`]. - fn rule_enter( - &mut self, - _node: &Rc, - _cursor: &Cursor, - ) -> Result, E> { - Ok(ControlFlow::Continue(Step::In)) - } - - /// Called when the [`Visitor`] exits a [`RuleNode`]. - fn rule_exit(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } - - /// Called when the [`Visitor`] enters a [`TokenNode`]. - fn token(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } -} - -/// Whether the [`Visitor`] should should enter the children of a [`RuleNode`] or not. -pub enum Step { - In, - Over, -} - -impl Cursor { - pub fn drive_visitor>( - &mut self, - visitor: &mut V, - ) -> Result, E> { - if self.is_completed() { - return Ok(ControlFlow::Continue(())); - } - - loop { - // Node clone is cheap because it's just an enum around an Rc - match self.node() { - Node::Rule(rule_node) => { - match visitor.rule_enter(&rule_node, self)? { - ControlFlow::Break(()) => return Ok(ControlFlow::Break(())), - ControlFlow::Continue(Step::In) => { - if self.go_to_first_child() { - self.drive_visitor(visitor)?; - self.go_to_parent(); - } - } - ControlFlow::Continue(Step::Over) => {} - } - if visitor.rule_exit(&rule_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - - Node::Token(token_node) => { - if visitor.token(&token_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - } - - if !self.go_to_next_sibling() { - return Ok(ControlFlow::Continue(())); - } - } - } -} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs b/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs index 2a8585df5d..b8a2159452 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs @@ -1,78 +1 @@ // This file is generated automatically by infrastructure scripts. Please don't edit by hand. - -use std::ops::ControlFlow; -use std::rc::Rc; - -use super::{cst::*, cursor::Cursor}; - -/// A Visitor pattern for traversing the CST. -/// -/// The trait supports fallible iteration, i.e. the visitor can early return an error from the visit. -pub trait Visitor { - /// Called when the [`Visitor`] enters a [`RuleNode`]. - fn rule_enter( - &mut self, - _node: &Rc, - _cursor: &Cursor, - ) -> Result, E> { - Ok(ControlFlow::Continue(Step::In)) - } - - /// Called when the [`Visitor`] exits a [`RuleNode`]. - fn rule_exit(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } - - /// Called when the [`Visitor`] enters a [`TokenNode`]. - fn token(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } -} - -/// Whether the [`Visitor`] should should enter the children of a [`RuleNode`] or not. -pub enum Step { - In, - Over, -} - -impl Cursor { - pub fn drive_visitor>( - &mut self, - visitor: &mut V, - ) -> Result, E> { - if self.is_completed() { - return Ok(ControlFlow::Continue(())); - } - - loop { - // Node clone is cheap because it's just an enum around an Rc - match self.node() { - Node::Rule(rule_node) => { - match visitor.rule_enter(&rule_node, self)? { - ControlFlow::Break(()) => return Ok(ControlFlow::Break(())), - ControlFlow::Continue(Step::In) => { - if self.go_to_first_child() { - self.drive_visitor(visitor)?; - self.go_to_parent(); - } - } - ControlFlow::Continue(Step::Over) => {} - } - if visitor.rule_exit(&rule_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - - Node::Token(token_node) => { - if visitor.token(&token_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - } - - if !self.go_to_next_sibling() { - return Ok(ControlFlow::Continue(())); - } - } - } -} diff --git a/crates/solidity/outputs/cargo/tests/src/doc_examples/mod.rs b/crates/solidity/outputs/cargo/tests/src/doc_examples/mod.rs index b68ceef00e..670bdee50b 100644 --- a/crates/solidity/outputs/cargo/tests/src/doc_examples/mod.rs +++ b/crates/solidity/outputs/cargo/tests/src/doc_examples/mod.rs @@ -1,3 +1,2 @@ mod cursor_api; mod simple_contract; -mod visitor_api; diff --git a/crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs b/crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs deleted file mode 100644 index 1c7b5c8524..0000000000 --- a/crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::ops::ControlFlow; -use std::rc::Rc; - -use anyhow::{bail, ensure, Error, Result}; -use semver::Version; - -use slang_solidity::{ - cst::{Node, RuleNode}, - cursor::Cursor, - kinds::{ProductionKind, RuleKind, TokenKind}, - language::Language, - visitor::{Step, Visitor}, -}; - -struct ContractCollector { - contract_names: Vec, -} - -impl Visitor for ContractCollector { - fn rule_enter( - &mut self, - node: &Rc, - _cursor: &Cursor, - ) -> Result> { - if node.kind == RuleKind::ContractDefinition { - if let Node::Token(token) = &node.children[2] { - ensure!(token.kind == TokenKind::Identifier); - self.contract_names.push(token.text.to_owned()); - } else { - bail!("Expected contract identifier: {node:?}"); - }; - - return Ok(ControlFlow::Continue(Step::Over)); - } - - Ok(ControlFlow::Continue(Step::In)) - } -} - -#[test] -fn visitor_api() -> Result<()> { - let language = Language::new(Version::parse("0.8.0")?)?; - let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); - - let mut collector = ContractCollector { - contract_names: Vec::new(), - }; - - parse_output - .create_tree_cursor() - .drive_visitor(&mut collector)?; - - assert!(matches!(&collector.contract_names[..], [single] if single == "Foo")); - - return Ok(()); -} diff --git a/crates/solidity/outputs/npm/crate/src/generated/visitor.rs b/crates/solidity/outputs/npm/crate/src/generated/visitor.rs index 2a8585df5d..b8a2159452 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/visitor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/visitor.rs @@ -1,78 +1 @@ // This file is generated automatically by infrastructure scripts. Please don't edit by hand. - -use std::ops::ControlFlow; -use std::rc::Rc; - -use super::{cst::*, cursor::Cursor}; - -/// A Visitor pattern for traversing the CST. -/// -/// The trait supports fallible iteration, i.e. the visitor can early return an error from the visit. -pub trait Visitor { - /// Called when the [`Visitor`] enters a [`RuleNode`]. - fn rule_enter( - &mut self, - _node: &Rc, - _cursor: &Cursor, - ) -> Result, E> { - Ok(ControlFlow::Continue(Step::In)) - } - - /// Called when the [`Visitor`] exits a [`RuleNode`]. - fn rule_exit(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } - - /// Called when the [`Visitor`] enters a [`TokenNode`]. - fn token(&mut self, _node: &Rc, _cursor: &Cursor) -> Result, E> { - Ok(ControlFlow::Continue(())) - } -} - -/// Whether the [`Visitor`] should should enter the children of a [`RuleNode`] or not. -pub enum Step { - In, - Over, -} - -impl Cursor { - pub fn drive_visitor>( - &mut self, - visitor: &mut V, - ) -> Result, E> { - if self.is_completed() { - return Ok(ControlFlow::Continue(())); - } - - loop { - // Node clone is cheap because it's just an enum around an Rc - match self.node() { - Node::Rule(rule_node) => { - match visitor.rule_enter(&rule_node, self)? { - ControlFlow::Break(()) => return Ok(ControlFlow::Break(())), - ControlFlow::Continue(Step::In) => { - if self.go_to_first_child() { - self.drive_visitor(visitor)?; - self.go_to_parent(); - } - } - ControlFlow::Continue(Step::Over) => {} - } - if visitor.rule_exit(&rule_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - - Node::Token(token_node) => { - if visitor.token(&token_node, self)? == ControlFlow::Break(()) { - return Ok(ControlFlow::Break(())); - } - } - } - - if !self.go_to_next_sibling() { - return Ok(ControlFlow::Continue(())); - } - } - } -} diff --git a/documentation/public/user-guide/cargo-crate/index.md b/documentation/public/user-guide/cargo-crate/index.md index a9a2138bff..04e2086fa1 100644 --- a/documentation/public/user-guide/cargo-crate/index.md +++ b/documentation/public/user-guide/cargo-crate/index.md @@ -46,24 +46,8 @@ You can then iterate over the resulting children, and assert that they match the For many code analysis tasks, it is useful to traverse the parse tree and visit each node. The `Cursor` object allows callers to traverse the parse tree in a pre-order depth-first manner. -This is an internal iterator. The `Cursor` can drive an external iterator i.e. the `Visitor` trait, which is described below. - The below example uses a cursor to collect the names of all contracts in a source file, and returns them as a `Vec`: ```{ .rust } --8<-- "crates/solidity/outputs/cargo/tests/src/doc_examples/cursor_api.rs" ``` - -## Visitor API - -The `Visitor` trait allows callers to implement a visitor that will be called for each node in the tree. -The `std::ops::ControlFlow` enum coupled with the `Step` enum allows callers to control the traversal behavior. - -For example, if the visitor is only interested in the top-level nodes, it can return `ControlFlow::Continue(Step::Over)` to skip the children of the current node. -If the visitor is interested in the children of the current node, it can return `ControlFlow::Continue(Step::In)` to visit them. - -The below example defines a visitor that collects the names of all contracts in a source file, and returns them as a `Vec`: - -```{ .rust } ---8<-- "crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs" -``` From 9ddf5cb7d068429f4845a098fd460aef7a04be9c Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 15:45:42 +0100 Subject: [PATCH 6/9] Add a changeset file --- .changeset/purple-parents-teach.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/purple-parents-teach.md diff --git a/.changeset/purple-parents-teach.md b/.changeset/purple-parents-teach.md new file mode 100644 index 0000000000..ad3cea04dd --- /dev/null +++ b/.changeset/purple-parents-teach.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/slang": minor +--- + +Remove the CST Visitor API in favor of the Cursor API From 47663c9313726734550b4c87bbef2208f1d5bf0b Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 15:57:22 +0100 Subject: [PATCH 7/9] fix: Also skip whitespace-only EndOfFileTrivia in CST tests --- .../SourceUnit/everything/generated/0.4.11-failure.yml | 1 - .../SourceUnit/everything/generated/0.8.13-failure.yml | 1 - .../SourceUnit/using_directive/generated/0.4.11-failure.yml | 1 - crates/solidity/testing/utils/src/node_extensions/mod.rs | 5 ++++- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml index 242ab96c25..87b33986f8 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.4.11-failure.yml @@ -60,5 +60,4 @@ Tree: - PathImport (Rule): # 30..40 ' "foo.sol"' - AsciiStringLiteral (Token): '"foo.sol"' # 31..40 - Semicolon (Token): ";" # 40..41 - - EndOfFileTrivia (Rule): # 42..43 "\n" - SKIPPED (Token): "using A for B;\n\ncontract C { }\n\ninterface I { }\n\nl..." # 43..243 diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml index 1e5065aae4..38f8634a2e 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/everything/generated/0.8.13-failure.yml @@ -131,5 +131,4 @@ Tree: - IsKeyword (Token): "is" # 208..210 - BoolKeyword (Token): "bool" # 211..215 - Semicolon (Token): ";" # 215..216 - - EndOfFileTrivia (Rule): # 217..218 "\n" - SKIPPED (Token): "event E1(uint256 value);\n" # 218..243 diff --git a/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml b/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml index 7e34a1f2e3..7a3cb2e3b4 100644 --- a/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml +++ b/crates/solidity/testing/snapshots/cst_output/SourceUnit/using_directive/generated/0.4.11-failure.yml @@ -58,5 +58,4 @@ Tree: - Period (Token): "." # 52..53 - VersionPragmaValue (Token): "0" # 53..54 - Semicolon (Token): ";" # 54..55 - - EndOfFileTrivia (Rule): # 56..57 "\n" - SKIPPED (Token): "using EnvelopeUtils for Envelope global;\nusing Tra..." # 57..793 diff --git a/crates/solidity/testing/utils/src/node_extensions/mod.rs b/crates/solidity/testing/utils/src/node_extensions/mod.rs index 77d0f72852..f72bcec620 100644 --- a/crates/solidity/testing/utils/src/node_extensions/mod.rs +++ b/crates/solidity/testing/utils/src/node_extensions/mod.rs @@ -29,7 +29,10 @@ impl NodeExtensions for Node { impl NodeExtensions for RuleNode { fn is_trivia(&self) -> bool { - return self.kind == RuleKind::LeadingTrivia || self.kind == RuleKind::TrailingTrivia; + matches!( + self.kind, + RuleKind::LeadingTrivia | RuleKind::TrailingTrivia | RuleKind::EndOfFileTrivia + ) } fn extract_non_trivia(&self) -> String { From 9a6e0e33df433d5524c137709f3a89241563afde Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 19:32:36 +0100 Subject: [PATCH 8/9] Stop generating visitor.rs --- crates/codegen/parser/generator/src/code_generator.rs | 1 - crates/codegen/parser/runtime/src/templates/mod.rs.jinja2 | 1 - crates/solidity/outputs/cargo/crate/src/generated/mod.rs | 1 - crates/solidity/outputs/cargo/crate/src/generated/visitor.rs | 1 - crates/solidity/outputs/npm/crate/src/generated/mod.rs | 1 - crates/solidity/outputs/npm/crate/src/generated/visitor.rs | 1 - 6 files changed, 6 deletions(-) delete mode 100644 crates/solidity/outputs/cargo/crate/src/generated/visitor.rs delete mode 100644 crates/solidity/outputs/npm/crate/src/generated/visitor.rs diff --git a/crates/codegen/parser/generator/src/code_generator.rs b/crates/codegen/parser/generator/src/code_generator.rs index 63fb5c578b..59c23460b4 100644 --- a/crates/codegen/parser/generator/src/code_generator.rs +++ b/crates/codegen/parser/generator/src/code_generator.rs @@ -113,7 +113,6 @@ impl CodeGenerator { "parse_error.rs", "parse_output.rs", "text_index.rs", - "visitor.rs", "napi/napi_cst.rs", "napi/napi_cursor.rs", "napi/napi_parse_error.rs", diff --git a/crates/codegen/parser/runtime/src/templates/mod.rs.jinja2 b/crates/codegen/parser/runtime/src/templates/mod.rs.jinja2 index 711c87092a..4bb91487cf 100644 --- a/crates/codegen/parser/runtime/src/templates/mod.rs.jinja2 +++ b/crates/codegen/parser/runtime/src/templates/mod.rs.jinja2 @@ -9,7 +9,6 @@ pub(crate) mod lexer; pub mod parse_error; pub mod parse_output; pub mod text_index; -pub mod visitor; #[cfg(feature = "slang_napi_interfaces")] pub mod napi; diff --git a/crates/solidity/outputs/cargo/crate/src/generated/mod.rs b/crates/solidity/outputs/cargo/crate/src/generated/mod.rs index 45a9519857..aa488c9b16 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/mod.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/mod.rs @@ -11,7 +11,6 @@ pub(crate) mod lexer; pub mod parse_error; pub mod parse_output; pub mod text_index; -pub mod visitor; #[cfg(feature = "slang_napi_interfaces")] pub mod napi; diff --git a/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs b/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs deleted file mode 100644 index b8a2159452..0000000000 --- a/crates/solidity/outputs/cargo/crate/src/generated/visitor.rs +++ /dev/null @@ -1 +0,0 @@ -// This file is generated automatically by infrastructure scripts. Please don't edit by hand. diff --git a/crates/solidity/outputs/npm/crate/src/generated/mod.rs b/crates/solidity/outputs/npm/crate/src/generated/mod.rs index 45a9519857..aa488c9b16 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/mod.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/mod.rs @@ -11,7 +11,6 @@ pub(crate) mod lexer; pub mod parse_error; pub mod parse_output; pub mod text_index; -pub mod visitor; #[cfg(feature = "slang_napi_interfaces")] pub mod napi; diff --git a/crates/solidity/outputs/npm/crate/src/generated/visitor.rs b/crates/solidity/outputs/npm/crate/src/generated/visitor.rs deleted file mode 100644 index b8a2159452..0000000000 --- a/crates/solidity/outputs/npm/crate/src/generated/visitor.rs +++ /dev/null @@ -1 +0,0 @@ -// This file is generated automatically by infrastructure scripts. Please don't edit by hand. From f705de917781e98a83c6a52fba5eccfc1cfeb6c8 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Mon, 20 Nov 2023 19:36:46 +0100 Subject: [PATCH 9/9] Add doc comments --- crates/codegen/parser/runtime/src/cst.rs | 1 + crates/codegen/parser/runtime/src/cursor.rs | 1 + crates/solidity/outputs/cargo/crate/src/generated/cst.rs | 1 + crates/solidity/outputs/cargo/crate/src/generated/cursor.rs | 1 + crates/solidity/outputs/npm/crate/src/generated/cst.rs | 1 + crates/solidity/outputs/npm/crate/src/generated/cursor.rs | 1 + 6 files changed, 6 insertions(+) diff --git a/crates/codegen/parser/runtime/src/cst.rs b/crates/codegen/parser/runtime/src/cst.rs index 4f8833e876..0a3cfbb664 100644 --- a/crates/codegen/parser/runtime/src/cst.rs +++ b/crates/codegen/parser/runtime/src/cst.rs @@ -46,6 +46,7 @@ impl Node { } } + /// Returns a slice of the children (not all descendants) of this node. pub fn children(&self) -> &[Node] { match self { Self::Rule(node) => &node.children, diff --git a/crates/codegen/parser/runtime/src/cursor.rs b/crates/codegen/parser/runtime/src/cursor.rs index 1cb1babecd..a2cdaac93d 100644 --- a/crates/codegen/parser/runtime/src/cursor.rs +++ b/crates/codegen/parser/runtime/src/cursor.rs @@ -144,6 +144,7 @@ impl Cursor { self.current.text_range() } + /// Returns the depth of the current node in the CST, i.e. the number of ancestors. pub fn depth(&self) -> usize { self.path.len() } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs index 28b996b98c..77154c22b6 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs @@ -48,6 +48,7 @@ impl Node { } } + /// Returns a slice of the children (not all descendants) of this node. pub fn children(&self) -> &[Node] { match self { Self::Rule(node) => &node.children, diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs index 6dca60823e..2c265f043c 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs @@ -146,6 +146,7 @@ impl Cursor { self.current.text_range() } + /// Returns the depth of the current node in the CST, i.e. the number of ancestors. pub fn depth(&self) -> usize { self.path.len() } diff --git a/crates/solidity/outputs/npm/crate/src/generated/cst.rs b/crates/solidity/outputs/npm/crate/src/generated/cst.rs index 28b996b98c..77154c22b6 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cst.rs @@ -48,6 +48,7 @@ impl Node { } } + /// Returns a slice of the children (not all descendants) of this node. pub fn children(&self) -> &[Node] { match self { Self::Rule(node) => &node.children, diff --git a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs index 6dca60823e..2c265f043c 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs @@ -146,6 +146,7 @@ impl Cursor { self.current.text_range() } + /// Returns the depth of the current node in the CST, i.e. the number of ancestors. pub fn depth(&self) -> usize { self.path.len() }