diff --git a/.github/codecov.yml b/.github/codecov.yml index de4391876ed4c..0eeaf91b9ae43 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -22,7 +22,5 @@ ignore: - "crates/oxc_wasm" # Remove this once wasm is completed - "crates/oxc_diagnostics" - "crates/oxc_type_synthesis" - - "crates/oxc_query" # Not aiming for test coverage right now with @u9g - - "crates/oxc_linter_plugin" - "crates/oxc_transformer" # not ready - "crates/oxc_js_regex" # not ready diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 6720afba0daab..b1c3377eacb7d 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -13,7 +13,6 @@ on: - 'crates/oxc/**' - 'crates/oxc_cli/**' - 'crates/oxc_linter/**' - - 'crates/oxc_query/**' - 'crates/oxc_type_synthesis/**' - 'crates/oxc_wasm/**' - 'crates/oxc_prettier/**' @@ -30,7 +29,6 @@ on: - 'crates/oxc/**' - 'crates/oxc_cli/**' - 'crates/oxc_linter/**' - - 'crates/oxc_query/**' - 'crates/oxc_type_synthesis/**' - 'crates/oxc_wasm/**' diff --git a/.typos.toml b/.typos.toml index df8a079b286f3..0850c991ca8aa 100644 --- a/.typos.toml +++ b/.typos.toml @@ -14,7 +14,6 @@ extend-exclude = [ "crates/oxc_syntax/src/xml_entities.rs", "**/*.snap", "pnpm-lock.yaml", - "crates/oxc_linter_plugin/examples/queries/unicorn/prefer-string-slice/rule.yml" ] [default.extend-words] diff --git a/Cargo.lock b/Cargo.lock index d16cd774c00c9..964ee78826034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,37 +53,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" -[[package]] -name = "anyhow" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" - -[[package]] -name = "async-graphql-parser" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99841c1f890fda6712054e7e37b207738f4aa97870cb1bffcab2f09f2df0957a" -dependencies = [ - "async-graphql-value", - "pest", - "pest_derive", - "serde", - "serde_json", -] - -[[package]] -name = "async-graphql-value" -version = "2.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cecac7ab6737364cff7b16e9273dd51fac7cfbd14ab5d84127df5a56ca9d422" -dependencies = [ - "bytes", - "indexmap 1.9.3", - "serde", - "serde_json", -] - [[package]] name = "async-trait" version = "0.1.77" @@ -128,15 +97,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "backtrace-ext" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" -dependencies = [ - "backtrace", -] - [[package]] name = "base64" version = "0.21.5" @@ -249,9 +209,6 @@ name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -dependencies = [ - "serde", -] [[package]] name = "cast" @@ -627,18 +584,6 @@ dependencies = [ "encoding_rs", ] -[[package]] -name = "enum-as-inner" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "enum-variants-strings" version = "0.2.3" @@ -998,7 +943,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -1158,9 +1102,6 @@ name = "linked-hash-map" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -dependencies = [ - "serde", -] [[package]] name = "linux-raw-sys" @@ -1168,17 +1109,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" -[[package]] -name = "located_yaml" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc68ee6f87a1be7fdba1dcfd854528371aa84a8390279b5d7a99d5da82add76" -dependencies = [ - "linked-hash-map", - "serde", - "yaml-rust", -] - [[package]] name = "lock_api" version = "0.4.11" @@ -1217,12 +1147,6 @@ dependencies = [ "serde", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matchers" version = "0.1.0" @@ -1244,8 +1168,6 @@ version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" dependencies = [ - "backtrace", - "backtrace-ext", "is-terminal", "miette-derive", "once_cell", @@ -1741,26 +1663,6 @@ dependencies = [ "url", ] -[[package]] -name = "oxc_linter_plugin" -version = "0.0.0" -dependencies = [ - "ignore", - "located_yaml", - "miette", - "oxc_allocator", - "oxc_diagnostics", - "oxc_linter", - "oxc_parser", - "oxc_query", - "oxc_semantic", - "oxc_span", - "path-calculate", - "serde", - "serde_yaml", - "trustfall", -] - [[package]] name = "oxc_macros" version = "0.0.0" @@ -1876,22 +1778,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "oxc_query" -version = "0.0.0" -dependencies = [ - "enum-as-inner", - "oxc_allocator", - "oxc_ast", - "oxc_parser", - "oxc_semantic", - "oxc_span", - "rustc-hash", - "serde", - "trustfall", - "url", -] - [[package]] name = "oxc_resolver" version = "1.2.0" @@ -2025,12 +1911,9 @@ dependencies = [ "oxc", "oxc_linter", "oxc_prettier", - "oxc_query", "oxc_type_synthesis", "serde", "serde-wasm-bindgen", - "serde_json", - "trustfall", "wasm-bindgen", "wasm-bindgen-test", ] @@ -2067,15 +1950,6 @@ dependencies = [ "path-dedot", ] -[[package]] -name = "path-calculate" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4690055139867a4a0d11d18ab98d80b325d7aa573b99e0ae8e1bc787a4282da7" -dependencies = [ - "path-absolutize", -] - [[package]] name = "path-dedot" version = "3.1.1" @@ -2661,9 +2535,6 @@ name = "smallvec" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -dependencies = [ - "serde", -] [[package]] name = "smawk" @@ -3049,46 +2920,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "trustfall" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c5a5b0a24849741733d22afe23b2784dd06a9c1100edd43de0e814a9f391b0b" -dependencies = [ - "anyhow", - "trustfall_core", - "trustfall_derive", -] - -[[package]] -name = "trustfall_core" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "994d4a15d0cf514b856567f85a166ee0e2427f845b194b3744adeb8caf674385" -dependencies = [ - "async-graphql-parser", - "async-graphql-value", - "itertools 0.10.5", - "maplit", - "once_cell", - "regex", - "serde", - "serde_json", - "smallvec", - "thiserror", -] - -[[package]] -name = "trustfall_derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb14eb4f23b3b669d232a5c7d2b3d6c89ad9e15be1cbdd2c1e14d87d62569ec" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "typenum" version = "1.17.0" diff --git a/Cargo.toml b/Cargo.toml index e66bec822d4f8..42629a780ccc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,8 +78,6 @@ oxc_transformer = { version = "0.4.0", path = "crates/oxc_transformer" } oxc_macros = { path = "crates/oxc_macros" } oxc_linter = { path = "crates/oxc_linter" } oxc_type_synthesis = { path = "crates/oxc_type_synthesis" } -oxc_query = { path = "crates/oxc_query" } -oxc_linter_plugin = { path = "crates/oxc_linter_plugin" } oxc_prettier = { path = "crates/oxc_prettier" } oxc_tasks_common = { path = "tasks/common" } @@ -130,7 +128,6 @@ static_assertions = { version = "1.1.0" } stacker = { version = "0.1.15" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3" } -trustfall = { version = "0.6.1" } insta = { version = "1.34.0", features = ["glob"] } codspeed-criterion-compat = { version = "2.3.3", default-features = false } glob = { version = "0.3.1" } diff --git a/README.md b/README.md index c792dce6f413b..6e04a22109212 100644 --- a/README.md +++ b/README.md @@ -155,13 +155,6 @@ this lets you run the linter without a Node.js installation in your CI. -#### Linter Plugin - -We are currently developing a DSL-based plugin system. -The plugin system uses [trustfall] as its query engine and a subset of GraphQL as its query language. - -You will not need to use JavaScript or Rust to write a plugin, this is useful for QAs and security researchers. - ### 🔸 Resolver Module resolution plays a crucial role in JavaScript tooling, especially for tasks like multi-file analysis or bundling. However, it can often become a performance bottleneck. @@ -254,7 +247,6 @@ And also - [@kaleidawave](https://github.com/kaleidawave) for [Ezno Type Checker](#-ezno-type-checker) - [@zackradisic](https://github.com/zackradisic) for [tyvm](https://github.com/zackradisic/tyvm) -- [@u9g](https://github.com/u9g) for the work in progress [oxc_linter_plugin](./crates/oxc_linter_plugin) ## 📖 License @@ -328,6 +320,5 @@ Oxc partially copies code from the following projects, their licenses are listed [swc]: https://swc.rs [tdewolff-minify]: https://github.com/tdewolff/minify [terser]: https://terser.org -[trustfall]: https://github.com/obi1kenobi/trustfall [vscode]: https://github.com/microsoft/vscode [@typescript-eslint]: https://typescript-eslint.io diff --git a/crates/oxc_language_server/Cargo.toml b/crates/oxc_language_server/Cargo.toml index c00e25b3df42a..d2dce2f942c84 100644 --- a/crates/oxc_language_server/Cargo.toml +++ b/crates/oxc_language_server/Cargo.toml @@ -20,21 +20,21 @@ name = "oxc_language_server" test = false [dependencies] -oxc_allocator = { workspace = true } -oxc_diagnostics = { workspace = true } -oxc_linter = { workspace = true } -oxc_parser = { workspace = true } -oxc_semantic = { workspace = true } -oxc_span = { workspace = true } -dashmap = { workspace = true } -env_logger = { workspace = true } -futures = { workspace = true } -ignore = { workspace = true, features = ["simd-accel"] } -miette = { workspace = true, features = ["fancy-no-backtrace"] } -ropey = { workspace = true } -tokio = { workspace = true, features = ["full"] } -tower-lsp = { workspace = true, features = ["proposed"] } -log = "0.4.20" -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -globset = "0.4.14" +oxc_allocator = { workspace = true } +oxc_diagnostics = { workspace = true } +oxc_linter = { workspace = true } +oxc_parser = { workspace = true } +oxc_semantic = { workspace = true } +oxc_span = { workspace = true } +dashmap = { workspace = true } +env_logger = { workspace = true } +futures = { workspace = true } +ignore = { workspace = true, features = ["simd-accel"] } +miette = { workspace = true, features = ["fancy-no-backtrace"] } +ropey = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tower-lsp = { workspace = true, features = ["proposed"] } +log = "0.4.20" +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +globset = "0.4.14" diff --git a/crates/oxc_linter_plugin/Cargo.toml b/crates/oxc_linter_plugin/Cargo.toml deleted file mode 100644 index ad9a9ccc52a48..0000000000000 --- a/crates/oxc_linter_plugin/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "oxc_linter_plugin" -version = "0.0.0" -publish = false -authors.workspace = true -description.workspace = true -edition.workspace = true -homepage.workspace = true -keywords.workspace = true -license.workspace = true -repository.workspace = true -rust-version.workspace = true -categories.workspace = true - -[lints] -workspace = true - -[lib] -doctest = false - -[dependencies] -oxc_span = { workspace = true } -oxc_query = { workspace = true } -oxc_diagnostics = { workspace = true } -oxc_semantic = { workspace = true } -oxc_linter = { workspace = true } -oxc_parser = { workspace = true } -oxc_allocator = { workspace = true } -ignore = { workspace = true } - -serde = { workspace = true, features = ["derive"] } -trustfall = { workspace = true } - -serde_yaml = "0.9.29" -located_yaml = "0.2.1" -path-calculate = "0.1.3" - -[dev_dependencies] -miette = { workspace = true, features = ["fancy"] } diff --git a/crates/oxc_linter_plugin/examples/queries/next/google-font-display/display-has-bad-value.yml b/crates/oxc_linter_plugin/examples/queries/next/google-font-display/display-has-bad-value.yml deleted file mode 100644 index 2704056713e7f..0000000000000 --- a/crates/oxc_linter_plugin/examples/queries/next/google-font-display/display-has-bad-value.yml +++ /dev/null @@ -1,158 +0,0 @@ -name: "next:google-font-display:display-has-bad-value" -query: | - query { - File { - jsx_element { - opening_element { - name @filter(op: "=", value: ["$link"]) - - span_: span { - start @output - end @output - } - - attribute { - name @filter(op: "=", value: ["$href"]) - value_as_constant_string @filter(op: "has_prefix", value: ["$href_value_start"]) - - value_as_url { - search_parameter @fold @transform(op: "count") @filter(op: ">", value:["$zero"]) { - key @filter(op: "=", value: ["$display"]) - value @filter(op: "one_of", value: ["$bad_display_values"]) - } - } - } - } - } - } - } - -args: - zero: 0 - link: "link" - href: "href" - display: "display" - href_value_start: "https://fonts.googleapis.com/css" - bad_display_values: - - "auto" - - "block" - - "fallback" - -summary: "Replace '{display_value}' with 'optional'" -reason: "Specifying display=optional minimizes the risk of invisible text or layout shift. If swapping to the custom font after it has loaded is important to you, then use display=swap instead." - -tests: - pass: - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( -
- - - - - - ); - }; - - relative_path: - - "index.tsx" - code: | - import Document, { Html, Head } from "next/document"; - - class MyDocument extends Document { - render() { - return ( - - - - - - ); - } - } - - export default MyDocument; - - relative_path: - - "index.tsx" - code: | - import Document, { Html, Head } from "next/document"; - - class MyDocument extends Document { - render() { - return ( - - - - - - ); - } - } - - export default MyDocument; - fail: - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( - - - - ); - }; - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( - - - - ); - }; - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( - - - - ); - }; diff --git a/crates/oxc_linter_plugin/examples/queries/next/google-font-display/font-display-param-missing.yml b/crates/oxc_linter_plugin/examples/queries/next/google-font-display/font-display-param-missing.yml deleted file mode 100644 index 9c6652c1040b9..0000000000000 --- a/crates/oxc_linter_plugin/examples/queries/next/google-font-display/font-display-param-missing.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: "next:google-font-display:font-display-param-missing" - -query: | - query { - File { - jsx_element { - opening_element { - name @filter(op: "=", value: ["$link"]) - - span_: span { - start @output - end @output - } - - attribute { - name @filter(op: "=", value: ["$href"]) - value_as_constant_string @filter(op: "has_prefix", value: ["$href_value_start"]) - - value_as_url { - search_parameter @fold @transform(op: "count") @filter(op: "=", value:["$zero"]) { - key @filter(op: "=", value: ["$display"]) - } - } - } - } - } - } - } - -args: - zero: 0 - link: "link" - href: "href" - display: "display" - href_value_start: "https://fonts.googleapis.com/css" - -summary: "A font-display parameter is missing (adding `&display=optional` is recommended)" -reason: "Specifying display=optional minimizes the risk of invisible text or layout shift. If swapping to the custom font after it has loaded is important to you, then use display=swap instead." - -tests: - pass: - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( - - - - - - - ); - }; - - relative_path: - - "index.tsx" - code: | - import Document, { Html, Head } from "next/document"; - - class MyDocument extends Document { - render() { - return ( - - - - - - ); - } - } - - export default MyDocument; - - relative_path: - - "index.tsx" - code: | - import Document, { Html, Head } from "next/document"; - - class MyDocument extends Document { - render() { - return ( - - - - - - ); - } - } - - export default MyDocument; - fail: - - relative_path: - - "index.tsx" - code: | - import Head from "next/head"; - - export default Test = () => { - return ( - - - - ); - }; diff --git a/crates/oxc_linter_plugin/examples/queries/next/google-font-preconnect/rule.yml b/crates/oxc_linter_plugin/examples/queries/next/google-font-preconnect/rule.yml deleted file mode 100644 index 8776262cc090e..0000000000000 --- a/crates/oxc_linter_plugin/examples/queries/next/google-font-preconnect/rule.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: "next:google-font-preconnect" - -query: | - query { - File { - jsx_element { - opening_element { - name @filter(op: "=", value: ["$link"]) - - span_: span { - start @output - end @output - } - - attribute @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { - name @filter(op: "=", value: ["$rel"]) - value_as_constant_string @filter(op: "=", value: ["$preconnect"]) - } - - attribute { - name @output @filter(op: "=", value: ["$href"]) - value_as_constant_string @output @filter(op: "has_prefix", value: ["$href_value_start"]) - } - } - } - } - } - -args: - zero: 0 - link: "link" - href: "href" - rel: "rel" - preconnect: "preconnect" - href_value_start: "https://fonts.gstatic.com" - -summary: "Add `rel=\"preconnect\"`" -reason: "Adding preconnect is recommended to initiate an early connection to the origin." - -tests: - pass: - - relative_path: - - "index.tsx" - code: | - export const Test = () => ( -Test
- - - relative_path: - - "pages" - - "tests.js" - - code: | - import Document from "next/document" - - export const Test = () =>Test
diff --git a/crates/oxc_linter_plugin/examples/queries/next/no-duplicate-head/rule.DOESNTRUN b/crates/oxc_linter_plugin/examples/queries/next/no-duplicate-head/rule.DOESNTRUN deleted file mode 100644 index 5092104f3e5be..0000000000000 --- a/crates/oxc_linter_plugin/examples/queries/next/no-duplicate-head/rule.DOESNTRUN +++ /dev/null @@ -1,159 +0,0 @@ -name: "next:no-duplicate-head" - -# We don't run this lint now beacuause it outputs a List-
-
- - ) - } - } - - export default MyDocument - - relative_path: - - "pages" - - "_document.page.tsx" - - code: | - import Document, { Html, Main, NextScript } from 'next/document' - import Head from 'next/head' - - class MyDocument extends Document { - render() { - return ( - -
- - - -
` from `next/head` instead." -reason: | - A `
` element was used to include page-level metadata, but this can cause unexpected behavior - in a Next.js application. Use Next.js' built-in `next/head` component instead. - - -tests: - pass: - - relative_path: - - "pages" - - "index.js" - - code: | - import Head from 'next/head'; - - export class MyComponent { - render() { - return ( -
- ); - } - } - - - relative_path: - - "pages" - - "index.tsx" - - code: | - import Head from 'next/head'; - - export class MyComponent { - render() { - return ( -
- ); - } - } - - - relative_path: - - "app" - - "layout.js" - - code: | - export default function Layout({ children }) { - return ( - -
-
- -
` from `next/document` instead." -reason: "This can cause unexpected issues in your application." - -tests: - pass: - - relative_path: - - "pages" - - "_document.tsx" - - code: | - import Document, { Html, Head, Main, NextScript } from 'next/document' - - class MyDocument extends Document { - static async getInitialProps(ctx) { - //... - } - - render() { - return ( - -
- - - ) - } - } - - export default MyDocument - - - relative_path: - - "pages" - - "index.tsx" - - code: | - import Head from "next/head"; - - export default function IndexPage() { - return ( -
-
- - - ); - } - - - relative_path: - - "pages" - - "_document.js" - - code: | - import Document, { Html, Main, NextScript } from 'next/document' - import Head from 'next/head' - - class MyDocument extends Document { - render() { - return ( - -
-