From 79fc49f554379497acc4b2d3f60d2f7d4443a2ee Mon Sep 17 00:00:00 2001 From: plotchy Date: Tue, 25 Jun 2024 22:51:28 -0400 Subject: [PATCH] fix: merge conflict resolutions --- Cargo.lock | 10 +- crates/cli/src/main.rs | 55 ++++---- crates/graph/src/graph_elements.rs | 48 +++++-- crates/pyrometer/src/analyzer_backend.rs | 3 +- crates/pyrometer/src/graph_backend.rs | 158 +++++------------------ crates/shared/src/graph_like.rs | 30 ++--- 6 files changed, 119 insertions(+), 185 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07f1ae80..431407f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44055e597c674aef7cb903b2b9f6e4cba1277ed0d2d61dae7cd52d7ffa81f8e2" dependencies = [ "unicode-width", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -1770,7 +1770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ "diff", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -3195,6 +3195,12 @@ dependencies = [ "tap", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "yansi" version = "1.0.1" diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 0df1f60f..e6571151 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -6,7 +6,7 @@ use graph::{ }; use pyrometer::{Analyzer, Root, SourcePath}; use reqwest::Client; -use shared::Search; +use shared::{post_to_site, Search}; use shared::{GraphDot, USE_DEBUG_SITE}; use ariadne::sources; @@ -235,27 +235,7 @@ fn main() { }, }; - if args.debug_site { - unsafe { - USE_DEBUG_SITE = true; - } - - let rt = Runtime::new().unwrap(); - rt.block_on(async { - let client = Client::new(); - let res = client - .post("http://127.0.0.1:8545/clear") - .send() - .await - .expect("Failed to send request"); - if res.status().is_success() { - trace!("Successfully cleared history of site"); - } else { - error!("Failed to clear history of site: {:?}", res.status()); - } - }); - } let mut analyzer = Analyzer { max_depth: args.max_stack_depth, @@ -288,6 +268,30 @@ fn main() { let mut arena_base = Default::default(); let arena = &mut arena_base; + + if args.debug_site { + unsafe { + USE_DEBUG_SITE = true; + } + + let rt = Runtime::new().unwrap(); + rt.block_on(async { + let client = Client::new(); + let res = client + .post("http://127.0.0.1:8545/clear") + .send() + .await + .expect("Failed to send request"); + + if res.status().is_success() { + trace!("Successfully cleared history of site"); + } else { + error!("Failed to clear history of site: {:?}", res.status()); + } + }); + post_to_site(&analyzer, arena); + } + let t0 = std::time::Instant::now(); let maybe_entry = analyzer.parse(arena, &sol, ¤t_path, true); let t_end = t0.elapsed(); @@ -297,13 +301,13 @@ fn main() { // println!("Arena: {:#?}", analyzer.range_arena); if unsafe { USE_DEBUG_SITE } { - use shared::GraphLike; use pyrometer::graph_backend::mermaid_str; use pyrometer::graph_backend::post_to_site_arena; use pyrometer::graph_backend::Elems; - match Elems::try_from(analyzer.range_arena()) { + let elems = Elems::try_from(&*arena); + match elems { Ok(elems) => { - let elems_graph = elems.to_graph(&analyzer); + let elems_graph = elems.to_graph(&analyzer, arena); let elems_graph_mermaid_str = mermaid_str(&elems_graph); post_to_site_arena(elems_graph_mermaid_str); } @@ -311,6 +315,9 @@ fn main() { eprintln!("Can't post arena, error creating Elems: {:?}", e); } }; + + // post the graph to the site + post_to_site(&analyzer, arena); } if args.stats { diff --git a/crates/graph/src/graph_elements.rs b/crates/graph/src/graph_elements.rs index 92087dae..494c7622 100644 --- a/crates/graph/src/graph_elements.rs +++ b/crates/graph/src/graph_elements.rs @@ -402,9 +402,7 @@ pub enum ContextEdge { } #[derive(Default)] -pub(crate) struct DummyGraph { - pub range_arena: RangeArena>, -} +pub(crate) struct DummyGraph {} impl GraphLike for DummyGraph { type Node = Node; @@ -417,12 +415,44 @@ impl GraphLike for DummyGraph { fn graph(&self) -> &Graph { panic!("Dummy Graph") } - fn range_arena(&self) -> &RangeArena> { - &self.range_arena - } - fn range_arena_mut(&mut self) -> &mut RangeArena> { - &mut self.range_arena - } } impl GraphBackend for DummyGraph {} +impl GraphDot for DummyGraph { + type T = Elem; + + fn dot_str(&self, _arena: &mut RangeArena<::T>) -> String { + // Provide a basic implementation or a placeholder + "digraph DummyGraph {}".to_string() + } + + fn cluster_str( + &self, + _arena: &mut RangeArena, + _node: NodeIdx, + _cluster_num: &mut usize, + _is_killed: bool, + _handled_nodes: std::sync::Arc>>, + _handled_edges: std::sync::Arc>>>, + _depth: usize, + _as_mermaid: bool, + ) -> Option + where + Self: std::marker::Sized { + todo!() + } + + fn dot_str_no_tmps(&self, _arena: &mut RangeArena) -> String + where + Self: std::marker::Sized, + { + todo!() + } + + fn mermaid_str(&self, _arena: &mut RangeArena) -> String + where + Self: std::marker::Sized, + { + todo!() + } +} \ No newline at end of file diff --git a/crates/pyrometer/src/analyzer_backend.rs b/crates/pyrometer/src/analyzer_backend.rs index 1c3fbe2c..d9171ebb 100644 --- a/crates/pyrometer/src/analyzer_backend.rs +++ b/crates/pyrometer/src/analyzer_backend.rs @@ -1,5 +1,4 @@ use crate::Analyzer; -use shared::GraphDot; use graph::{ elem::Elem, nodes::{ @@ -18,7 +17,7 @@ use solang_parser::{ pt::{Expression, Loc}, }; -use std::{collections::BTreeMap, path::PathBuf}; +use std::collections::BTreeMap; impl AnalyzerBackend for Analyzer { fn add_concrete_var( diff --git a/crates/pyrometer/src/graph_backend.rs b/crates/pyrometer/src/graph_backend.rs index d240c8b1..2c6d387e 100644 --- a/crates/pyrometer/src/graph_backend.rs +++ b/crates/pyrometer/src/graph_backend.rs @@ -5,13 +5,11 @@ use graph::elem::RangeElem; use graph::nodes::Concrete; use reqwest::Client; use serde::{Deserialize, Serialize}; -use shared::{post_to_site, RangeArena, USE_DEBUG_SITE}; +use shared::RangeArena; use tokio::runtime::Runtime; -use std::cell::RefCell; use std::collections::hash_map::DefaultHasher; use std::hash::Hash; use std::hash::Hasher; -use std::rc::Rc; use tracing::{trace, error, warn}; use graph::{ as_dot_str, nodes::ContextNode, AnalyzerBackend, AsDotStr, ContextEdge, Edge, GraphBackend, @@ -38,85 +36,12 @@ impl GraphLike for Analyzer { &self.graph } - fn range_arena(&self) -> &RangeArena> { - &self.range_arena - } - - fn range_arena_mut(&mut self) -> &mut RangeArena> { - &mut self.range_arena - } - - fn range_arena_idx(&self, elem: &Self::RangeElem) -> Option { - if let Elem::Arena(idx) = elem { - Some(*idx) - } else { - self.range_arena().map.get(elem).copied() - } - } - - fn range_arena_idx_or_upsert(&mut self, elem: Self::RangeElem) -> usize { - // tracing::trace!("arenaizing: {}", elem); - if let Elem::Arena(idx) = elem { - return idx; - } - - let res_idx = if let Some(idx) = self.range_arena_idx(&elem) { - let existing = &self.range_arena().ranges[idx]; - let Ok(existing) = existing.try_borrow_mut() else { - return idx; - }; - let (min_cached, max_cached) = existing.is_min_max_cached(self); - let mut existing_count = 0; - if min_cached { - existing_count += 1; - } - if max_cached { - existing_count += 1; - } - if existing.is_flatten_cached(self) { - existing_count += 1; - } - - let (min_cached, max_cached) = elem.is_min_max_cached(self); - let mut new_count = 0; - if min_cached { - new_count += 1; - } - if max_cached { - new_count += 1; - } - if elem.is_flatten_cached(self) { - new_count += 1; - } - - drop(existing); - - if new_count >= existing_count { - self.range_arena_mut().ranges[idx] = Rc::new(RefCell::new(elem)); - } - - idx - } else { - let idx = self.range_arena().ranges.len(); - self.range_arena_mut() - .ranges - .push(Rc::new(RefCell::new(elem.clone()))); - self.range_arena_mut().map.insert(elem, idx); - idx - }; - - res_idx - } - fn add_node(&mut self, node: impl Into) -> NodeIdx where Self: std::marker::Sized, Self: GraphLike, { let res = self.graph_mut().add_node(node.into()); - if unsafe { USE_DEBUG_SITE } { - post_to_site(self); - } res } @@ -131,10 +56,6 @@ impl GraphLike for Analyzer { { self.graph_mut() .add_edge(from_node.into(), to_node.into(), edge.into()); - - if unsafe { USE_DEBUG_SITE } { - post_to_site(self); - } } } @@ -260,25 +181,14 @@ impl TryFrom<&RangeArena>> for Elems { // Collect the elements and their indices first from ranges // Collect the elements and their indices first from ranges let mut inner = Vec::new(); - for rc in &arena.ranges { - // Attempt to borrow the RefCell - match rc.try_borrow() { - Ok(borrowed) => { - let elem = borrowed.clone(); - // Get the map value - if let Some(map_value) = arena.map.get(&elem).copied() { - // println!("Adding idx {} to elems {}", map_value, elem); - inner.push((map_value, elem)); - } else { - // println!("NONE REF elem: {:?}", elem); - return Err(ElemsError::MissingMap(format!("elem {:?}", elem))); - } - }, - Err(e) => { - // Print an error message if borrowing fails - // eprintln!("Failed to borrow RefCell: {:?}", e); - return Err(ElemsError::BorrowError(format!("error {:?}", e))); - } + for elem in &arena.ranges { + // Get the map value + if let Some(map_value) = arena.map.get(&elem).copied() { + // println!("Adding idx {} to elems {}", map_value, elem); + inner.push((map_value, elem.clone())); + } else { + // println!("NONE REF elem: {:?}", elem); + return Err(ElemsError::MissingMap(format!("elem {:?}", elem))); } } @@ -304,9 +214,7 @@ impl TryFrom<&RangeArena>> for Elems { // Add any missing entries to inner for (_elem, &idx) in missing_entries { if let Some(range_elem) = arena.ranges.get(idx) { - if let Ok(borrowed_elem) = range_elem.try_borrow() { - inner.push((idx, borrowed_elem.clone())); - } + inner.push((idx, range_elem.clone())); } } @@ -339,7 +247,7 @@ impl Elems { /// Third pass: /// - for each ContextVar node, create edges to the arena indices that it depends on /// - pub fn to_graph(&self, graph_backend: &impl GraphBackend) -> Graph { + pub fn to_graph(&self, graph_backend: &impl GraphBackend, arena: &mut RangeArena>) -> Graph { let mut graph = Graph::default(); let mut arena_idx_to_node_idx = HashMap::new(); let mut dependency_map: HashMap> = HashMap::new(); @@ -363,14 +271,14 @@ impl Elems { let node_idx = graph.add_node(ArenaNode::ELEM(node_str)); // attempt to add in the ContextVar node that the elem is referencing - let context_var_nodes = elem.dependent_on(graph_backend).into_iter().collect::>(); + let context_var_nodes = elem.dependent_on(graph_backend, arena).into_iter().collect::>(); context_var_nodes.into_iter().for_each(|dep_elem| { let dep_node_idx = if let Some(&existing_node_idx) = dependency_map.get(&dep_elem) { // don't make a new ContextVar node, just use the existing one existing_node_idx } else { // make a new ContextVar Node for the Arena graph - let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend)))); + let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend, arena)))); dependency_map.insert(dep_elem.clone(), new_node_idx); new_node_idx }; @@ -400,14 +308,14 @@ impl Elems { Elem::Reference(_lhs) => { // println!("LHS is a reference: {}", range_expr.lhs); // attempt to add in the ContextVar node that the elem is referencing - let context_var_nodes = elem.dependent_on(graph_backend).into_iter().collect::>(); + let context_var_nodes = elem.dependent_on(graph_backend, arena).into_iter().collect::>(); context_var_nodes.iter().for_each(|dep_elem| { let dep_node_idx = if let Some(&existing_node_idx) = dependency_map.get(&dep_elem) { // don't make a new ContextVar node, just use the existing one existing_node_idx } else { // make a new ContextVar Node for the Arena graph - let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend)))); + let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend, arena)))); dependency_map.insert(dep_elem.clone(), new_node_idx); new_node_idx }; @@ -426,14 +334,14 @@ impl Elems { Elem::Reference(_rhs) => { // println!("RHS is a reference: {}", range_expr.rhs); // attempt to add in the ContextVar node that the elem is referencing - let context_var_nodes = elem.dependent_on(graph_backend).into_iter().collect::>(); + let context_var_nodes = elem.dependent_on(graph_backend, arena).into_iter().collect::>(); context_var_nodes.iter().for_each(|dep_elem| { let dep_node_idx = if let Some(&existing_node_idx) = dependency_map.get(&dep_elem) { // don't make a new ContextVar node, just use the existing one existing_node_idx } else { // make a new ContextVar Node for the Arena graph - let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend)))); + let new_node_idx = graph.add_node(ArenaNode::CVAR(format!("{}", dep_elem.as_dot_str(graph_backend, arena)))); dependency_map.insert(dep_elem.clone(), new_node_idx); new_node_idx }; @@ -882,7 +790,6 @@ impl GraphDot for Analyzer { )) } else { { - if handled_nodes.lock().unwrap().contains(child) { if handled_nodes.lock().unwrap().contains(child) { return None; } else { @@ -914,7 +821,6 @@ impl GraphDot for Analyzer { format!("{indent}{from:} -->|\"{edge_str}\"| {to:}\n{indent}class {to} linkSource{edge_idx}\n{indent}class {from} linkTarget{edge_idx}") } else { format!("{indent}{from:} -> {to:} [label = \"{edge_str}\"]",) - format!("{indent}{from:} -> {to:} [label = \"{edge_str}\"]",) } }) .collect::>() @@ -1262,45 +1168,42 @@ impl GraphLike for G<'_> { fn graph(&self) -> &Graph { self.graph } - fn range_arena(&self) -> &RangeArena> { - panic!("Should not call this") - } - fn range_arena_mut(&mut self) -> &mut RangeArena> { - panic!("Should not call this") - } } impl GraphDot for G<'_> { + type T = Elem; + fn cluster_str( &self, - node: NodeIdx, - cluster_num: &mut usize, - is_killed: bool, - handled_nodes: Arc>>, - handled_edges: Arc>>>, - depth: usize, - as_mermaid: bool, + _arena: &mut RangeArena, + _node: NodeIdx, + _cluster_num: &mut usize, + _is_killed: bool, + _handled_nodes: Arc>>, + _handled_edges: Arc>>>, + _depth: usize, + _as_mermaid: bool, ) -> Option where Self: std::marker::Sized { todo!() } - fn dot_str(&self) -> String + fn dot_str(&self, _arena: &mut RangeArena) -> String where Self: std::marker::Sized, Self: shared::AnalyzerLike { todo!() } - fn dot_str_no_tmps(&self) -> String + fn dot_str_no_tmps(&self, _arena: &mut RangeArena) -> String where Self: std::marker::Sized, Self: GraphLike + shared::AnalyzerLike { todo!() } - fn mermaid_str(&self) -> String + fn mermaid_str(&self, _arena: &mut RangeArena) -> String where Self: std::marker::Sized, Self: shared::AnalyzerLike { @@ -1317,7 +1220,6 @@ pub fn mermaid_node( node: NodeIdx, style: bool, loc: bool, - loc: bool, class: Option<&str>, ) -> String { let mut node_str = format!( diff --git a/crates/shared/src/graph_like.rs b/crates/shared/src/graph_like.rs index 89626b58..2330042e 100644 --- a/crates/shared/src/graph_like.rs +++ b/crates/shared/src/graph_like.rs @@ -66,22 +66,6 @@ pub trait GraphLike { self.graph_mut() .add_edge(from_node.into(), to_node.into(), edge.into()); } - - fn range_arena(&self) -> &RangeArena; - fn range_arena_mut(&mut self) -> &mut RangeArena; - fn try_take_range_arena(&mut self) -> Option> { - let arena = self.range_arena_mut(); - if !arena.ranges.is_empty() { - Some(std::mem::take(arena)) - } else { - None - } - } - - fn take_range_arena(&mut self) -> RangeArena { - let arena = self.range_arena_mut(); - std::mem::take(arena) - } } /// A trait that constructs dot-like visualization strings (either mermaid or graphviz) @@ -203,17 +187,23 @@ struct GraphMessage { } -pub fn post_to_site(graph: &(impl GraphDot + AnalyzerLike)) { +pub fn post_to_site(graph: &G, arena: &mut RangeArena) +where + G: GraphDot + AnalyzerLike, +{ let rt = Runtime::new().unwrap(); rt.block_on(async { - post_to_site_async(graph).await; + post_to_site_async(graph, arena).await; }); } -async fn post_to_site_async(graph: &(impl GraphDot + AnalyzerLike)) { +async fn post_to_site_async(graph: &G, arena: &mut RangeArena) +where + G: GraphDot + AnalyzerLike, +{ let client = Client::new(); let graph_msg = GraphMessage { - graph: graph.mermaid_str(), + graph: graph.mermaid_str(arena), timestamp: SystemTime::now() .duration_since(UNIX_EPOCH) .expect("Time went backwards")