Skip to content
This repository was archived by the owner on Jul 3, 2024. It is now read-only.

Commit 029575a

Browse files
committed
feat(libs/ast-references): add function to retrieve FileReference from ast
1 parent 0f61198 commit 029575a

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* file_retriever.rs
3+
* Function to retrieve a file reference from AST
4+
* author: ByFish
5+
*/
6+
use crate::types::contract_reference::ContractReference;
7+
use crate::types::file_reference::FileReference;
8+
use crate::types::location::{Bound, Location};
9+
use crate::types::struct_reference::StructReference;
10+
use proc_macro2::TokenStream;
11+
use std::cell::RefCell;
12+
use std::fs;
13+
use std::rc::Rc;
14+
use std::str::FromStr;
15+
use syn_solidity::{ItemContract, ItemStruct, Visit};
16+
17+
struct FileVisitor {
18+
file_reference: Rc<RefCell<FileReference>>,
19+
current_contract: Option<Rc<RefCell<ContractReference>>>,
20+
}
21+
22+
impl FileVisitor {
23+
pub fn new(path: String) -> Self {
24+
Self {
25+
file_reference: Rc::new(RefCell::new(FileReference::new(path.to_string()))),
26+
current_contract: None,
27+
}
28+
}
29+
}
30+
31+
impl<'ast> Visit<'ast> for FileVisitor {
32+
fn visit_item_contract(&mut self, i: &ItemContract) {
33+
let contract_reference = ContractReference::new(
34+
i.name.to_string(),
35+
Location::new(
36+
self.file_reference.borrow_mut().path.clone(),
37+
Bound::new(
38+
i.brace_token.span.join().start().line as u32,
39+
i.brace_token.span.join().start().column as u32,
40+
),
41+
Bound::new(
42+
i.brace_token.span.join().end().line as u32,
43+
i.brace_token.span.join().end().column as u32,
44+
),
45+
),
46+
&self.file_reference,
47+
);
48+
self.file_reference
49+
.borrow_mut()
50+
.add_contract(contract_reference);
51+
self.current_contract = Some(
52+
self.file_reference
53+
.borrow()
54+
.contracts
55+
.last()
56+
.unwrap()
57+
.clone(),
58+
);
59+
syn_solidity::visit::visit_item_contract(self, i);
60+
self.current_contract = None;
61+
}
62+
fn visit_item_struct(&mut self, i: &'ast ItemStruct) {
63+
let struct_reference = StructReference::new(
64+
i.name.to_string(),
65+
Location::new(
66+
self.file_reference.borrow_mut().path.clone(),
67+
Bound::new(
68+
i.brace_token.span.join().start().line as u32,
69+
i.brace_token.span.join().start().column as u32,
70+
),
71+
Bound::new(
72+
i.brace_token.span.join().end().line as u32,
73+
i.brace_token.span.join().end().column as u32,
74+
),
75+
),
76+
None,
77+
Some(&self.file_reference),
78+
);
79+
if self.current_contract.is_some() {
80+
self.current_contract
81+
.as_ref()
82+
.unwrap()
83+
.borrow_mut()
84+
.add_struct(&Rc::new(RefCell::new(struct_reference)));
85+
} else {
86+
self.file_reference
87+
.borrow_mut()
88+
.add_struct(struct_reference);
89+
}
90+
syn_solidity::visit::visit_item_struct(self, i)
91+
}
92+
}
93+
94+
pub fn retrieve_file_reference_from_path(path: String) -> Rc<RefCell<FileReference>> {
95+
let source = fs::read_to_string(path.to_string()).unwrap();
96+
let tokens = TokenStream::from_str(source.as_str()).unwrap();
97+
let ast = syn_solidity::parse2(tokens).unwrap();
98+
let mut visitor = FileVisitor::new(path.to_string());
99+
visitor.visit_file(&ast);
100+
visitor.file_reference
101+
}

libs/ast-references/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
pub mod file_retriever;
12
pub mod types;

0 commit comments

Comments
 (0)