1
1
use ruff_db:: files:: File ;
2
- use ruff_python_ast:: name :: Name ;
2
+ use ruff_python_ast as ast ;
3
3
4
4
use crate :: builtins:: builtins_scope;
5
- use crate :: semantic_index:: definition:: Definition ;
5
+ use crate :: semantic_index:: ast_ids:: HasScopedAstId ;
6
+ use crate :: semantic_index:: definition:: { Definition , DefinitionKind } ;
6
7
use crate :: semantic_index:: symbol:: { ScopeId , ScopedSymbolId } ;
7
8
use crate :: semantic_index:: {
8
9
global_scope, semantic_index, symbol_table, use_def_map, DefinitionWithConstraints ,
@@ -14,7 +15,8 @@ use crate::{Db, FxOrderSet};
14
15
pub ( crate ) use self :: builder:: { IntersectionBuilder , UnionBuilder } ;
15
16
pub ( crate ) use self :: diagnostic:: TypeCheckDiagnostics ;
16
17
pub ( crate ) use self :: infer:: {
17
- infer_definition_types, infer_expression_types, infer_scope_types, TypeInference ,
18
+ infer_deferred_types, infer_definition_types, infer_expression_types, infer_scope_types,
19
+ TypeInference ,
18
20
} ;
19
21
20
22
mod builder;
@@ -88,6 +90,24 @@ pub(crate) fn definition_ty<'db>(db: &'db dyn Db, definition: Definition<'db>) -
88
90
inference. definition_ty ( definition)
89
91
}
90
92
93
+ /// Infer the type of a (possibly deferred) sub-expression of a [`Definition`].
94
+ ///
95
+ /// ## Panics
96
+ /// If the given expression is not a sub-expression of the given [`Definition`].
97
+ pub ( crate ) fn definition_expression_ty < ' db > (
98
+ db : & ' db dyn Db ,
99
+ definition : Definition < ' db > ,
100
+ expression : & ast:: Expr ,
101
+ ) -> Type < ' db > {
102
+ let expr_id = expression. scoped_ast_id ( db, definition. scope ( db) ) ;
103
+ let inference = infer_definition_types ( db, definition) ;
104
+ if let Some ( ty) = inference. try_expression_ty ( expr_id) {
105
+ ty
106
+ } else {
107
+ infer_deferred_types ( db, definition) . expression_ty ( expr_id)
108
+ }
109
+ }
110
+
91
111
/// Infer the combined type of an array of [`Definition`]s, plus one optional "unbound type".
92
112
///
93
113
/// Will return a union if there is more than one definition, or at least one plus an unbound
@@ -243,7 +263,7 @@ impl<'db> Type<'db> {
243
263
/// us to explicitly consider whether to handle an error or propagate
244
264
/// it up the call stack.
245
265
#[ must_use]
246
- pub fn member ( & self , db : & ' db dyn Db , name : & Name ) -> Type < ' db > {
266
+ pub fn member ( & self , db : & ' db dyn Db , name : & ast :: name :: Name ) -> Type < ' db > {
247
267
match self {
248
268
Type :: Any => Type :: Any ,
249
269
Type :: Never => {
@@ -314,7 +334,7 @@ impl<'db> Type<'db> {
314
334
#[ salsa:: interned]
315
335
pub struct FunctionType < ' db > {
316
336
/// name of the function at definition
317
- pub name : Name ,
337
+ pub name : ast :: name :: Name ,
318
338
319
339
/// types of all decorators on this function
320
340
decorators : Vec < Type < ' db > > ,
@@ -329,19 +349,33 @@ impl<'db> FunctionType<'db> {
329
349
#[ salsa:: interned]
330
350
pub struct ClassType < ' db > {
331
351
/// Name of the class at definition
332
- pub name : Name ,
352
+ pub name : ast :: name :: Name ,
333
353
334
- /// Types of all class bases
335
- bases : Vec < Type < ' db > > ,
354
+ definition : Definition < ' db > ,
336
355
337
356
body_scope : ScopeId < ' db > ,
338
357
}
339
358
340
359
impl < ' db > ClassType < ' db > {
360
+ /// Return an iterator over the types of this class's bases.
361
+ ///
362
+ /// # Panics:
363
+ /// If `definition` is not a `DefinitionKind::Class`.
364
+ pub fn bases ( & self , db : & ' db dyn Db ) -> impl Iterator < Item = Type < ' db > > {
365
+ let definition = self . definition ( db) ;
366
+ let DefinitionKind :: Class ( class_stmt_node) = definition. node ( db) else {
367
+ panic ! ( "Class type definition must have DefinitionKind::Class" ) ;
368
+ } ;
369
+ class_stmt_node
370
+ . bases ( )
371
+ . iter ( )
372
+ . map ( move |base_expr| definition_expression_ty ( db, definition, base_expr) )
373
+ }
374
+
341
375
/// Returns the class member of this class named `name`.
342
376
///
343
377
/// The member resolves to a member of the class itself or any of its bases.
344
- pub fn class_member ( self , db : & ' db dyn Db , name : & Name ) -> Type < ' db > {
378
+ pub fn class_member ( self , db : & ' db dyn Db , name : & ast :: name :: Name ) -> Type < ' db > {
345
379
let member = self . own_class_member ( db, name) ;
346
380
if !member. is_unbound ( ) {
347
381
return member;
@@ -351,12 +385,12 @@ impl<'db> ClassType<'db> {
351
385
}
352
386
353
387
/// Returns the inferred type of the class member named `name`.
354
- pub fn own_class_member ( self , db : & ' db dyn Db , name : & Name ) -> Type < ' db > {
388
+ pub fn own_class_member ( self , db : & ' db dyn Db , name : & ast :: name :: Name ) -> Type < ' db > {
355
389
let scope = self . body_scope ( db) ;
356
390
symbol_ty_by_name ( db, scope, name)
357
391
}
358
392
359
- pub fn inherited_class_member ( self , db : & ' db dyn Db , name : & Name ) -> Type < ' db > {
393
+ pub fn inherited_class_member ( self , db : & ' db dyn Db , name : & ast :: name :: Name ) -> Type < ' db > {
360
394
for base in self . bases ( db) {
361
395
let member = base. member ( db, name) ;
362
396
if !member. is_unbound ( ) {
0 commit comments