Skip to content

Commit

Permalink
fix: Issues with compile_flags.txt (bergercookie#149)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
WillLillis authored Oct 15, 2024
1 parent 228f054 commit 52d7097
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
9 changes: 7 additions & 2 deletions src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ pub fn handle_diagnostics(
let mut diagnostics: Vec<Diagnostic> = 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
Expand All @@ -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 {
Expand Down
54 changes: 46 additions & 8 deletions src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,17 +358,14 @@ pub fn get_default_compile_cmd(uri: &Uri, cfg: &Config) -> CompileCommand {
pub fn apply_compile_cmd(
cfg: &Config,
diagnostics: &mut Vec<Diagnostic>,
uri: &Uri,
compile_cmd: &CompileCommand,
) {
// TODO: Consolidate this logic, a little tricky because we need to capture
// compile_cmd.arguments by reference, but we get an owned Vec out of args_from_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()]
Expand All @@ -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);
Expand Down Expand Up @@ -435,12 +436,49 @@ pub fn apply_compile_cmd(
///
/// # Panics
fn get_diagnostics(diagnostics: &mut Vec<Diagnostic>, tool_output: &str) {
static DIAG_REG: Lazy<Regex> = Lazy::new(|| Regex::new(r"^.*:(\d+):\s+(.*)$").unwrap());
static DIAG_REG_LINE_COLUMN: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^.*:(\d+):(\d+):\s+(.*)$").unwrap());
static DIAG_REG_LINE_ONLY: Lazy<Regex> =
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:
// :<line>:<column>: <error message here>
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::<u32>() else {
continue;
};
let Ok(column_number) = caps[2].parse::<u32>() 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:
// :<line>: <error message here>
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::<u32>() else {
Expand Down

0 comments on commit 52d7097

Please sign in to comment.