1use anyhow::{Context, Result};
2use tree_sitter::{Language, Parser, Tree};
3
4pub fn get_solidity_language() -> Language {
6 tree_sitter_solidity::LANGUAGE.into()
7}
8
9#[derive(Debug)] pub struct SolidityAST {
12 pub tree: Tree,
13 pub source: String,
14}
15
16pub fn parse_solidity(source: &str) -> Result<SolidityAST> {
18 let mut parser = Parser::new();
19 parser
20 .set_language(&get_solidity_language())
21 .context("Failed to set language for Solidity parser")?;
22
23 let tree = parser
25 .parse(source, None)
26 .context("Failed to parse Solidity source")?;
27
28 Ok(SolidityAST {
29 tree,
30 source: source.to_string(),
31 })
32}
33
34pub fn get_node_text<'a>(node: &tree_sitter::Node, source: &'a str) -> &'a str {
35 let start = node.start_byte();
36 let end = node.end_byte();
37 &source[start..end]
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn test_parse_solidity() {
46 let source = r#"
47 pragma solidity ^0.8.0;
48
49 contract SimpleStorage {
50 uint256 private value;
51
52 function setValue(uint256 _value) public {
53 value = _value;
54 }
55
56 function getValue() public view returns (uint256) {
57 return value;
58 }
59 }
60 "#;
61
62 let ast = parse_solidity(source).unwrap();
63 let root_node = ast.tree.root_node();
64
65 assert_eq!(root_node.kind(), "source_file");
66 assert!(root_node.child_count() > 0);
67 }
68}