mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-06 17:34:25 +00:00
perf(linter): reduce rule config dispatch size (#25461)
Generate `from_configuration` match arms only for the 341 rules that override the default implementation. The other 508 rules clone their default value from `RULES`. This reduces the release oxlint binary from 13,963,312 to 13,946,800 bytes (-16,512 bytes). AI-assisted.
This commit is contained in:
4 files changed
+25
-1650
No files matched your search
+1
-1646
File diff suppressed because it is too large.
Load diff
@@ -128,7 +128,18 @@ pub fn generate_rules_enum_file() -> io::Result<()> {
|
||||
.map_err(|e| std::io::Error::other(format!("could not find project root: {e}")))?;
|
||||
|
||||
let rules_file_contents = fs::read_to_string(root.join("crates/oxc_linter/src/rules.rs"))?;
|
||||
let rule_entries = get_all_rules(&rules_file_contents);
|
||||
let mut rule_entries = get_all_rules(&rules_file_contents);
|
||||
|
||||
for rule in &mut rule_entries {
|
||||
let Some(path) = find_rule_source_file(&root, rule) else { continue };
|
||||
let Ok(source) = fs::read_to_string(path) else { continue };
|
||||
let Ok(file) = syn::parse_file(&source) else { continue };
|
||||
let Some(rule_impl) = find_rule_impl_block(&file, &rule.rule_struct_name()) else {
|
||||
continue;
|
||||
};
|
||||
rule.has_custom_from_configuration =
|
||||
find_impl_function(rule_impl, "from_configuration").is_some();
|
||||
}
|
||||
|
||||
let out = rules_enum::generate_rules_enum(&rule_entries);
|
||||
let formatted_out = rust_fmt(&out);
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct RuleEntry<'e> {
|
||||
pub plugin_module_name: &'e str,
|
||||
/// The rule's module name, like `no_debugger` in `eslint::no_debugger:NoDebugger`.
|
||||
pub rule_module_name: &'e str,
|
||||
/// Whether the rule overrides `Rule::from_configuration`.
|
||||
pub has_custom_from_configuration: bool,
|
||||
}
|
||||
|
||||
impl RuleEntry<'_> {
|
||||
@@ -48,8 +50,13 @@ pub fn get_all_rules(contents: &str) -> Vec<RuleEntry<'_>> {
|
||||
&& line.ends_with(';')
|
||||
&& let Some(rule_name) = line.strip_prefix("pub mod ").and_then(|s| s.strip_suffix(';'))
|
||||
{
|
||||
rule_entries
|
||||
.push(RuleEntry { plugin_module_name: plugin, rule_module_name: rule_name });
|
||||
rule_entries.push(RuleEntry {
|
||||
plugin_module_name: plugin,
|
||||
rule_module_name: rule_name,
|
||||
// Preserve the existing generated behavior unless codegen confirms that the rule
|
||||
// uses the default implementation.
|
||||
has_custom_from_configuration: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,7 @@ fn generate_rule_enum_impl(rule_entries: &[RuleEntry<'_>]) -> TokenStream {
|
||||
|
||||
let from_configuration_arms: Vec<TokenStream> = rule_entries
|
||||
.iter()
|
||||
.filter(|rule| rule.has_custom_from_configuration)
|
||||
.map(|rule| {
|
||||
let enum_name = make_enum_ident(rule);
|
||||
quote! { Self::#enum_name(_) => Ok(Self::#enum_name(#enum_name::from_configuration(value)?)) }
|
||||
@@ -345,7 +346,8 @@ fn generate_rule_enum_impl(rule_entries: &[RuleEntry<'_>]) -> TokenStream {
|
||||
|
||||
pub fn from_configuration(&self, value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
|
||||
match self {
|
||||
#(#from_configuration_arms),*
|
||||
#(#from_configuration_arms,)*
|
||||
_ => Ok(RULES[self.id()].clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user