Skip to content

Commit 0f1e0e8

Browse files
committedMar 25, 2025·
refactor(linter): gate rule docs behind feature (#10027)
- related to #9998 Adds a `ruledocs` feature for capturing the documentation text in lint rule macros. This is only enabled for the website task currently. Locally, this removes ~429K bytes from the binary size when running `cargo build --release -p oxlint` <img width="247" alt="Screenshot 2025-03-25 at 12 18 23 AM" src="https://github.com/user-attachments/assets/52bbf254-eebf-45c5-8229-282fee921101" />
1 parent ab1a796 commit 0f1e0e8

File tree

7 files changed

+57
-16
lines changed

7 files changed

+57
-16
lines changed
 

Diff for: ‎crates/oxc_linter/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ repository.workspace = true
1313
rust-version.workspace = true
1414
description.workspace = true
1515

16+
[features]
17+
ruledocs = ["oxc_macros/ruledocs"] # Enables the `ruledocs` feature for conditional compilation
18+
1619
[lints]
1720
workspace = true
1821

@@ -28,7 +31,7 @@ oxc_codegen = { workspace = true }
2831
oxc_diagnostics = { workspace = true }
2932
oxc_ecmascript = { workspace = true }
3033
oxc_index = { workspace = true, features = ["serde"] }
31-
oxc_macros = { workspace = true }
34+
oxc_macros = { workspace = true, features = ["ruledocs"] }
3235
oxc_parser = { workspace = true }
3336
oxc_regular_expression = { workspace = true }
3437
oxc_resolver = { workspace = true }

Diff for: ‎crates/oxc_linter/src/rule.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,14 @@ impl RuleWithSeverity {
306306

307307
#[cfg(test)]
308308
mod test {
309-
use markdown::{Options, to_html_with_options};
310-
311309
use super::RuleCategory;
312-
use crate::rules::RULES;
313310

314311
#[test]
312+
#[cfg(feature = "ruledocs")]
315313
fn ensure_documentation() {
314+
use crate::rules::RULES;
315+
use markdown::{Options, to_html_with_options};
316+
316317
assert!(!RULES.is_empty());
317318
let options = Options::gfm();
318319

Diff for: ‎crates/oxc_linter/src/table.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct RuleTableRow {
2121
pub name: &'static str,
2222
pub plugin: String,
2323
pub category: RuleCategory,
24+
#[cfg(feature = "ruledocs")]
2425
pub documentation: Option<&'static str>,
2526
pub turned_on_by_default: bool,
2627
pub autofix: RuleFixMeta,
@@ -46,6 +47,7 @@ impl RuleTable {
4647
let name = rule.name();
4748
RuleTableRow {
4849
name,
50+
#[cfg(feature = "ruledocs")]
4951
documentation: rule.documentation(),
5052
plugin: rule.plugin_name().to_string(),
5153
category: rule.category(),

Diff for: ‎crates/oxc_linter/tests/integration_test.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ declare_oxc_lint_test!(
1111
correctness
1212
);
1313

14+
#[expect(dead_code)]
1415
struct TestRule2 {
15-
#[expect(dead_code)]
1616
dummy_field: u8,
1717
}
1818

@@ -26,9 +26,11 @@ declare_oxc_lint_test!(
2626
#[test]
2727
fn test_declare_oxc_lint() {
2828
// Simple, multiline documentation
29+
#[cfg(feature = "ruledocs")]
2930
assert_eq!(TestRule::documentation().unwrap(), "Dummy description\n# which is multiline\n");
3031

3132
// Ensure structs with fields can be passed to the macro
33+
#[cfg(feature = "ruledocs")]
3234
assert_eq!(TestRule2::documentation().unwrap(), "Dummy description2\n");
3335

3436
// Auto-generated kebab-case name

Diff for: ‎crates/oxc_macros/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ repository.workspace = true
1313
rust-version.workspace = true
1414
description.workspace = true
1515

16+
[features]
17+
ruledocs = [] # Enables the `ruledocs` feature for conditional compilation
18+
1619
[lints]
1720
workspace = true
1821

Diff for: ‎crates/oxc_macros/src/declare_oxc_lint.rs

+40-10
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@ pub struct LintRuleMeta {
1313
category: Ident,
1414
/// Describes what auto-fixing capabilities the rule has
1515
fix: Option<Ident>,
16+
#[cfg(feature = "ruledocs")]
1617
documentation: String,
1718
pub used_in_test: bool,
1819
}
1920

2021
impl Parse for LintRuleMeta {
2122
fn parse(input: ParseStream<'_>) -> Result<Self> {
23+
#[cfg(feature = "ruledocs")]
2224
let mut documentation = String::new();
25+
2326
for attr in input.call(Attribute::parse_outer)? {
2427
match parse_attr(["doc"], &attr) {
2528
Some(lit) => {
26-
let value = lit.value();
27-
let line = value.strip_prefix(' ').unwrap_or(&value);
28-
29-
documentation.push_str(line);
30-
documentation.push('\n');
29+
#[cfg(feature = "ruledocs")]
30+
{
31+
let value = lit.value();
32+
let line = value.strip_prefix(' ').unwrap_or(&value);
33+
34+
documentation.push_str(line);
35+
documentation.push('\n');
36+
}
3137
}
3238
_ => {
3339
return Err(Error::new_spanned(attr, "unexpected attribute"));
@@ -54,7 +60,15 @@ impl Parse for LintRuleMeta {
5460
// Ignore the rest
5561
input.parse::<proc_macro2::TokenStream>()?;
5662

57-
Ok(Self { name: struct_name, plugin, category, fix, documentation, used_in_test: false })
63+
Ok(Self {
64+
name: struct_name,
65+
plugin,
66+
category,
67+
fix,
68+
#[cfg(feature = "ruledocs")]
69+
documentation,
70+
used_in_test: false,
71+
})
5872
}
5973
}
6074

@@ -63,7 +77,15 @@ pub fn rule_name_converter() -> Converter {
6377
}
6478

6579
pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream {
66-
let LintRuleMeta { name, plugin, category, fix, documentation, used_in_test } = metadata;
80+
let LintRuleMeta {
81+
name,
82+
plugin,
83+
category,
84+
fix,
85+
#[cfg(feature = "ruledocs")]
86+
documentation,
87+
used_in_test,
88+
} = metadata;
6789

6890
let canonical_name = rule_name_converter().convert(name.to_string());
6991
let plugin = plugin.to_string(); // ToDo: validate plugin name
@@ -91,6 +113,16 @@ pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream {
91113
Some(quote! { use crate::{rule::{RuleCategory, RuleMeta, RuleFixMeta}, fixer::FixKind}; })
92114
};
93115

116+
#[cfg(not(feature = "ruledocs"))]
117+
let docs: Option<proc_macro2::TokenStream> = None;
118+
119+
#[cfg(feature = "ruledocs")]
120+
let docs = Some(quote! {
121+
fn documentation() -> Option<&'static str> {
122+
Some(#documentation)
123+
}
124+
});
125+
94126
let output = quote! {
95127
#import_statement
96128

@@ -103,9 +135,7 @@ pub fn declare_oxc_lint(metadata: LintRuleMeta) -> TokenStream {
103135

104136
#fix
105137

106-
fn documentation() -> Option<&'static str> {
107-
Some(#documentation)
108-
}
138+
#docs
109139
}
110140
};
111141

Diff for: ‎tasks/website/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ doctest = false
1919
[dependencies]
2020
bpaf = { workspace = true, features = ["docgen"] }
2121
handlebars = { workspace = true }
22-
oxc_linter = { workspace = true }
22+
oxc_linter = { workspace = true, features = ["ruledocs"] }
2323
oxlint = { path = "../../apps/oxlint" }
2424
pico-args = { workspace = true }
2525
project-root = { workspace = true }

0 commit comments

Comments
 (0)
Please sign in to comment.