mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 14:52:01 +00:00
Web playground with WASM (#1279)
This commit is contained in:
parent
8c018e8261
commit
bdb1505262
31 changed files with 3104 additions and 402 deletions
141
src/lib_wasm.rs
Normal file
141
src/lib_wasm.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use std::path::Path;
|
||||
|
||||
use rustpython_ast::Location;
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::checks::CheckCode;
|
||||
use crate::directives;
|
||||
use crate::linter::check_path;
|
||||
use crate::rustpython_helpers::tokenize;
|
||||
use crate::settings::configuration::Configuration;
|
||||
use crate::settings::options::Options;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code_locator::SourceCodeLocator;
|
||||
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TYPES: &'static str = r#"
|
||||
export interface Check {
|
||||
code: string;
|
||||
message: string;
|
||||
location: {
|
||||
row: number;
|
||||
column: number;
|
||||
};
|
||||
end_location: {
|
||||
row: number;
|
||||
column: number;
|
||||
};
|
||||
};
|
||||
"#;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
struct Message {
|
||||
code: CheckCode,
|
||||
message: String,
|
||||
location: Location,
|
||||
end_location: Location,
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn run() {
|
||||
use log::Level;
|
||||
console_error_panic_hook::set_once();
|
||||
console_log::init_with_level(Level::Debug).expect("Initializing logger went wrong.");
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn check(contents: &str, options: JsValue) -> Result<JsValue, JsValue> {
|
||||
let options: Options = serde_wasm_bindgen::from_value(options).map_err(|e| e.to_string())?;
|
||||
let configuration =
|
||||
Configuration::from_options(options, Path::new(".")).map_err(|e| e.to_string())?;
|
||||
let settings =
|
||||
Settings::from_configuration(configuration, Path::new(".")).map_err(|e| e.to_string())?;
|
||||
|
||||
// Tokenize once.
|
||||
let tokens: Vec<LexResult> = tokenize(contents);
|
||||
|
||||
// Initialize the SourceCodeLocator (which computes offsets lazily).
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
|
||||
// Extract the `# noqa` and `# isort: skip` directives from the source.
|
||||
let directives = directives::extract_directives(&tokens, &locator, directives::Flags::empty());
|
||||
|
||||
// Generate checks.
|
||||
let checks = check_path(
|
||||
Path::new("<filename>"),
|
||||
None,
|
||||
contents,
|
||||
tokens,
|
||||
&locator,
|
||||
&directives,
|
||||
&settings,
|
||||
false.into(),
|
||||
flags::Noqa::Enabled,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
let messages: Vec<Message> = checks
|
||||
.into_iter()
|
||||
.map(|check| Message {
|
||||
code: check.kind.code().clone(),
|
||||
message: check.kind.body(),
|
||||
location: check.location,
|
||||
end_location: check.end_location,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(serde_wasm_bindgen::to_value(&messages)?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use js_sys;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
macro_rules! check {
|
||||
($source:expr, $config:expr, $expected:expr) => {{
|
||||
let foo = js_sys::JSON::parse($config).unwrap();
|
||||
match check($source, foo) {
|
||||
Ok(output) => {
|
||||
let result: Vec<Message> = serde_wasm_bindgen::from_value(output).unwrap();
|
||||
assert_eq!(result, $expected);
|
||||
}
|
||||
Err(e) => assert!(false, "{:#?}", e),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn empty_config() {
|
||||
check!(
|
||||
"if (1, 2): pass",
|
||||
r#"{}"#,
|
||||
[Message {
|
||||
code: CheckCode::F634,
|
||||
message: "If test is a tuple, which is always `True`".to_string(),
|
||||
location: Location::new(1, 0),
|
||||
end_location: Location::new(1, 15)
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn partial_config() {
|
||||
check!("if (1, 2): pass", r#"{"ignore": ["F"]}"#, []);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn partial_nested_config() {
|
||||
let config = r#"{
|
||||
"select": ["Q"],
|
||||
"flake8-quotes": {
|
||||
"inline-quotes": "single"
|
||||
}
|
||||
}"#;
|
||||
check!(r#"print('hello world')"#, config, []);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue