Move the wasm lib, and cleanup rust directory and all references (#5585)
* git mv src/wasm-lib rust Signed-off-by: Jess Frazelle <github@jessfraz.com> * mv wasm-lib to workspace Signed-off-by: Jess Frazelle <github@jessfraz.com> * mv kcl-lib Signed-off-by: Jess Frazelle <github@jessfraz.com> * mv derive docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * resolve file paths Signed-off-by: Jess Frazelle <github@jessfraz.com> * clippy Signed-off-by: Jess Frazelle <github@jessfraz.com> * move more shit Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix more paths Signed-off-by: Jess Frazelle <github@jessfraz.com> * make yarn build:wasm work Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix scripts Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixups Signed-off-by: Jess Frazelle <github@jessfraz.com> * better references Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix cargo ci Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix reference Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix more ci Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * cargo sort Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix script Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix Signed-off-by: Jess Frazelle <github@jessfraz.com> * fmt Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix a dep Signed-off-by: Jess Frazelle <github@jessfraz.com> * sort Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove unused deps Signed-off-by: Jess Frazelle <github@jessfraz.com> * Revert "remove unused deps" This reverts commit fbabdb062e275fd5cbc1476f8480a1afee15d972. * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * deps; Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
229
rust/kcl-lib/src/lint/rule.rs
Normal file
229
rust/kcl-lib/src/lint/rule.rs
Normal file
@ -0,0 +1,229 @@
|
||||
use anyhow::Result;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
|
||||
use crate::{lsp::IntoDiagnostic, walk::Node, SourceRange};
|
||||
|
||||
/// Check the provided AST for any found rule violations.
|
||||
///
|
||||
/// The Rule trait is automatically implemented for a few other types,
|
||||
/// but it can also be manually implemented as required.
|
||||
pub trait Rule<'a> {
|
||||
/// Check the AST at this specific node for any Finding(s).
|
||||
fn check(&self, node: Node<'a>) -> Result<Vec<Discovered>>;
|
||||
}
|
||||
|
||||
impl<'a, FnT> Rule<'a> for FnT
|
||||
where
|
||||
FnT: Fn(Node<'a>) -> Result<Vec<Discovered>>,
|
||||
{
|
||||
fn check(&self, n: Node<'a>) -> Result<Vec<Discovered>> {
|
||||
self(n)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specific discovered lint rule Violation of a particular Finding.
|
||||
#[derive(Clone, Debug, ts_rs::TS, Serialize, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[cfg_attr(feature = "pyo3", pyo3::pyclass)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Discovered {
|
||||
/// Zoo Lint Finding information.
|
||||
pub finding: Finding,
|
||||
|
||||
/// Further information about the specific finding.
|
||||
pub description: String,
|
||||
|
||||
/// Source code location.
|
||||
pub pos: SourceRange,
|
||||
|
||||
/// Is this discovered issue overridden by the programmer?
|
||||
pub overridden: bool,
|
||||
}
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
#[pyo3::pymethods]
|
||||
impl Discovered {
|
||||
#[getter]
|
||||
pub fn finding(&self) -> Finding {
|
||||
self.finding.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn description(&self) -> String {
|
||||
self.description.clone()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn pos(&self) -> (usize, usize) {
|
||||
(self.pos.start(), self.pos.end())
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn overridden(&self) -> bool {
|
||||
self.overridden
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic for Discovered {
|
||||
fn to_lsp_diagnostics(&self, code: &str) -> Vec<Diagnostic> {
|
||||
(&self).to_lsp_diagnostics(code)
|
||||
}
|
||||
|
||||
fn severity(&self) -> DiagnosticSeverity {
|
||||
(&self).severity()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
vec![Diagnostic {
|
||||
range: source_range.to_lsp_range(code),
|
||||
severity: Some(self.severity()),
|
||||
code: None,
|
||||
// TODO: this is neat we can pass a URL to a help page here for this specific error.
|
||||
code_description: None,
|
||||
source: Some("lint".to_string()),
|
||||
message,
|
||||
related_information: None,
|
||||
tags: None,
|
||||
data: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn severity(&self) -> DiagnosticSeverity {
|
||||
DiagnosticSeverity::INFORMATION
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstract lint problem type.
|
||||
#[derive(Clone, Debug, PartialEq, ts_rs::TS, Serialize, JsonSchema)]
|
||||
#[ts(export)]
|
||||
#[cfg_attr(feature = "pyo3", pyo3::pyclass)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Finding {
|
||||
/// Unique identifier for this particular issue.
|
||||
pub code: &'static str,
|
||||
|
||||
/// Short one-line description of this issue.
|
||||
pub title: &'static str,
|
||||
|
||||
/// Long human-readable description of this issue.
|
||||
pub description: &'static str,
|
||||
|
||||
/// Is this discovered issue experimental?
|
||||
pub experimental: bool,
|
||||
}
|
||||
|
||||
impl Finding {
|
||||
/// Create a new Discovered finding at the specific Position.
|
||||
pub fn at(&self, description: String, pos: SourceRange) -> Discovered {
|
||||
Discovered {
|
||||
description,
|
||||
finding: self.clone(),
|
||||
pos,
|
||||
overridden: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
#[pyo3::pymethods]
|
||||
impl Finding {
|
||||
#[getter]
|
||||
pub fn code(&self) -> &'static str {
|
||||
self.code
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn title(&self) -> &'static str {
|
||||
self.title
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn description(&self) -> &'static str {
|
||||
self.description
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn experimental(&self) -> bool {
|
||||
self.experimental
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_finding {
|
||||
( $code:ident, $title:expr, $description:expr ) => {
|
||||
/// Generated Finding
|
||||
pub const $code: Finding = $crate::lint::rule::finding!($code, $title, $description);
|
||||
};
|
||||
}
|
||||
pub(crate) use def_finding;
|
||||
|
||||
macro_rules! finding {
|
||||
( $code:ident, $title:expr, $description:expr ) => {
|
||||
$crate::lint::rule::Finding {
|
||||
code: stringify!($code),
|
||||
title: $title,
|
||||
description: $description,
|
||||
experimental: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
pub(crate) use finding;
|
||||
#[cfg(test)]
|
||||
pub(crate) use test::{assert_finding, assert_no_finding, test_finding, test_no_finding};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
macro_rules! assert_no_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
let prog = $crate::parsing::top_level_parse($kcl).unwrap();
|
||||
for discovered_finding in prog.lint($check).unwrap() {
|
||||
if discovered_finding.finding == $finding {
|
||||
assert!(false, "Finding {:?} was emitted", $finding.code);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_finding {
|
||||
( $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
let prog = $crate::parsing::top_level_parse($kcl).unwrap();
|
||||
|
||||
for discovered_finding in prog.lint($check).unwrap() {
|
||||
if discovered_finding.finding == $finding {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert!(false, "Finding {:?} was not emitted", $finding.code);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! test_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
$crate::lint::rule::assert_finding!($check, $finding, $kcl);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! test_no_finding {
|
||||
( $name:ident, $check:expr, $finding:expr, $kcl:expr ) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
$crate::lint::rule::assert_no_finding!($check, $finding, $kcl);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use assert_finding;
|
||||
pub(crate) use assert_no_finding;
|
||||
pub(crate) use test_finding;
|
||||
pub(crate) use test_no_finding;
|
||||
}
|
Reference in New Issue
Block a user