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

Commit

Permalink
wip(solidity/references)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xSwapFeeder committed Feb 29, 2024
1 parent 69fd6c4 commit 0b3b947
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 226 deletions.
24 changes: 16 additions & 8 deletions libs/solc-references/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,58 @@ impl <'ast> Visit<'ast> for DefinitionFinder {
fn visit_contract_definition(&mut self, contract: &'ast ContractDefinition) {
if contract.id == self.id {
self.node = Some(InteractableNode::ContractDefinition(contract.clone()));
} else {
visit::visit_contract_definition(self, contract);
}
visit::visit_contract_definition(self, contract);
}
fn visit_function_definition(&mut self, function: &'ast FunctionDefinition) {
if function.id == self.id {
self.node = Some(InteractableNode::FunctionDefinition(function.clone()));
} else {
visit::visit_function_definition(self, function);
}
visit::visit_function_definition(self, function);
}
fn visit_modifier_definition(&mut self, modifier: &'ast ModifierDefinition) {
if modifier.id == self.id {
self.node = Some(InteractableNode::ModifierDefinition(modifier.clone()));
} else {
visit::visit_modifier_definition(self, modifier);
}
visit::visit_modifier_definition(self, modifier);
}
fn visit_struct_definition(&mut self, struct_def: &'ast StructDefinition) {
if struct_def.id == self.id {
self.node = Some(InteractableNode::StructDefinition(struct_def.clone()));
} else {
visit::visit_struct_definition(self, struct_def);
}
visit::visit_struct_definition(self, struct_def);
}
fn visit_enum_definition(&mut self, enum_def: &'ast EnumDefinition) {
if enum_def.id == self.id {
self.node = Some(InteractableNode::EnumDefinition(enum_def.clone()));
} else {
visit::visit_enum_definition(self, enum_def);
}
visit::visit_enum_definition(self, enum_def);
}
fn visit_variable_declaration(&mut self, variable: &'ast VariableDeclaration) {
if variable.id == self.id {
self.node = Some(InteractableNode::VariableDeclaration(variable.clone()));
} else {
visit::visit_variable_declaration(self, variable);
}
visit::visit_variable_declaration(self, variable);
}
fn visit_event_definition(&mut self, event: &'ast EventDefinition) {
if event.id == self.id {
self.node = Some(InteractableNode::EventDefinition(event.clone()));
} else {
visit::visit_event_definition(self, event);
}
visit::visit_event_definition(self, event);
}
fn visit_enum_value(&mut self, enum_value: &'ast EnumValue) {
if enum_value.id == self.id {
self.node = Some(InteractableNode::EnumValue(enum_value.clone()));
} else {
visit::visit_enum_value(self, enum_value);
}
visit::visit_enum_value(self, enum_value);
}
}

Expand Down
3 changes: 2 additions & 1 deletion libs/solc-references/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ use solc_wrapper::SolcWrapperError;
pub enum ReferencesError {
#[error("Solc error: {0}")]
Solc(#[from] SolcWrapperError)
}
}

98 changes: 33 additions & 65 deletions libs/solc-references/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[macro_use]
mod types;
mod error;
mod definitions;
Expand All @@ -12,12 +11,12 @@ use solc_wrapper::{get_ast_for_file, SolcAstFile};
pub use solc_wrapper::SolcFile;
pub use solc_ast_rs_types::types::*;
pub use types::{Location, Position};
use types::{get_id, get_range, get_reference_id, InteractableNode};
use types::InteractableNode;
use usages::UsagesFinder;
use definitions::DefinitionFinder;
use utils::{index_to_position, join_path};
use utils::join_path;

use crate::utils::is_node_a_type;
use crate::utils::get_location;

#[derive(Debug)]
pub struct ReferencesProvider {
Expand All @@ -29,111 +28,80 @@ impl ReferencesProvider {
pub fn set_base_path(&mut self, base_path: String) {
self.base_path = base_path;
}

pub fn update_file_content(&mut self) -> Result<(), ReferencesError> {
self.files = get_ast_for_file(self.base_path.clone())?;
Ok(())
}

pub fn get_definition(&self, uri: &str, position: Position) -> Option<Location> {
fn get_node(&self, uri: &str, position: Position) -> Option<(SolcAstFile, InteractableNode)> {
let found_node: Option<InteractableNode>;
let mut node_finder = NodeVisitor::new(position.clone(), String::from(""));
let source_file;
if let Some(file) = self.files.iter().find(|file| file.file.path == uri) {
let mut node_finder = NodeVisitor::new(position.clone(), &file.file.content);
source_file = file;
found_node = node_finder.find(&file.ast, &file.file.content);
found_node = node_finder.find(&file.ast);
}
else {
eprintln!("No file found at uri: {}", uri);
return None;
}
if found_node.is_none() {
eprintln!("No node found at position: {:?}", &position);
eprintln!("[NODE FINDER] No node found at position: {:?}", &position);
return None;
}
let found_node = found_node.unwrap();
Some((source_file.clone(), found_node.unwrap()))
}

pub fn get_definition(&self, uri: &str, position: Position) -> Option<Location> {
let (source_file, found_node) = match self.get_node(uri, position) {
Some((file, node)) => (file, node),
None => return None
};

let ref_id = match get_reference_id(&found_node.clone())
{
let ref_id = match found_node.get_reference_id() {
Some(id) => id,
None => {
match found_node {
InteractableNode::ImportDirective(import) => {
let uri = join_path(&self.base_path, &import.absolute_path);
return Some(Location {
start: Position {
line: 1,
column: 1
},
end: Position {
line: 1,
column: 1
},
uri: uri
start: Position::default(),
end: Position::default(),
uri: join_path(&self.base_path, &import.absolute_path)
});
},
_ => {}
_ => {
return Some(get_location(&found_node, &source_file));
}
}
let range = get_range(&found_node);
return Some(Location {
start: index_to_position(range.index, &source_file.file.content),
end: index_to_position(range.index + range.length, &source_file.file.content),
uri: uri.to_string()
});
}
};
let mut def_finder = DefinitionFinder::new(ref_id);
for file in &self.files {
if let Some(node) = def_finder.find(&file.ast) {
let range = get_range(&node);
let start = index_to_position(range.index, &file.file.content);
let end = index_to_position(range.index + range.length, &file.file.content);
return Some(Location {
start,
end,
uri: file.file.path.clone()
});
return Some(get_location(&node, file));
}
}
None
}

pub fn get_references(&self, uri: &str, position: Position) -> Vec<Location> {
let mut references: Vec<Location> = Vec::new();
let mut found_node: Option<InteractableNode> = None;
let mut node_finder = NodeVisitor::new(position.clone(), String::from(""));
if let Some(file) = self.files.iter().find(|file| file.file.path == uri) {
found_node = node_finder.find(&file.ast, &file.file.content);
eprintln!("Found node: {:?}", found_node);
}
else {
eprintln!("No file found at uri: {}", uri);
return references;
}
if found_node.is_none() {
eprintln!("No node found at position: {:?}", &position);
return references;
}
let found_node = found_node.unwrap();
let ref_id = get_id(&found_node.clone());
eprintln!("Id: {:?}", ref_id);
let (_, found_node) = match self.get_node(uri, position) {
Some((file, node)) => (file, node),
None => return vec![]
};

let mut usages_finder = UsagesFinder::new(ref_id, is_node_a_type(&found_node));
let id = found_node.get_id();
eprintln!("Id: {:?}", id);

let mut usages_finder = UsagesFinder::new(id);
for file in &self.files {
let nodes = usages_finder.find(&file.ast);
for node in nodes {
let range = get_range(&node);
let start = index_to_position(range.index, &file.file.content);
let end = index_to_position(range.index + range.length, &file.file.content);
let location = Location {
start,
end,
uri: file.file.path.clone()
};
references.push(location);
references.push(get_location(&node, &file));
}
}

references
}
}
12 changes: 4 additions & 8 deletions libs/solc-references/src/node_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::utils::*;
pub struct NodeVisitor {
position: Position,
pub node: Option<InteractableNode>,
pub token: String,
above_node: Option<InteractableNode>,
source: String
}
Expand Down Expand Up @@ -166,20 +165,17 @@ impl <'ast> Visit<'ast> for NodeVisitor {


impl NodeVisitor {
pub fn new(position: Position, token: String) -> Self {
pub fn new(position: Position, source: &String) -> Self {
NodeVisitor {
position,
node: None,
token,
above_node: None,
source: String::from("")
source: source.clone()
}
}
pub fn find(&mut self, src: &SourceUnit, source: &String) -> Option<InteractableNode> {
self.source = source.clone();
self.node = None;
pub fn find(&mut self, src: &SourceUnit) -> Option<InteractableNode> {
self.visit_source_unit(src);
eprintln!("Found node: {:?}", self.node);
//eprintln!("[NODE FINDER] Found node: {:?}", self.node);
self.node.clone()
}
}
Loading

0 comments on commit 0b3b947

Please sign in to comment.