Skip to content

Commit 73f065b

Browse files
authored
fix: account for Solc inexplicably not formatting the message (#85)
Apparently it's not just old solc versions, some errors just are not formatted on the latest versions too. Edit: if the file name does not end in .sol, the source locations are not formatted. Lol
1 parent 790e8e6 commit 73f065b

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

src/artifacts/error.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,6 @@ impl fmt::Display for Error {
128128
let mut short_msg = self.message.trim();
129129
let fmtd_msg = self.formatted_message.as_deref().unwrap_or("");
130130

131-
// Don't bother with old solc messages which have a different format
132-
if !Paint::is_enabled() || !fmtd_msg.contains(" | ") {
133-
return f.write_str(self.formatted_message.as_deref().unwrap_or(&self.message));
134-
}
135-
136131
if short_msg.is_empty() {
137132
// if the message is empty, try to extract the first line from the formatted message
138133
if let Some(first_line) = fmtd_msg.lines().next() {
@@ -151,8 +146,15 @@ impl fmt::Display for Error {
151146

152147
let mut lines = fmtd_msg.lines();
153148

154-
// skip the first line which contains the same message as the one we already printed
155-
let _ = lines.next();
149+
// skip the first line if it contains the same message as the one we just formatted,
150+
// unless it also contains a source location, in which case the entire error message is an
151+
// old style error message, like:
152+
// path/to/file:line:column: ErrorType: message
153+
if lines.clone().next().map_or(false, |l| {
154+
l.contains(short_msg) && l.bytes().filter(|b| *b == b':').count() < 3
155+
}) {
156+
let _ = lines.next();
157+
}
156158

157159
// format the main source location
158160
fmt_source_location(f, &mut lines)?;
@@ -225,9 +227,15 @@ fn styled<F>(f: &mut fmt::Formatter<'_>, style: Style, fun: F) -> fmt::Result
225227
where
226228
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
227229
{
228-
style.fmt_prefix(f)?;
230+
let enabled = Paint::is_enabled();
231+
if enabled {
232+
style.fmt_prefix(f)?;
233+
}
229234
fun(f)?;
230-
style.fmt_suffix(f)
235+
if enabled {
236+
style.fmt_suffix(f)?;
237+
}
238+
Ok(())
231239
}
232240

233241
/// Formats the diagnostic message.
@@ -389,7 +397,27 @@ mod tests {
389397
assert_eq!(errors.len(), 1);
390398
let s = errors[0].to_string();
391399
eprintln!("{s}");
392-
assert!(s.contains("test/Counter.t.sol:7:1"), "{s}");
393-
assert!(s.contains("ABI coder v2"), "{s}");
400+
assert!(s.contains("test/Counter.t.sol:7:1"), "\n{s}");
401+
assert!(s.contains("ABI coder v2"), "\n{s}");
402+
}
403+
404+
#[test]
405+
fn solc_not_formatting_the_message1() {
406+
let error = r#"{"component":"general","errorCode":"6553","formattedMessage":"SyntaxError: The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction.\n\n","message":"The msize instruction cannot be used when the Yul optimizer is activated because it can change its semantics. Either disable the Yul optimizer or do not use the instruction.","severity":"error","sourceLocation":{"end":173,"file":"","start":114},"type":"SyntaxError"}"#;
407+
let error = serde_json::from_str::<Error>(error).unwrap();
408+
let s = error.to_string();
409+
eprintln!("{s}");
410+
assert!(s.contains("Error (6553)"), "\n{s}");
411+
assert!(s.contains("The msize instruction cannot be used"), "\n{s}");
412+
}
413+
414+
#[test]
415+
fn solc_not_formatting_the_message2() {
416+
let error = r#"{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":104,"file":"","start":95},"type":"Warning"}"#;
417+
let error = serde_json::from_str::<Error>(error).unwrap();
418+
let s = error.to_string();
419+
eprintln!("{s}");
420+
assert!(s.contains("Warning (5667)"), "\n{s}");
421+
assert!(s.contains("Unused function parameter. Remove or comment out the variable name to silence this warning."), "\n{s}");
394422
}
395423
}

0 commit comments

Comments
 (0)