From f19529ab455a08fd0d108490fd226b91e3225f32 Mon Sep 17 00:00:00 2001 From: Grant Wuerker Date: Wed, 13 Dec 2023 15:08:56 -0700 Subject: [PATCH] hacking --- crates/analyzer/src/context.rs | 40 +++++++++++++--- crates/analyzer/src/db.rs | 2 + crates/analyzer/src/db/queries/module.rs | 60 ++++++++++++++++++++++++ crates/analyzer/src/namespace/items.rs | 15 +++++- 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/crates/analyzer/src/context.rs b/crates/analyzer/src/context.rs index 180b741cce..359df1b0b1 100644 --- a/crates/analyzer/src/context.rs +++ b/crates/analyzer/src/context.rs @@ -295,14 +295,42 @@ impl NamedThing { } } - match self { - Self::Item(item) => item - .items(db) - .get(segment) - .map(|resolved| NamedThing::Item(*resolved)), + if let Self::Item(Item::Type(TypeDef::Struct(struct_))) = self { + if let Some(fun) = struct_ + .all_functions(db) + .iter() + .find(|fun| fun.name(db) == *segment) + { + return Some(NamedThing::Item(Item::Function(*fun))); + } + } + + if let Self::Item(Item::Module(module)) = self { + if let Some(item) = module.resolve_name(db, &segment).unwrap() { + return Some(item); + } + } + + if let Self::Item(Item::Ingot(ingot)) = self { + if let Some(module) = ingot + .all_modules(db) + .iter() + .find(|module| module.name(db) == *segment) + { + return Some(NamedThing::Item(Item::Module(*module))); + } - _ => None, + if let Some(item) = ingot + .root_module(db) + .unwrap() + .resolve_name(db, &segment) + .unwrap() + { + return Some(item); + } } + + None } } diff --git a/crates/analyzer/src/db.rs b/crates/analyzer/src/db.rs index bfe6f08ebf..9084b1c18b 100644 --- a/crates/analyzer/src/db.rs +++ b/crates/analyzer/src/db.rs @@ -83,6 +83,8 @@ pub trait AnalyzerDb: SourceDb + Upcast + UpcastMut fn module_parse(&self, module: ModuleId) -> Analysis>; #[salsa::invoke(queries::module::module_is_incomplete)] fn module_is_incomplete(&self, module: ModuleId) -> bool; + #[salsa::invoke(queries::module::module_named_item)] + fn module_named_item(&self, module: ModuleId, name: SmolStr) -> Option; #[salsa::invoke(queries::module::module_all_items)] fn module_all_items(&self, module: ModuleId) -> Rc<[Item]>; #[salsa::invoke(queries::module::module_all_impls)] diff --git a/crates/analyzer/src/db/queries/module.rs b/crates/analyzer/src/db/queries/module.rs index 6874ffbae4..63e312e5ed 100644 --- a/crates/analyzer/src/db/queries/module.rs +++ b/crates/analyzer/src/db/queries/module.rs @@ -113,6 +113,66 @@ pub fn module_all_items(db: &dyn AnalyzerDb, module: ModuleId) -> Rc<[Item]> { .collect() } +pub fn module_named_item(db: &dyn AnalyzerDb, module: ModuleId, name: SmolStr) -> Option { + let body = &module.ast(db).body; + for stmt in body { + if let Some(item) = match stmt { + ast::ModuleStmt::TypeAlias(node) => Some(Item::Type(TypeDef::Alias( + db.intern_type_alias(Rc::new(TypeAlias { + ast: node.clone(), + module, + })), + ))), + ast::ModuleStmt::Contract(node) => Some(Item::Type(TypeDef::Contract( + db.intern_contract(Rc::new(Contract { + name: node.name().into(), + ast: node.clone(), + module, + })), + ))), + ast::ModuleStmt::Struct(node) => Some(Item::Type(TypeDef::Struct(db.intern_struct( + Rc::new(Struct { + ast: node.clone(), + module, + }), + )))), + ast::ModuleStmt::Enum(node) => { + Some(Item::Type(TypeDef::Enum(db.intern_enum(Rc::new(Enum { + ast: node.clone(), + module, + }))))) + } + ast::ModuleStmt::Constant(node) => Some(Item::Constant(db.intern_module_const( + Rc::new(ModuleConstant { + ast: node.clone(), + module, + }), + ))), + ast::ModuleStmt::Function(node) => Some(Item::Function( + db.intern_function(Rc::new(Function::new(db, node, None, module))), + )), + ast::ModuleStmt::Trait(node) => Some(Item::Trait(db.intern_trait(Rc::new(Trait { + ast: node.clone(), + module, + })))), + ast::ModuleStmt::Attribute(node) => { + Some(Item::Attribute(db.intern_attribute(Rc::new(Attribute { + ast: node.clone(), + module, + })))) + } + ast::ModuleStmt::Pragma(_) | ast::ModuleStmt::Use(_) | ast::ModuleStmt::Impl(_) => None, + ast::ModuleStmt::ParseError(_) => None, + } { + if item.name(db) == name { + return Some(item); + } + } + } + + None +} + pub fn module_all_impls(db: &dyn AnalyzerDb, module: ModuleId) -> Analysis> { let body = &module.ast(db).body; let mut scope = ItemScope::new(db, module); diff --git a/crates/analyzer/src/namespace/items.rs b/crates/analyzer/src/namespace/items.rs index 2ff5a3c625..1ca7a61eca 100644 --- a/crates/analyzer/src/namespace/items.rs +++ b/crates/analyzer/src/namespace/items.rs @@ -704,8 +704,18 @@ impl ModuleId { db: &dyn AnalyzerDb, name: &str, ) -> Result, IncompleteItem> { - if let Some(thing) = self.internal_items(db).get(name) { - Ok(Some(NamedThing::Item(*thing))) + if let Some(thing) = db.module_named_item(*self, name.into()) { + Ok(Some(NamedThing::Item(thing))) + } else if let Some(item) = self.global_items(db).get(name) { + Ok(Some(NamedThing::Item(*item))) + } else if let Some(item) = db.module_used_item_map(*self).value.get(name) { + Ok(Some(NamedThing::Item(item.1))) + } else if let Some(item) = self + .submodules(db) + .iter() + .find(|module| module.name(db) == name) + { + Ok(Some(NamedThing::Item(Item::Module(*item)))) } else if self.is_incomplete(db) { Err(IncompleteItem::new()) } else { @@ -731,6 +741,7 @@ impl ModuleId { Ok(None) } } + pub fn submodules(&self, db: &dyn AnalyzerDb) -> Rc<[ModuleId]> { db.module_submodules(*self) }