1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* 1:1 */
use std::collections::HashMap;
/* 2:1 */
use std::env;
/* 3:1 */
use std::fs;
/* 4:1 */
use std::path::MAIN_SEPARATOR;
/* 5:1 */
use std::path::PathBuf;
/* 6:1 */
use std::process::Command;
/* 7:1 */
use std::process::Stdio;
/* 8:1 */
use cargo_metadata::CompilerMessage;
/* 9:1 */
use cargo_metadata::Message;
/* 10:1 */
use mist_parser::rev_mapper;
#[derive(Debug, Clone)]
/* 13:1 */
pub struct MistDiagnosticMessage {
/* 14:5 */ pub message: String,
/* 15:5 */ pub file_path: PathBuf,
/* 16:5 */ pub file_name: String,
/* 17:5 */ pub line: usize,
/* 18:5 */ pub column: usize,
}
#[derive(Debug, Clone)]
/* 22:1 */
pub enum MistDiagnostic {
/* 23:5 */ Error (MistDiagnosticMessage),
/* 24:5 */ Warning (MistDiagnosticMessage),
/* 25:5 */ Rust (CompilerMessage),
}
/* 28:1 */
pub fn build(mut args: Vec<String>, root: PathBuf) -> bool {
/* 29:5 */
args.remove(0);
/* 30:5 */
args.insert(1, "--message-format=json".to_string());
/* 32:5 */
let is_root = root==env::current_dir().expect("Failed getting env");
/* 34:5 */
let mut command = Command::new("cargo").args(args).stdout(Stdio::piped()).stderr(Stdio::inherit()).stdin(Stdio::inherit()).spawn().expect("Failed to run cargo");
/* 42:5 */
let mut reader = std::io::BufReader::new(command.stdout.take().expect("Failed to get reader"));
/* 44:5 */
let mut diagnostics = Vec::new();
/* 46:5 */
let mut mapping = HashMap::new();
/* 48:5 */
let mist_src = format!(".mist{MAIN_SEPARATOR}src");
/* 50:5 */
for message in cargo_metadata::Message::parse_stream(&mut reader){
/* 51:9 */
match message { /* 52:13 */
Ok (Message::CompilerMessage (msg,),) => {
/* 53:17 */
for span in &msg.message.spans{
/* 54:21 */
if span.is_primary {
/* 55:25 */
let rust_path = root.join(&span.file_name);
/* 57:25 */
let mist_file = span.file_name.replacen(&mist_src, "src", 1).trim_end_matches(".rs").to_string()+".mist";
/* 64:25 */
let mist_path = root.join(&mist_file);
/* 66:25 */
if !fs::exists(&mist_path).expect("Unable to check if mist file exists") {
/* 67:29 */
diagnostics.push(MistDiagnostic::Rust(msg));
/* 68:29 */
break
;
}
/* 71:25 */
let map = mapping.entry(rust_path.clone()).or_insert_with(|| {
/* 72:29 */
rev_mapper::get_mapping(&fs::read_to_string(rust_path).expect("Failed to read file for mapping"))
});
/* 78:25 */
let (_,rev_mapper::MistMap (line,column,),) = rev_mapper::find_mapping(&map, &rev_mapper::RustMap(span.line_end, span.column_start)).expect("Unable to find mapping");
/* 82:25 */
let mist_msg = MistDiagnosticMessage{message: format!("{}: {}",
msg.message.message,
span.label.clone().unwrap_or_default()),file_name: if is_root {
/* 89:33 */
mist_file
} else {
/* 91:33 */
mist_path.to_string_lossy().to_string()
},file_path: mist_path,line: line,column: column,};
/* 98:25 */
match msg.message.level { /* 99:29 */
cargo_metadata::diagnostic::DiagnosticLevel::Error => {
/* 100:33 */
diagnostics.push(MistDiagnostic::Error(mist_msg))
} /* 103:29 */
cargo_metadata::diagnostic::DiagnosticLevel::Warning => {
/* 104:33 */
diagnostics.push(MistDiagnostic::Warning(mist_msg))
} /* 107:29 */
_ => {
}
}
}
}
} /* 113:13 */
Ok (Message::BuildFinished (finish,),) => {
/* 114:17 */
print_diagnostics(&diagnostics);
/* 116:17 */
let mut raw_reader = reader.into_inner();
/* 117:17 */
let mut stdout = std::io::stdout();
/* 119:17 */
std::io::copy(&mut raw_reader, &mut stdout).map_err(|v| v.to_string()).expect("(Mist) Failed to copy IO");
/* 123:17 */
command.wait().unwrap();
/* 125:17 */
return finish.success;
} /* 128:13 */
Ok (Message::TextLine (text,),) => {println!("{text}");} /* 129:13 */
_ => {
}
}
}
/* 133:5 */
false
}/* 136:1 */
pub fn print_diagnostics(diagnostics: &Vec<MistDiagnostic>) -> () {
/* 137:5 */
let mut files = HashMap::new();
/* 139:5 */
for diag in diagnostics{
/* 140:9 */
match diag { /* 141:13 */
MistDiagnostic::Error (msg,) => {
/* 142:17 */
let line = get_line(&mut files, &msg);
/* 144:17 */
println!("\n{}:{}:{}\n \x1b[31mError\x1b[0m: {}\n\t{}",
msg.file_name,
msg.line,
msg.column,
msg.message,
line.unwrap_or_default(),)
} /* 154:13 */
MistDiagnostic::Warning (msg,) => {
/* 155:17 */
let line = get_line(&mut files, &msg);
/* 157:17 */
println!("\n{}:{}:{}\n \x1b[33mWarning\x1b[0m: {}\n\t{}",
msg.file_name,
msg.line,
msg.column,
msg.message,
line.unwrap_or_default(),)
} /* 167:13 */
MistDiagnostic::Rust (rs,) => {println!("{rs}")}
}
}
}/* 172:1 */
pub fn get_line(files: &mut HashMap<PathBuf, Vec<String>>, msg: &MistDiagnosticMessage) -> Option<String> {
/* 176:5 */
let src_path = msg.file_path.clone();
/* 178:5 */
let lines = files.entry(src_path.clone()).or_insert_with(|| {
/* 179:9 */
fs::read_to_string(src_path).expect("Unable to read mist file").lines().into_iter().map(String::from).collect()
});
/* 187:5 */
lines.get(msg.line-1).map(|v| v.trim().to_string())
}