From 52d7097340bc2f4acb37d9587695e17a7a550b01 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 14 Oct 2024 21:21:17 -0400 Subject: [PATCH] fix: Issues with `compile_flags.txt` (#149) * fix: Handle compiler error messages with column data fix: Pass file path as argument when generating diagnostics with compile_flags.txt * fix: Allow server to produce diagnostics when using an empty `compile_flags.txt` file --- src/handle.rs | 9 +++++++-- src/lsp.rs | 54 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/handle.rs b/src/handle.rs index 0597ba36..17334413 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -344,7 +344,7 @@ pub fn handle_diagnostics( let mut diagnostics: Vec = Vec::new(); for entry in source_entries { has_entries = true; - apply_compile_cmd(cfg, &mut diagnostics, entry); + apply_compile_cmd(cfg, &mut diagnostics, uri, entry); } // If no user-provided entries corresponded to the file, just try out @@ -355,7 +355,12 @@ pub fn handle_diagnostics( "No applicable user-provided commands for {}. Applying default compile command", uri.path().as_str() ); - apply_compile_cmd(cfg, &mut diagnostics, &get_default_compile_cmd(uri, cfg)); + apply_compile_cmd( + cfg, + &mut diagnostics, + uri, + &get_default_compile_cmd(uri, cfg), + ); } let params = PublishDiagnosticsParams { diff --git a/src/lsp.rs b/src/lsp.rs index 49a9fc06..6737b3f1 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -358,6 +358,7 @@ pub fn get_default_compile_cmd(uri: &Uri, cfg: &Config) -> CompileCommand { pub fn apply_compile_cmd( cfg: &Config, diagnostics: &mut Vec, + uri: &Uri, compile_cmd: &CompileCommand, ) { // TODO: Consolidate this logic, a little tricky because we need to capture @@ -365,10 +366,6 @@ pub fn apply_compile_cmd( if let Some(ref args) = compile_cmd.arguments { match args { CompileArgs::Flags(flags) => { - if flags.is_empty() { - return; - } - let compilers = if let Some(ref compiler) = cfg.opts.compiler { // If the user specified a compiler in their config, use it vec![compiler.as_str()] @@ -378,7 +375,11 @@ pub fn apply_compile_cmd( }; for compiler in compilers { - match Command::new(compiler).args(flags).output() { + match Command::new(compiler) // default or user-supplied compiler + .args(flags) // user supplied args + .arg(uri.path().as_str()) // the source file in question + .output() + { Ok(result) => { if let Ok(output_str) = String::from_utf8(result.stderr) { get_diagnostics(diagnostics, &output_str); @@ -435,12 +436,49 @@ pub fn apply_compile_cmd( /// /// # Panics fn get_diagnostics(diagnostics: &mut Vec, tool_output: &str) { - static DIAG_REG: Lazy = Lazy::new(|| Regex::new(r"^.*:(\d+):\s+(.*)$").unwrap()); + static DIAG_REG_LINE_COLUMN: Lazy = + Lazy::new(|| Regex::new(r"^.*:(\d+):(\d+):\s+(.*)$").unwrap()); + static DIAG_REG_LINE_ONLY: Lazy = + Lazy::new(|| Regex::new(r"^.*:(\d+):\s+(.*)$").unwrap()); + // TODO: Consolidate/ clean this up...regexes are hard for line in tool_output.lines() { - if let Some(caps) = DIAG_REG.captures(line) { + // first check if we have an error message of the form: + // ::: + if let Some(caps) = DIAG_REG_LINE_COLUMN.captures(line) { + // the entire capture is always at the 0th index, + // then we have 3 more explicit capture groups + if caps.len() == 4 { + let Ok(line_number) = caps[1].parse::() else { + continue; + }; + let Ok(column_number) = caps[2].parse::() else { + continue; + }; + let err_msg = &caps[3]; + diagnostics.push(Diagnostic::new_simple( + Range { + start: Position { + line: line_number - 1, + character: column_number, + }, + end: Position { + line: line_number - 1, + character: column_number, + }, + }, + String::from(err_msg), + )); + continue; + } + } + // if the above check for lines *and* columns didn't match, see if we + // have an error message of the form: + // :: + if let Some(caps) = DIAG_REG_LINE_ONLY.captures(line) { if caps.len() < 3 { - // the entire capture is always at the 0th index + // the entire capture is always at the 0th index, + // then we have 2 more explicit capture groups continue; } let Ok(line_number) = caps[1].parse::() else {