@@ -168,7 +168,7 @@ fn try_metaclass_cycle_initial<'db>(
168168}
169169
170170/// A category of classes with code generation capabilities (with synthesized methods).
171- #[ derive( Clone , Copy , Debug , PartialEq ) ]
171+ #[ derive( Clone , Copy , Debug , PartialEq , salsa :: Update , get_size2 :: GetSize ) ]
172172pub ( crate ) enum CodeGeneratorKind {
173173 /// Classes decorated with `@dataclass` or similar dataclass-like decorators
174174 DataclassLike ,
@@ -180,31 +180,58 @@ pub(crate) enum CodeGeneratorKind {
180180
181181impl CodeGeneratorKind {
182182 pub ( crate ) fn from_class ( db : & dyn Db , class : ClassLiteral < ' _ > ) -> Option < Self > {
183- if CodeGeneratorKind :: DataclassLike . matches ( db, class) {
184- Some ( CodeGeneratorKind :: DataclassLike )
185- } else if CodeGeneratorKind :: NamedTuple . matches ( db, class) {
186- Some ( CodeGeneratorKind :: NamedTuple )
187- } else if CodeGeneratorKind :: TypedDict . matches ( db, class) {
188- Some ( CodeGeneratorKind :: TypedDict )
189- } else {
183+ #[ salsa:: tracked(
184+ cycle_fn=code_generator_of_class_recover,
185+ cycle_initial=code_generator_of_class_initial,
186+ heap_size=ruff_memory_usage:: heap_size
187+ ) ]
188+ fn code_generator_of_class < ' db > (
189+ db : & ' db dyn Db ,
190+ class : ClassLiteral < ' db > ,
191+ ) -> Option < CodeGeneratorKind > {
192+ if class. dataclass_params ( db) . is_some ( )
193+ || class
194+ . try_metaclass ( db)
195+ . is_ok_and ( |( _, transformer_params) | transformer_params. is_some ( ) )
196+ {
197+ Some ( CodeGeneratorKind :: DataclassLike )
198+ } else if class
199+ . explicit_bases ( db)
200+ . iter ( )
201+ . copied ( )
202+ . filter_map ( Type :: into_class_literal)
203+ . any ( |class| class. is_known ( db, KnownClass :: NamedTuple ) )
204+ {
205+ Some ( CodeGeneratorKind :: NamedTuple )
206+ } else if class. is_typed_dict ( db) {
207+ Some ( CodeGeneratorKind :: TypedDict )
208+ } else {
209+ None
210+ }
211+ }
212+
213+ fn code_generator_of_class_initial (
214+ _db : & dyn Db ,
215+ _class : ClassLiteral < ' _ > ,
216+ ) -> Option < CodeGeneratorKind > {
190217 None
191218 }
192- }
193219
194- fn matches < ' db > ( self , db : & ' db dyn Db , class : ClassLiteral < ' db > ) -> bool {
195- match self {
196- Self :: DataclassLike => {
197- class. dataclass_params ( db) . is_some ( )
198- || class
199- . try_metaclass ( db)
200- . is_ok_and ( |( _, transformer_params) | transformer_params. is_some ( ) )
201- }
202- Self :: NamedTuple => class. explicit_bases ( db) . iter ( ) . any ( |base| {
203- base. into_class_literal ( )
204- . is_some_and ( |c| c. is_known ( db, KnownClass :: NamedTuple ) )
205- } ) ,
206- Self :: TypedDict => class. is_typed_dict ( db) ,
220+ #[ expect( clippy:: ref_option, clippy:: trivially_copy_pass_by_ref) ]
221+ fn code_generator_of_class_recover (
222+ _db : & dyn Db ,
223+ _value : & Option < CodeGeneratorKind > ,
224+ _count : u32 ,
225+ _class : ClassLiteral < ' _ > ,
226+ ) -> salsa:: CycleRecoveryAction < Option < CodeGeneratorKind > > {
227+ salsa:: CycleRecoveryAction :: Iterate
207228 }
229+
230+ code_generator_of_class ( db, class)
231+ }
232+
233+ fn matches ( self , db : & dyn Db , class : ClassLiteral < ' _ > ) -> bool {
234+ CodeGeneratorKind :: from_class ( db, class) == Some ( self )
208235 }
209236}
210237
0 commit comments