mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +00:00
refactor: Extract ruff_wasm
(#3401)
This commit is contained in:
parent
a7f3532395
commit
229f1c34cb
14 changed files with 193 additions and 181 deletions
22
.github/workflows/ci.yaml
vendored
22
.github/workflows/ci.yaml
vendored
|
@ -47,7 +47,7 @@ jobs:
|
||||||
rustup component add clippy
|
rustup component add clippy
|
||||||
rustup target add wasm32-unknown-unknown
|
rustup target add wasm32-unknown-unknown
|
||||||
- uses: Swatinem/rust-cache@v1
|
- uses: Swatinem/rust-cache@v1
|
||||||
- run: cargo clippy -p ruff --target wasm32-unknown-unknown --all-features -- -D warnings
|
- run: cargo clippy -p ruff_wasm --target wasm32-unknown-unknown --all-features -- -D warnings
|
||||||
|
|
||||||
cargo-test:
|
cargo-test:
|
||||||
strategy:
|
strategy:
|
||||||
|
@ -80,6 +80,26 @@ jobs:
|
||||||
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
||||||
RUSTDOCFLAGS: "-D warnings"
|
RUSTDOCFLAGS: "-D warnings"
|
||||||
|
|
||||||
|
|
||||||
|
cargo-test-wasm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: "cargo test (wasm)"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: "Install Rust toolchain"
|
||||||
|
run: rustup target add wasm32-unknown-unknown
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: playground/package-lock.json
|
||||||
|
- uses: jetli/wasm-pack-action@v0.4.0
|
||||||
|
- uses: Swatinem/rust-cache@v1
|
||||||
|
- name: "Run wasm-pack"
|
||||||
|
run: |
|
||||||
|
cd crates/ruff_wasm
|
||||||
|
wasm-pack test --node
|
||||||
|
|
||||||
scripts:
|
scripts:
|
||||||
name: "test scripts"
|
name: "test scripts"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
2
.github/workflows/playground.yaml
vendored
2
.github/workflows/playground.yaml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
||||||
- uses: jetli/wasm-pack-action@v0.4.0
|
- uses: jetli/wasm-pack-action@v0.4.0
|
||||||
- uses: jetli/wasm-bindgen-action@v0.2.0
|
- uses: jetli/wasm-bindgen-action@v0.2.0
|
||||||
- name: "Run wasm-pack"
|
- name: "Run wasm-pack"
|
||||||
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff
|
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff_wasm
|
||||||
- name: "Install Node dependencies"
|
- name: "Install Node dependencies"
|
||||||
run: npm ci
|
run: npm ci
|
||||||
working-directory: playground
|
working-directory: playground
|
||||||
|
|
44
Cargo.lock
generated
44
Cargo.lock
generated
|
@ -608,17 +608,6 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derivative"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diff"
|
name = "diff"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
|
@ -1969,17 +1958,12 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bisection",
|
"bisection",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.1.8",
|
"clap 4.1.8",
|
||||||
"colored",
|
"colored",
|
||||||
"console_error_panic_hook",
|
|
||||||
"console_log",
|
|
||||||
"criterion",
|
"criterion",
|
||||||
"derivative",
|
|
||||||
"dirs",
|
"dirs",
|
||||||
"fern",
|
"fern",
|
||||||
"getrandom",
|
|
||||||
"glob",
|
"glob",
|
||||||
"globset",
|
"globset",
|
||||||
"ignore",
|
"ignore",
|
||||||
|
@ -1987,7 +1971,6 @@ dependencies = [
|
||||||
"insta",
|
"insta",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
"itertools",
|
"itertools",
|
||||||
"js-sys",
|
|
||||||
"libcst",
|
"libcst",
|
||||||
"log",
|
"log",
|
||||||
"natord",
|
"natord",
|
||||||
|
@ -2009,7 +1992,6 @@ dependencies = [
|
||||||
"schemars",
|
"schemars",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-wasm-bindgen",
|
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"strum",
|
"strum",
|
||||||
|
@ -2018,8 +2000,6 @@ dependencies = [
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml",
|
"toml",
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-test",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2190,7 +2170,6 @@ name = "ruff_testing_macros"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -2206,6 +2185,25 @@ dependencies = [
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruff_wasm"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
|
"console_log",
|
||||||
|
"getrandom",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"ruff",
|
||||||
|
"ruff_python_ast",
|
||||||
|
"ruff_rustpython",
|
||||||
|
"rustpython-parser",
|
||||||
|
"serde",
|
||||||
|
"serde-wasm-bindgen",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-test",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-stemmers"
|
name = "rust-stemmers"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -2411,9 +2409,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde-wasm-bindgen"
|
name = "serde-wasm-bindgen"
|
||||||
version = "0.4.5"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
|
checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -25,11 +25,9 @@ ruff_rustpython = { path = "../ruff_rustpython" }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
bisection = { version = "0.1.0" }
|
bisection = { version = "0.1.0" }
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
cfg-if = { version = "1.0.0" }
|
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
clap = { workspace = true, features = ["derive", "env", "string"] }
|
clap = { workspace = true, features = ["derive", "env", "string"] }
|
||||||
colored = { workspace = true }
|
colored = { workspace = true }
|
||||||
derivative = { version = "2.2.0" }
|
|
||||||
dirs = { version = "4.0.0" }
|
dirs = { version = "4.0.0" }
|
||||||
fern = { version = "0.6.1" }
|
fern = { version = "0.6.1" }
|
||||||
glob = { workspace = true }
|
glob = { workspace = true }
|
||||||
|
@ -65,23 +63,12 @@ textwrap = { workspace = true }
|
||||||
thiserror = { version = "1.0.38" }
|
thiserror = { version = "1.0.38" }
|
||||||
toml = { workspace = true }
|
toml = { workspace = true }
|
||||||
|
|
||||||
# https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support
|
|
||||||
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies]
|
|
||||||
getrandom = { version = "0.2.8", features = ["js"] }
|
|
||||||
console_error_panic_hook = { version = "0.1.7" }
|
|
||||||
console_log = { version = "0.2.1" }
|
|
||||||
serde-wasm-bindgen = { version = "0.4.5" }
|
|
||||||
js-sys = { version = "0.3.61" }
|
|
||||||
wasm-bindgen = { version = "0.2.84" }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = { workspace = true, features = ["yaml", "redactions"] }
|
insta = { workspace = true, features = ["yaml", "redactions"] }
|
||||||
test-case = { workspace = true }
|
test-case = { workspace = true }
|
||||||
wasm-bindgen-test = { version = "0.3.34" }
|
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
|
|
||||||
criterion = { version = "0.4.0" }
|
criterion = { version = "0.4.0" }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
logical_lines = []
|
logical_lines = []
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
use crate::registry::{Linter, Rule};
|
use crate::registry::{Linter, Rule};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct NoqaCode(&'static str, &'static str);
|
||||||
|
|
||||||
|
impl std::fmt::Display for NoqaCode {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
write!(f, "{}{}", self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<&str> for NoqaCode {
|
||||||
|
fn eq(&self, other: &&str) -> bool {
|
||||||
|
match other.strip_prefix(self.0) {
|
||||||
|
Some(suffix) => suffix == self.1,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[ruff_macros::map_codes]
|
#[ruff_macros::map_codes]
|
||||||
pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||||
#[allow(clippy::enum_glob_use)]
|
#[allow(clippy::enum_glob_use)]
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//!
|
//!
|
||||||
//! [Ruff]: https://github.com/charliermarsh/ruff
|
//! [Ruff]: https://github.com/charliermarsh/ruff
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
|
||||||
pub use ruff_python_ast::source_code::round_trip;
|
pub use ruff_python_ast::source_code::round_trip;
|
||||||
pub use ruff_python_ast::types::Range;
|
pub use ruff_python_ast::types::Range;
|
||||||
pub use rule_selector::RuleSelector;
|
pub use rule_selector::RuleSelector;
|
||||||
|
@ -16,7 +15,7 @@ mod autofix;
|
||||||
mod checkers;
|
mod checkers;
|
||||||
mod codes;
|
mod codes;
|
||||||
mod cst;
|
mod cst;
|
||||||
mod directives;
|
pub mod directives;
|
||||||
mod doc_lines;
|
mod doc_lines;
|
||||||
mod docstrings;
|
mod docstrings;
|
||||||
pub mod fix;
|
pub mod fix;
|
||||||
|
@ -27,22 +26,14 @@ pub mod linter;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod message;
|
pub mod message;
|
||||||
mod noqa;
|
mod noqa;
|
||||||
|
pub mod packaging;
|
||||||
pub mod registry;
|
pub mod registry;
|
||||||
pub mod resolver;
|
pub mod resolver;
|
||||||
mod rule_redirects;
|
mod rule_redirects;
|
||||||
mod rule_selector;
|
mod rule_selector;
|
||||||
mod rules;
|
pub mod rules;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
mod violation;
|
mod violation;
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(target_family = "wasm")] {
|
|
||||||
mod lib_wasm;
|
|
||||||
pub use lib_wasm::check;
|
|
||||||
} else {
|
|
||||||
pub mod packaging;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
|
@ -611,6 +611,20 @@ ruff_macros::register_rules!(
|
||||||
rules::flake8_django::rules::NonLeadingReceiverDecorator,
|
rules::flake8_django::rules::NonLeadingReceiverDecorator,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl Rule {
|
||||||
|
pub fn from_code(code: &str) -> Result<Self, FromCodeError> {
|
||||||
|
let (linter, code) = Linter::parse_code(code).ok_or(FromCodeError::Unknown)?;
|
||||||
|
let prefix: RuleCodePrefix = RuleCodePrefix::parse(&linter, code)?;
|
||||||
|
Ok(prefix.into_iter().next().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum FromCodeError {
|
||||||
|
#[error("unknown rule code")]
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(EnumIter, Debug, PartialEq, Eq, Clone, Hash, RuleNamespace)]
|
#[derive(EnumIter, Debug, PartialEq, Eq, Clone, Hash, RuleNamespace)]
|
||||||
pub enum Linter {
|
pub enum Linter {
|
||||||
/// [Pyflakes](https://pypi.org/project/pyflakes/)
|
/// [Pyflakes](https://pypi.org/project/pyflakes/)
|
||||||
|
|
|
@ -156,27 +156,16 @@ pub fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
||||||
|
|
||||||
out.extend(quote! {
|
out.extend(quote! {
|
||||||
impl RuleCodePrefix {
|
impl RuleCodePrefix {
|
||||||
pub fn parse(linter: &Linter, code: &str) -> Result<Self, FromCodeError> {
|
pub fn parse(linter: &Linter, code: &str) -> Result<Self, crate::registry::FromCodeError> {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
Ok(match linter {
|
Ok(match linter {
|
||||||
#(Linter::#linter_idents => RuleCodePrefix::#linter_idents(#linter_idents::from_str(code).map_err(|_| FromCodeError::Unknown)?),)*
|
#(Linter::#linter_idents => RuleCodePrefix::#linter_idents(#linter_idents::from_str(code).map_err(|_| crate::registry::FromCodeError::Unknown)?),)*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
out.extend(quote! {
|
|
||||||
impl crate::registry::Rule {
|
|
||||||
pub fn from_code(code: &str) -> Result<Self, FromCodeError> {
|
|
||||||
use crate::registry::RuleNamespace;
|
|
||||||
let (linter, code) = Linter::parse_code(code).ok_or(FromCodeError::Unknown)?;
|
|
||||||
let prefix: RuleCodePrefix = RuleCodePrefix::parse(&linter, code)?;
|
|
||||||
Ok(prefix.into_iter().next().unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
let mut rule_to_codes: HashMap<&Path, Vec<(&Ident, &String, &Vec<Attribute>)>> = HashMap::new();
|
let mut rule_to_codes: HashMap<&Path, Vec<(&Ident, &String, &Vec<Attribute>)>> = HashMap::new();
|
||||||
let mut linter_code_for_rule_match_arms = quote!();
|
let mut linter_code_for_rule_match_arms = quote!();
|
||||||
|
@ -245,25 +234,6 @@ pub fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct NoqaCode(&'static str, &'static str);
|
|
||||||
|
|
||||||
impl std::fmt::Display for NoqaCode {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
|
||||||
use std::fmt::Write;
|
|
||||||
write!(f, "{}{}", self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq<&str> for NoqaCode {
|
|
||||||
fn eq(&self, other: &&str) -> bool {
|
|
||||||
match other.strip_prefix(self.0) {
|
|
||||||
Some(suffix) => suffix == self.1,
|
|
||||||
None => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut linter_into_iter_match_arms = quote!();
|
let mut linter_into_iter_match_arms = quote!();
|
||||||
|
@ -295,12 +265,6 @@ pub fn map_codes(func: &ItemFn) -> syn::Result<TokenStream> {
|
||||||
vec![ #(#all_codes,)* ].into_iter()
|
vec![ #(#all_codes,)* ].into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum FromCodeError {
|
|
||||||
#[error("unknown rule code")]
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
|
|
|
@ -66,12 +66,12 @@ pub fn expand<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for #prefix_ident {
|
impl std::str::FromStr for #prefix_ident {
|
||||||
type Err = FromCodeError;
|
type Err = crate::registry::FromCodeError;
|
||||||
|
|
||||||
fn from_str(code: &str) -> Result<Self, Self::Err> {
|
fn from_str(code: &str) -> Result<Self, Self::Err> {
|
||||||
match code {
|
match code {
|
||||||
#(#attributes #variant_strs => Ok(Self::#variant_idents),)*
|
#(#attributes #variant_strs => Ok(Self::#variant_idents),)*
|
||||||
_ => Err(FromCodeError::Unknown)
|
_ => Err(crate::registry::FromCodeError::Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glob = { workspace = true }
|
glob = { workspace = true }
|
||||||
proc-macro-error = { version = "1.0.4", default-features = false }
|
|
||||||
proc-macro2 = { workspace = true }
|
proc-macro2 = { workspace = true }
|
||||||
quote = { workspace = true }
|
quote = { workspace = true }
|
||||||
syn = { workspace = true }
|
syn = { workspace = true }
|
||||||
|
|
30
crates/ruff_wasm/Cargo.toml
Normal file
30
crates/ruff_wasm/Cargo.toml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[package]
|
||||||
|
name = "ruff_wasm"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
edition = { workspace = true }
|
||||||
|
rust-version = { workspace = true }
|
||||||
|
description = "WebAssembly bindings for Ruff"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
console_log = { version = "0.2.1" }
|
||||||
|
getrandom = { version = "0.2.8", features = ["js"] }
|
||||||
|
log = { workspace = true }
|
||||||
|
ruff = { path = "../ruff" }
|
||||||
|
ruff_python_ast = { path = "../ruff_python_ast" }
|
||||||
|
ruff_rustpython = { path = "../ruff_rustpython" }
|
||||||
|
rustpython-parser = { workspace = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
serde-wasm-bindgen = { version = "0.5.0" }
|
||||||
|
wasm-bindgen = { version = "0.2.84" }
|
||||||
|
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
js-sys = { version = "0.3.61" }
|
||||||
|
wasm-bindgen-test = { version = "0.3.34" }
|
|
@ -2,21 +2,20 @@ use std::path::Path;
|
||||||
|
|
||||||
use rustpython_parser::ast::Location;
|
use rustpython_parser::ast::Location;
|
||||||
use rustpython_parser::lexer::LexResult;
|
use rustpython_parser::lexer::LexResult;
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use crate::directives;
|
use ruff::directives;
|
||||||
use crate::linter::{check_path, LinterResult};
|
use ruff::linter::{check_path, LinterResult};
|
||||||
use crate::registry::{AsRule, Rule};
|
use ruff::rules::{
|
||||||
use crate::rules::{
|
|
||||||
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
flake8_annotations, flake8_bandit, flake8_bugbear, flake8_builtins, flake8_comprehensions,
|
||||||
flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style,
|
flake8_errmsg, flake8_implicit_str_concat, flake8_import_conventions, flake8_pytest_style,
|
||||||
flake8_quotes, flake8_self, flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments,
|
flake8_quotes, flake8_self, flake8_tidy_imports, flake8_type_checking, flake8_unused_arguments,
|
||||||
isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pylint, pyupgrade,
|
isort, mccabe, pep8_naming, pycodestyle, pydocstyle, pylint, pyupgrade,
|
||||||
};
|
};
|
||||||
use crate::settings::configuration::Configuration;
|
use ruff::settings::configuration::Configuration;
|
||||||
use crate::settings::options::Options;
|
use ruff::settings::options::Options;
|
||||||
use crate::settings::{defaults, flags, Settings};
|
use ruff::settings::{defaults, flags, Settings};
|
||||||
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
||||||
|
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
@ -49,34 +48,17 @@ export interface Diagnostic {
|
||||||
};
|
};
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
struct ExpandedMessage<'a> {
|
pub struct ExpandedMessage {
|
||||||
code: SerializeRuleAsCode<'a>,
|
pub code: String,
|
||||||
message: String,
|
pub message: String,
|
||||||
location: Location,
|
pub location: Location,
|
||||||
end_location: Location,
|
pub end_location: Location,
|
||||||
fix: Option<ExpandedFix>,
|
pub fix: Option<ExpandedFix>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SerializeRuleAsCode<'a>(&'a Rule);
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
|
pub struct ExpandedFix {
|
||||||
impl Serialize for SerializeRuleAsCode<'_> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
serializer.serialize_str(&self.0.noqa_code().to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a Rule> for SerializeRuleAsCode<'a> {
|
|
||||||
fn from(rule: &'a Rule) -> Self {
|
|
||||||
Self(rule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
struct ExpandedFix {
|
|
||||||
content: String,
|
content: String,
|
||||||
message: Option<String>,
|
message: Option<String>,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
@ -86,7 +68,16 @@ struct ExpandedFix {
|
||||||
#[wasm_bindgen(start)]
|
#[wasm_bindgen(start)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
use log::Level;
|
use log::Level;
|
||||||
|
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
console_log::init_with_level(Level::Debug).expect("Initializing logger went wrong.");
|
console_log::init_with_level(Level::Debug).expect("Initializing logger went wrong.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +199,8 @@ pub fn check(contents: &str, options: JsValue) -> Result<JsValue, JsValue> {
|
||||||
let messages: Vec<ExpandedMessage> = diagnostics
|
let messages: Vec<ExpandedMessage> = diagnostics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|message| ExpandedMessage {
|
.map(|message| ExpandedMessage {
|
||||||
code: message.kind.rule().into(),
|
code: message.kind.name,
|
||||||
message: message.kind.body.clone(),
|
message: message.kind.body,
|
||||||
location: message.location,
|
location: message.location,
|
||||||
end_location: message.end_location,
|
end_location: message.end_location,
|
||||||
fix: message.fix.map(|fix| ExpandedFix {
|
fix: message.fix.map(|fix| ExpandedFix {
|
||||||
|
@ -223,55 +214,3 @@ pub fn check(contents: &str, options: JsValue) -> Result<JsValue, JsValue> {
|
||||||
|
|
||||||
Ok(serde_wasm_bindgen::to_value(&messages)?)
|
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#"{}"#,
|
|
||||||
[ExpandedMessage {
|
|
||||||
code: Rule::IfTuple.into(),
|
|
||||||
message: "If test is a tuple, which is always `True`".to_string(),
|
|
||||||
location: Location::new(1, 0),
|
|
||||||
end_location: Location::new(1, 15),
|
|
||||||
fix: None,
|
|
||||||
}]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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, []);
|
|
||||||
}
|
|
||||||
}
|
|
52
crates/ruff_wasm/tests/api.rs
Normal file
52
crates/ruff_wasm/tests/api.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
|
use js_sys;
|
||||||
|
use rustpython_parser::ast::Location;
|
||||||
|
use wasm_bindgen_test::*;
|
||||||
|
|
||||||
|
use ruff::registry::Rule;
|
||||||
|
use ruff_wasm::*;
|
||||||
|
|
||||||
|
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<ExpandedMessage> = 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):\n pass",
|
||||||
|
r#"{}"#,
|
||||||
|
[ExpandedMessage {
|
||||||
|
code: Rule::IfTuple.noqa_code().to_string(),
|
||||||
|
message: "If test is a tuple, which is always `True`".to_string(),
|
||||||
|
location: Location::new(1, 0),
|
||||||
|
end_location: Location::new(2, 5),
|
||||||
|
fix: None,
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen_test]
|
||||||
|
fn partial_config() {
|
||||||
|
check!("if (1, 2):\n 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, []);
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ In-browser playground for Ruff. Available [https://play.ruff.rs/](https://play.r
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
- To build the WASM module, run `wasm-pack build ../crates/ruff --target web --out-dir ../../playground/src/pkg`
|
- To build the WASM module, run `wasm-pack build ../crates/ruff_wasm --target web --out-dir ../../playground/src/pkg`
|
||||||
from the `./playground` directory.
|
from the `./playground` directory.
|
||||||
- Install TypeScript dependencies with: `npm install`.
|
- Install TypeScript dependencies with: `npm install`.
|
||||||
- Start the development server with: `npm run dev`.
|
- Start the development server with: `npm run dev`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue