1+ use std:: collections:: BTreeMap ;
2+
13use ruff_python_ast:: name:: Name ;
24use rustc_hash:: FxHashMap ;
35
46use crate :: {
5- Db , FxOrderSet ,
7+ Db , FxOrderMap ,
68 place:: { Place , PlaceAndQualifiers , place_from_bindings, place_from_declarations} ,
79 semantic_index:: { place_table, use_def_map} ,
810 types:: {
@@ -11,44 +13,52 @@ use crate::{
1113 } ,
1214} ;
1315
14- #[ derive( Debug , PartialEq , Eq ) ]
15- pub ( crate ) struct EnumMetadata {
16- pub ( crate ) members : FxOrderSet < Name > ,
17- pub ( crate ) aliases : FxHashMap < Name , Name > ,
16+ #[ salsa:: interned( debug, heap_size=EnumMetadata :: heap_size) ]
17+ pub ( crate ) struct EnumMetadata < ' db > {
18+ #[ returns( ref) ]
19+ pub ( crate ) members : FxOrderMap < Name , Type < ' db > > ,
20+ #[ returns( ref) ]
21+ pub ( crate ) aliases : BTreeMap < Name , Name > ,
1822}
1923
20- impl get_size2:: GetSize for EnumMetadata { }
24+ impl get_size2:: GetSize for EnumMetadata < ' _ > { }
2125
22- impl EnumMetadata {
23- fn empty ( ) -> Self {
24- EnumMetadata {
25- members : FxOrderSet :: default ( ) ,
26- aliases : FxHashMap :: default ( ) ,
27- }
26+ impl < ' db > EnumMetadata < ' db > {
27+ fn empty ( db : & ' db dyn Db ) -> Self {
28+ EnumMetadata :: new ( db, FxOrderMap :: default ( ) , BTreeMap :: default ( ) )
2829 }
2930
30- pub ( crate ) fn resolve_member < ' a > ( & ' a self , name : & ' a Name ) -> Option < & ' a Name > {
31- if self . members . contains ( name) {
31+ pub ( crate ) fn resolve_member < ' a > ( & ' a self , db : & ' a dyn Db , name : & ' a Name ) -> Option < & ' a Name > {
32+ if self . members ( db ) . contains_key ( name) {
3233 Some ( name)
3334 } else {
34- self . aliases . get ( name)
35+ self . aliases ( db ) . get ( name)
3536 }
3637 }
38+
39+ fn heap_size (
40+ ( members, aliases) : & ( FxOrderMap < Name , Type < ' db > > , BTreeMap < Name , Name > ) ,
41+ ) -> usize {
42+ ruff_memory_usage:: order_map_heap_size ( members) + ruff_memory_usage:: heap_size ( aliases)
43+ }
3744}
3845
39- #[ allow( clippy:: ref_option) ]
40- fn enum_metadata_cycle_recover (
41- _db : & dyn Db ,
42- _value : & Option < EnumMetadata > ,
46+ #[ allow( clippy:: ref_option, clippy :: trivially_copy_pass_by_ref ) ]
47+ fn enum_metadata_cycle_recover < ' db > (
48+ _db : & ' db dyn Db ,
49+ _value : & Option < EnumMetadata < ' db > > ,
4350 _count : u32 ,
44- _class : ClassLiteral < ' _ > ,
45- ) -> salsa:: CycleRecoveryAction < Option < EnumMetadata > > {
51+ _class : ClassLiteral < ' db > ,
52+ ) -> salsa:: CycleRecoveryAction < Option < EnumMetadata < ' db > > > {
4653 salsa:: CycleRecoveryAction :: Iterate
4754}
4855
4956#[ allow( clippy:: unnecessary_wraps) ]
50- fn enum_metadata_cycle_initial ( _db : & dyn Db , _class : ClassLiteral < ' _ > ) -> Option < EnumMetadata > {
51- Some ( EnumMetadata :: empty ( ) )
57+ fn enum_metadata_cycle_initial < ' db > (
58+ db : & ' db dyn Db ,
59+ _class : ClassLiteral < ' db > ,
60+ ) -> Option < EnumMetadata < ' db > > {
61+ Some ( EnumMetadata :: empty ( db) )
5262}
5363
5464/// List all members of an enum.
@@ -57,7 +67,7 @@ fn enum_metadata_cycle_initial(_db: &dyn Db, _class: ClassLiteral<'_>) -> Option
5767pub ( crate ) fn enum_metadata < ' db > (
5868 db : & ' db dyn Db ,
5969 class : ClassLiteral < ' db > ,
60- ) -> Option < EnumMetadata > {
70+ ) -> Option < EnumMetadata < ' db > > {
6171 // This is a fast path to avoid traversing the MRO of known classes
6272 if class
6373 . known ( db)
@@ -97,7 +107,7 @@ pub(crate) fn enum_metadata<'db>(
97107 None
98108 } ;
99109
100- let mut aliases = FxHashMap :: default ( ) ;
110+ let mut aliases = BTreeMap :: default ( ) ;
101111
102112 let members = use_def_map
103113 . all_end_of_scope_symbol_bindings ( )
@@ -217,16 +227,16 @@ pub(crate) fn enum_metadata<'db>(
217227 }
218228 }
219229
220- Some ( name. clone ( ) )
230+ Some ( ( name. clone ( ) , value_ty ) )
221231 } )
222- . collect :: < FxOrderSet < _ > > ( ) ;
232+ . collect :: < FxOrderMap < _ , _ > > ( ) ;
223233
224234 if members. is_empty ( ) {
225235 // Enum subclasses without members are not considered enums.
226236 return None ;
227237 }
228238
229- Some ( EnumMetadata { members, aliases } )
239+ Some ( EnumMetadata :: new ( db , members, aliases) )
230240}
231241
232242pub ( crate ) fn enum_member_literals < ' a , ' db : ' a > (
@@ -236,15 +246,15 @@ pub(crate) fn enum_member_literals<'a, 'db: 'a>(
236246) -> Option < impl Iterator < Item = Type < ' a > > + ' a > {
237247 enum_metadata ( db, class) . map ( |metadata| {
238248 metadata
239- . members
240- . iter ( )
249+ . members ( db )
250+ . keys ( )
241251 . filter ( move |name| Some ( * name) != exclude_member)
242252 . map ( move |name| Type :: EnumLiteral ( EnumLiteralType :: new ( db, class, name. clone ( ) ) ) )
243253 } )
244254}
245255
246256pub ( crate ) fn is_single_member_enum < ' db > ( db : & ' db dyn Db , class : ClassLiteral < ' db > ) -> bool {
247- enum_metadata ( db, class) . is_some_and ( |metadata| metadata. members . len ( ) == 1 )
257+ enum_metadata ( db, class) . is_some_and ( |metadata| metadata. members ( db ) . len ( ) == 1 )
248258}
249259
250260pub ( crate ) fn is_enum_class < ' db > ( db : & ' db dyn Db , ty : Type < ' db > ) -> bool {
0 commit comments