@@ -168,7 +168,7 @@ fn try_metaclass_cycle_initial<'db>(
168
168
}
169
169
170
170
/// 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 ) ]
172
172
pub ( crate ) enum CodeGeneratorKind {
173
173
/// Classes decorated with `@dataclass` or similar dataclass-like decorators
174
174
DataclassLike ,
@@ -180,31 +180,58 @@ pub(crate) enum CodeGeneratorKind {
180
180
181
181
impl CodeGeneratorKind {
182
182
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 > {
190
217
None
191
218
}
192
- }
193
219
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
207
228
}
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 )
208
235
}
209
236
}
210
237
0 commit comments