diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a96f04..2fa0aeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.2.1...Unreleased) - ReleaseDate +* [Changed] SyntaxTree::get_str can take &RefNode * [Added] unwrap_locate macro ## [v0.2.1](https://github.com/dalance/sv-parser/compare/v0.2.0...v0.2.1) - 2019-10-28 diff --git a/sv-parser/examples/module_list.rs b/sv-parser/examples/module_list.rs index e36d6a1..2d043ae 100644 --- a/sv-parser/examples/module_list.rs +++ b/sv-parser/examples/module_list.rs @@ -27,14 +27,14 @@ fn main() { let id = get_identifier(id).unwrap(); - // Original string can be got by SyntexTree::get_str(self, locate: &Locate) - let id = syntax_tree.get_str(&id); + // Original string can be got by SyntexTree::get_str(self, node: &RefNode) + let id = syntax_tree.get_str(&id).unwrap(); println!("module: {}", id); } RefNode::ModuleDeclarationAnsi(x) => { let id = unwrap_node!(x, ModuleIdentifier).unwrap(); let id = get_identifier(id).unwrap(); - let id = syntax_tree.get_str(&id); + let id = syntax_tree.get_str(&id).unwrap(); println!("module: {}", id); } _ => (), diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index 06babb7..8397d00 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -16,11 +16,25 @@ pub struct SyntaxTree { } impl SyntaxTree { - pub fn get_str(&self, locate: &Locate) -> &str { - unsafe { - self.text - .text() - .get_unchecked(locate.offset..locate.offset + locate.len) + pub fn get_str<'a, T: Into>>(&self, nodes: T) -> Option<&str> { + let mut beg = None; + let mut end = 0; + for n in Iter::new(nodes.into()) { + match n { + RefNode::Locate(x) => { + if beg.is_none() { + beg = Some(x.offset); + } + end = x.offset + x.len; + } + _ => (), + } + } + if let Some(beg) = beg { + let ret = unsafe { self.text.text().get_unchecked(beg..end) }; + Some(ret) + } else { + None } } @@ -37,7 +51,11 @@ impl fmt::Display for SyntaxTree { for node in self.into_iter().event() { match node { NodeEvent::Enter(RefNode::Locate(locate)) if !skip => { - ret.push_str(&format!("{}{}\n", " ".repeat(depth), self.get_str(locate))); + ret.push_str(&format!( + "{}{}\n", + " ".repeat(depth), + self.get_str(locate).unwrap() + )); depth += 1; } NodeEvent::Enter(RefNode::WhiteSpace(_)) => {