完成 verilator 的诊断
This commit is contained in:
parent
f7caccc338
commit
ae083bdad4
@ -50,79 +50,6 @@ fn verilator_severity(severity: &str) -> Option<DiagnosticSeverity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// syntax checking using verilator --lint-only
|
|
||||||
fn verilator_syntax(
|
|
||||||
rope: &Rope,
|
|
||||||
file_path: PathBuf,
|
|
||||||
verilator_syntax_path: &str,
|
|
||||||
verilator_syntax_args: &[String],
|
|
||||||
) -> Option<Vec<Diagnostic>> {
|
|
||||||
let mut child = Command::new(verilator_syntax_path)
|
|
||||||
.stdin(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.args(verilator_syntax_args)
|
|
||||||
.arg(file_path.to_str()?)
|
|
||||||
.spawn()
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
static RE: std::sync::OnceLock<Regex> = std::sync::OnceLock::new();
|
|
||||||
let re = RE.get_or_init(|| {
|
|
||||||
Regex::new(
|
|
||||||
r"%(?P<severity>Error|Warning)(-(?P<warning_type>[A-Z0-9_]+))?: (?P<filepath>[^:]+):(?P<line>\d+):((?P<col>\d+):)? ?(?P<message>.*)",
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
});
|
|
||||||
// write file to stdin, read output from stdout
|
|
||||||
rope.write_to(child.stdin.as_mut()?).ok()?;
|
|
||||||
let output = child.wait_with_output().ok()?;
|
|
||||||
if !output.status.success() {
|
|
||||||
let mut diags: Vec<Diagnostic> = Vec::new();
|
|
||||||
let raw_output = String::from_utf8(output.stderr).ok()?;
|
|
||||||
let filtered_output = raw_output
|
|
||||||
.lines()
|
|
||||||
.filter(|line| line.starts_with('%'))
|
|
||||||
.collect::<Vec<&str>>();
|
|
||||||
for error in filtered_output {
|
|
||||||
let caps = match re.captures(error) {
|
|
||||||
Some(caps) => caps,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
// check if diagnostic is for this file, since verilator can provide diagnostics for
|
|
||||||
// included files
|
|
||||||
if caps.name("filepath")?.as_str() != file_path.to_str().unwrap_or("") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let severity = verilator_severity(caps.name("severity")?.as_str());
|
|
||||||
let line: u32 = caps.name("line")?.as_str().to_string().parse().ok()?;
|
|
||||||
let col: u32 = caps.name("col").map_or("1", |m| m.as_str()).parse().ok()?;
|
|
||||||
let pos = Position::new(line - 1, col - 1);
|
|
||||||
let msg = match severity {
|
|
||||||
Some(DiagnosticSeverity::ERROR) => caps.name("message")?.as_str().to_string(),
|
|
||||||
Some(DiagnosticSeverity::WARNING) => format!(
|
|
||||||
"{}: {}",
|
|
||||||
caps.name("warning_type")?.as_str(),
|
|
||||||
caps.name("message")?.as_str()
|
|
||||||
),
|
|
||||||
_ => "".to_string(),
|
|
||||||
};
|
|
||||||
diags.push(Diagnostic::new(
|
|
||||||
Range::new(pos, pos),
|
|
||||||
severity,
|
|
||||||
None,
|
|
||||||
Some("verilator".to_string()),
|
|
||||||
msg,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Some(diags)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl AbstractLinterConfiguration for VerilatorConfiguration {
|
impl AbstractLinterConfiguration for VerilatorConfiguration {
|
||||||
fn new(language_id: &str, invoker: &str, args: Vec<String>) -> Self {
|
fn new(language_id: &str, invoker: &str, args: Vec<String>) -> Self {
|
||||||
@ -197,6 +124,8 @@ impl AbstractLinterConfiguration for VerilatorConfiguration {
|
|||||||
if captures.name("filepath")?.as_str().replace("\\", "/") != path_string {
|
if captures.name("filepath")?.as_str().replace("\\", "/") != path_string {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 对于 NOTFOUNDMODULE
|
||||||
|
|
||||||
let line: u32 = captures.name("line")?.as_str().to_string().parse().ok()?;
|
let line: u32 = captures.name("line")?.as_str().to_string().parse().ok()?;
|
||||||
let col: u32 = captures.name("col").map_or("1", |m| m.as_str()).parse().ok()?;
|
let col: u32 = captures.name("col").map_or("1", |m| m.as_str()).parse().ok()?;
|
||||||
@ -215,7 +144,7 @@ impl AbstractLinterConfiguration for VerilatorConfiguration {
|
|||||||
_ => "".to_string(),
|
_ => "".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = format!("{}\n\n---\n\n{}", message, error_tuple.1);
|
let message = format!("{}\n\n{}", message, error_tuple.1);
|
||||||
|
|
||||||
let diagnostic = Diagnostic {
|
let diagnostic = Diagnostic {
|
||||||
range: Range::new(pos, pos),
|
range: Range::new(pos, pos),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user