forked from Orchid/orchid
Massive improvements across the board. One day I'll adopt incremental commits.
56 lines
1.8 KiB
Rust
56 lines
1.8 KiB
Rust
use itertools::Itertools;
|
|
use orchidlang::pipeline::project::{ItemKind, ProjItem, ProjectMod};
|
|
use orchidlang::tree::{ModEntry, ModMember};
|
|
|
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
|
pub struct ProjPrintOpts {
|
|
pub width: u16,
|
|
pub hide_locations: bool,
|
|
}
|
|
|
|
fn indent(amount: u16) -> String { " ".repeat(amount.into()) }
|
|
|
|
pub fn print_proj_mod(module: &ProjectMod, lvl: u16, opts: ProjPrintOpts) -> String {
|
|
let mut acc = String::new();
|
|
let tab = indent(lvl);
|
|
for (key, ModEntry { member, x }) in &module.entries {
|
|
let mut line_acc = String::new();
|
|
for c in &x.comments {
|
|
line_acc += &format!("{tab}, --[|{}|]--\n", c);
|
|
}
|
|
if x.exported {
|
|
line_acc += &format!("{tab}export ");
|
|
} else {
|
|
line_acc += &tab
|
|
}
|
|
match member {
|
|
ModMember::Sub(module) => {
|
|
line_acc += &format!("module {key} {{\n");
|
|
line_acc += &print_proj_mod(module, lvl + 1, opts);
|
|
line_acc += &format!("{tab}}}");
|
|
},
|
|
ModMember::Item(ProjItem { kind: ItemKind::None }) => {
|
|
line_acc += &format!("keyword {key}");
|
|
},
|
|
ModMember::Item(ProjItem { kind: ItemKind::Alias(tgt) }) => {
|
|
line_acc += &format!("alias {key} => {tgt}");
|
|
},
|
|
ModMember::Item(ProjItem { kind: ItemKind::Const(val) }) => {
|
|
line_acc += &format!("const {key} := {val}");
|
|
},
|
|
}
|
|
if !x.locations.is_empty() && !opts.hide_locations {
|
|
let locs = x.locations.iter().map(|l| l.to_string()).join(", ");
|
|
let line_len = line_acc.split('\n').last().unwrap().len();
|
|
match usize::from(opts.width).checked_sub(locs.len() + line_len + 4) {
|
|
Some(padding) => line_acc += &" ".repeat(padding),
|
|
None => line_acc += &format!("\n{tab} @ "),
|
|
}
|
|
line_acc += &locs;
|
|
}
|
|
line_acc += "\n";
|
|
acc += &line_acc
|
|
}
|
|
acc
|
|
}
|