Skip to content
This repository has been archived by the owner on Jul 3, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/ast-extractor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod errors;
pub mod extract;
pub mod retriever;


// Expose syn_solidity crate
pub use syn_solidity::*;

Expand Down
3 changes: 2 additions & 1 deletion libs/ast-extractor/src/retriever.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ mod udt;
pub use udt::*;

mod using;
mod finder;
pub mod finder;
pub use finder::*;

pub use using::*;

Expand Down
69 changes: 48 additions & 21 deletions libs/ast-extractor/src/retriever/finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}
}

fn visit_stmt_var_decl(&mut self, stmt_var_decl: &'ast StmtVarDecl) {
if is_in_range!(stmt_var_decl.span().start(), stmt_var_decl.span().end(), self.to_find) {
println!("stmt: {:?}", stmt_var_decl);
visit::visit_stmt_var_decl(self, stmt_var_decl);
}
}


fn visit_expr(&mut self, expr: &'ast Expr) {
if is_in_range!(expr.span().start(), expr.span().end(), self.to_find) {
println!("expr: {:?}", expr);
Expand All @@ -106,7 +114,6 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}
}


fn visit_expr_call(&mut self, call: &'ast ExprCall) {
if is_in_range!(call.span().start(), call.span().end(), self.to_find) {
if !is_in_range!(call.args.span().start(), call.args.span().end(), self.to_find) {
Expand All @@ -124,9 +131,18 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}
}

fn visit_ident(&mut self, ident: &'ast SolIdent) {
if self.found.is_some() {
return;
}
if is_in_range!(ident.span().start(), ident.span().end(), self.to_find) {
self.found = Some(FoundNode::IdentUsageName(self.current_contract.clone(), self.current_function.clone(), self.current_expr.clone(), ident.clone()));
}
}

fn visit_type(&mut self, ty: &'ast Type) {
println!("type: {:?}", ty);
if is_in_range!(ty.span().start(), ty.span().end(), self.to_find) {
println!("type: {:?}", ty);
self.found = Some(FoundNode::TypeUsage(self.current_contract.clone(), self.current_function.clone(), self.current_expr.clone(), ty.clone()));
visit::visit_type(self, ty);
}
Expand All @@ -146,12 +162,6 @@ impl<'ast> Visit<'ast> for FinderVisitor {

}

fn visit_stmt_var_decl(&mut self, stmt_var_decl: &'ast StmtVarDecl) {
if is_in_range!(stmt_var_decl.span().start(), stmt_var_decl.span().end(), self.to_find) {
visit::visit_stmt_var_decl(self, stmt_var_decl);
}
}

fn visit_variable_definition(&mut self, var: &'ast VariableDefinition) {
if is_in_range!(var.span().start(), var.span().end(), self.to_find) {
self.current_property = Some(var.clone());
Expand All @@ -168,6 +178,7 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}

fn visit_item_contract(&mut self, contract: &'ast ItemContract) {
println!("contract: {:?}", contract);
let _contract_start = contract.brace_token.span().start();
let _contract_end = contract.brace_token.span().end();
self.current_contract = Some(contract.clone());
Expand Down Expand Up @@ -231,6 +242,7 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}

fn visit_item_function(&mut self, function: &'ast ItemFunction) {
println!("function: {:?}", function);
self.current_function = Some(function.clone());
if is_in_range!(function.name.span().start(), function.name.span().end(), self.to_find) {
self.found = Some(FoundNode::FunctionDefName(self.current_contract.clone().unwrap(), function.clone()));
Expand All @@ -245,24 +257,18 @@ impl<'ast> Visit<'ast> for FinderVisitor {
}
}
}
if let Some(ret) = function.return_type() {
visit::visit_type(self, &ret);
}
if let FunctionBody::Block(block) = &function.body {
let _block_start = block.span().start();
let _block_end = block.span().end();
if is_in_range!(block.span().start(), block.span().end(), self.to_find) {
visit::visit_item_function(self, function);
}
}
if let Some(ret) = function.return_type() {
visit::visit_type(self, &ret);
}
self.current_function = None;
}

fn visit_ident(&mut self, ident: &'ast SolIdent) {
if self.found.is_some() {
return;
}
if is_in_range!(ident.span().start(), ident.span().end(), self.to_find) {
self.found = Some(FoundNode::IdentUsageName(self.current_contract.clone(), self.current_function.clone(), self.current_expr.clone(), ident.clone()));
}
self.current_function = None;
}

fn visit_item_struct(&mut self, strukt: &'ast ItemStruct) {
Expand Down Expand Up @@ -900,7 +906,7 @@ mod tests {

let tokens = TokenStream::from_str(source.as_str()).unwrap();
let ast = parse2(tokens).unwrap();
let res = retrieve_node_from_position(&ast, Position::new(5, 14));
let res = retrieve_node_from_position(&ast, Position::new(16, 36));

if let Some(FoundNode::IdentUsageName(_contract, _func, _expr, ident)) = res {
assert_eq!(ident.to_string(), "storedData");
Expand Down Expand Up @@ -949,4 +955,25 @@ mod tests {
}
}

#[test]
fn test_retrieve_const_usage() {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests");
path.push("files");
path.push("contracts");
path.push("two.sol");
let source = fs::read_to_string(path).unwrap();

let tokens = TokenStream::from_str(source.as_str()).unwrap();
let ast = parse2(tokens).unwrap();
let res = retrieve_node_from_position(&ast, Position::new(16, 29));
println!("{:?}", res);

if let Some(FoundNode::IdentUsageName(_contract, _func, _expr, ident)) = res {
assert_eq!(ident.to_string(), "x");
} else {
panic!()
}
}

}
3 changes: 2 additions & 1 deletion libs/ast-extractor/tests/files/contracts/two.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ abstract contract One {
function get() public view returns (uint) {
return storedData;
}
uint8 constant myConst = 1;
}

abstract contract Two {
uint storedData;
function set(uint x) public {
uint storedData = One.myConst;
storedData = x;
}

Expand Down
8 changes: 8 additions & 0 deletions libs/ast-references/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions libs/ast-references/.idea/ast-references.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions libs/ast-references/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions libs/ast-references/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/ast-references/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion libs/ast-references/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ edition = "2021"

[dependencies]
proc-macro2 = { version = "1.0.66", features = ["span-locations"]}
ast-extractor = { path = "../ast-extractor"}
ast-extractor = { path = "../ast-extractor"}
thiserror = "1.0.48"
55 changes: 55 additions & 0 deletions libs/ast-references/src/definition_finder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::fmt::Error;
use ast_extractor::retriever::{Position, retrieve_node_from_position};
use ast_extractor::retriever::finder::{FoundNode};
use ast_extractor::{ItemContract, ItemFunction, ItemStruct, Type, Visit, visit};
use thiserror::Error;

#[derive(Error, Debug)]
pub enum RetrieveDefinitionError {
Extract(#[from] ast_extractor::extract::ExtractError)
}

pub struct DefinitionFinder {
pos: Position,
definitions: Vec<FoundNode>
}

impl <'ast>Visit <'ast> for DefinitionFinder {
fn visit_item_contract(&mut self, contract: &'ast ItemContract) {
if is_in_range!(self.pos, contract) {
visit::visit_item_contract(self, contract);
}
}



fn visit_item_struct(&mut self, strukt: &'ast ItemStruct) {

}

}


fn retreive_definition_from_pos(file: &str, files: Vec<&str>, pos: Position) -> Result<FoundNode, Error> {
let fileAst = ast_extractor::extract::extract_ast_from_content(file)?;
let res = retrieve_node_from_position(&fileAst, pos);

if let Some(node) = res {
match &node {
FoundNode::TypeUsage(_, _, _, Type::Custom(t)) => {
Ok(node)
}
FoundNode::IdentUsageCall(_, _, _) => {

}
FoundNode::IdentUsageName(_, _, _, _) => {}
_ => {Ok(node)}
}
} else {
}
}




uint256 myNewVariable = MyContract.constVar;
Loading