11use std:: {
2- cell:: { Ref , RefCell } ,
32 fmt:: { self , Debug , Display } ,
43 path:: PathBuf ,
54} ;
@@ -23,7 +22,6 @@ pub struct ConfigStoreBuilder {
2322 config : LintConfig ,
2423 categories : OxlintCategories ,
2524 overrides : OxlintOverrides ,
26- cache : RulesCache ,
2725
2826 // Collect all `extends` file paths for the language server.
2927 // The server will tell the clients to watch for the extends files.
@@ -46,10 +44,9 @@ impl ConfigStoreBuilder {
4644 let rules = FxHashMap :: default ( ) ;
4745 let categories: OxlintCategories = OxlintCategories :: default ( ) ;
4846 let overrides = OxlintOverrides :: default ( ) ;
49- let cache = RulesCache :: new ( config. plugins ) ;
5047 let extended_paths = Vec :: new ( ) ;
5148
52- Self { rules, config, categories, overrides, cache , extended_paths }
49+ Self { rules, config, categories, overrides, extended_paths }
5350 }
5451
5552 /// Warn on all rules in all plugins and categories, including those in `nursery`.
@@ -60,10 +57,9 @@ impl ConfigStoreBuilder {
6057 let config = LintConfig { plugins : LintPlugins :: all ( ) , ..LintConfig :: default ( ) } ;
6158 let overrides = OxlintOverrides :: default ( ) ;
6259 let categories: OxlintCategories = OxlintCategories :: default ( ) ;
63- let cache = RulesCache :: new ( config. plugins ) ;
6460 let rules = RULES . iter ( ) . map ( |rule| ( rule. clone ( ) , AllowWarnDeny :: Warn ) ) . collect ( ) ;
6561 let extended_paths = Vec :: new ( ) ;
66- Self { rules, config, categories, overrides, cache , extended_paths }
62+ Self { rules, config, categories, overrides, extended_paths }
6763 }
6864
6965 /// Create a [`ConfigStoreBuilder`] from a loaded or manually built [`Oxlintrc`].
@@ -154,25 +150,18 @@ impl ConfigStoreBuilder {
154150 globals : oxlintrc. globals ,
155151 path : Some ( oxlintrc. path ) ,
156152 } ;
157- let cache = RulesCache :: new ( config. plugins ) ;
158-
159- let mut builder = Self {
160- rules,
161- config,
162- categories,
163- overrides : oxlintrc. overrides ,
164- cache,
165- extended_paths,
166- } ;
153+
154+ let mut builder =
155+ Self { rules, config, categories, overrides : oxlintrc. overrides , extended_paths } ;
167156
168157 for filter in oxlintrc. categories . filters ( ) {
169158 builder = builder. with_filter ( & filter) ;
170159 }
171160
172161 {
173- let all_rules = builder. cache . borrow ( ) ;
162+ let all_rules = builder. get_all_rules ( ) ;
174163
175- oxlintrc. rules . override_rules ( & mut builder. rules , all_rules. as_slice ( ) ) ;
164+ oxlintrc. rules . override_rules ( & mut builder. rules , & all_rules) ;
176165 }
177166
178167 Ok ( builder)
@@ -194,7 +183,6 @@ impl ConfigStoreBuilder {
194183 #[ inline]
195184 pub fn with_plugins ( mut self , plugins : LintPlugins ) -> Self {
196185 self . config . plugins = plugins;
197- self . cache . set_plugins ( plugins) ;
198186 self
199187 }
200188
@@ -210,7 +198,6 @@ impl ConfigStoreBuilder {
210198 #[ inline]
211199 pub fn and_plugins ( mut self , plugins : LintPlugins , enabled : bool ) -> Self {
212200 self . config . plugins . set ( plugins, enabled) ;
213- self . cache . set_plugins ( self . config . plugins ) ;
214201 self
215202 }
216203
@@ -272,11 +259,30 @@ impl ConfigStoreBuilder {
272259 /// Warn/Deny a let of rules based on some predicate. Rules already in `self.rules` get
273260 /// re-configured, while those that are not are added. Affects rules where `query` returns
274261 /// `true`.
262+ fn get_all_rules ( & self ) -> Vec < RuleEnum > {
263+ if self . config . plugins . is_all ( ) {
264+ RULES . clone ( )
265+ } else {
266+ let mut plugins = self . config . plugins ;
267+
268+ // we need to include some jest rules when vitest is enabled, see [`VITEST_COMPATIBLE_JEST_RULES`]
269+ if plugins. contains ( LintPlugins :: VITEST ) {
270+ plugins = plugins. union ( LintPlugins :: JEST ) ;
271+ }
272+
273+ RULES
274+ . iter ( )
275+ . filter ( |rule| plugins. contains ( LintPlugins :: from ( rule. plugin_name ( ) ) ) )
276+ . cloned ( )
277+ . collect ( )
278+ }
279+ }
280+
275281 fn upsert_where < F > ( & mut self , severity : AllowWarnDeny , query : F )
276282 where
277283 F : Fn ( & & RuleEnum ) -> bool ,
278284 {
279- let all_rules = self . cache . borrow ( ) ;
285+ let all_rules = self . get_all_rules ( ) ;
280286 // NOTE: we may want to warn users if they're configuring a rule that does not exist.
281287 let rules_to_configure = all_rules. iter ( ) . filter ( query) ;
282288 for rule in rules_to_configure {
@@ -295,15 +301,18 @@ impl ConfigStoreBuilder {
295301 // When a plugin gets disabled before build(), rules for that plugin aren't removed until
296302 // with_filters() gets called. If the user never calls it, those now-undesired rules need
297303 // to be taken out.
298- let plugins = self . plugins ( ) ;
299- let mut rules = if self . cache . is_stale ( ) {
300- self . rules
301- . into_iter ( )
302- . filter ( |( r, _) | plugins. contains ( r. plugin_name ( ) . into ( ) ) )
303- . collect ( )
304- } else {
305- self . rules . into_iter ( ) . collect :: < Vec < _ > > ( )
306- } ;
304+ let mut plugins = self . plugins ( ) ;
305+
306+ // Apply the same Vitest->Jest logic as in get_all_rules()
307+ if plugins. contains ( LintPlugins :: VITEST ) {
308+ plugins = plugins. union ( LintPlugins :: JEST ) ;
309+ }
310+
311+ let mut rules: Vec < _ > = self
312+ . rules
313+ . into_iter ( )
314+ . filter ( |( r, _) | plugins. contains ( r. plugin_name ( ) . into ( ) ) )
315+ . collect ( ) ;
307316 rules. sort_unstable_by_key ( |( r, _) | r. id ( ) ) ;
308317 Config :: new ( rules, self . categories , self . config , self . overrides )
309318 }
@@ -411,94 +420,6 @@ impl Display for ConfigBuilderError {
411420
412421impl std:: error:: Error for ConfigBuilderError { }
413422
414- struct RulesCache {
415- all_rules : RefCell < Option < Vec < RuleEnum > > > ,
416- plugins : LintPlugins ,
417- last_fresh_plugins : LintPlugins ,
418- }
419-
420- impl RulesCache {
421- #[ inline]
422- #[ must_use]
423- pub fn new ( plugins : LintPlugins ) -> Self {
424- Self { all_rules : RefCell :: new ( None ) , plugins, last_fresh_plugins : plugins }
425- }
426-
427- pub fn set_plugins ( & mut self , plugins : LintPlugins ) {
428- if self . plugins == plugins {
429- return ;
430- }
431- self . last_fresh_plugins = self . plugins ;
432- self . plugins = plugins;
433- self . clear ( ) ;
434- }
435-
436- pub fn is_stale ( & self ) -> bool {
437- // NOTE: After all_rules cache has been initialized _at least once_ (e.g. its borrowed, or
438- // initialize() is called), all_rules will be some if and only if last_fresh_plugins ==
439- // plugins. Right before creation, (::new()) and before initialize() is called, these two
440- // fields will be equal _but all_rules will be none_. This is OK for this function, but is
441- // a possible future foot-gun. ConfigBuilder uses this to re-build its rules list in
442- // ::build(). If cache is created but never made stale (by changing plugins),
443- // ConfigBuilder's rule list won't need updating anyways, meaning its sound for this to
444- // return `false`.
445- self . last_fresh_plugins != self . plugins
446- }
447-
448- #[ must_use]
449- fn borrow ( & self ) -> Ref < ' _ , Vec < RuleEnum > > {
450- let cached = self . all_rules . borrow ( ) ;
451- if cached. is_some ( ) {
452- Ref :: map ( cached, |cached| cached. as_ref ( ) . unwrap ( ) )
453- } else {
454- drop ( cached) ;
455- self . initialize ( ) ;
456- Ref :: map ( self . all_rules . borrow ( ) , |cached| cached. as_ref ( ) . unwrap ( ) )
457- }
458- }
459-
460- /// # Panics
461- /// If the cache cell is currently borrowed.
462- fn clear ( & self ) {
463- * self . all_rules . borrow_mut ( ) = None ;
464- }
465-
466- /// Forcefully initialize this cache with all rules in all plugins currently
467- /// enabled.
468- ///
469- /// This will clobber whatever value is currently stored. It should only be
470- /// called when the cache is not populated, either because it has not been
471- /// initialized yet or it was cleared with [`Self::clear`].
472- ///
473- /// # Panics
474- /// If the cache cell is currently borrowed.
475- fn initialize ( & self ) {
476- debug_assert ! (
477- self . all_rules. borrow( ) . is_none( ) ,
478- "Cannot re-initialize a populated rules cache. It must be cleared first."
479- ) ;
480-
481- let all_rules: Vec < _ > = if self . plugins . is_all ( ) {
482- RULES . clone ( )
483- } else {
484- let mut plugins = self . plugins ;
485-
486- // we need to include some jest rules when vitest is enabled, see [`VITEST_COMPATIBLE_JEST_RULES`]
487- if plugins. contains ( LintPlugins :: VITEST ) {
488- plugins = plugins. union ( LintPlugins :: JEST ) ;
489- }
490-
491- RULES
492- . iter ( )
493- . filter ( |rule| plugins. contains ( LintPlugins :: from ( rule. plugin_name ( ) ) ) )
494- . cloned ( )
495- . collect ( )
496- } ;
497-
498- * self . all_rules . borrow_mut ( ) = Some ( all_rules) ;
499- }
500- }
501-
502423#[ cfg( test) ]
503424mod test {
504425 use std:: path:: PathBuf ;
0 commit comments