Skip to main content

cargo_show_asm/
mir.rs

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                    // go home clippy, you're drunk
25                    #[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}