|
| 1 | +use crate::module_name::ModuleName; |
| 2 | +use crate::module_resolver::resolve_module; |
| 3 | +use crate::semantic_index::global_scope; |
| 4 | +use crate::semantic_index::symbol::ScopeId; |
| 5 | +use crate::types::{global_symbol_ty, Type}; |
| 6 | +use crate::Db; |
| 7 | + |
| 8 | +/// Enumeration of various core stdlib modules, for which we have dedicated Salsa queries. |
| 9 | +#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 10 | +enum CoreStdlibModule { |
| 11 | + Builtins, |
| 12 | + Types, |
| 13 | + Typeshed, |
| 14 | +} |
| 15 | + |
| 16 | +impl CoreStdlibModule { |
| 17 | + fn name(self) -> ModuleName { |
| 18 | + let module_name = match self { |
| 19 | + Self::Builtins => "builtins", |
| 20 | + Self::Types => "types", |
| 21 | + Self::Typeshed => "_typeshed", |
| 22 | + }; |
| 23 | + ModuleName::new_static(module_name) |
| 24 | + .unwrap_or_else(|| panic!("{module_name} should be a valid module name!")) |
| 25 | + } |
| 26 | +} |
| 27 | + |
| 28 | +/// Lookup the type of `symbol` in a given core module |
| 29 | +/// |
| 30 | +/// Returns `Unbound` if the given core module cannot be resolved for some reason |
| 31 | +fn core_module_symbol_ty<'db>( |
| 32 | + db: &'db dyn Db, |
| 33 | + core_module: CoreStdlibModule, |
| 34 | + symbol: &str, |
| 35 | +) -> Type<'db> { |
| 36 | + resolve_module(db, core_module.name()) |
| 37 | + .map(|module| global_symbol_ty(db, module.file(), symbol)) |
| 38 | + .unwrap_or(Type::Unbound) |
| 39 | +} |
| 40 | + |
| 41 | +/// Lookup the type of `symbol` in the builtins namespace. |
| 42 | +/// |
| 43 | +/// Returns `Unbound` if the `builtins` module isn't available for some reason. |
| 44 | +#[inline] |
| 45 | +pub(crate) fn builtins_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> { |
| 46 | + core_module_symbol_ty(db, CoreStdlibModule::Builtins, symbol) |
| 47 | +} |
| 48 | + |
| 49 | +/// Lookup the type of `symbol` in the `types` module namespace. |
| 50 | +/// |
| 51 | +/// Returns `Unbound` if the `types` module isn't available for some reason. |
| 52 | +#[inline] |
| 53 | +pub(crate) fn types_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> { |
| 54 | + core_module_symbol_ty(db, CoreStdlibModule::Types, symbol) |
| 55 | +} |
| 56 | + |
| 57 | +/// Lookup the type of `symbol` in the `_typeshed` module namespace. |
| 58 | +/// |
| 59 | +/// Returns `Unbound` if the `_typeshed` module isn't available for some reason. |
| 60 | +#[inline] |
| 61 | +pub(crate) fn typeshed_symbol_ty<'db>(db: &'db dyn Db, symbol: &str) -> Type<'db> { |
| 62 | + core_module_symbol_ty(db, CoreStdlibModule::Typeshed, symbol) |
| 63 | +} |
| 64 | + |
| 65 | +/// Get the scope of a core stdlib module. |
| 66 | +/// |
| 67 | +/// Can return `None` if a custom typeshed is used that is missing the core module in question. |
| 68 | +fn core_module_scope(db: &dyn Db, core_module: CoreStdlibModule) -> Option<ScopeId<'_>> { |
| 69 | + resolve_module(db, core_module.name()).map(|module| global_scope(db, module.file())) |
| 70 | +} |
| 71 | + |
| 72 | +/// Get the `builtins` module scope. |
| 73 | +/// |
| 74 | +/// Can return `None` if a custom typeshed is used that is missing `builtins.pyi`. |
| 75 | +pub(crate) fn builtins_module_scope(db: &dyn Db) -> Option<ScopeId<'_>> { |
| 76 | + core_module_scope(db, CoreStdlibModule::Builtins) |
| 77 | +} |
0 commit comments