1use crate::Dumpable;
2use crate::{color, opts::Format, safeprintln, Item};
3use line_span::LineSpans;
4use owo_colors::OwoColorize;
5use std::{collections::BTreeMap, ops::Range};
6
7pub struct Mir;
8
9impl Dumpable for Mir {
10 type Line<'a> = &'a str;
11
12 fn find_items(lines: &[&str]) -> BTreeMap<Item, Range<usize>> {
13 let mut res = BTreeMap::new();
14 let mut current_item = None::<Item>;
15 let mut block_start = None;
16
17 for (ix, &line) in lines.iter().enumerate() {
18 if line.starts_with("//") {
19 if block_start.is_none() {
20 block_start = Some(ix);
21 }
22 } else if line == "}" {
23 if let Some(mut cur) = current_item.take() {
24 #[allow(clippy::range_plus_one)]
26 let range = cur.len..ix + 1;
27 cur.len = range.len();
28 res.insert(cur, range);
29 }
30 } else if !(line.starts_with(' ') || line.is_empty()) && current_item.is_none() {
31 let start = block_start.take().unwrap_or(ix);
32 let mut name = line;
33 'outer: loop {
34 for suffix in [" {", " =", " -> ()"] {
35 if let Some(rest) = name.strip_suffix(suffix) {
36 name = rest;
37 continue 'outer;
38 }
39 }
40 break;
41 }
42 current_item = Some(Item {
43 mangled_name: name.to_owned(),
44 name: name.to_owned(),
45 hashed: name.to_owned(),
46 index: res.len(),
47 len: start,
48 non_blank_len: 0,
49 });
50 }
51 }
52
53 res
54 }
55
56 fn dump_range(&self, _fmt: &Format, strings: &[&str]) -> anyhow::Result<()> {
57 for line in strings {
58 if let Some(ix) = line.rfind("//") {
59 safeprintln!("{}{}", &line[..ix], color!(&line[ix..], OwoColorize::cyan));
60 } else {
61 safeprintln!("{line}");
62 }
63 }
64 Ok(())
65 }
66
67 fn split_lines(contents: &str) -> anyhow::Result<Vec<&str>> {
68 Ok(contents
69 .line_spans()
70 .map(|s| s.as_str())
71 .collect::<Vec<_>>())
72 }
73}