dotgraphviz.rs 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::sema::{
  3. ast::*,
  4. symtable::Symtable,
  5. yul::{
  6. ast::{YulBlock, YulExpression, YulStatement},
  7. builtin::YulBuiltInFunction,
  8. },
  9. };
  10. use solang_parser::{pt, pt::Loc};
  11. use std::fmt::Write;
  12. struct Node {
  13. name: String,
  14. labels: Vec<String>,
  15. }
  16. impl Node {
  17. fn new(name: &str, labels: Vec<String>) -> Self {
  18. Node {
  19. name: name.to_owned(),
  20. labels,
  21. }
  22. }
  23. }
  24. struct Edge {
  25. from: usize,
  26. to: usize,
  27. label: Option<String>,
  28. }
  29. struct Dot {
  30. filename: String,
  31. nodes: Vec<Node>,
  32. edges: Vec<Edge>,
  33. }
  34. impl Dot {
  35. fn write(&self) -> String {
  36. let mut result = format!("strict digraph \"{}\" {{\n", self.filename);
  37. for node in &self.nodes {
  38. if !node.labels.is_empty() {
  39. writeln!(
  40. result,
  41. "\t{} [label=\"{}\"]",
  42. node.name,
  43. node.labels.join("\\n")
  44. )
  45. .unwrap();
  46. }
  47. }
  48. for edge in &self.edges {
  49. if let Some(label) = &edge.label {
  50. writeln!(
  51. result,
  52. "\t{} -> {} [label=\"{}\"]",
  53. self.nodes[edge.from].name, self.nodes[edge.to].name, label
  54. )
  55. .unwrap();
  56. } else {
  57. writeln!(
  58. result,
  59. "\t{} -> {}",
  60. self.nodes[edge.from].name, self.nodes[edge.to].name
  61. )
  62. .unwrap();
  63. }
  64. }
  65. result.push_str("}\n");
  66. result
  67. }
  68. fn add_node(
  69. &mut self,
  70. mut node: Node,
  71. parent: Option<usize>,
  72. parent_rel: Option<String>,
  73. ) -> usize {
  74. let no = self.nodes.len();
  75. debug_assert!(
  76. !node.name.chars().any(|c| c.is_whitespace()),
  77. "{} contains whitespace",
  78. node.name
  79. );
  80. if node.name.is_empty() || node.name == "node" {
  81. node.name = format!("node_{}", no);
  82. } else {
  83. while self.nodes.iter().any(|n| n.name == node.name) {
  84. node.name = format!("{}_{}", node.name, no);
  85. }
  86. }
  87. self.nodes.push(node);
  88. if let Some(parent) = parent {
  89. self.edges.push(Edge {
  90. from: parent,
  91. to: no,
  92. label: parent_rel,
  93. })
  94. }
  95. no
  96. }
  97. fn add_tags(&mut self, tags: &[Tag], parent: usize) {
  98. if !tags.is_empty() {
  99. let labels = tags
  100. .iter()
  101. .map(|tag| format!("{}: {}", tag.tag, tag.value.replace('\n', " ")))
  102. .collect();
  103. self.add_node(
  104. Node::new("tags", labels),
  105. Some(parent),
  106. Some(String::from("tags")),
  107. );
  108. }
  109. }
  110. fn add_function(&mut self, func: &Function, ns: &Namespace, parent: usize) {
  111. let mut labels = vec![
  112. format!("{} {}", func.ty, func.name),
  113. ns.loc_to_string(&func.loc),
  114. ];
  115. if let Some(contract) = func.contract_no {
  116. labels.insert(1, format!("contract: {}", ns.contracts[contract].name));
  117. }
  118. if func.ty == pt::FunctionTy::Constructor || func.ty == pt::FunctionTy::Function {
  119. labels.push(format!("signature {}", func.signature));
  120. labels.push(format!("visibility {}", func.visibility));
  121. }
  122. labels.push(format!("mutability {}", func.mutability));
  123. if func.is_virtual {
  124. labels.push(String::from("virtual"));
  125. }
  126. if let Some((_, is_overrides)) = &func.is_override {
  127. if is_overrides.is_empty() {
  128. labels.push(String::from("override"));
  129. } else {
  130. for is_override in is_overrides {
  131. labels.push(format!("override {}", ns.contracts[*is_override].name));
  132. }
  133. }
  134. }
  135. let func_node = self.add_node(
  136. Node::new(&func.name, labels),
  137. Some(parent),
  138. Some(format!("{}", func.ty)),
  139. );
  140. self.add_tags(&func.tags, func_node);
  141. // parameters
  142. if !func.params.is_empty() {
  143. let mut labels = vec![String::from("parameters")];
  144. for param in &*func.params {
  145. labels.push(format!(
  146. "{} {}",
  147. param.ty.to_string(ns),
  148. param.name_as_str()
  149. ));
  150. }
  151. self.add_node(
  152. Node::new("parameters", labels),
  153. Some(func_node),
  154. Some(String::from("parameters")),
  155. );
  156. }
  157. // returns
  158. if !func.returns.is_empty() {
  159. let mut labels = vec![String::from("returns")];
  160. for param in &*func.returns {
  161. labels.push(format!(
  162. "{} {}",
  163. param.ty.to_string(ns),
  164. param.name_as_str()
  165. ));
  166. }
  167. self.add_node(
  168. Node::new("returns", labels),
  169. Some(func_node),
  170. Some(String::from("returns")),
  171. );
  172. }
  173. // bases
  174. for (base_no, (_, _, args)) in &func.bases {
  175. let node = self.add_node(
  176. Node::new(
  177. &ns.contracts[*base_no].name,
  178. vec![ns.contracts[*base_no].name.to_string()],
  179. ),
  180. Some(func_node),
  181. Some(String::from("base")),
  182. );
  183. for (no, arg) in args.iter().enumerate() {
  184. self.add_expression(arg, Some(func), ns, node, format!("arg #{}", no));
  185. }
  186. }
  187. // body
  188. self.add_statement(&func.body, func, ns, func_node, String::from("body"));
  189. }
  190. fn add_expression(
  191. &mut self,
  192. expr: &Expression,
  193. func: Option<&Function>,
  194. ns: &Namespace,
  195. parent: usize,
  196. parent_rel: String,
  197. ) {
  198. match expr {
  199. Expression::BoolLiteral(loc, val) => {
  200. let labels = vec![
  201. format!("bool literal: {}", if *val { "true" } else { "false" }),
  202. ns.loc_to_string(loc),
  203. ];
  204. self.add_node(
  205. Node::new("bool_literal", labels),
  206. Some(parent),
  207. Some(parent_rel),
  208. );
  209. }
  210. Expression::BytesLiteral(loc, ty, val) => {
  211. let labels = vec![
  212. format!("{} literal: {}", ty.to_string(ns), hex::encode(val)),
  213. ns.loc_to_string(loc),
  214. ];
  215. self.add_node(
  216. Node::new("bytes_literal", labels),
  217. Some(parent),
  218. Some(parent_rel),
  219. );
  220. }
  221. Expression::CodeLiteral(loc, contract_no, runtime) => {
  222. let labels = vec![
  223. format!(
  224. "code {}literal contract {}",
  225. if *runtime { "runtime " } else { "" },
  226. ns.contracts[*contract_no].name,
  227. ),
  228. ns.loc_to_string(loc),
  229. ];
  230. self.add_node(
  231. Node::new("code_literal", labels),
  232. Some(parent),
  233. Some(parent_rel),
  234. );
  235. }
  236. Expression::NumberLiteral(loc, ty, val) => {
  237. let labels = vec![
  238. format!("{} literal: {}", ty.to_string(ns), val),
  239. ns.loc_to_string(loc),
  240. ];
  241. self.add_node(
  242. Node::new("number_literal", labels),
  243. Some(parent),
  244. Some(parent_rel),
  245. );
  246. }
  247. Expression::RationalNumberLiteral(loc, ty, val) => {
  248. let labels = vec![
  249. format!("rational {} literal: {}", ty.to_string(ns), val),
  250. ns.loc_to_string(loc),
  251. ];
  252. self.add_node(
  253. Node::new("rational_literal", labels),
  254. Some(parent),
  255. Some(parent_rel),
  256. );
  257. }
  258. Expression::StructLiteral(loc, ty, args) => {
  259. let labels = vec![
  260. format!("struct literal: {}", ty.to_string(ns)),
  261. ns.loc_to_string(loc),
  262. ];
  263. let node = self.add_node(
  264. Node::new("struct_literal", labels),
  265. Some(parent),
  266. Some(parent_rel),
  267. );
  268. for (no, arg) in args.iter().enumerate() {
  269. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  270. }
  271. }
  272. Expression::ArrayLiteral(loc, ty, _, args) => {
  273. let labels = vec![
  274. format!("array literal: {}", ty.to_string(ns)),
  275. ns.loc_to_string(loc),
  276. ];
  277. let node = self.add_node(
  278. Node::new("array_literal", labels),
  279. Some(parent),
  280. Some(parent_rel),
  281. );
  282. for (no, arg) in args.iter().enumerate() {
  283. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  284. }
  285. }
  286. Expression::ConstArrayLiteral(loc, ty, _, args) => {
  287. let labels = vec![
  288. format!("array literal: {}", ty.to_string(ns)),
  289. ns.loc_to_string(loc),
  290. ];
  291. let node = self.add_node(
  292. Node::new("array_literal", labels),
  293. Some(parent),
  294. Some(parent_rel),
  295. );
  296. for (no, arg) in args.iter().enumerate() {
  297. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  298. }
  299. }
  300. Expression::Add(loc, ty, unchecked, left, right) => {
  301. let mut labels = vec![String::from("add"), ty.to_string(ns), ns.loc_to_string(loc)];
  302. if *unchecked {
  303. labels.push(String::from("unchecked"));
  304. }
  305. let node = self.add_node(Node::new("add", labels), Some(parent), Some(parent_rel));
  306. self.add_expression(left, func, ns, node, String::from("left"));
  307. self.add_expression(right, func, ns, node, String::from("right"));
  308. }
  309. Expression::Subtract(loc, ty, unchecked, left, right) => {
  310. let mut labels = vec![
  311. String::from("subtract"),
  312. ty.to_string(ns),
  313. ns.loc_to_string(loc),
  314. ];
  315. if *unchecked {
  316. labels.push(String::from("unchecked"));
  317. }
  318. let node = self.add_node(
  319. Node::new("subtract", labels),
  320. Some(parent),
  321. Some(parent_rel),
  322. );
  323. self.add_expression(left, func, ns, node, String::from("left"));
  324. self.add_expression(right, func, ns, node, String::from("right"));
  325. }
  326. Expression::Multiply(loc, ty, unchecked, left, right) => {
  327. let mut labels = vec![
  328. String::from("multiply"),
  329. ty.to_string(ns),
  330. ns.loc_to_string(loc),
  331. ];
  332. if *unchecked {
  333. labels.push(String::from("unchecked"));
  334. }
  335. let node = self.add_node(
  336. Node::new("multiply", labels),
  337. Some(parent),
  338. Some(parent_rel),
  339. );
  340. self.add_expression(left, func, ns, node, String::from("left"));
  341. self.add_expression(right, func, ns, node, String::from("right"));
  342. }
  343. Expression::Divide(loc, ty, left, right) => {
  344. let labels = vec![
  345. String::from("divide"),
  346. ty.to_string(ns),
  347. ns.loc_to_string(loc),
  348. ];
  349. let node =
  350. self.add_node(Node::new("divide", labels), Some(parent), Some(parent_rel));
  351. self.add_expression(left, func, ns, node, String::from("left"));
  352. self.add_expression(right, func, ns, node, String::from("right"));
  353. }
  354. Expression::Modulo(loc, ty, left, right) => {
  355. let labels = vec![
  356. String::from("modulo"),
  357. ty.to_string(ns),
  358. ns.loc_to_string(loc),
  359. ];
  360. let node =
  361. self.add_node(Node::new("modulo", labels), Some(parent), Some(parent_rel));
  362. self.add_expression(left, func, ns, node, String::from("left"));
  363. self.add_expression(right, func, ns, node, String::from("right"));
  364. }
  365. Expression::Power(loc, ty, unchecked, left, right) => {
  366. let mut labels = vec![
  367. String::from("power"),
  368. ty.to_string(ns),
  369. ns.loc_to_string(loc),
  370. ];
  371. if *unchecked {
  372. labels.push(String::from("unchecked"));
  373. }
  374. let node =
  375. self.add_node(Node::new("power", labels), Some(parent), Some(parent_rel));
  376. self.add_expression(left, func, ns, node, String::from("left"));
  377. self.add_expression(right, func, ns, node, String::from("right"));
  378. }
  379. Expression::BitwiseOr(loc, ty, left, right) => {
  380. let labels = vec![
  381. String::from("bitwise or"),
  382. ty.to_string(ns),
  383. ns.loc_to_string(loc),
  384. ];
  385. let node = self.add_node(
  386. Node::new("bitwise_or", labels),
  387. Some(parent),
  388. Some(parent_rel),
  389. );
  390. self.add_expression(left, func, ns, node, String::from("left"));
  391. self.add_expression(right, func, ns, node, String::from("right"));
  392. }
  393. Expression::BitwiseAnd(loc, ty, left, right) => {
  394. let labels = vec![
  395. String::from("bitwise and"),
  396. ty.to_string(ns),
  397. ns.loc_to_string(loc),
  398. ];
  399. let node = self.add_node(
  400. Node::new("bitwise_and", labels),
  401. Some(parent),
  402. Some(parent_rel),
  403. );
  404. self.add_expression(left, func, ns, node, String::from("left"));
  405. self.add_expression(right, func, ns, node, String::from("right"));
  406. }
  407. Expression::BitwiseXor(loc, ty, left, right) => {
  408. let labels = vec![
  409. String::from("bitwise xor"),
  410. ty.to_string(ns),
  411. ns.loc_to_string(loc),
  412. ];
  413. let node = self.add_node(
  414. Node::new("bitwise_xor", labels),
  415. Some(parent),
  416. Some(parent_rel),
  417. );
  418. self.add_expression(left, func, ns, node, String::from("left"));
  419. self.add_expression(right, func, ns, node, String::from("right"));
  420. }
  421. Expression::ShiftLeft(loc, ty, left, right) => {
  422. let labels = vec![
  423. String::from("shift left"),
  424. ty.to_string(ns),
  425. ns.loc_to_string(loc),
  426. ];
  427. let node = self.add_node(
  428. Node::new("shift_left", labels),
  429. Some(parent),
  430. Some(parent_rel),
  431. );
  432. self.add_expression(left, func, ns, node, String::from("left"));
  433. self.add_expression(right, func, ns, node, String::from("right"));
  434. }
  435. Expression::ShiftRight(loc, ty, left, right, _) => {
  436. let labels = vec![
  437. String::from("shift right"),
  438. ty.to_string(ns),
  439. ns.loc_to_string(loc),
  440. ];
  441. let node = self.add_node(
  442. Node::new("shift_right", labels),
  443. Some(parent),
  444. Some(parent_rel),
  445. );
  446. self.add_expression(left, func, ns, node, String::from("left"));
  447. self.add_expression(right, func, ns, node, String::from("right"));
  448. }
  449. Expression::ConstantVariable(loc, ty, contract, var_no) => {
  450. self.add_constant_variable(loc, ty, contract, var_no, parent, parent_rel, ns);
  451. }
  452. Expression::Variable(loc, ty, var_no) => {
  453. let labels = vec![
  454. format!("variable: {}", func.unwrap().symtable.vars[var_no].id.name),
  455. ty.to_string(ns),
  456. ns.loc_to_string(loc),
  457. ];
  458. self.add_node(
  459. Node::new("variable", labels),
  460. Some(parent),
  461. Some(parent_rel),
  462. );
  463. }
  464. Expression::StorageVariable(loc, ty, contract, var_no) => {
  465. self.add_storage_variable(loc, ty, contract, var_no, parent, parent_rel, ns);
  466. }
  467. Expression::Load(loc, ty, expr) => {
  468. let node = self.add_node(
  469. Node::new(
  470. "load",
  471. vec![format!("load {}", ty.to_string(ns)), ns.loc_to_string(loc)],
  472. ),
  473. Some(parent),
  474. Some(parent_rel),
  475. );
  476. self.add_expression(expr, func, ns, node, String::from("expr"));
  477. }
  478. Expression::GetRef(loc, ty, expr) => {
  479. let node = self.add_node(
  480. Node::new(
  481. "getref",
  482. vec![
  483. format!("getref {}", ty.to_string(ns)),
  484. ns.loc_to_string(loc),
  485. ],
  486. ),
  487. Some(parent),
  488. Some(parent_rel),
  489. );
  490. self.add_expression(expr, func, ns, node, String::from("expr"));
  491. }
  492. Expression::StorageLoad(loc, ty, expr) => {
  493. let node = self.add_node(
  494. Node::new(
  495. "storage_load",
  496. vec![
  497. format!("storage load {}", ty.to_string(ns)),
  498. ns.loc_to_string(loc),
  499. ],
  500. ),
  501. Some(parent),
  502. Some(parent_rel),
  503. );
  504. self.add_expression(expr, func, ns, node, String::from("expr"));
  505. }
  506. Expression::ZeroExt(loc, ty, expr) => {
  507. let node = self.add_node(
  508. Node::new(
  509. "zero_ext",
  510. vec![
  511. format!("zero extend {}", ty.to_string(ns)),
  512. ns.loc_to_string(loc),
  513. ],
  514. ),
  515. Some(parent),
  516. Some(parent_rel),
  517. );
  518. self.add_expression(expr, func, ns, node, String::from("expr"));
  519. }
  520. Expression::SignExt(loc, ty, expr) => {
  521. let node = self.add_node(
  522. Node::new(
  523. "sign_ext",
  524. vec![
  525. format!("sign extend {}", ty.to_string(ns)),
  526. ns.loc_to_string(loc),
  527. ],
  528. ),
  529. Some(parent),
  530. Some(parent_rel),
  531. );
  532. self.add_expression(expr, func, ns, node, String::from("expr"));
  533. }
  534. Expression::Trunc(loc, ty, expr) => {
  535. let node = self.add_node(
  536. Node::new(
  537. "trunc",
  538. vec![
  539. format!("truncate {}", ty.to_string(ns)),
  540. ns.loc_to_string(loc),
  541. ],
  542. ),
  543. Some(parent),
  544. Some(parent_rel),
  545. );
  546. self.add_expression(expr, func, ns, node, String::from("expr"));
  547. }
  548. Expression::CheckingTrunc(loc, ty, expr) => {
  549. let node = self.add_node(
  550. Node::new(
  551. "trunc",
  552. vec![
  553. format!("checking truncate {}", ty.to_string(ns)),
  554. ns.loc_to_string(loc),
  555. ],
  556. ),
  557. Some(parent),
  558. Some(parent_rel),
  559. );
  560. self.add_expression(expr, func, ns, node, String::from("expr"));
  561. }
  562. Expression::Cast(loc, ty, expr) => {
  563. let node = self.add_node(
  564. Node::new(
  565. "cast",
  566. vec![format!("cast {}", ty.to_string(ns)), ns.loc_to_string(loc)],
  567. ),
  568. Some(parent),
  569. Some(parent_rel),
  570. );
  571. self.add_expression(expr, func, ns, node, String::from("expr"));
  572. }
  573. Expression::BytesCast(loc, from, to, expr) => {
  574. let node = self.add_node(
  575. Node::new(
  576. "bytes_cast",
  577. vec![
  578. format!(
  579. "bytes cast from {} to {}",
  580. from.to_string(ns),
  581. to.to_string(ns)
  582. ),
  583. ns.loc_to_string(loc),
  584. ],
  585. ),
  586. Some(parent),
  587. Some(parent_rel),
  588. );
  589. self.add_expression(expr, func, ns, node, String::from("expr"));
  590. }
  591. Expression::PreIncrement(loc, ty, unchecked, expr) => {
  592. let mut labels = vec![
  593. String::from("pre increment"),
  594. ty.to_string(ns),
  595. ns.loc_to_string(loc),
  596. ];
  597. if *unchecked {
  598. labels.push(String::from("unchecked"));
  599. }
  600. let node = self.add_node(
  601. Node::new("pre_increment", labels),
  602. Some(parent),
  603. Some(parent_rel),
  604. );
  605. self.add_expression(expr, func, ns, node, String::from("expr"));
  606. }
  607. Expression::PreDecrement(loc, ty, unchecked, expr) => {
  608. let mut labels = vec![
  609. String::from("pre decrement"),
  610. ty.to_string(ns),
  611. ns.loc_to_string(loc),
  612. ];
  613. if *unchecked {
  614. labels.push(String::from("unchecked"));
  615. }
  616. let node = self.add_node(
  617. Node::new("pre_decrement", labels),
  618. Some(parent),
  619. Some(parent_rel),
  620. );
  621. self.add_expression(expr, func, ns, node, String::from("expr"));
  622. }
  623. Expression::PostIncrement(loc, ty, unchecked, expr) => {
  624. let mut labels = vec![
  625. String::from("post increment"),
  626. ty.to_string(ns),
  627. ns.loc_to_string(loc),
  628. ];
  629. if *unchecked {
  630. labels.push(String::from("unchecked"));
  631. }
  632. let node = self.add_node(
  633. Node::new("post_increment", labels),
  634. Some(parent),
  635. Some(parent_rel),
  636. );
  637. self.add_expression(expr, func, ns, node, String::from("expr"));
  638. }
  639. Expression::PostDecrement(loc, ty, unchecked, expr) => {
  640. let mut labels = vec![
  641. String::from("post decrement"),
  642. ty.to_string(ns),
  643. ns.loc_to_string(loc),
  644. ];
  645. if *unchecked {
  646. labels.push(String::from("unchecked"));
  647. }
  648. let node = self.add_node(
  649. Node::new("post_decrement", labels),
  650. Some(parent),
  651. Some(parent_rel),
  652. );
  653. self.add_expression(expr, func, ns, node, String::from("expr"));
  654. }
  655. Expression::Assign(loc, ty, left, right) => {
  656. let labels = vec![
  657. String::from("assign"),
  658. ty.to_string(ns),
  659. ns.loc_to_string(loc),
  660. ];
  661. let node =
  662. self.add_node(Node::new("assign", labels), Some(parent), Some(parent_rel));
  663. self.add_expression(left, func, ns, node, String::from("left"));
  664. self.add_expression(right, func, ns, node, String::from("right"));
  665. }
  666. Expression::More(loc, left, right) => {
  667. let labels = vec![String::from("more"), ns.loc_to_string(loc)];
  668. let node = self.add_node(Node::new("more", labels), Some(parent), Some(parent_rel));
  669. self.add_expression(left, func, ns, node, String::from("left"));
  670. self.add_expression(right, func, ns, node, String::from("right"));
  671. }
  672. Expression::Less(loc, left, right) => {
  673. let labels = vec![String::from("less"), ns.loc_to_string(loc)];
  674. let node = self.add_node(Node::new("less", labels), Some(parent), Some(parent_rel));
  675. self.add_expression(left, func, ns, node, String::from("left"));
  676. self.add_expression(right, func, ns, node, String::from("right"));
  677. }
  678. Expression::MoreEqual(loc, left, right) => {
  679. let labels = vec![String::from("more equal"), ns.loc_to_string(loc)];
  680. let node = self.add_node(
  681. Node::new("more_equal", labels),
  682. Some(parent),
  683. Some(parent_rel),
  684. );
  685. self.add_expression(left, func, ns, node, String::from("left"));
  686. self.add_expression(right, func, ns, node, String::from("right"));
  687. }
  688. Expression::LessEqual(loc, left, right) => {
  689. let labels = vec![String::from("less equal"), ns.loc_to_string(loc)];
  690. let node = self.add_node(
  691. Node::new("less_equal", labels),
  692. Some(parent),
  693. Some(parent_rel),
  694. );
  695. self.add_expression(left, func, ns, node, String::from("left"));
  696. self.add_expression(right, func, ns, node, String::from("right"));
  697. }
  698. Expression::Equal(loc, left, right) => {
  699. let labels = vec![String::from("equal"), ns.loc_to_string(loc)];
  700. let node =
  701. self.add_node(Node::new("equal", labels), Some(parent), Some(parent_rel));
  702. self.add_expression(left, func, ns, node, String::from("left"));
  703. self.add_expression(right, func, ns, node, String::from("right"));
  704. }
  705. Expression::NotEqual(loc, left, right) => {
  706. let labels = vec![String::from("not equal"), ns.loc_to_string(loc)];
  707. let node = self.add_node(
  708. Node::new("not_qual", labels),
  709. Some(parent),
  710. Some(parent_rel),
  711. );
  712. self.add_expression(left, func, ns, node, String::from("left"));
  713. self.add_expression(right, func, ns, node, String::from("right"));
  714. }
  715. Expression::Not(loc, expr) => {
  716. let node = self.add_node(
  717. Node::new("not", vec![String::from("not"), ns.loc_to_string(loc)]),
  718. Some(parent),
  719. Some(parent_rel),
  720. );
  721. self.add_expression(expr, func, ns, node, String::from("expr"));
  722. }
  723. Expression::Complement(loc, ty, expr) => {
  724. let node = self.add_node(
  725. Node::new(
  726. "complement",
  727. vec![
  728. format!("complement {}", ty.to_string(ns)),
  729. ns.loc_to_string(loc),
  730. ],
  731. ),
  732. Some(parent),
  733. Some(parent_rel),
  734. );
  735. self.add_expression(expr, func, ns, node, String::from("expr"));
  736. }
  737. Expression::UnaryMinus(loc, ty, expr) => {
  738. let node = self.add_node(
  739. Node::new(
  740. "unary_minus",
  741. vec![
  742. format!("unary minus {}", ty.to_string(ns)),
  743. ns.loc_to_string(loc),
  744. ],
  745. ),
  746. Some(parent),
  747. Some(parent_rel),
  748. );
  749. self.add_expression(expr, func, ns, node, String::from("expr"));
  750. }
  751. Expression::Ternary(loc, ty, cond, left, right) => {
  752. let node = self.add_node(
  753. Node::new(
  754. "conditional",
  755. vec![
  756. format!("conditiona {}", ty.to_string(ns)),
  757. ns.loc_to_string(loc),
  758. ],
  759. ),
  760. Some(parent),
  761. Some(parent_rel),
  762. );
  763. self.add_expression(cond, func, ns, node, String::from("cond"));
  764. self.add_expression(left, func, ns, node, String::from("left"));
  765. self.add_expression(right, func, ns, node, String::from("right"));
  766. }
  767. Expression::Subscript(loc, _, ty, array, index) => {
  768. let node = self.add_node(
  769. Node::new(
  770. "subscript",
  771. vec![
  772. format!("subscript {}", ty.to_string(ns)),
  773. ns.loc_to_string(loc),
  774. ],
  775. ),
  776. Some(parent),
  777. Some(parent_rel),
  778. );
  779. self.add_expression(array, func, ns, node, String::from("array"));
  780. self.add_expression(index, func, ns, node, String::from("index"));
  781. }
  782. Expression::StructMember(loc, ty, var, member) => {
  783. let node = self.add_node(
  784. Node::new(
  785. "structmember",
  786. vec![
  787. format!("struct member #{} {}", member, ty.to_string(ns)),
  788. ns.loc_to_string(loc),
  789. ],
  790. ),
  791. Some(parent),
  792. Some(parent_rel),
  793. );
  794. self.add_expression(var, func, ns, node, String::from("var"));
  795. }
  796. Expression::AllocDynamicArray(loc, ty, length, initializer) => {
  797. let mut labels = vec![
  798. format!("alloc array {}", ty.to_string(ns)),
  799. ns.loc_to_string(loc),
  800. ];
  801. if let Some(initializer) = initializer {
  802. labels.insert(1, format!("initializer: {}", hex::encode(initializer)));
  803. }
  804. let node = self.add_node(
  805. Node::new("alloc_array", labels),
  806. Some(parent),
  807. Some(parent_rel),
  808. );
  809. self.add_expression(length, func, ns, node, String::from("length"));
  810. }
  811. Expression::StorageArrayLength {
  812. loc,
  813. ty,
  814. array,
  815. elem_ty,
  816. } => {
  817. let node = self.add_node(
  818. Node::new(
  819. "array_length",
  820. vec![
  821. format!("array length {}", ty.to_string(ns)),
  822. format!("element {}", elem_ty.to_string(ns)),
  823. ns.loc_to_string(loc),
  824. ],
  825. ),
  826. Some(parent),
  827. Some(parent_rel),
  828. );
  829. self.add_expression(array, func, ns, node, String::from("array"));
  830. }
  831. Expression::StringCompare(loc, left, right) => {
  832. let node = self.add_node(
  833. Node::new(
  834. "string_cmp",
  835. vec![String::from("string compare"), ns.loc_to_string(loc)],
  836. ),
  837. Some(parent),
  838. Some(parent_rel),
  839. );
  840. self.add_string_location(left, func, ns, node, String::from("left"));
  841. self.add_string_location(right, func, ns, node, String::from("right"));
  842. }
  843. Expression::StringConcat(loc, ty, left, right) => {
  844. let node = self.add_node(
  845. Node::new(
  846. "string_concat",
  847. vec![
  848. format!("string concat {}", ty.to_string(ns)),
  849. ns.loc_to_string(loc),
  850. ],
  851. ),
  852. Some(parent),
  853. Some(parent_rel),
  854. );
  855. self.add_string_location(left, func, ns, node, String::from("left"));
  856. self.add_string_location(right, func, ns, node, String::from("right"));
  857. }
  858. Expression::Or(loc, left, right) => {
  859. let labels = vec![String::from("logical or"), ns.loc_to_string(loc)];
  860. let node = self.add_node(
  861. Node::new("logical_or", labels),
  862. Some(parent),
  863. Some(parent_rel),
  864. );
  865. self.add_expression(left, func, ns, node, String::from("left"));
  866. self.add_expression(right, func, ns, node, String::from("right"));
  867. }
  868. Expression::And(loc, left, right) => {
  869. let labels = vec![String::from("logical and"), ns.loc_to_string(loc)];
  870. let node = self.add_node(
  871. Node::new("logical_and", labels),
  872. Some(parent),
  873. Some(parent_rel),
  874. );
  875. self.add_expression(left, func, ns, node, String::from("left"));
  876. self.add_expression(right, func, ns, node, String::from("right"));
  877. }
  878. Expression::InternalFunction {
  879. loc,
  880. ty,
  881. function_no,
  882. signature,
  883. } => {
  884. let mut labels = vec![ty.to_string(ns), ns.loc_to_string(loc)];
  885. let func = &ns.functions[*function_no];
  886. if let Some(contract_no) = func.contract_no {
  887. labels.insert(
  888. 1,
  889. format!("{}.{}", ns.contracts[contract_no].name, func.name),
  890. )
  891. } else {
  892. labels.insert(1, format!("free function {}", func.name))
  893. }
  894. if let Some(signature) = signature {
  895. labels.insert(1, format!("signature {}", signature))
  896. }
  897. self.add_node(
  898. Node::new("internal_function", labels),
  899. Some(parent),
  900. Some(parent_rel),
  901. );
  902. }
  903. Expression::ExternalFunction {
  904. loc,
  905. ty,
  906. function_no,
  907. address,
  908. } => {
  909. let mut labels = vec![ty.to_string(ns), ns.loc_to_string(loc)];
  910. let f = &ns.functions[*function_no];
  911. if let Some(contract_no) = f.contract_no {
  912. labels.insert(1, format!("{}.{}", ns.contracts[contract_no].name, f.name))
  913. }
  914. let node = self.add_node(
  915. Node::new("external_function", labels),
  916. Some(parent),
  917. Some(parent_rel),
  918. );
  919. self.add_expression(address, func, ns, node, String::from("address"));
  920. }
  921. Expression::InternalFunctionCall {
  922. loc,
  923. function,
  924. args,
  925. ..
  926. } => {
  927. let labels = vec![
  928. String::from("call internal function"),
  929. ns.loc_to_string(loc),
  930. ];
  931. let node = self.add_node(
  932. Node::new("call_internal_function", labels),
  933. Some(parent),
  934. Some(parent_rel),
  935. );
  936. self.add_expression(function, func, ns, node, String::from("function"));
  937. for (no, arg) in args.iter().enumerate() {
  938. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  939. }
  940. }
  941. Expression::ExternalFunctionCall {
  942. loc,
  943. function,
  944. args,
  945. call_args,
  946. ..
  947. } => {
  948. let labels = vec![
  949. String::from("call external function"),
  950. ns.loc_to_string(loc),
  951. ];
  952. let node = self.add_node(
  953. Node::new("call_external_function", labels),
  954. Some(parent),
  955. Some(parent_rel),
  956. );
  957. self.add_expression(function, func, ns, node, String::from("function"));
  958. for (no, arg) in args.iter().enumerate() {
  959. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  960. }
  961. self.add_call_args(call_args, func, ns, node);
  962. }
  963. Expression::ExternalFunctionCallRaw {
  964. loc,
  965. address,
  966. args,
  967. call_args,
  968. ..
  969. } => {
  970. let labels = vec![
  971. String::from("call external function"),
  972. ns.loc_to_string(loc),
  973. ];
  974. let node = self.add_node(
  975. Node::new("call_external_function", labels),
  976. Some(parent),
  977. Some(parent_rel),
  978. );
  979. self.add_expression(address, func, ns, node, String::from("address"));
  980. self.add_expression(args, func, ns, node, String::from("args"));
  981. self.add_call_args(call_args, func, ns, node);
  982. }
  983. Expression::Constructor {
  984. loc,
  985. contract_no,
  986. args,
  987. call_args,
  988. ..
  989. } => {
  990. let labels = vec![
  991. format!("constructor contract {}", ns.contracts[*contract_no].name),
  992. ns.loc_to_string(loc),
  993. ];
  994. let node = self.add_node(
  995. Node::new("constructor", labels),
  996. Some(parent),
  997. Some(parent_rel),
  998. );
  999. for (no, arg) in args.iter().enumerate() {
  1000. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  1001. }
  1002. self.add_call_args(call_args, func, ns, node);
  1003. }
  1004. Expression::FormatString(loc, args) => {
  1005. let labels = vec![String::from("string format"), ns.loc_to_string(loc)];
  1006. let node = self.add_node(
  1007. Node::new("string_format", labels),
  1008. Some(parent),
  1009. Some(parent_rel),
  1010. );
  1011. for (no, (_, arg)) in args.iter().enumerate() {
  1012. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  1013. }
  1014. }
  1015. Expression::Builtin(loc, _, builtin, args) => {
  1016. let labels = vec![format!("builtin {:?}", builtin), ns.loc_to_string(loc)];
  1017. let node = self.add_node(
  1018. Node::new("builtins", labels),
  1019. Some(parent),
  1020. Some(parent_rel),
  1021. );
  1022. for (no, arg) in args.iter().enumerate() {
  1023. self.add_expression(arg, func, ns, node, format!("arg #{}", no));
  1024. }
  1025. }
  1026. Expression::InterfaceId(loc, contract_no) => {
  1027. let labels = vec![
  1028. format!("interfaceid contract {}", ns.contracts[*contract_no].name),
  1029. ns.loc_to_string(loc),
  1030. ];
  1031. self.add_node(
  1032. Node::new("interfaceid", labels),
  1033. Some(parent),
  1034. Some(parent_rel),
  1035. );
  1036. }
  1037. Expression::List(loc, list) => {
  1038. let labels = vec![String::from("list"), ns.loc_to_string(loc)];
  1039. let node = self.add_node(Node::new("list", labels), Some(parent), Some(parent_rel));
  1040. for (no, expr) in list.iter().enumerate() {
  1041. self.add_expression(expr, func, ns, node, format!("entry #{}", no));
  1042. }
  1043. }
  1044. }
  1045. }
  1046. fn add_call_args(
  1047. &mut self,
  1048. call_args: &CallArgs,
  1049. func: Option<&Function>,
  1050. ns: &Namespace,
  1051. node: usize,
  1052. ) {
  1053. if let Some(gas) = &call_args.gas {
  1054. self.add_expression(gas, func, ns, node, String::from("gas"));
  1055. }
  1056. if let Some(value) = &call_args.value {
  1057. self.add_expression(value, func, ns, node, String::from("value"));
  1058. }
  1059. if let Some(salt) = &call_args.salt {
  1060. self.add_expression(salt, func, ns, node, String::from("salt"));
  1061. }
  1062. if let Some(space) = &call_args.space {
  1063. self.add_expression(space, func, ns, node, String::from("space"));
  1064. }
  1065. if let Some(accounts) = &call_args.accounts {
  1066. self.add_expression(accounts, func, ns, node, String::from("accounts"));
  1067. }
  1068. }
  1069. fn add_string_location(
  1070. &mut self,
  1071. loc: &StringLocation<Expression>,
  1072. func: Option<&Function>,
  1073. ns: &Namespace,
  1074. parent: usize,
  1075. parent_rel: String,
  1076. ) {
  1077. match loc {
  1078. StringLocation::CompileTime(val) => {
  1079. self.add_node(
  1080. Node::new(
  1081. "compile_time_string",
  1082. vec![format!("const string {}", hex::encode(val))],
  1083. ),
  1084. Some(parent),
  1085. Some(parent_rel),
  1086. );
  1087. }
  1088. StringLocation::RunTime(expr) => {
  1089. self.add_expression(expr, func, ns, parent, parent_rel);
  1090. }
  1091. }
  1092. }
  1093. fn add_statement(
  1094. &mut self,
  1095. stmts: &[Statement],
  1096. func: &Function,
  1097. ns: &Namespace,
  1098. parent: usize,
  1099. parent_rel: String,
  1100. ) {
  1101. let mut parent = parent;
  1102. let mut parent_rel = parent_rel;
  1103. for stmt in stmts {
  1104. match stmt {
  1105. Statement::Block {
  1106. loc,
  1107. unchecked,
  1108. statements,
  1109. } => {
  1110. let mut labels = vec![String::from("block"), ns.loc_to_string(loc)];
  1111. if *unchecked {
  1112. labels.push(String::from("unchecked"));
  1113. }
  1114. parent =
  1115. self.add_node(Node::new("block", labels), Some(parent), Some(parent_rel));
  1116. self.add_statement(statements, func, ns, parent, String::from("statements"));
  1117. }
  1118. Statement::VariableDecl(loc, _, param, init) => {
  1119. let labels = vec![
  1120. format!(
  1121. "variable decl {} {}",
  1122. param.ty.to_string(ns),
  1123. param.name_as_str()
  1124. ),
  1125. ns.loc_to_string(loc),
  1126. ];
  1127. parent = self.add_node(
  1128. Node::new("var_decl", labels),
  1129. Some(parent),
  1130. Some(parent_rel),
  1131. );
  1132. if let Some(init) = init {
  1133. self.add_expression(init, Some(func), ns, parent, String::from("init"));
  1134. }
  1135. }
  1136. Statement::If(loc, _, cond, then, else_) => {
  1137. let labels = vec![String::from("if"), ns.loc_to_string(loc)];
  1138. parent = self.add_node(Node::new("if", labels), Some(parent), Some(parent_rel));
  1139. self.add_expression(cond, Some(func), ns, parent, String::from("cond"));
  1140. self.add_statement(then, func, ns, parent, String::from("then"));
  1141. self.add_statement(else_, func, ns, parent, String::from("else"));
  1142. }
  1143. Statement::While(loc, _, cond, body) => {
  1144. let labels = vec![String::from("while"), ns.loc_to_string(loc)];
  1145. parent =
  1146. self.add_node(Node::new("while", labels), Some(parent), Some(parent_rel));
  1147. self.add_expression(cond, Some(func), ns, parent, String::from("cond"));
  1148. self.add_statement(body, func, ns, parent, String::from("body"));
  1149. }
  1150. Statement::For {
  1151. loc,
  1152. init,
  1153. cond,
  1154. next,
  1155. body,
  1156. ..
  1157. } => {
  1158. let labels = vec![String::from("for"), ns.loc_to_string(loc)];
  1159. parent =
  1160. self.add_node(Node::new("for", labels), Some(parent), Some(parent_rel));
  1161. self.add_statement(init, func, ns, parent, String::from("init"));
  1162. if let Some(cond) = cond {
  1163. self.add_expression(cond, Some(func), ns, parent, String::from("cond"));
  1164. }
  1165. self.add_statement(next, func, ns, parent, String::from("next"));
  1166. self.add_statement(body, func, ns, parent, String::from("body"));
  1167. }
  1168. Statement::DoWhile(loc, _, body, cond) => {
  1169. let labels = vec![String::from("do while"), ns.loc_to_string(loc)];
  1170. parent =
  1171. self.add_node(Node::new("dowhile", labels), Some(parent), Some(parent_rel));
  1172. self.add_statement(body, func, ns, parent, String::from("body"));
  1173. self.add_expression(cond, Some(func), ns, parent, String::from("cond"));
  1174. }
  1175. Statement::Expression(loc, _, expr) => {
  1176. let labels = vec![String::from("expression"), ns.loc_to_string(loc)];
  1177. parent =
  1178. self.add_node(Node::new("expr", labels), Some(parent), Some(parent_rel));
  1179. self.add_expression(expr, Some(func), ns, parent, String::from("expr"));
  1180. }
  1181. Statement::Delete(loc, ty, expr) => {
  1182. let labels = vec![
  1183. String::from("delete"),
  1184. format!("ty: {}", ty.to_string(ns)),
  1185. ns.loc_to_string(loc),
  1186. ];
  1187. parent =
  1188. self.add_node(Node::new("delete", labels), Some(parent), Some(parent_rel));
  1189. self.add_expression(expr, Some(func), ns, parent, String::from("expr"));
  1190. }
  1191. Statement::Destructure(loc, fields, expr) => {
  1192. let labels = vec![String::from("destructure"), ns.loc_to_string(loc)];
  1193. parent = self.add_node(
  1194. Node::new("destructure", labels),
  1195. Some(parent),
  1196. Some(parent_rel),
  1197. );
  1198. for (no, field) in fields.iter().enumerate() {
  1199. let parent_rel = format!("arg #{}", no);
  1200. match field {
  1201. DestructureField::None => {
  1202. self.add_node(
  1203. Node::new("none", vec![String::from("none")]),
  1204. Some(parent),
  1205. Some(parent_rel),
  1206. );
  1207. }
  1208. DestructureField::Expression(expr) => {
  1209. self.add_expression(expr, Some(func), ns, parent, parent_rel);
  1210. }
  1211. DestructureField::VariableDecl(_, param) => {
  1212. self.add_node(
  1213. Node::new(
  1214. "param",
  1215. vec![format!(
  1216. "{} {}",
  1217. param.ty.to_string(ns),
  1218. param.name_as_str()
  1219. )],
  1220. ),
  1221. Some(parent),
  1222. Some(parent_rel),
  1223. );
  1224. }
  1225. }
  1226. }
  1227. self.add_expression(expr, Some(func), ns, parent, String::from("expr"));
  1228. }
  1229. Statement::Continue(loc) => {
  1230. let labels = vec![String::from("continue"), ns.loc_to_string(loc)];
  1231. parent = self.add_node(
  1232. Node::new("continue", labels),
  1233. Some(parent),
  1234. Some(parent_rel),
  1235. );
  1236. }
  1237. Statement::Break(loc) => {
  1238. let labels = vec![String::from("break"), ns.loc_to_string(loc)];
  1239. parent =
  1240. self.add_node(Node::new("break", labels), Some(parent), Some(parent_rel));
  1241. }
  1242. Statement::Return(loc, expr) => {
  1243. let labels = vec![String::from("return"), ns.loc_to_string(loc)];
  1244. parent =
  1245. self.add_node(Node::new("return", labels), Some(parent), Some(parent_rel));
  1246. if let Some(expr) = expr {
  1247. self.add_expression(expr, Some(func), ns, parent, String::from("expr"));
  1248. }
  1249. }
  1250. Statement::Emit {
  1251. loc,
  1252. event_no,
  1253. args,
  1254. ..
  1255. } => {
  1256. let mut labels = vec![String::from("emit"), ns.loc_to_string(loc)];
  1257. let event = &ns.events[*event_no];
  1258. if let Some(contract) = event.contract {
  1259. labels.insert(
  1260. 1,
  1261. format!("event {}.{}", ns.contracts[contract].name, event.name),
  1262. );
  1263. } else {
  1264. labels.insert(1, format!("event {}", event.name));
  1265. }
  1266. parent =
  1267. self.add_node(Node::new("emit", labels), Some(parent), Some(parent_rel));
  1268. for (no, arg) in args.iter().enumerate() {
  1269. self.add_expression(arg, Some(func), ns, parent, format!("arg #{}", no));
  1270. }
  1271. }
  1272. Statement::TryCatch(loc, _, try_catch) => {
  1273. let labels = vec![String::from("try"), ns.loc_to_string(loc)];
  1274. self.add_expression(
  1275. &try_catch.expr,
  1276. Some(func),
  1277. ns,
  1278. parent,
  1279. String::from("expr"),
  1280. );
  1281. parent =
  1282. self.add_node(Node::new("try", labels), Some(parent), Some(parent_rel));
  1283. for (no, (_, param)) in try_catch.returns.iter().enumerate() {
  1284. let parent_rel = format!("return #{}", no);
  1285. self.add_node(
  1286. Node::new(
  1287. "return",
  1288. vec![format!(
  1289. "{} {}",
  1290. param.ty.to_string(ns),
  1291. param.name_as_str()
  1292. )],
  1293. ),
  1294. Some(parent),
  1295. Some(parent_rel),
  1296. );
  1297. }
  1298. self.add_statement(&try_catch.ok_stmt, func, ns, parent, String::from("ok"));
  1299. for (_, param, stmt) in &try_catch.errors {
  1300. self.add_node(
  1301. Node::new(
  1302. "error_param",
  1303. vec![format!(
  1304. "{} {}",
  1305. param.ty.to_string(ns),
  1306. param.name_as_str()
  1307. )],
  1308. ),
  1309. Some(parent),
  1310. Some(String::from("error parameter")),
  1311. );
  1312. self.add_statement(stmt, func, ns, parent, String::from("error"));
  1313. }
  1314. if let Some(param) = &try_catch.catch_param {
  1315. self.add_node(
  1316. Node::new(
  1317. "catch_param",
  1318. vec![format!(
  1319. "{} {}",
  1320. param.ty.to_string(ns),
  1321. param.name_as_str()
  1322. )],
  1323. ),
  1324. Some(parent),
  1325. Some(String::from("catch parameter")),
  1326. );
  1327. }
  1328. self.add_statement(
  1329. &try_catch.catch_stmt,
  1330. func,
  1331. ns,
  1332. parent,
  1333. String::from("catch"),
  1334. );
  1335. }
  1336. Statement::Underscore(loc) => {
  1337. let labels = vec![String::from("undersore"), ns.loc_to_string(loc)];
  1338. parent = self.add_node(
  1339. Node::new("underscore", labels),
  1340. Some(parent),
  1341. Some(parent_rel),
  1342. );
  1343. }
  1344. Statement::Assembly(inline_assembly, ..) => {
  1345. let labels = vec![
  1346. "inline assembly".to_string(),
  1347. ns.loc_to_string(&inline_assembly.loc),
  1348. ];
  1349. parent = self.add_node(
  1350. Node::new("inline_assembly", labels),
  1351. Some(parent),
  1352. Some(parent_rel),
  1353. );
  1354. let mut local_parent = parent;
  1355. for n in inline_assembly.functions.start..inline_assembly.functions.end {
  1356. self.add_yul_function(
  1357. n,
  1358. ns,
  1359. local_parent,
  1360. format!("func def #{}", inline_assembly.functions.end - n),
  1361. );
  1362. }
  1363. local_parent = parent;
  1364. for (item_no, item) in inline_assembly.body.iter().enumerate() {
  1365. local_parent = self.add_yul_statement(
  1366. item,
  1367. local_parent,
  1368. format!("statement #{}", item_no),
  1369. &func.symtable,
  1370. ns,
  1371. );
  1372. }
  1373. }
  1374. }
  1375. parent_rel = String::from("next");
  1376. }
  1377. }
  1378. fn add_yul_function(
  1379. &mut self,
  1380. func_no: usize,
  1381. ns: &Namespace,
  1382. parent: usize,
  1383. parent_rel: String,
  1384. ) {
  1385. let labels = vec![
  1386. format!("function definition {}", ns.yul_functions[func_no].name),
  1387. ns.loc_to_string(&ns.yul_functions[func_no].loc),
  1388. ];
  1389. let func_node = self.add_node(
  1390. Node::new("yul_function_definition", labels),
  1391. Some(parent),
  1392. Some(parent_rel),
  1393. );
  1394. let mut local_parent = func_node;
  1395. for (item_no, item) in (*ns.yul_functions[func_no].params).iter().enumerate() {
  1396. let labels = vec![
  1397. format!(
  1398. "function parameter {}: {}",
  1399. item.ty.to_string(ns),
  1400. item.id.as_ref().unwrap().name,
  1401. ),
  1402. ns.loc_to_string(&item.loc),
  1403. ];
  1404. local_parent = self.add_node(
  1405. Node::new("yul_function_parameter", labels),
  1406. Some(local_parent),
  1407. Some(format!("parameter #{}", item_no)),
  1408. );
  1409. }
  1410. local_parent = func_node;
  1411. for (item_no, item) in (*ns.yul_functions[func_no].returns).iter().enumerate() {
  1412. let labels = vec![
  1413. format!(
  1414. "return parameter {}: {}",
  1415. item.ty.to_string(ns),
  1416. item.id.as_ref().unwrap().name
  1417. ),
  1418. ns.loc_to_string(&item.loc),
  1419. ];
  1420. local_parent = self.add_node(
  1421. Node::new("yul_function_return", labels),
  1422. Some(local_parent),
  1423. Some(format!("return #{}", item_no)),
  1424. );
  1425. }
  1426. local_parent = func_node;
  1427. for (item_no, item) in ns.yul_functions[func_no].body.iter().enumerate() {
  1428. local_parent = self.add_yul_statement(
  1429. item,
  1430. local_parent,
  1431. format!("statement #{}", item_no),
  1432. &ns.yul_functions[func_no].symtable,
  1433. ns,
  1434. );
  1435. }
  1436. }
  1437. fn add_yul_expression(
  1438. &mut self,
  1439. expr: &YulExpression,
  1440. symtable: &Symtable,
  1441. ns: &Namespace,
  1442. parent: usize,
  1443. parent_rel: String,
  1444. ) {
  1445. match expr {
  1446. YulExpression::BoolLiteral(loc, value, ty) => {
  1447. let labels = vec![
  1448. format!(
  1449. "bool literal: {} of type {}",
  1450. if *value { "true" } else { "false" },
  1451. ty.to_string(ns)
  1452. ),
  1453. ns.loc_to_string(loc),
  1454. ];
  1455. self.add_node(
  1456. Node::new("yul_bool_literal", labels),
  1457. Some(parent),
  1458. Some(parent_rel),
  1459. );
  1460. }
  1461. YulExpression::NumberLiteral(loc, value, ty) => {
  1462. let labels = vec![
  1463. format!("{} literal: {}", ty.to_string(ns), value),
  1464. ns.loc_to_string(loc),
  1465. ];
  1466. self.add_node(
  1467. Node::new("yul_number_literal", labels),
  1468. Some(parent),
  1469. Some(parent_rel),
  1470. );
  1471. }
  1472. YulExpression::StringLiteral(loc, value, ty) => {
  1473. let labels = vec![
  1474. format!("{} literal: {}", ty.to_string(ns), hex::encode(value)),
  1475. ns.loc_to_string(loc),
  1476. ];
  1477. self.add_node(
  1478. Node::new("bytes_literal", labels),
  1479. Some(parent),
  1480. Some(parent_rel),
  1481. );
  1482. }
  1483. YulExpression::YulLocalVariable(loc, ty, var_no) => {
  1484. let labels = vec![
  1485. format!("yul variable: {}", symtable.vars[var_no].id.name),
  1486. ty.to_string(ns),
  1487. ns.loc_to_string(loc),
  1488. ];
  1489. self.add_node(
  1490. Node::new("yul_variable", labels),
  1491. Some(parent),
  1492. Some(parent_rel),
  1493. );
  1494. }
  1495. YulExpression::SolidityLocalVariable(loc, ty, _, var_no) => {
  1496. let labels = vec![
  1497. format!("solidity variable: {}", symtable.vars[var_no].id.name),
  1498. ty.to_string(ns),
  1499. ns.loc_to_string(loc),
  1500. ];
  1501. self.add_node(
  1502. Node::new("solidity_variable", labels),
  1503. Some(parent),
  1504. Some(parent_rel),
  1505. );
  1506. }
  1507. YulExpression::ConstantVariable(loc, ty, contract, var_no) => {
  1508. self.add_constant_variable(loc, ty, contract, var_no, parent, parent_rel, ns);
  1509. }
  1510. YulExpression::StorageVariable(loc, ty, contract, var_no) => {
  1511. self.add_storage_variable(loc, ty, contract, var_no, parent, parent_rel, ns);
  1512. }
  1513. YulExpression::BuiltInCall(loc, builtin_ty, args) => {
  1514. self.add_yul_builtin_call(loc, builtin_ty, args, parent, parent_rel, symtable, ns);
  1515. }
  1516. YulExpression::FunctionCall(loc, func_no, args, _) => {
  1517. self.add_yul_function_call(loc, func_no, args, parent, parent_rel, symtable, ns);
  1518. }
  1519. YulExpression::SuffixAccess(loc, member, suffix) => {
  1520. let labels = vec![
  1521. format!("yul suffix '{}' access", suffix.to_string()),
  1522. ns.loc_to_string(loc),
  1523. ];
  1524. let node = self.add_node(
  1525. Node::new("yul_suffix_access", labels),
  1526. Some(parent),
  1527. Some(parent_rel),
  1528. );
  1529. self.add_yul_expression(member, symtable, ns, node, "parent".to_string());
  1530. }
  1531. }
  1532. }
  1533. fn add_constant_variable(
  1534. &mut self,
  1535. loc: &Loc,
  1536. ty: &Type,
  1537. contract: &Option<usize>,
  1538. var_no: &usize,
  1539. parent: usize,
  1540. parent_rel: String,
  1541. ns: &Namespace,
  1542. ) {
  1543. let mut labels = vec![
  1544. String::from("constant variable"),
  1545. ty.to_string(ns),
  1546. ns.loc_to_string(loc),
  1547. ];
  1548. if let Some(contract) = contract {
  1549. labels.insert(
  1550. 1,
  1551. format!(
  1552. "{}.{}",
  1553. ns.contracts[*contract].name, ns.contracts[*contract].variables[*var_no].name
  1554. ),
  1555. );
  1556. } else {
  1557. labels.insert(1, ns.constants[*var_no].name.to_string());
  1558. }
  1559. self.add_node(
  1560. Node::new("constant", labels),
  1561. Some(parent),
  1562. Some(parent_rel),
  1563. );
  1564. }
  1565. fn add_storage_variable(
  1566. &mut self,
  1567. loc: &Loc,
  1568. ty: &Type,
  1569. contract: &usize,
  1570. var_no: &usize,
  1571. parent: usize,
  1572. parent_rel: String,
  1573. ns: &Namespace,
  1574. ) {
  1575. let labels = vec![
  1576. String::from("storage variable"),
  1577. format!(
  1578. "{}.{}",
  1579. ns.contracts[*contract].name, ns.contracts[*contract].variables[*var_no].name
  1580. ),
  1581. ty.to_string(ns),
  1582. ns.loc_to_string(loc),
  1583. ];
  1584. self.add_node(
  1585. Node::new("storage_var", labels),
  1586. Some(parent),
  1587. Some(parent_rel),
  1588. );
  1589. }
  1590. fn add_yul_statement(
  1591. &mut self,
  1592. statement: &YulStatement,
  1593. parent: usize,
  1594. parent_rel: String,
  1595. symtable: &Symtable,
  1596. ns: &Namespace,
  1597. ) -> usize {
  1598. match statement {
  1599. YulStatement::FunctionCall(loc, _, func_no, args) => {
  1600. self.add_yul_function_call(loc, func_no, args, parent, parent_rel, symtable, ns)
  1601. }
  1602. YulStatement::BuiltInCall(loc, _, builtin_ty, args) => {
  1603. self.add_yul_builtin_call(loc, builtin_ty, args, parent, parent_rel, symtable, ns)
  1604. }
  1605. YulStatement::Block(block) => {
  1606. self.add_yul_block(block, parent, parent_rel, symtable, ns)
  1607. }
  1608. YulStatement::VariableDeclaration(loc, _, declared_vars, initializer) => {
  1609. let labels = vec![
  1610. "yul variable declaration".to_string(),
  1611. ns.loc_to_string(loc),
  1612. ];
  1613. let node = self.add_node(
  1614. Node::new("yul_var_decl", labels),
  1615. Some(parent),
  1616. Some(parent_rel),
  1617. );
  1618. for (decl_no, item) in declared_vars.iter().enumerate() {
  1619. let var = &symtable.vars[&item.0];
  1620. self.add_node(
  1621. Node::new(
  1622. "var_decl_item",
  1623. vec![
  1624. format!(
  1625. "yul variable declaration {} {}",
  1626. var.ty.to_string(ns),
  1627. var.id.name
  1628. ),
  1629. ns.loc_to_string(&var.id.loc),
  1630. ],
  1631. ),
  1632. Some(node),
  1633. Some(format!("decl item #{}", decl_no)),
  1634. );
  1635. }
  1636. if let Some(init) = initializer {
  1637. self.add_yul_expression(init, symtable, ns, node, "init".to_string());
  1638. }
  1639. node
  1640. }
  1641. YulStatement::Assignment(loc, _, lhs, rhs) => {
  1642. let labels = vec!["yul assignment".to_string(), ns.loc_to_string(loc)];
  1643. let node = self.add_node(
  1644. Node::new("yul_assignment", labels),
  1645. Some(parent),
  1646. Some(parent_rel),
  1647. );
  1648. for (item_no, item) in lhs.iter().enumerate() {
  1649. self.add_yul_expression(item, symtable, ns, node, format!("rhs #{}", item_no));
  1650. }
  1651. self.add_yul_expression(rhs, symtable, ns, node, "lhs".to_string());
  1652. node
  1653. }
  1654. YulStatement::IfBlock(loc, _, condition, block) => {
  1655. let labels = vec!["yul if".to_string(), ns.loc_to_string(loc)];
  1656. let node = self.add_node(Node::new("if", labels), Some(parent), Some(parent_rel));
  1657. self.add_yul_expression(condition, symtable, ns, node, "cond".to_string());
  1658. self.add_yul_block(block, node, "if-block".to_string(), symtable, ns);
  1659. node
  1660. }
  1661. YulStatement::Switch {
  1662. loc,
  1663. condition,
  1664. cases,
  1665. default,
  1666. ..
  1667. } => {
  1668. let labels = vec!["yul switch".to_string(), ns.loc_to_string(loc)];
  1669. let node =
  1670. self.add_node(Node::new("switch", labels), Some(parent), Some(parent_rel));
  1671. self.add_yul_expression(condition, symtable, ns, node, "cond".to_string());
  1672. for (item_no, item) in cases.iter().enumerate() {
  1673. let case_block = self.add_node(
  1674. Node::new(
  1675. "case",
  1676. vec!["yul switch case".to_string(), ns.loc_to_string(&item.loc)],
  1677. ),
  1678. Some(node),
  1679. Some(format!("case #{}", item_no)),
  1680. );
  1681. self.add_yul_expression(
  1682. &item.condition,
  1683. symtable,
  1684. ns,
  1685. case_block,
  1686. "case-condition".to_string(),
  1687. );
  1688. self.add_yul_block(
  1689. &item.block,
  1690. case_block,
  1691. "case block".to_string(),
  1692. symtable,
  1693. ns,
  1694. );
  1695. }
  1696. if let Some(default_block) = default {
  1697. let default_node = self.add_node(
  1698. Node::new(
  1699. "default",
  1700. vec![
  1701. "yul switch default".to_string(),
  1702. ns.loc_to_string(&default_block.loc),
  1703. ],
  1704. ),
  1705. Some(node),
  1706. Some("default".to_string()),
  1707. );
  1708. self.add_yul_block(
  1709. default_block,
  1710. default_node,
  1711. "default block".to_string(),
  1712. symtable,
  1713. ns,
  1714. );
  1715. }
  1716. node
  1717. }
  1718. YulStatement::For {
  1719. loc,
  1720. init_block,
  1721. condition,
  1722. post_block,
  1723. execution_block,
  1724. ..
  1725. } => {
  1726. let labels = vec!["yul for".to_string(), ns.loc_to_string(loc)];
  1727. let node = self.add_node(Node::new("for", labels), Some(parent), Some(parent_rel));
  1728. self.add_yul_block(init_block, node, "init block".to_string(), symtable, ns);
  1729. self.add_yul_expression(condition, symtable, ns, node, "for condition".to_string());
  1730. self.add_yul_block(post_block, node, "post block".to_string(), symtable, ns);
  1731. self.add_yul_block(
  1732. execution_block,
  1733. node,
  1734. "execution block".to_string(),
  1735. symtable,
  1736. ns,
  1737. );
  1738. node
  1739. }
  1740. YulStatement::Leave(loc, _) => {
  1741. let labels = vec!["leave".to_string(), ns.loc_to_string(loc)];
  1742. self.add_node(Node::new("leave", labels), Some(parent), Some(parent_rel))
  1743. }
  1744. YulStatement::Break(loc, _) => {
  1745. let labels = vec!["break".to_string(), ns.loc_to_string(loc)];
  1746. self.add_node(Node::new("break", labels), Some(parent), Some(parent_rel))
  1747. }
  1748. YulStatement::Continue(loc, _) => {
  1749. let labels = vec!["continue".to_string(), ns.loc_to_string(loc)];
  1750. self.add_node(
  1751. Node::new("continue", labels),
  1752. Some(parent),
  1753. Some(parent_rel),
  1754. )
  1755. }
  1756. }
  1757. }
  1758. fn add_yul_block(
  1759. &mut self,
  1760. block: &YulBlock,
  1761. mut parent: usize,
  1762. parent_rel: String,
  1763. symtable: &Symtable,
  1764. ns: &Namespace,
  1765. ) -> usize {
  1766. let label = vec!["assembly block".to_string(), ns.loc_to_string(&block.loc)];
  1767. let node = self.add_node(
  1768. Node::new("assembly_block", label),
  1769. Some(parent),
  1770. Some(parent_rel),
  1771. );
  1772. parent = node;
  1773. for (statement_no, child_statement) in block.body.iter().enumerate() {
  1774. parent = self.add_yul_statement(
  1775. child_statement,
  1776. parent,
  1777. format!("statement #{}", statement_no),
  1778. symtable,
  1779. ns,
  1780. );
  1781. }
  1782. node
  1783. }
  1784. fn add_yul_function_call(
  1785. &mut self,
  1786. loc: &Loc,
  1787. func_no: &usize,
  1788. args: &[YulExpression],
  1789. parent: usize,
  1790. parent_rel: String,
  1791. symtable: &Symtable,
  1792. ns: &Namespace,
  1793. ) -> usize {
  1794. let labels = vec![
  1795. format!("yul function call '{}'", ns.yul_functions[*func_no].name),
  1796. ns.loc_to_string(loc),
  1797. ];
  1798. let node = self.add_node(
  1799. Node::new("yul_function_call", labels),
  1800. Some(parent),
  1801. Some(parent_rel),
  1802. );
  1803. for (arg_no, arg) in args.iter().enumerate() {
  1804. self.add_yul_expression(arg, symtable, ns, node, format!("arg #{}", arg_no));
  1805. }
  1806. node
  1807. }
  1808. fn add_yul_builtin_call(
  1809. &mut self,
  1810. loc: &Loc,
  1811. builtin_ty: &YulBuiltInFunction,
  1812. args: &[YulExpression],
  1813. parent: usize,
  1814. parent_rel: String,
  1815. symtable: &Symtable,
  1816. ns: &Namespace,
  1817. ) -> usize {
  1818. let labels = vec![
  1819. format!("yul builtin call '{}'", builtin_ty.to_string()),
  1820. ns.loc_to_string(loc),
  1821. ];
  1822. let node = self.add_node(
  1823. Node::new("yul_builtin_call", labels),
  1824. Some(parent),
  1825. Some(parent_rel),
  1826. );
  1827. for (arg_no, arg) in args.iter().enumerate() {
  1828. self.add_yul_expression(arg, symtable, ns, node, format!("arg #{}", arg_no));
  1829. }
  1830. node
  1831. }
  1832. }
  1833. impl Namespace {
  1834. pub fn dotgraphviz(&self) -> String {
  1835. let mut dot = Dot {
  1836. filename: format!("{}", self.files[self.top_file_no()].path.display()),
  1837. nodes: Vec::new(),
  1838. edges: Vec::new(),
  1839. };
  1840. // enums
  1841. if !self.enums.is_empty() {
  1842. let enums = dot.add_node(Node::new("enums", Vec::new()), None, None);
  1843. for decl in &self.enums {
  1844. let mut labels = vec![String::new(); decl.values.len()];
  1845. for (name, (_, pos)) in &decl.values {
  1846. labels[*pos] = format!("value: {}", name);
  1847. }
  1848. labels.insert(0, self.loc_to_string(&decl.loc));
  1849. if let Some(contract) = &decl.contract {
  1850. labels.insert(0, format!("contract: {}", contract));
  1851. }
  1852. labels.insert(0, format!("name: {}", decl.name));
  1853. let e = Node::new(&decl.name, labels);
  1854. let node = dot.add_node(e, Some(enums), None);
  1855. dot.add_tags(&decl.tags, node);
  1856. }
  1857. }
  1858. // structs
  1859. if !self.structs.is_empty() {
  1860. let structs = dot.add_node(Node::new("structs", Vec::new()), None, None);
  1861. for decl in &self.structs {
  1862. if let pt::Loc::File(..) = &decl.loc {
  1863. let mut labels =
  1864. vec![format!("name:{}", decl.name), self.loc_to_string(&decl.loc)];
  1865. if let Some(contract) = &decl.contract {
  1866. labels.insert(1, format!("contract: {}", contract));
  1867. }
  1868. for field in &decl.fields {
  1869. labels.push(format!(
  1870. "field name:{} ty:{}",
  1871. field.name_as_str(),
  1872. field.ty.to_string(self)
  1873. ));
  1874. }
  1875. let e = Node::new(&decl.name, labels);
  1876. let node = dot.add_node(e, Some(structs), None);
  1877. dot.add_tags(&decl.tags, node);
  1878. }
  1879. }
  1880. }
  1881. // events
  1882. if !self.events.is_empty() {
  1883. let events = dot.add_node(Node::new("events", Vec::new()), None, None);
  1884. for decl in &self.events {
  1885. let mut labels = vec![format!("name:{}", decl.name), self.loc_to_string(&decl.loc)];
  1886. if let Some(contract) = &decl.contract {
  1887. labels.insert(1, format!("contract: {}", contract));
  1888. }
  1889. if decl.anonymous {
  1890. labels.push(String::from("anonymous"));
  1891. }
  1892. for field in &decl.fields {
  1893. labels.push(format!(
  1894. "field name:{} ty:{} indexed:{}",
  1895. field.name_as_str(),
  1896. field.ty.to_string(self),
  1897. if field.indexed { "yes" } else { "no" }
  1898. ));
  1899. }
  1900. let e = Node::new(&decl.name, labels);
  1901. let node = dot.add_node(e, Some(events), None);
  1902. dot.add_tags(&decl.tags, node);
  1903. }
  1904. }
  1905. // user types
  1906. if !self.user_types.is_empty() {
  1907. let types = dot.add_node(Node::new("types", Vec::new()), None, None);
  1908. for decl in &self.user_types {
  1909. let mut labels = vec![
  1910. format!("name:{} ty:{}", decl.name, decl.ty.to_string(self)),
  1911. self.loc_to_string(&decl.loc),
  1912. ];
  1913. if let Some(contract) = &decl.contract {
  1914. labels.insert(1, format!("contract: {}", contract));
  1915. }
  1916. let e = Node::new(&decl.name, labels);
  1917. let node = dot.add_node(e, Some(types), None);
  1918. dot.add_tags(&decl.tags, node);
  1919. }
  1920. }
  1921. // free functions
  1922. if self
  1923. .functions
  1924. .iter()
  1925. .any(|func| func.contract_no.is_none() && func.loc != pt::Loc::Builtin)
  1926. {
  1927. let functions = dot.add_node(Node::new("free_functions", Vec::new()), None, None);
  1928. for func in &self.functions {
  1929. if func.contract_no.is_none() && func.loc != pt::Loc::Builtin {
  1930. dot.add_function(func, self, functions);
  1931. }
  1932. }
  1933. }
  1934. let contracts = dot.add_node(Node::new("contracts", Vec::new()), None, None);
  1935. // contracts
  1936. for c in &self.contracts {
  1937. let contract = dot.add_node(
  1938. Node::new(
  1939. "contract",
  1940. vec![format!("contract {}", c.name), self.loc_to_string(&c.loc)],
  1941. ),
  1942. Some(contracts),
  1943. None,
  1944. );
  1945. dot.add_tags(&c.tags, contract);
  1946. for base in &c.bases {
  1947. let node = dot.add_node(
  1948. Node::new(
  1949. "base",
  1950. vec![
  1951. format!("base {}", self.contracts[base.contract_no].name),
  1952. self.loc_to_string(&base.loc),
  1953. ],
  1954. ),
  1955. Some(contract),
  1956. Some(String::from("base")),
  1957. );
  1958. if let Some((_, args)) = &base.constructor {
  1959. for (no, arg) in args.iter().enumerate() {
  1960. dot.add_expression(arg, None, self, node, format!("arg #{}", no));
  1961. }
  1962. }
  1963. }
  1964. for var in &c.variables {
  1965. let mut labels = vec![
  1966. format!("variable {}", var.name),
  1967. format!("visibility {}", var.visibility),
  1968. self.loc_to_string(&var.loc),
  1969. ];
  1970. if var.immutable {
  1971. labels.insert(2, String::from("immutable"));
  1972. }
  1973. if var.constant {
  1974. labels.insert(2, String::from("constant"));
  1975. }
  1976. let node = dot.add_node(
  1977. Node::new("var", labels),
  1978. Some(contract),
  1979. Some(String::from("variable")),
  1980. );
  1981. if let Some(initializer) = &var.initializer {
  1982. dot.add_expression(initializer, None, self, node, String::from("initializer"));
  1983. }
  1984. dot.add_tags(&var.tags, node);
  1985. }
  1986. for using in &c.using {
  1987. let mut labels = match &using.list {
  1988. UsingList::Functions(functions) => functions
  1989. .iter()
  1990. .map(|func_no| {
  1991. let func = &self.functions[*func_no];
  1992. format!("function {} {}", func.name, self.loc_to_string(&func.loc))
  1993. })
  1994. .collect(),
  1995. UsingList::Library(library_no) => {
  1996. let library = &self.contracts[*library_no];
  1997. vec![format!("library {}", library.name)]
  1998. }
  1999. };
  2000. if let Some(ty) = &using.ty {
  2001. labels.insert(0, format!("using for {}", ty.to_string(self)));
  2002. }
  2003. dot.add_node(
  2004. Node::new("using", labels),
  2005. Some(contract),
  2006. Some(String::from("base")),
  2007. );
  2008. }
  2009. for func in &c.functions {
  2010. dot.add_function(&self.functions[*func], self, contract);
  2011. }
  2012. }
  2013. // diagnostics
  2014. if !self.diagnostics.is_empty() {
  2015. let diagnostics = dot.add_node(Node::new("diagnostics", Vec::new()), None, None);
  2016. for diag in self.diagnostics.iter() {
  2017. let mut labels = vec![diag.message.to_string(), format!("level {:?}", diag.level)];
  2018. labels.push(self.loc_to_string(&diag.loc));
  2019. let node = dot.add_node(
  2020. Node::new("diagnostic", labels),
  2021. Some(diagnostics),
  2022. Some(format!("{:?}", diag.level)),
  2023. );
  2024. for note in &diag.notes {
  2025. dot.add_node(
  2026. Node::new(
  2027. "note",
  2028. vec![note.message.to_string(), self.loc_to_string(&note.loc)],
  2029. ),
  2030. Some(node),
  2031. Some(String::from("note")),
  2032. );
  2033. }
  2034. }
  2035. }
  2036. dot.write()
  2037. }
  2038. }