1
1
#![ allow( dead_code) ]
2
2
use crate :: ast_ids:: NodeKey ;
3
+ use crate :: db:: { HasJar , QueryResult , SemanticDb , SemanticJar } ;
3
4
use crate :: files:: FileId ;
4
- use crate :: symbols:: SymbolId ;
5
+ use crate :: symbols:: { ScopeId , SymbolId } ;
5
6
use crate :: { FxDashMap , FxIndexSet , Name } ;
6
7
use ruff_index:: { newtype_index, IndexVec } ;
7
8
use rustc_hash:: FxHashMap ;
@@ -124,8 +125,15 @@ impl TypeStore {
124
125
. add_function ( name, decorators)
125
126
}
126
127
127
- fn add_class ( & self , file_id : FileId , name : & str , bases : Vec < Type > ) -> ClassTypeId {
128
- self . add_or_get_module ( file_id) . add_class ( name, bases)
128
+ fn add_class (
129
+ & self ,
130
+ file_id : FileId ,
131
+ name : & str ,
132
+ scope_id : ScopeId ,
133
+ bases : Vec < Type > ,
134
+ ) -> ClassTypeId {
135
+ self . add_or_get_module ( file_id)
136
+ . add_class ( name, scope_id, bases)
129
137
}
130
138
131
139
fn add_union ( & mut self , file_id : FileId , elems : & [ Type ] ) -> UnionTypeId {
@@ -253,6 +261,24 @@ pub struct ClassTypeId {
253
261
class_id : ModuleClassTypeId ,
254
262
}
255
263
264
+ impl ClassTypeId {
265
+ fn get_own_class_member < Db > ( self , db : & Db , name : & Name ) -> QueryResult < Option < Type > >
266
+ where
267
+ Db : SemanticDb + HasJar < SemanticJar > ,
268
+ {
269
+ // TODO: this should distinguish instance-only members (e.g. `x: int`) and not return them
270
+ let ClassType { scope_id, .. } = * db. jar ( ) ?. type_store . get_class ( self ) ;
271
+ let table = db. symbol_table ( self . file_id ) ?;
272
+ if let Some ( symbol_id) = table. symbol_id_by_name ( scope_id, name) {
273
+ Ok ( Some ( db. infer_symbol_type ( self . file_id , symbol_id) ?) )
274
+ } else {
275
+ Ok ( None )
276
+ }
277
+ }
278
+
279
+ // TODO: get_own_instance_member, get_class_member, get_instance_member
280
+ }
281
+
256
282
#[ derive( Copy , Clone , Debug , Hash , Eq , PartialEq ) ]
257
283
pub struct UnionTypeId {
258
284
file_id : FileId ,
@@ -318,9 +344,10 @@ impl ModuleTypeStore {
318
344
}
319
345
}
320
346
321
- fn add_class ( & mut self , name : & str , bases : Vec < Type > ) -> ClassTypeId {
347
+ fn add_class ( & mut self , name : & str , scope_id : ScopeId , bases : Vec < Type > ) -> ClassTypeId {
322
348
let class_id = self . classes . push ( ClassType {
323
349
name : Name :: new ( name) ,
350
+ scope_id,
324
351
// TODO: if no bases are given, that should imply [object]
325
352
bases,
326
353
} ) ;
@@ -405,7 +432,11 @@ impl std::fmt::Display for DisplayType<'_> {
405
432
406
433
#[ derive( Debug ) ]
407
434
pub ( crate ) struct ClassType {
435
+ /// Name of the class at definition
408
436
name : Name ,
437
+ /// `ScopeId` of the class body
438
+ pub ( crate ) scope_id : ScopeId ,
439
+ /// Types of all class bases
409
440
bases : Vec < Type > ,
410
441
}
411
442
@@ -496,6 +527,7 @@ impl IntersectionType {
496
527
#[ cfg( test) ]
497
528
mod tests {
498
529
use crate :: files:: Files ;
530
+ use crate :: symbols:: SymbolTable ;
499
531
use crate :: types:: { Type , TypeStore } ;
500
532
use crate :: FxIndexSet ;
501
533
use std:: path:: Path ;
@@ -505,7 +537,7 @@ mod tests {
505
537
let store = TypeStore :: default ( ) ;
506
538
let files = Files :: default ( ) ;
507
539
let file_id = files. intern ( Path :: new ( "/foo" ) ) ;
508
- let id = store. add_class ( file_id, "C" , Vec :: new ( ) ) ;
540
+ let id = store. add_class ( file_id, "C" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
509
541
assert_eq ! ( store. get_class( id) . name( ) , "C" ) ;
510
542
let inst = Type :: Instance ( id) ;
511
543
assert_eq ! ( format!( "{}" , inst. display( & store) ) , "C" ) ;
@@ -528,8 +560,8 @@ mod tests {
528
560
let mut store = TypeStore :: default ( ) ;
529
561
let files = Files :: default ( ) ;
530
562
let file_id = files. intern ( Path :: new ( "/foo" ) ) ;
531
- let c1 = store. add_class ( file_id, "C1" , Vec :: new ( ) ) ;
532
- let c2 = store. add_class ( file_id, "C2" , Vec :: new ( ) ) ;
563
+ let c1 = store. add_class ( file_id, "C1" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
564
+ let c2 = store. add_class ( file_id, "C2" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
533
565
let elems = vec ! [ Type :: Instance ( c1) , Type :: Instance ( c2) ] ;
534
566
let id = store. add_union ( file_id, & elems) ;
535
567
assert_eq ! (
@@ -545,9 +577,9 @@ mod tests {
545
577
let mut store = TypeStore :: default ( ) ;
546
578
let files = Files :: default ( ) ;
547
579
let file_id = files. intern ( Path :: new ( "/foo" ) ) ;
548
- let c1 = store. add_class ( file_id, "C1" , Vec :: new ( ) ) ;
549
- let c2 = store. add_class ( file_id, "C2" , Vec :: new ( ) ) ;
550
- let c3 = store. add_class ( file_id, "C3" , Vec :: new ( ) ) ;
580
+ let c1 = store. add_class ( file_id, "C1" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
581
+ let c2 = store. add_class ( file_id, "C2" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
582
+ let c3 = store. add_class ( file_id, "C3" , SymbolTable :: root_scope_id ( ) , Vec :: new ( ) ) ;
551
583
let pos = vec ! [ Type :: Instance ( c1) , Type :: Instance ( c2) ] ;
552
584
let neg = vec ! [ Type :: Instance ( c3) ] ;
553
585
let id = store. add_intersection ( file_id, & pos, & neg) ;
0 commit comments