* start to gut and seperate the kcl lint from execute * fix type signature * re-add old codepath when not wasm * also lint in the mock * fix syntax * fix message
This commit is contained in:
@ -786,7 +786,7 @@ test('if you write invalid kcl you get inlined errors', async ({ page }) => {
|
||||
|
||||
// error text on hover
|
||||
await page.hover('.cm-lint-marker-error')
|
||||
await expect(page.getByText('syntax: Unexpected token')).toBeVisible()
|
||||
await expect(page.getByText('Unexpected token')).toBeVisible()
|
||||
|
||||
// select the line that's causing the error and delete it
|
||||
await page.getByText('$ error').click()
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { executeAst } from 'useStore'
|
||||
import { executeAst, lintAst } from 'useStore'
|
||||
import { Selections } from 'lib/selections'
|
||||
import { KCLError, kclErrorsToDiagnostics } from './errors'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
@ -211,6 +211,9 @@ export class KclManager {
|
||||
ast,
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
})
|
||||
|
||||
editorManager.addDiagnostics(await lintAst({ ast: ast }))
|
||||
|
||||
sceneInfra.modelingSend({ type: 'code edit during sketch' })
|
||||
defaultSelectionFilter(programMemory, this.engineCommandManager)
|
||||
|
||||
@ -261,7 +264,10 @@ export class KclManager {
|
||||
return
|
||||
}
|
||||
const newAst = this.safeParse(newCode)
|
||||
if (!newAst) return
|
||||
if (!newAst) {
|
||||
this.clearAst()
|
||||
return
|
||||
}
|
||||
codeManager.updateCodeEditor(newCode)
|
||||
// Write the file to disk.
|
||||
await codeManager.writeToFile()
|
||||
@ -278,6 +284,9 @@ export class KclManager {
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
useFakeExecutor: true,
|
||||
})
|
||||
|
||||
editorManager.addDiagnostics(await lintAst({ ast: ast }))
|
||||
|
||||
this._logs = logs
|
||||
this._kclErrors = errors
|
||||
this._programMemory = programMemory
|
||||
|
@ -2,6 +2,7 @@ import init, {
|
||||
parse_wasm,
|
||||
recast_wasm,
|
||||
execute_wasm,
|
||||
kcl_lint,
|
||||
lexer_wasm,
|
||||
modify_ast_for_sketch_wasm,
|
||||
is_points_ccw,
|
||||
@ -20,6 +21,7 @@ import { KCLError } from './errors'
|
||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||
import { EngineCommandManager } from './std/engineConnection'
|
||||
import { ProgramReturn } from '../wasm-lib/kcl/bindings/ProgramReturn'
|
||||
import { Discovered } from '../wasm-lib/kcl/bindings/Discovered'
|
||||
import { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
||||
import type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||
import type { Token } from '../wasm-lib/kcl/bindings/Token'
|
||||
@ -205,6 +207,17 @@ export const _executor = async (
|
||||
}
|
||||
}
|
||||
|
||||
export const kclLint = async (ast: Program): Promise<Array<Discovered>> => {
|
||||
try {
|
||||
const discovered_findings: Array<Discovered> = await kcl_lint(
|
||||
JSON.stringify(ast)
|
||||
)
|
||||
return discovered_findings
|
||||
} catch (e: any) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export const recast = (ast: Program): string | Error => {
|
||||
return recast_wasm(JSON.stringify(ast))
|
||||
}
|
||||
|
@ -5,11 +5,13 @@ import {
|
||||
_executor,
|
||||
ProgramMemory,
|
||||
programMemoryInit,
|
||||
kclLint,
|
||||
} from './lang/wasm'
|
||||
import { enginelessExecutor } from './lib/testHelpers'
|
||||
import { EngineCommandManager } from './lang/std/engineConnection'
|
||||
import { KCLError } from './lang/errors'
|
||||
import { SidebarType } from 'components/ModelingSidebar/ModelingPanes'
|
||||
import { Diagnostic } from '@codemirror/lint'
|
||||
|
||||
export type ToolTip =
|
||||
| 'lineTo'
|
||||
@ -187,3 +189,24 @@ export async function executeAst({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function lintAst({
|
||||
ast,
|
||||
}: {
|
||||
ast: Program
|
||||
}): Promise<Array<Diagnostic>> {
|
||||
try {
|
||||
const discovered_findings = await kclLint(ast)
|
||||
return discovered_findings.map((lint) => {
|
||||
return {
|
||||
message: lint.finding.title,
|
||||
severity: 'info',
|
||||
from: lint.pos[0],
|
||||
to: lint.pos[1],
|
||||
}
|
||||
})
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||
|
||||
use crate::{executor::SourceRange, lint::Node, lsp::IntoDiagnostic};
|
||||
@ -22,8 +24,10 @@ where
|
||||
}
|
||||
|
||||
/// Specific discovered lint rule Violation of a particular Finding.
|
||||
#[derive(Clone, Debug)]
|
||||
#[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,
|
||||
@ -83,8 +87,10 @@ impl IntoDiagnostic for Discovered {
|
||||
}
|
||||
|
||||
/// Abstract lint problem type.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[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,
|
||||
|
@ -37,11 +37,13 @@ use super::backend::{InnerHandle, UpdateHandle};
|
||||
use crate::{
|
||||
ast::types::VariableKind,
|
||||
executor::SourceRange,
|
||||
lint::checks,
|
||||
lsp::{backend::Backend as _, safemap::SafeMap, util::IntoDiagnostic},
|
||||
parser::PIPE_OPERATOR,
|
||||
};
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::lint::checks;
|
||||
|
||||
/// A subcommand for running the server.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "cli", derive(Parser))]
|
||||
@ -256,12 +258,14 @@ impl crate::lsp::backend::Backend for Backend {
|
||||
// This function automatically executes if we should & updates the diagnostics if we got
|
||||
// errors.
|
||||
if self.execute(¶ms, ast.clone()).await.is_err() {
|
||||
// if there was an issue, let's bail and avoid trying to lint.
|
||||
return;
|
||||
}
|
||||
|
||||
for discovered_finding in ast.lint(checks::lint_variables).into_iter().flatten() {
|
||||
self.add_to_diagnostics(¶ms, discovered_finding).await;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
for discovered_finding in ast.lint(checks::lint_variables).into_iter().flatten() {
|
||||
self.add_to_diagnostics(¶ms, discovered_finding).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use std::{
|
||||
|
||||
use futures::stream::TryStreamExt;
|
||||
use gloo_utils::format::JsValueSerdeExt;
|
||||
use kcl_lib::{coredump::CoreDump, engine::EngineManager, executor::ExecutorSettings};
|
||||
use kcl_lib::{coredump::CoreDump, engine::EngineManager, executor::ExecutorSettings, lint::checks};
|
||||
use tower_lsp::{LspService, Server};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@ -59,6 +59,20 @@ pub async fn execute_wasm(
|
||||
JsValue::from_serde(&memory).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
// wasm_bindgen wrapper for execute
|
||||
#[wasm_bindgen]
|
||||
pub async fn kcl_lint(program_str: &str) -> Result<JsValue, String> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
|
||||
let mut findings = vec![];
|
||||
for discovered_finding in program.lint(checks::lint_variables).into_iter().flatten() {
|
||||
findings.push(discovered_finding);
|
||||
}
|
||||
|
||||
Ok(JsValue::from_serde(&findings).map_err(|e| e.to_string())?)
|
||||
}
|
||||
|
||||
// wasm_bindgen wrapper for creating default planes
|
||||
#[wasm_bindgen]
|
||||
pub async fn make_default_planes(
|
||||
|
Reference in New Issue
Block a user