From b1dced355ce83f3bd858c02837d67665f7ef281d Mon Sep 17 00:00:00 2001 From: Omar Tawfik <15987992+OmarTawfik@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:11:27 -0800 Subject: [PATCH] public API overhaul (#647) - rename `with_colour` to `with_color` as we are using a single `en-US` locale in the entire project. - use `SUPPORTED_VERSIONS.binary_search()` in `Language::new()` - use functions instead of properties for expensive operations -> #628 - require specifying an initial offset when creating a CST cursor -> #628 --- .changeset/weak-turkeys-lie.md | 5 + crates/codegen/parser/runtime/src/cst.rs | 4 +- crates/codegen/parser/runtime/src/cursor.rs | 4 +- .../parser/runtime/src/napi/napi_cst.rs | 18 ++- .../parser/runtime/src/napi/napi_cursor.rs | 10 +- .../runtime/src/napi/napi_parse_error.rs | 4 +- .../runtime/src/napi/napi_parse_output.rs | 14 +- .../runtime/src/napi/napi_text_index.rs | 10 ++ .../codegen/parser/runtime/src/parse_error.rs | 4 +- .../parser/runtime/src/parse_output.rs | 9 +- .../runtime/src/support/choice_helper.rs | 2 +- .../runtime/src/support/parser_function.rs | 2 +- .../runtime/src/support/parser_result.rs | 2 +- .../runtime/src/templates/language.rs.jinja2 | 2 +- .../outputs/cargo/crate/src/generated/cst.rs | 4 +- .../cargo/crate/src/generated/cursor.rs | 4 +- .../cargo/crate/src/generated/language.rs | 2 +- .../crate/src/generated/napi/napi_cst.rs | 18 ++- .../crate/src/generated/napi/napi_cursor.rs | 10 +- .../src/generated/napi/napi_parse_error.rs | 4 +- .../src/generated/napi/napi_parse_output.rs | 14 +- .../src/generated/napi/napi_text_index.rs | 10 ++ .../cargo/crate/src/generated/parse_error.rs | 4 +- .../cargo/crate/src/generated/parse_output.rs | 9 +- .../src/generated/support/choice_helper.rs | 2 +- .../src/generated/support/parser_function.rs | 2 +- .../src/generated/support/parser_result.rs | 2 +- .../solidity/outputs/cargo/crate/src/main.rs | 4 +- .../cargo/tests/src/cst_output/runner.rs | 6 +- .../tests/src/doc_examples/cursor_api.rs | 8 +- .../tests/src/doc_examples/simple_contract.rs | 2 +- .../tests/src/doc_examples/visitor_api.rs | 3 +- .../outputs/npm/crate/src/generated/cst.rs | 4 +- .../outputs/npm/crate/src/generated/cursor.rs | 4 +- .../npm/crate/src/generated/language.rs | 2 +- .../npm/crate/src/generated/napi/napi_cst.rs | 18 ++- .../crate/src/generated/napi/napi_cursor.rs | 10 +- .../src/generated/napi/napi_parse_error.rs | 4 +- .../src/generated/napi/napi_parse_output.rs | 14 +- .../src/generated/napi/napi_text_index.rs | 10 ++ .../npm/crate/src/generated/parse_error.rs | 4 +- .../npm/crate/src/generated/parse_output.rs | 9 +- .../src/generated/support/choice_helper.rs | 2 +- .../src/generated/support/parser_function.rs | 2 +- .../src/generated/support/parser_result.rs | 2 +- .../npm/package/src/generated/index.d.ts | 18 ++- .../solidity/outputs/npm/tests/jest.config.ts | 10 +- .../outputs/npm/tests/src/cst-cursor.ts | 146 ------------------ .../outputs/npm/tests/src/cst-output.ts | 89 ----------- .../tests/src/doc-examples/simple-contract.ts | 4 +- .../outputs/npm/tests/src/tests/cst-cursor.ts | 102 ++++++++++++ .../outputs/npm/tests/src/tests/cst-output.ts | 66 ++++++++ .../npm/tests/src/{ => tests}/errors.ts | 5 +- .../npm/tests/src/{ => tests}/public-api.ts | 0 .../npm/tests/src/{ => tests}/versions.ts | 0 .../npm/tests/src/utils/cst-helpers.ts | 19 +++ .../testing/sanctuary/src/reporting.rs | 2 +- .../testing/utils/src/cst_snapshots/mod.rs | 19 +-- .../utils/src/cst_snapshots/test_nodes.rs | 8 +- .../utils/src/node_extensions/tests.rs | 2 +- .../testing/utils/src/version_pragmas/mod.rs | 2 +- 61 files changed, 409 insertions(+), 366 deletions(-) create mode 100644 .changeset/weak-turkeys-lie.md delete mode 100644 crates/solidity/outputs/npm/tests/src/cst-cursor.ts delete mode 100644 crates/solidity/outputs/npm/tests/src/cst-output.ts create mode 100644 crates/solidity/outputs/npm/tests/src/tests/cst-cursor.ts create mode 100644 crates/solidity/outputs/npm/tests/src/tests/cst-output.ts rename crates/solidity/outputs/npm/tests/src/{ => tests}/errors.ts (85%) rename crates/solidity/outputs/npm/tests/src/{ => tests}/public-api.ts (100%) rename crates/solidity/outputs/npm/tests/src/{ => tests}/versions.ts (100%) create mode 100644 crates/solidity/outputs/npm/tests/src/utils/cst-helpers.ts diff --git a/.changeset/weak-turkeys-lie.md b/.changeset/weak-turkeys-lie.md new file mode 100644 index 0000000000..5fd78f43fd --- /dev/null +++ b/.changeset/weak-turkeys-lie.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/slang": minor +--- + +Require specifying an initial offset when creating a CST cursor. diff --git a/crates/codegen/parser/runtime/src/cst.rs b/crates/codegen/parser/runtime/src/cst.rs index d9eb1ec7fc..e3c1437a91 100644 --- a/crates/codegen/parser/runtime/src/cst.rs +++ b/crates/codegen/parser/runtime/src/cst.rs @@ -46,8 +46,8 @@ impl Node { } } - pub fn cursor(&self) -> Cursor { - Cursor::new(self.clone()) + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + Cursor::new(self.clone(), text_offset) } pub fn as_rule(&self) -> Option<&Rc> { diff --git a/crates/codegen/parser/runtime/src/cursor.rs b/crates/codegen/parser/runtime/src/cursor.rs index 658f5f0c40..89bf585049 100644 --- a/crates/codegen/parser/runtime/src/cursor.rs +++ b/crates/codegen/parser/runtime/src/cursor.rs @@ -87,13 +87,13 @@ impl Iterator for Cursor { } impl Cursor { - pub(crate) fn new(node: Node) -> Self { + pub(crate) fn new(node: Node, text_offset: TextIndex) -> Self { Self { path: vec![], current: PathNode { node, child_number: 0, - text_offset: Default::default(), + text_offset, }, is_completed: false, } diff --git a/crates/codegen/parser/runtime/src/napi/napi_cst.rs b/crates/codegen/parser/runtime/src/napi/napi_cst.rs index 6875b82570..2b5432603f 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_cst.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_cst.rs @@ -42,7 +42,7 @@ impl RuleNode { (&self.0.text_len).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn children(&self, env: Env) -> Vec { self.0 .children @@ -51,9 +51,11 @@ impl RuleNode { .collect() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Rule(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Rule(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } @@ -83,9 +85,11 @@ impl TokenNode { self.0.text.clone() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Token(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Token(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } diff --git a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs index e2889f652c..33abaf9e19 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_cursor.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_cursor.rs @@ -10,6 +10,12 @@ use napi_text_index::*; #[napi(namespace = "cursor")] pub struct Cursor(Box); +impl From for Cursor { + fn from(value: RustCursor) -> Self { + Self(value.into()) + } +} + #[napi(namespace = "cursor")] impl Cursor { pub(crate) fn new(cursor: RustCursor) -> Self { @@ -41,7 +47,7 @@ impl Cursor { self.0.is_completed() } - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] pub fn node(&self, env: Env) -> JsObject { self.0.node().to_js(&env) } @@ -56,7 +62,7 @@ impl Cursor { (&self.0.text_range()).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 .path_rule_nodes() diff --git a/crates/codegen/parser/runtime/src/napi/napi_parse_error.rs b/crates/codegen/parser/runtime/src/napi/napi_parse_error.rs index 87a1458578..26ca55f96c 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_parse_error.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_parse_error.rs @@ -29,7 +29,7 @@ impl ParseError { } #[napi(namespace = "parse_error")] - pub fn to_error_report(&self, source_id: String, source: String, with_colour: bool) -> String { - self.0.to_error_report(&source_id, &source, with_colour) + pub fn to_error_report(&self, source_id: String, source: String, with_color: bool) -> String { + self.0.to_error_report(&source_id, &source, with_color) } } diff --git a/crates/codegen/parser/runtime/src/napi/napi_parse_output.rs b/crates/codegen/parser/runtime/src/napi/napi_parse_output.rs index a85a4e8091..7dc7f67c32 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_parse_output.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_parse_output.rs @@ -14,12 +14,12 @@ impl From for ParseOutput { #[napi(namespace = "parse_output")] impl ParseOutput { - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] - pub fn parse_tree(&self, env: Env) -> napi::JsObject { - return self.0.parse_tree().to_js(&env); + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] + pub fn tree(&self, env: Env) -> napi::JsObject { + return self.0.tree().to_js(&env); } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn errors(&self) -> Vec { self.0.errors().iter().map(|x| x.clone().into()).collect() } @@ -28,4 +28,10 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { self.0.is_valid() } + + /// Creates a cursor that starts at the root of the parse tree. + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_tree_cursor(&self) -> napi_cursor::Cursor { + return self.0.create_tree_cursor().into(); + } } diff --git a/crates/codegen/parser/runtime/src/napi/napi_text_index.rs b/crates/codegen/parser/runtime/src/napi/napi_text_index.rs index 3d94316ebb..e44bd5b587 100644 --- a/crates/codegen/parser/runtime/src/napi/napi_text_index.rs +++ b/crates/codegen/parser/runtime/src/napi/napi_text_index.rs @@ -20,6 +20,16 @@ impl From<&RustTextIndex> for TextIndex { } } +impl From<&TextIndex> for RustTextIndex { + fn from(value: &TextIndex) -> Self { + Self { + utf8: value.utf8 as usize, + utf16: value.utf16 as usize, + char: value.char as usize, + } + } +} + #[napi(object, namespace = "text_index")] #[derive(Copy, Clone)] pub struct TextRange { diff --git a/crates/codegen/parser/runtime/src/parse_error.rs b/crates/codegen/parser/runtime/src/parse_error.rs index dad58173da..1a4aed476c 100644 --- a/crates/codegen/parser/runtime/src/parse_error.rs +++ b/crates/codegen/parser/runtime/src/parse_error.rs @@ -28,8 +28,8 @@ impl ParseError { .collect(); } - pub fn to_error_report(&self, source_id: &str, source: &str, with_colour: bool) -> String { - return render_error_report(self, source_id, source, with_colour); + pub fn to_error_report(&self, source_id: &str, source: &str, with_color: bool) -> String { + return render_error_report(self, source_id, source, with_color); } } diff --git a/crates/codegen/parser/runtime/src/parse_output.rs b/crates/codegen/parser/runtime/src/parse_output.rs index 644bb53b77..b698270b51 100644 --- a/crates/codegen/parser/runtime/src/parse_output.rs +++ b/crates/codegen/parser/runtime/src/parse_output.rs @@ -1,4 +1,4 @@ -use super::{cst, parse_error::ParseError}; +use crate::{cst, cursor::Cursor, parse_error::ParseError}; #[derive(Debug, PartialEq)] pub struct ParseOutput { @@ -7,7 +7,7 @@ pub struct ParseOutput { } impl ParseOutput { - pub fn parse_tree(&self) -> cst::Node { + pub fn tree(&self) -> cst::Node { return self.parse_tree.clone(); } @@ -18,4 +18,9 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { return self.errors.is_empty(); } + + /// Creates a cursor that starts at the root of the parse tree. + pub fn create_tree_cursor(&self) -> Cursor { + return self.parse_tree.create_cursor(Default::default()); + } } diff --git a/crates/codegen/parser/runtime/src/support/choice_helper.rs b/crates/codegen/parser/runtime/src/support/choice_helper.rs index 8c6cd9ad5e..bc56bb57c1 100644 --- a/crates/codegen/parser/runtime/src/support/choice_helper.rs +++ b/crates/codegen/parser/runtime/src/support/choice_helper.rs @@ -146,7 +146,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .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 22355d9378..86cf275615 100644 --- a/crates/codegen/parser/runtime/src/support/parser_function.rs +++ b/crates/codegen/parser/runtime/src/support/parser_function.rs @@ -95,7 +95,7 @@ where debug_assert_eq!( errors.len() > 0, parse_tree - .cursor() + .create_cursor(Default::default()) .any(|x| x.as_token_with_kind(&[TokenKind::SKIPPED]).is_some()) ); diff --git a/crates/codegen/parser/runtime/src/support/parser_result.rs b/crates/codegen/parser/runtime/src/support/parser_result.rs index aea9ebdc51..a10f230791 100644 --- a/crates/codegen/parser/runtime/src/support/parser_result.rs +++ b/crates/codegen/parser/runtime/src/support/parser_result.rs @@ -93,7 +93,7 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/codegen/parser/runtime/src/templates/language.rs.jinja2 b/crates/codegen/parser/runtime/src/templates/language.rs.jinja2 index e071b6370d..e79447b144 100644 --- a/crates/codegen/parser/runtime/src/templates/language.rs.jinja2 +++ b/crates/codegen/parser/runtime/src/templates/language.rs.jinja2 @@ -49,7 +49,7 @@ impl Language { ]; pub fn new(version: Version) -> std::result::Result { - if Self::SUPPORTED_VERSIONS.contains(&version) { + if Self::SUPPORTED_VERSIONS.binary_search(&version).is_ok() { Ok(Self { {%- for version in code.referenced_versions %} version_is_at_least_{{ version | replace(from=".", to="_") }}: Version::new({{ version | split(pat=".") | join(sep=", ") }}) <= version, diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs index 95876e2fd0..f20fe136e9 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cst.rs @@ -48,8 +48,8 @@ impl Node { } } - pub fn cursor(&self) -> Cursor { - Cursor::new(self.clone()) + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + Cursor::new(self.clone(), text_offset) } pub fn as_rule(&self) -> Option<&Rc> { diff --git a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs index 59e7a60d6a..b3743ec4b6 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/cursor.rs @@ -89,13 +89,13 @@ impl Iterator for Cursor { } impl Cursor { - pub(crate) fn new(node: Node) -> Self { + pub(crate) fn new(node: Node, text_offset: TextIndex) -> Self { Self { path: vec![], current: PathNode { node, child_number: 0, - text_offset: Default::default(), + text_offset, }, is_completed: false, } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/language.rs b/crates/solidity/outputs/cargo/crate/src/generated/language.rs index fd1d062af3..5068f4002e 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/language.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/language.rs @@ -140,7 +140,7 @@ impl Language { ]; pub fn new(version: Version) -> std::result::Result { - if Self::SUPPORTED_VERSIONS.contains(&version) { + if Self::SUPPORTED_VERSIONS.binary_search(&version).is_ok() { Ok(Self { version_is_at_least_0_4_21: Version::new(0, 4, 21) <= version, version_is_at_least_0_4_22: Version::new(0, 4, 22) <= version, diff --git a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cst.rs b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cst.rs index 0c80e2dd66..ffb079c7c3 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cst.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_cst.rs @@ -44,7 +44,7 @@ impl RuleNode { (&self.0.text_len).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn children(&self, env: Env) -> Vec { self.0 .children @@ -53,9 +53,11 @@ impl RuleNode { .collect() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Rule(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Rule(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } @@ -85,9 +87,11 @@ impl TokenNode { self.0.text.clone() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Token(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Token(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } 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 e0d950f686..0dc62a5db8 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 @@ -12,6 +12,12 @@ use napi_text_index::*; #[napi(namespace = "cursor")] pub struct Cursor(Box); +impl From for Cursor { + fn from(value: RustCursor) -> Self { + Self(value.into()) + } +} + #[napi(namespace = "cursor")] impl Cursor { pub(crate) fn new(cursor: RustCursor) -> Self { @@ -43,7 +49,7 @@ impl Cursor { self.0.is_completed() } - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] pub fn node(&self, env: Env) -> JsObject { self.0.node().to_js(&env) } @@ -58,7 +64,7 @@ impl Cursor { (&self.0.text_range()).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 .path_rule_nodes() diff --git a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_error.rs b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_error.rs index b5febf3bb2..e88c6e739c 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_error.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_error.rs @@ -31,7 +31,7 @@ impl ParseError { } #[napi(namespace = "parse_error")] - pub fn to_error_report(&self, source_id: String, source: String, with_colour: bool) -> String { - self.0.to_error_report(&source_id, &source, with_colour) + pub fn to_error_report(&self, source_id: String, source: String, with_color: bool) -> String { + self.0.to_error_report(&source_id, &source, with_color) } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_output.rs b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_output.rs index b25b030d37..7853cfdbe0 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_output.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_parse_output.rs @@ -16,12 +16,12 @@ impl From for ParseOutput { #[napi(namespace = "parse_output")] impl ParseOutput { - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] - pub fn parse_tree(&self, env: Env) -> napi::JsObject { - return self.0.parse_tree().to_js(&env); + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] + pub fn tree(&self, env: Env) -> napi::JsObject { + return self.0.tree().to_js(&env); } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn errors(&self) -> Vec { self.0.errors().iter().map(|x| x.clone().into()).collect() } @@ -30,4 +30,10 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { self.0.is_valid() } + + /// Creates a cursor that starts at the root of the parse tree. + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_tree_cursor(&self) -> napi_cursor::Cursor { + return self.0.create_tree_cursor().into(); + } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_text_index.rs b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_text_index.rs index c0e30360dd..900fdfbaca 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_text_index.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/napi/napi_text_index.rs @@ -22,6 +22,16 @@ impl From<&RustTextIndex> for TextIndex { } } +impl From<&TextIndex> for RustTextIndex { + fn from(value: &TextIndex) -> Self { + Self { + utf8: value.utf8 as usize, + utf16: value.utf16 as usize, + char: value.char as usize, + } + } +} + #[napi(object, namespace = "text_index")] #[derive(Copy, Clone)] pub struct TextRange { diff --git a/crates/solidity/outputs/cargo/crate/src/generated/parse_error.rs b/crates/solidity/outputs/cargo/crate/src/generated/parse_error.rs index e155c7bc8a..9d997bc81e 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/parse_error.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/parse_error.rs @@ -30,8 +30,8 @@ impl ParseError { .collect(); } - pub fn to_error_report(&self, source_id: &str, source: &str, with_colour: bool) -> String { - return render_error_report(self, source_id, source, with_colour); + pub fn to_error_report(&self, source_id: &str, source: &str, with_color: bool) -> String { + return render_error_report(self, source_id, source, with_color); } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/parse_output.rs b/crates/solidity/outputs/cargo/crate/src/generated/parse_output.rs index 52b9a054bc..42381c44aa 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/parse_output.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/parse_output.rs @@ -1,6 +1,6 @@ // This file is generated automatically by infrastructure scripts. Please don't edit by hand. -use super::{cst, parse_error::ParseError}; +use crate::{cst, cursor::Cursor, parse_error::ParseError}; #[derive(Debug, PartialEq)] pub struct ParseOutput { @@ -9,7 +9,7 @@ pub struct ParseOutput { } impl ParseOutput { - pub fn parse_tree(&self) -> cst::Node { + pub fn tree(&self) -> cst::Node { return self.parse_tree.clone(); } @@ -20,4 +20,9 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { return self.errors.is_empty(); } + + /// Creates a cursor that starts at the root of the parse tree. + pub fn create_tree_cursor(&self) -> Cursor { + return self.parse_tree.create_cursor(Default::default()); + } } 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 0b9ab410a2..aad70bd51c 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 @@ -148,7 +148,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .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 da70a20109..5e98666bd7 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 @@ -97,7 +97,7 @@ where debug_assert_eq!( errors.len() > 0, parse_tree - .cursor() + .create_cursor(Default::default()) .any(|x| x.as_token_with_kind(&[TokenKind::SKIPPED]).is_some()) ); 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 c177478291..591b7cc0ce 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 @@ -95,7 +95,7 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/solidity/outputs/cargo/crate/src/main.rs b/crates/solidity/outputs/cargo/crate/src/main.rs index 98dc35df9e..9a524293cc 100644 --- a/crates/solidity/outputs/cargo/crate/src/main.rs +++ b/crates/solidity/outputs/cargo/crate/src/main.rs @@ -63,12 +63,12 @@ fn execute_parse_command(file_path_string: String, version: Version, json: bool) let errors = output.errors(); for error in errors { - let report = error.to_error_report(&file_path_string, &input, /* with_colour */ true); + let report = error.to_error_report(&file_path_string, &input, /* with_color */ true); eprintln!("{report}"); } if json { - let root_node = output.parse_tree(); + let root_node = output.tree(); let json = serde_json::to_string_pretty(&root_node)?; println!("{json}"); } diff --git a/crates/solidity/outputs/cargo/tests/src/cst_output/runner.rs b/crates/solidity/outputs/cargo/tests/src/cst_output/runner.rs index 30c67a1abb..86c1181c40 100644 --- a/crates/solidity/outputs/cargo/tests/src/cst_output/runner.rs +++ b/crates/solidity/outputs/cargo/tests/src/cst_output/runner.rs @@ -47,11 +47,11 @@ pub fn run(parser_name: &str, test_name: &str) -> Result<()> { .errors() .iter() .map(|error| { - error.to_error_report(source_id, &source, /* with_colour */ false) + error.to_error_report(source_id, &source, /* with_color */ false) }) .collect(); - let tree = Some(output.parse_tree()); + let cursor = output.create_tree_cursor(); let status = if output.is_valid() { TestStatus::Success @@ -59,7 +59,7 @@ pub fn run(parser_name: &str, test_name: &str) -> Result<()> { TestStatus::Failure }; - let snapshot = CstSnapshots::render(&source, &errors, &tree)?; + let snapshot = CstSnapshots::render(&source, &errors, cursor)?; let snapshot_path = test_dir .join("generated") 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 a5b4effde8..e22290632a 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 @@ -13,7 +13,7 @@ fn cursor_api() -> Result<()> { let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); let mut contract_names = Vec::new(); - let mut cursor = parse_output.parse_tree().cursor(); + let mut cursor = parse_output.create_tree_cursor(); while let Some(_rule_node) = cursor.find_rule_with_kind(&[RuleKind::ContractDefinition]) { // You have to make sure you return the cursor to original position if cursor.go_to_first_child() { @@ -40,7 +40,7 @@ fn cursor_api_using_spawn() -> Result<()> { let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); let mut contract_names = Vec::new(); - let mut cursor = parse_output.parse_tree().cursor(); + let mut cursor = parse_output.create_tree_cursor(); while let Some(_rule_node) = cursor.find_rule_with_kind(&[RuleKind::ContractDefinition]) { // `.spawn()` creates a new cursor without the path history, which is cheaper // than `.clone()`, which copies the path history. @@ -72,7 +72,7 @@ fn cursor_api_using_iter() -> Result<()> { let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); let mut contract_names = Vec::new(); - let mut cursor = parse_output.parse_tree().cursor(); + let mut cursor = parse_output.create_tree_cursor(); while let Some(_rule_node) = cursor.find_rule_with_kind(&[RuleKind::ContractDefinition]) { if let Some(token_node) = _rule_node .children @@ -97,7 +97,7 @@ fn cursor_as_iter() -> Result<()> { let language = Language::new(Version::parse("0.8.0")?)?; let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); - let mut cursor = parse_output.parse_tree().cursor(); + let mut cursor = parse_output.create_tree_cursor(); assert_eq!( cursor.node().as_rule().unwrap().kind, RuleKind::ContractDefinition diff --git a/crates/solidity/outputs/cargo/tests/src/doc_examples/simple_contract.rs b/crates/solidity/outputs/cargo/tests/src/doc_examples/simple_contract.rs index f0cdd6a2c0..e64ae1d6b3 100644 --- a/crates/solidity/outputs/cargo/tests/src/doc_examples/simple_contract.rs +++ b/crates/solidity/outputs/cargo/tests/src/doc_examples/simple_contract.rs @@ -12,7 +12,7 @@ fn simple_contract() -> Result<()> { let language = Language::new(Version::parse("0.8.0")?)?; let parse_output = language.parse(ProductionKind::ContractDefinition, "contract Foo {}"); - let parse_tree = parse_output.parse_tree(); + let parse_tree = parse_output.tree(); let children = if let Node::Rule(rule) = &parse_tree { assert_eq!(rule.kind, RuleKind::ContractDefinition); 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 index 832a91e1c2..1c7b5c8524 100644 --- a/crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs +++ b/crates/solidity/outputs/cargo/tests/src/doc_examples/visitor_api.rs @@ -47,8 +47,7 @@ fn visitor_api() -> Result<()> { }; parse_output - .parse_tree() - .cursor() + .create_tree_cursor() .drive_visitor(&mut collector)?; assert!(matches!(&collector.contract_names[..], [single] if single == "Foo")); diff --git a/crates/solidity/outputs/npm/crate/src/generated/cst.rs b/crates/solidity/outputs/npm/crate/src/generated/cst.rs index 95876e2fd0..f20fe136e9 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cst.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cst.rs @@ -48,8 +48,8 @@ impl Node { } } - pub fn cursor(&self) -> Cursor { - Cursor::new(self.clone()) + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + Cursor::new(self.clone(), text_offset) } pub fn as_rule(&self) -> Option<&Rc> { diff --git a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs index 59e7a60d6a..b3743ec4b6 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/cursor.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/cursor.rs @@ -89,13 +89,13 @@ impl Iterator for Cursor { } impl Cursor { - pub(crate) fn new(node: Node) -> Self { + pub(crate) fn new(node: Node, text_offset: TextIndex) -> Self { Self { path: vec![], current: PathNode { node, child_number: 0, - text_offset: Default::default(), + text_offset, }, is_completed: false, } diff --git a/crates/solidity/outputs/npm/crate/src/generated/language.rs b/crates/solidity/outputs/npm/crate/src/generated/language.rs index fd1d062af3..5068f4002e 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/language.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/language.rs @@ -140,7 +140,7 @@ impl Language { ]; pub fn new(version: Version) -> std::result::Result { - if Self::SUPPORTED_VERSIONS.contains(&version) { + if Self::SUPPORTED_VERSIONS.binary_search(&version).is_ok() { Ok(Self { version_is_at_least_0_4_21: Version::new(0, 4, 21) <= version, version_is_at_least_0_4_22: Version::new(0, 4, 22) <= version, diff --git a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cst.rs b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cst.rs index 0c80e2dd66..ffb079c7c3 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cst.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_cst.rs @@ -44,7 +44,7 @@ impl RuleNode { (&self.0.text_len).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn children(&self, env: Env) -> Vec { self.0 .children @@ -53,9 +53,11 @@ impl RuleNode { .collect() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Rule(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Rule(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } @@ -85,9 +87,11 @@ impl TokenNode { self.0.text.clone() } - #[napi(getter, ts_return_type = "cursor.Cursor")] - pub fn cursor(&self) -> Cursor { - Cursor::new(RustNode::Token(self.0.clone()).cursor()) + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_cursor(&self, text_offset: TextIndex) -> Cursor { + RustNode::Token(self.0.clone()) + .create_cursor((&text_offset).into()) + .into() } } 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 e0d950f686..0dc62a5db8 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 @@ -12,6 +12,12 @@ use napi_text_index::*; #[napi(namespace = "cursor")] pub struct Cursor(Box); +impl From for Cursor { + fn from(value: RustCursor) -> Self { + Self(value.into()) + } +} + #[napi(namespace = "cursor")] impl Cursor { pub(crate) fn new(cursor: RustCursor) -> Self { @@ -43,7 +49,7 @@ impl Cursor { self.0.is_completed() } - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] pub fn node(&self, env: Env) -> JsObject { self.0.node().to_js(&env) } @@ -58,7 +64,7 @@ impl Cursor { (&self.0.text_range()).into() } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn path_rule_nodes(&self, env: Env) -> Vec { self.0 .path_rule_nodes() diff --git a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_error.rs b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_error.rs index b5febf3bb2..e88c6e739c 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_error.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_error.rs @@ -31,7 +31,7 @@ impl ParseError { } #[napi(namespace = "parse_error")] - pub fn to_error_report(&self, source_id: String, source: String, with_colour: bool) -> String { - self.0.to_error_report(&source_id, &source, with_colour) + pub fn to_error_report(&self, source_id: String, source: String, with_color: bool) -> String { + self.0.to_error_report(&source_id, &source, with_color) } } diff --git a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_output.rs b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_output.rs index b25b030d37..7853cfdbe0 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_output.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_parse_output.rs @@ -16,12 +16,12 @@ impl From for ParseOutput { #[napi(namespace = "parse_output")] impl ParseOutput { - #[napi(getter, ts_return_type = "cst.RuleNode | cst.TokenNode")] - pub fn parse_tree(&self, env: Env) -> napi::JsObject { - return self.0.parse_tree().to_js(&env); + #[napi(ts_return_type = "cst.RuleNode | cst.TokenNode")] + pub fn tree(&self, env: Env) -> napi::JsObject { + return self.0.tree().to_js(&env); } - #[napi(getter, ts_return_type = "Array")] + #[napi(ts_return_type = "Array")] pub fn errors(&self) -> Vec { self.0.errors().iter().map(|x| x.clone().into()).collect() } @@ -30,4 +30,10 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { self.0.is_valid() } + + /// Creates a cursor that starts at the root of the parse tree. + #[napi(ts_return_type = "cursor.Cursor")] + pub fn create_tree_cursor(&self) -> napi_cursor::Cursor { + return self.0.create_tree_cursor().into(); + } } diff --git a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_text_index.rs b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_text_index.rs index c0e30360dd..900fdfbaca 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/napi/napi_text_index.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/napi/napi_text_index.rs @@ -22,6 +22,16 @@ impl From<&RustTextIndex> for TextIndex { } } +impl From<&TextIndex> for RustTextIndex { + fn from(value: &TextIndex) -> Self { + Self { + utf8: value.utf8 as usize, + utf16: value.utf16 as usize, + char: value.char as usize, + } + } +} + #[napi(object, namespace = "text_index")] #[derive(Copy, Clone)] pub struct TextRange { diff --git a/crates/solidity/outputs/npm/crate/src/generated/parse_error.rs b/crates/solidity/outputs/npm/crate/src/generated/parse_error.rs index e155c7bc8a..9d997bc81e 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/parse_error.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/parse_error.rs @@ -30,8 +30,8 @@ impl ParseError { .collect(); } - pub fn to_error_report(&self, source_id: &str, source: &str, with_colour: bool) -> String { - return render_error_report(self, source_id, source, with_colour); + pub fn to_error_report(&self, source_id: &str, source: &str, with_color: bool) -> String { + return render_error_report(self, source_id, source, with_color); } } diff --git a/crates/solidity/outputs/npm/crate/src/generated/parse_output.rs b/crates/solidity/outputs/npm/crate/src/generated/parse_output.rs index 52b9a054bc..42381c44aa 100644 --- a/crates/solidity/outputs/npm/crate/src/generated/parse_output.rs +++ b/crates/solidity/outputs/npm/crate/src/generated/parse_output.rs @@ -1,6 +1,6 @@ // This file is generated automatically by infrastructure scripts. Please don't edit by hand. -use super::{cst, parse_error::ParseError}; +use crate::{cst, cursor::Cursor, parse_error::ParseError}; #[derive(Debug, PartialEq)] pub struct ParseOutput { @@ -9,7 +9,7 @@ pub struct ParseOutput { } impl ParseOutput { - pub fn parse_tree(&self) -> cst::Node { + pub fn tree(&self) -> cst::Node { return self.parse_tree.clone(); } @@ -20,4 +20,9 @@ impl ParseOutput { pub fn is_valid(&self) -> bool { return self.errors.is_empty(); } + + /// Creates a cursor that starts at the root of the parse tree. + pub fn create_tree_cursor(&self) -> Cursor { + return self.parse_tree.create_cursor(Default::default()); + } } 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 0b9ab410a2..aad70bd51c 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 @@ -148,7 +148,7 @@ pub fn total_not_skipped_span(result: &ParserResult) -> usize { nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .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 da70a20109..5e98666bd7 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 @@ -97,7 +97,7 @@ where debug_assert_eq!( errors.len() > 0, parse_tree - .cursor() + .create_cursor(Default::default()) .any(|x| x.as_token_with_kind(&[TokenKind::SKIPPED]).is_some()) ); 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 c177478291..591b7cc0ce 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 @@ -95,7 +95,7 @@ impl Match { pub fn is_full_recursive(&self) -> bool { self.nodes .iter() - .flat_map(cst::Node::cursor) + .flat_map(|node| cst::Node::create_cursor(node, Default::default())) .all(|node| node.as_token_with_kind(&[TokenKind::SKIPPED]).is_none()) } } diff --git a/crates/solidity/outputs/npm/package/src/generated/index.d.ts b/crates/solidity/outputs/npm/package/src/generated/index.d.ts index e21e80f7a2..614b4bad76 100644 --- a/crates/solidity/outputs/npm/package/src/generated/index.d.ts +++ b/crates/solidity/outputs/npm/package/src/generated/index.d.ts @@ -509,15 +509,15 @@ export namespace cst { get type(): NodeType.Rule; get kind(): kinds.RuleKind; get textLength(): text_index.TextIndex; - get children(): Array; - get cursor(): cursor.Cursor; + children(): Array; + createCursor(textOffset: TextIndex): cursor.Cursor; } export class TokenNode { get type(): NodeType.Token; get kind(): kinds.TokenKind; get textLength(): text_index.TextIndex; get text(): string; - get cursor(): cursor.Cursor; + createCursor(textOffset: TextIndex): cursor.Cursor; } } export namespace cursor { @@ -527,10 +527,10 @@ export namespace cursor { clone(): Cursor; spawn(): Cursor; get isCompleted(): boolean; - get node(): cst.RuleNode | cst.TokenNode; + node(): cst.RuleNode | cst.TokenNode; get textOffset(): text_index.TextIndex; get textRange(): text_index.TextRange; - get pathRuleNodes(): Array; + pathRuleNodes(): Array; goToNext(): boolean; goToNextNonDescendent(): boolean; goToPrevious(): boolean; @@ -547,14 +547,16 @@ export namespace cursor { export namespace parse_error { export class ParseError { get textRange(): text_index.TextRange; - toErrorReport(sourceId: string, source: string, withColour: boolean): string; + toErrorReport(sourceId: string, source: string, withColor: boolean): string; } } export namespace parse_output { export class ParseOutput { - get parseTree(): cst.RuleNode | cst.TokenNode; - get errors(): Array; + tree(): cst.RuleNode | cst.TokenNode; + errors(): Array; get isValid(): boolean; + /** Creates a cursor that starts at the root of the parse tree. */ + createTreeCursor(): cursor.Cursor; } } export namespace text_index { diff --git a/crates/solidity/outputs/npm/tests/jest.config.ts b/crates/solidity/outputs/npm/tests/jest.config.ts index 929c703259..2b5bebf838 100644 --- a/crates/solidity/outputs/npm/tests/jest.config.ts +++ b/crates/solidity/outputs/npm/tests/jest.config.ts @@ -1,22 +1,18 @@ import type { Config } from "jest"; -import * as path from "path"; const config: Config = { - rootDir: path.join(__dirname, "src"), - testMatch: ["**/*.ts"], + rootDir: __dirname, + testMatch: ["/src/doc-examples/**/*.ts", "/src/tests/**/*.ts"], testEnvironment: "node", preset: "ts-jest", - cacheDirectory: path.join(__dirname, "target/jest/cache"), + cacheDirectory: "/target/jest/cache", slowTestThreshold: 5, verbose: true, clearMocks: true, resetMocks: true, - - globalSetup: undefined, - globalTeardown: undefined, }; export default config; diff --git a/crates/solidity/outputs/npm/tests/src/cst-cursor.ts b/crates/solidity/outputs/npm/tests/src/cst-cursor.ts deleted file mode 100644 index f1084e5725..0000000000 --- a/crates/solidity/outputs/npm/tests/src/cst-cursor.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Language } from "@nomicfoundation/slang/language"; -import { NodeType, RuleNode, TokenNode } from "@nomicfoundation/slang/cst"; -import { ProductionKind } from "@nomicfoundation/slang/kinds"; -import { Cursor } from "@nomicfoundation/slang/cursor"; - -test("use cursor", () => { - const source = "int256 constant z = 1 + 2;"; - const language = new Language("0.8.1"); - - const { parseTree } = language.parse(ProductionKind.SourceUnit, source); - const cursor: Cursor = parseTree.cursor; - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("int256"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("constant"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("z"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("="); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("1"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("+"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Rule); - expect(cursor.node).toBeInstanceOf(RuleNode); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(" "); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe("2"); - expect(cursor.goToNext()).toBe(true); - - expect(cursor.node.type).toBe(NodeType.Token); - expect(cursor.node).toBeInstanceOf(TokenNode); - expect((cursor.node as TokenNode).text).toBe(";"); - expect(cursor.goToNext()).toBe(false); -}); diff --git a/crates/solidity/outputs/npm/tests/src/cst-output.ts b/crates/solidity/outputs/npm/tests/src/cst-output.ts deleted file mode 100644 index f35287eab2..0000000000 --- a/crates/solidity/outputs/npm/tests/src/cst-output.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Language } from "@nomicfoundation/slang/language"; -import { NodeType, RuleNode, TokenNode } from "@nomicfoundation/slang/cst"; -import { ProductionKind, RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; - -test("parse token", () => { - const source = "5_286_981"; - const language = new Language("0.8.1"); - - const { parseTree } = language.parse(ProductionKind.NumericExpression, source); - - if (parseTree instanceof RuleNode) { - expect(parseTree.type).toEqual(NodeType.Rule); - expect(parseTree.kind).toEqual(RuleKind.NumericExpression); - expect(parseTree.children).toHaveLength(1); - const token = parseTree.children[0]; - if (token instanceof TokenNode) { - expect(token.type).toEqual(NodeType.Token); - expect(token.kind).toEqual(TokenKind.DecimalLiteral); - } else { - fail("Expected TokenNode"); - } - } else { - fail("Expected RuleNode"); - } -}); - -test("parse rule", () => { - const source = "int256 constant z = 1**2**3;"; - const language = new Language("0.8.1"); - - const { parseTree } = language.parse(ProductionKind.SourceUnit, source); - - if (parseTree instanceof RuleNode) { - expect(parseTree.type).toEqual(NodeType.Rule); - expect(parseTree.kind).toEqual(RuleKind.SourceUnit); - expect(parseTree.children).toHaveLength(1); - } else { - fail("Expected RuleNode"); - } -}); - -test("trivial cursor access", () => { - const source = "int256 constant z = 1**2**3;"; - const language = new Language("0.8.1"); - - const { parseTree } = language.parse(ProductionKind.SourceUnit, source); - - let cursor = parseTree.cursor; - let node = cursor.node; - if (node instanceof RuleNode) { - expect(node.type).toEqual(NodeType.Rule); - expect(node.kind).toEqual(RuleKind.SourceUnit); - expect(node.children).toHaveLength(1); - } else { - fail("Expected RuleNode"); - } -}); - -test("calculate unicode characters text length", () => { - const source = `unicode"some 😁 emoji"`; - const language = new Language("0.8.1"); - - const { parseTree } = language.parse(ProductionKind.UnicodeStringLiteralsList, source); - - if (parseTree instanceof RuleNode) { - expect(parseTree.type).toEqual(NodeType.Rule); - expect(parseTree.kind).toEqual(RuleKind.UnicodeStringLiteralsList); - expect(parseTree.children).toHaveLength(1); - expect(parseTree.textLength).toEqual({ - char: 21, - utf16: 22, - utf8: 24, - }); - const token = parseTree.children[0]; - if (token instanceof TokenNode) { - expect(token.type).toEqual(NodeType.Token); - expect(token.kind).toEqual(TokenKind.UnicodeStringLiteral); - expect(token.textLength).toEqual({ - char: 21, - utf16: 22, - utf8: 24, - }); - } else { - fail("Expected TokenNode"); - } - } else { - fail("Expected RuleNode"); - } -}); diff --git a/crates/solidity/outputs/npm/tests/src/doc-examples/simple-contract.ts b/crates/solidity/outputs/npm/tests/src/doc-examples/simple-contract.ts index 50db91c740..4a0c29eabf 100644 --- a/crates/solidity/outputs/npm/tests/src/doc-examples/simple-contract.ts +++ b/crates/solidity/outputs/npm/tests/src/doc-examples/simple-contract.ts @@ -6,10 +6,10 @@ test("simple contract", () => { const language = new Language("0.8.0"); const parseOutput = language.parse(ProductionKind.ContractDefinition, "contract Foo {}"); - const parseTree = parseOutput.parseTree as RuleNode; + const parseTree = parseOutput.tree() as RuleNode; expect(parseTree.kind).toEqual(RuleKind.ContractDefinition); - const children = parseTree.children; + const children = parseTree.children(); expect(children).toHaveLength(6); expect((children[0] as TokenNode).kind).toEqual(TokenKind.ContractKeyword); diff --git a/crates/solidity/outputs/npm/tests/src/tests/cst-cursor.ts b/crates/solidity/outputs/npm/tests/src/tests/cst-cursor.ts new file mode 100644 index 0000000000..428982db3f --- /dev/null +++ b/crates/solidity/outputs/npm/tests/src/tests/cst-cursor.ts @@ -0,0 +1,102 @@ +import { Language } from "@nomicfoundation/slang/language"; +import { ProductionKind, RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { Cursor } from "@nomicfoundation/slang/cursor"; +import { expectRule, expectToken } from "../utils/cst-helpers"; + +test("use cursor", () => { + const source = "int256 constant z = 1 + 2;"; + const language = new Language("0.8.1"); + + const parseOutput = language.parse(ProductionKind.SourceUnit, source); + const cursor: Cursor = parseOutput.createTreeCursor(); + + expectRule(cursor.node(), RuleKind.SourceUnit); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.SourceUnitMembersList); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.ConstantDefinition); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.TypeName); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.SignedIntegerType, "int256"); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.ConstantKeyword, "constant"); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Identifier, "z"); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Equal, "="); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.Expression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.BinaryExpression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.Expression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.NumericExpression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.DecimalLiteral, "1"); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Plus, "+"); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.Expression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.NumericExpression); + expect(cursor.goToNext()).toBe(true); + + expectRule(cursor.node(), RuleKind.LeadingTrivia); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Whitespace, " "); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.DecimalLiteral, "2"); + expect(cursor.goToNext()).toBe(true); + + expectToken(cursor.node(), TokenKind.Semicolon, ";"); + expect(cursor.goToNext()).toBe(false); +}); diff --git a/crates/solidity/outputs/npm/tests/src/tests/cst-output.ts b/crates/solidity/outputs/npm/tests/src/tests/cst-output.ts new file mode 100644 index 0000000000..cdf80af8d9 --- /dev/null +++ b/crates/solidity/outputs/npm/tests/src/tests/cst-output.ts @@ -0,0 +1,66 @@ +import { Language } from "@nomicfoundation/slang/language"; +import { ProductionKind, RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { expectRule, expectToken } from "../utils/cst-helpers"; + +test("parse token", () => { + const source = "5_286_981"; + const language = new Language("0.8.1"); + + const parseTree = language.parse(ProductionKind.NumericExpression, source).tree(); + expectRule(parseTree, RuleKind.NumericExpression); + + const children = parseTree.children(); + expect(children).toHaveLength(1); + + expectToken(children[0]!, TokenKind.DecimalLiteral, "5_286_981"); +}); + +test("parse rule", () => { + const source = "int256 constant z = 1**2**3;"; + const language = new Language("0.8.1"); + + const parseTree = language.parse(ProductionKind.SourceUnit, source).tree(); + expectRule(parseTree, RuleKind.SourceUnit); + + const children = parseTree.children(); + expect(children).toHaveLength(1); + + expectRule(children[0]!, RuleKind.SourceUnitMembersList); +}); + +test("trivial cursor access", () => { + const source = "int256 constant z = 1**2**3;"; + const language = new Language("0.8.1"); + + const parseOutput = language.parse(ProductionKind.SourceUnit, source); + const node = parseOutput.createTreeCursor().node(); + expectRule(node, RuleKind.SourceUnit); + + const children = node.children(); + expect(children).toHaveLength(1); +}); + +test("calculate unicode characters text length", () => { + const source = `unicode"some 😁 emoji"`; + const language = new Language("0.8.1"); + + const parseTree = language.parse(ProductionKind.UnicodeStringLiteralsList, source).tree(); + expectRule(parseTree, RuleKind.UnicodeStringLiteralsList); + + expect(parseTree.textLength).toEqual({ + char: 21, + utf16: 22, + utf8: 24, + }); + + const children = parseTree.children(); + expect(children).toHaveLength(1); + + const token = children[0]!; + expectToken(token, TokenKind.UnicodeStringLiteral, `unicode"some 😁 emoji"`); + expect(token.textLength).toEqual({ + char: 21, + utf16: 22, + utf8: 24, + }); +}); diff --git a/crates/solidity/outputs/npm/tests/src/errors.ts b/crates/solidity/outputs/npm/tests/src/tests/errors.ts similarity index 85% rename from crates/solidity/outputs/npm/tests/src/errors.ts rename to crates/solidity/outputs/npm/tests/src/tests/errors.ts index 341089a3b0..02f07a84db 100644 --- a/crates/solidity/outputs/npm/tests/src/errors.ts +++ b/crates/solidity/outputs/npm/tests/src/tests/errors.ts @@ -5,11 +5,10 @@ test("render error reports", () => { const source = "int256 constant"; const language = new Language("0.8.1"); - const { errors } = language.parse(ProductionKind.SourceUnit, source); + const errors = language.parse(ProductionKind.SourceUnit, source).errors(); expect(errors).toHaveLength(1); - const report = errors[0]?.toErrorReport("test.sol", source, /* withColor */ false); - + const report = errors[0]!.toErrorReport("test.sol", source, /* withColor */ false); expect(report).toEqual( ` Error: Expected Identifier. diff --git a/crates/solidity/outputs/npm/tests/src/public-api.ts b/crates/solidity/outputs/npm/tests/src/tests/public-api.ts similarity index 100% rename from crates/solidity/outputs/npm/tests/src/public-api.ts rename to crates/solidity/outputs/npm/tests/src/tests/public-api.ts diff --git a/crates/solidity/outputs/npm/tests/src/versions.ts b/crates/solidity/outputs/npm/tests/src/tests/versions.ts similarity index 100% rename from crates/solidity/outputs/npm/tests/src/versions.ts rename to crates/solidity/outputs/npm/tests/src/tests/versions.ts diff --git a/crates/solidity/outputs/npm/tests/src/utils/cst-helpers.ts b/crates/solidity/outputs/npm/tests/src/utils/cst-helpers.ts new file mode 100644 index 0000000000..810cb95cd8 --- /dev/null +++ b/crates/solidity/outputs/npm/tests/src/utils/cst-helpers.ts @@ -0,0 +1,19 @@ +import { NodeType, RuleNode, TokenNode } from "@nomicfoundation/slang/cst"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; + +export function expectRule(node: RuleNode | TokenNode, kind: RuleKind): asserts node is RuleNode { + expect(node).toBeInstanceOf(RuleNode); + expect(node.type).toEqual(NodeType.Rule); + + const rule = node as TokenNode; + expect(rule.kind).toEqual(kind); +} + +export function expectToken(node: RuleNode | TokenNode, kind: TokenKind, text: string): asserts node is TokenNode { + expect(node).toBeInstanceOf(TokenNode); + expect(node.type).toEqual(NodeType.Token); + + const token = node as TokenNode; + expect(token.kind).toEqual(kind); + expect(token.text).toEqual(text); +} diff --git a/crates/solidity/testing/sanctuary/src/reporting.rs b/crates/solidity/testing/sanctuary/src/reporting.rs index c3d696b30c..ab2899c364 100644 --- a/crates/solidity/testing/sanctuary/src/reporting.rs +++ b/crates/solidity/testing/sanctuary/src/reporting.rs @@ -71,7 +71,7 @@ impl Reporter { let reports = errors .iter() .take(Self::MAX_PRINTED_FAILURES - failures_before_update) - .map(|error| error.to_error_report(source_id, source, /* with_colour */ true)) + .map(|error| error.to_error_report(source_id, source, /* with_color */ true)) .collect::>(); self.progress_bar.suspend(|| { diff --git a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs index 16062a6292..e85b331b86 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/mod.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/mod.rs @@ -3,14 +3,14 @@ mod test_nodes; use std::{self, cmp::max, fmt::Write}; use anyhow::Result; -use slang_solidity::{cst::Node, text_index::TextRangeExtensions}; +use slang_solidity::{cursor::Cursor, text_index::TextRangeExtensions}; use crate::cst_snapshots::test_nodes::{TestNode, TestNodeKind}; pub struct CstSnapshots; impl CstSnapshots { - pub fn render(source: &str, errors: &Vec, tree: &Option) -> Result { + pub fn render(source: &str, errors: &Vec, cursor: Cursor) -> Result { let mut w = String::new(); write_source(&mut w, source)?; @@ -19,7 +19,7 @@ impl CstSnapshots { write_errors(&mut w, errors)?; writeln!(&mut w)?; - write_tree(&mut w, tree, source)?; + write_tree(&mut w, cursor, source)?; return Ok(w); } @@ -83,17 +83,12 @@ fn write_errors(w: &mut W, errors: &Vec) -> Result<()> { return Ok(()); } -fn write_tree(w: &mut W, tree: &Option, source: &str) -> Result<()> { +fn write_tree(w: &mut W, cursor: Cursor, source: &str) -> Result<()> { write!(w, "Tree:")?; + writeln!(w)?; - if let Some(tree) = tree { - writeln!(w)?; - - let tree = TestNode::from_cst(tree); - write_node(w, &tree, source, 0)?; - } else { - writeln!(w, " null")?; - } + let tree = TestNode::from_cst(cursor); + write_node(w, &tree, source, 0)?; return 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 f50f48c34f..429a6b249c 100644 --- a/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs +++ b/crates/solidity/testing/utils/src/cst_snapshots/test_nodes.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use anyhow::Result; use slang_solidity::{ - cst::Node, cst::RuleNode, cst::TokenNode, cursor::Cursor, kinds::RuleKind, kinds::TokenKind, + cst::RuleNode, cst::TokenNode, cursor::Cursor, kinds::RuleKind, kinds::TokenKind, text_index::TextRange, visitor::Step, visitor::Visitor, }; @@ -85,11 +85,13 @@ impl TestNodeBuilder { } impl TestNode { - pub fn from_cst(node: &Node) -> Self { + pub fn from_cst(mut cursor: Cursor) -> Self { let mut visitor = TestNodeBuilder { stack: vec![vec![]], }; - node.cursor().drive_visitor(&mut visitor).unwrap(); + + cursor.drive_visitor(&mut visitor).unwrap(); + return visitor.stack.remove(0).remove(0); } diff --git a/crates/solidity/testing/utils/src/node_extensions/tests.rs b/crates/solidity/testing/utils/src/node_extensions/tests.rs index c4834a577d..bd4ddf6201 100644 --- a/crates/solidity/testing/utils/src/node_extensions/tests.rs +++ b/crates/solidity/testing/utils/src/node_extensions/tests.rs @@ -18,7 +18,7 @@ fn extract_non_trivia() -> Result<()> { assert_eq!(output.errors().len(), 0); - let parse_tree = output.parse_tree(); + let parse_tree = output.tree(); let value = parse_tree.extract_non_trivia(); assert_eq!(value, "x=(1+2)"); diff --git a/crates/solidity/testing/utils/src/version_pragmas/mod.rs b/crates/solidity/testing/utils/src/version_pragmas/mod.rs index 1e5b05941a..c986b0e321 100644 --- a/crates/solidity/testing/utils/src/version_pragmas/mod.rs +++ b/crates/solidity/testing/utils/src/version_pragmas/mod.rs @@ -20,7 +20,7 @@ pub fn extract_version_pragmas( let language = &Language::new(latest_version.to_owned())?; let output = language.parse(ProductionKind::SourceUnit, source); - let mut cursor = output.parse_tree().cursor(); + let mut cursor = output.create_tree_cursor(); let mut pragmas = vec![]; while let Some(rule_node) = cursor.find_rule_with_kind(&[RuleKind::VersionPragmaExpression]) { pragmas.push(