ability to set suggestions on lints (#6535)
* fix the lint tests which were not compiling Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * apply sugggestions for offsetplanes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * diagnostics and suggestions for offset planes Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -3,7 +3,7 @@ use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
|
||||
use crate::{lsp::IntoDiagnostic, walk::Node, SourceRange};
|
||||
use crate::{errors::Suggestion, lsp::IntoDiagnostic, walk::Node, SourceRange};
|
||||
|
||||
/// Check the provided AST for any found rule violations.
|
||||
///
|
||||
@ -40,6 +40,22 @@ pub struct Discovered {
|
||||
|
||||
/// Is this discovered issue overridden by the programmer?
|
||||
pub overridden: bool,
|
||||
|
||||
/// Suggestion to fix the issue.
|
||||
pub suggestion: Option<Suggestion>,
|
||||
}
|
||||
|
||||
impl Discovered {
|
||||
#[cfg(test)]
|
||||
pub fn apply_suggestion(&self, src: &str) -> Option<String> {
|
||||
let suggestion = self.suggestion.as_ref()?;
|
||||
Some(format!(
|
||||
"{}{}{}",
|
||||
&src[0..suggestion.source_range.start()],
|
||||
suggestion.insert,
|
||||
&src[suggestion.source_range.end()..]
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
@ -80,6 +96,7 @@ impl IntoDiagnostic for &Discovered {
|
||||
fn to_lsp_diagnostics(&self, code: &str) -> Vec<Diagnostic> {
|
||||
let message = self.finding.title.to_owned();
|
||||
let source_range = self.pos;
|
||||
let edit = self.suggestion.as_ref().map(|s| s.to_lsp_edit(code));
|
||||
|
||||
vec![Diagnostic {
|
||||
range: source_range.to_lsp_range(code),
|
||||
@ -91,7 +108,7 @@ impl IntoDiagnostic for &Discovered {
|
||||
message,
|
||||
related_information: None,
|
||||
tags: None,
|
||||
data: None,
|
||||
data: edit.map(|e| serde_json::to_value(e).unwrap()),
|
||||
}]
|
||||
}
|
||||
|
||||
@ -121,12 +138,13 @@ pub struct Finding {
|
||||
|
||||
impl Finding {
|
||||
/// Create a new Discovered finding at the specific Position.
|
||||
pub fn at(&self, description: String, pos: SourceRange) -> Discovered {
|
||||
pub fn at(&self, description: String, pos: SourceRange, suggestion: Option<Suggestion>) -> Discovered {
|
||||
Discovered {
|
||||
description,
|
||||
finding: self.clone(),
|
||||
pos,
|
||||
overridden: false,
|
||||
suggestion,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,7 +200,11 @@ mod test {
|
||||
|
||||
macro_rules! assert_no_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
let prog = $crate::parsing::top_level_parse($kcl).unwrap();
|
||||
let prog = $crate::Program::parse_no_errs($kcl).unwrap();
|
||||
|
||||
// Ensure the code still works.
|
||||
$crate::execution::parse_execute($kcl).await.unwrap();
|
||||
|
||||
for discovered_finding in prog.lint($check).unwrap() {
|
||||
if discovered_finding.finding == $finding {
|
||||
assert!(false, "Finding {:?} was emitted", $finding.code);
|
||||
@ -192,11 +214,28 @@ mod test {
|
||||
}
|
||||
|
||||
macro_rules! assert_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
let prog = $crate::parsing::top_level_parse($kcl).unwrap();
|
||||
( $check:expr, $finding:expr, $kcl:expr, $output:expr, $suggestion:expr ) => {
|
||||
let prog = $crate::Program::parse_no_errs($kcl).unwrap();
|
||||
|
||||
// Ensure the code still works.
|
||||
$crate::execution::parse_execute($kcl).await.unwrap();
|
||||
|
||||
for discovered_finding in prog.lint($check).unwrap() {
|
||||
pretty_assertions::assert_eq!(discovered_finding.description, $output,);
|
||||
|
||||
if discovered_finding.finding == $finding {
|
||||
pretty_assertions::assert_eq!(
|
||||
discovered_finding.suggestion.clone().map(|s| s.insert),
|
||||
$suggestion,
|
||||
);
|
||||
|
||||
if discovered_finding.suggestion.is_some() {
|
||||
// Apply the suggestion to the source code.
|
||||
let code = discovered_finding.apply_suggestion($kcl).unwrap();
|
||||
|
||||
// Ensure the code still works.
|
||||
$crate::execution::parse_execute(&code).await.unwrap();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -205,18 +244,18 @@ mod test {
|
||||
}
|
||||
|
||||
macro_rules! test_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
$crate::lint::rule::assert_finding!($check, $finding, $kcl);
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr, $output:expr, $suggestion:expr ) => {
|
||||
#[tokio::test]
|
||||
async fn $name() {
|
||||
$crate::lint::rule::assert_finding!($check, $finding, $kcl, $output, $suggestion);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! test_no_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
#[tokio::test]
|
||||
async fn $name() {
|
||||
$crate::lint::rule::assert_no_finding!($check, $finding, $kcl);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user