diff --git a/crates/analyzer/src/names.rs b/crates/analyzer/src/names.rs index 2a6e2b91..ffb5f3f9 100644 --- a/crates/analyzer/src/names.rs +++ b/crates/analyzer/src/names.rs @@ -4,7 +4,7 @@ //! the interning mechanism [`interner::Interner`]; this makes them cheap to clone and relatively //! easy to clean up as they're discarded. -use std::sync::Arc; +use std::{fmt::Display, ops::Deref, sync::Arc}; use rowan::ast::AstNode; use syntax::ast; @@ -81,16 +81,30 @@ impl AsRef for Name { } } -/// Names appearing as usages. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct NameRef(Arc); +impl Deref for Name { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} -impl NameRef { - pub(crate) fn from_raw(raw: Arc) -> NameRef { - NameRef(raw) +impl From for Name { + fn from(value: NameRef) -> Name { + Name(value.0) } } +impl Display for Name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.as_ref().fmt(f) + } +} + +/// Names appearing as usages. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct NameRef(Arc); + impl InDb for ast::NameRef { fn in_db(self, db: &(impl SourceDatabase + ?Sized)) -> Option { Some(NameRef(db.interner().intern(self.token()?.text()))) @@ -103,6 +117,26 @@ impl AsRef for NameRef { } } +impl Deref for NameRef { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for NameRef { + fn from(value: Name) -> NameRef { + NameRef(value.0) + } +} + +impl Display for NameRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.as_ref().fmt(f) + } +} + /// Values optionally qualified by a [`ModuleName`]. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Qualified { diff --git a/crates/analyzer/src/resolver/nominal.rs b/crates/analyzer/src/resolver/nominal.rs index a5b37ad6..ebc5e065 100644 --- a/crates/analyzer/src/resolver/nominal.rs +++ b/crates/analyzer/src/resolver/nominal.rs @@ -7,11 +7,11 @@ use itertools::Itertools; use la_arena::{Arena, Idx}; use rowan::ast::{AstChildren, AstNode}; use rustc_hash::{FxHashMap, FxHashSet}; -use smol_str::SmolStr; use syntax::ast; use crate::{ id::{AstId, InFile}, + names::{InDb, Name}, ResolverDatabase, }; @@ -19,17 +19,17 @@ use super::PositionalMap; #[derive(Debug, PartialEq, Eq)] pub struct DataGroup { - pub name: SmolStr, + pub name: Name, pub annotation: Option>, pub declaration: AstId, - pub constructors: FxHashMap>, + pub constructors: FxHashMap>, } pub type DataGroupId = Idx; #[derive(Debug, PartialEq, Eq)] pub struct ValueGroup { - pub name: SmolStr, + pub name: Name, pub annotation: Option>, pub equations: FxHashSet>, } @@ -53,11 +53,11 @@ pub struct NominalMap { file_id: FileId, data_groups: Arena, - name_to_data: FxHashMap, - name_to_constructor: FxHashMap)>, + name_to_data: FxHashMap, DataGroupId>, + name_to_constructor: FxHashMap, (DataGroupId, AstId)>, value_groups: Arena, - name_to_value: FxHashMap, + name_to_value: FxHashMap, ValueGroupId>, } impl NominalMap { @@ -88,7 +88,7 @@ impl NominalMap { if let Some(declarations) = declarations { let positional_map = db.positional_map(file_id); - collect(&mut nominal_map, &positional_map, declarations); + collect(db, &mut nominal_map, &positional_map, declarations); } Arc::new(nominal_map) @@ -142,11 +142,12 @@ impl NominalMap { #[derive(Debug, PartialEq, Eq)] enum DeclarationKey { - Data(Option), - Value(Option), + Data(Option), + Value(Option), } fn collect( + db: &dyn ResolverDatabase, nominal_map: &mut NominalMap, positional_map: &PositionalMap, declarations: AstChildren, @@ -159,24 +160,24 @@ fn collect( let groups = declarations.group_by(|declaration| match declaration { ast::Declaration::DataAnnotation(data) => { - DeclarationKey::Data(data.name().and_then(|name| name.as_str())) + DeclarationKey::Data(data.name().and_then(|name| name.in_db(db))) } ast::Declaration::DataDeclaration(data) => { - DeclarationKey::Data(data.name().and_then(|name| name.as_str())) + DeclarationKey::Data(data.name().and_then(|name| name.in_db(db))) } ast::Declaration::ForeignDataDeclaration(_) => todo!("Unimplemented!"), ast::Declaration::ValueAnnotationDeclaration(value) => { - DeclarationKey::Value(value.name().and_then(|name| name.as_str())) + DeclarationKey::Value(value.name().and_then(|name| name.in_db(db))) } ast::Declaration::ValueEquationDeclaration(value) => { - DeclarationKey::Value(value.name().and_then(|name| name.as_str())) + DeclarationKey::Value(value.name().and_then(|name| name.in_db(db))) } }); for (key, group) in groups.into_iter() { match key { DeclarationKey::Data(name) => { - collect_data(nominal_map, positional_map, name, group)?; + collect_data(db, nominal_map, positional_map, name, group)?; } DeclarationKey::Value(name) => { collect_value(nominal_map, positional_map, name, group)?; @@ -188,9 +189,10 @@ fn collect( } fn collect_data( + db: &dyn ResolverDatabase, nominal_map: &mut NominalMap, positional_map: &PositionalMap, - name: Option, + name: Option, group: impl Iterator, ) -> Option<()> { let name = name?; @@ -209,11 +211,11 @@ fn collect_data( let mut constructors = FxHashMap::default(); for constructor_ast in d.constructors()?.children() { - let constructor_name = constructor_ast.name()?.as_str()?; + let constructor_name = constructor_ast.name()?.in_db(db)?; constructors.insert(constructor_name, positional_map.ast_id(&constructor_ast)); } - let data_name = name.clone(); + let data_name = Arc::clone(&name); let data_group_id = nominal_map.data_groups.alloc(DataGroup { name, annotation, @@ -227,7 +229,7 @@ fn collect_data( for (constructor_name, constructor_id) in data_group.constructors.iter() { nominal_map .name_to_constructor - .insert(constructor_name.clone(), (data_group_id, *constructor_id)); + .insert(Arc::clone(constructor_name), (data_group_id, *constructor_id)); } } else { unreachable!("Impossible."); @@ -239,7 +241,7 @@ fn collect_data( fn collect_value( nominal_map: &mut NominalMap, positional_map: &PositionalMap, - name: Option, + name: Option, group: impl Iterator, ) -> Option<()> { let name = name?; @@ -266,7 +268,7 @@ fn collect_value( } })); - let value_name = name.clone(); + let value_name = Arc::clone(&name); let value_index = nominal_map.value_groups.alloc(ValueGroup { name, annotation, equations }); nominal_map.name_to_value.insert(value_name, value_index); diff --git a/crates/analyzer/src/surface/lower.rs b/crates/analyzer/src/surface/lower.rs index 4cd8c47c..16465f27 100644 --- a/crates/analyzer/src/surface/lower.rs +++ b/crates/analyzer/src/surface/lower.rs @@ -67,7 +67,7 @@ impl<'db> SurfaceContext<'db> { let group_data = nominal_map.data_group_data(id); let mut surface_context = SurfaceContext::new(db); - let name = group_data.name.clone(); + let name = Name::clone(&group_data.name); let annotation = group_data.annotation.and_then(|annotation| { let annotation = annotation.in_file(id.file_id).to_ast(db); surface_context.lower_data_annotation(&annotation) @@ -119,7 +119,7 @@ impl<'db> SurfaceContext<'db> { let group_data = nominal_map.value_group_data(id); let mut surface_context = SurfaceContext::new(db); - let name = group_data.name.clone(); + let name = Name::clone(&group_data.name); let annotation = group_data.annotation.and_then(|annotation| { let annotation = annotation.in_file(id.file_id).to_ast(db); surface_context.lower_value_annotation(&annotation) @@ -578,7 +578,7 @@ impl<'db> SurfaceContext<'db> { &mut self, constructor: &ast::DataConstructor, ) -> Option { - let name = constructor.name()?.as_str()?; + let name = constructor.name()?.in_db(self.db)?; let fields = constructor .fields()? .children() @@ -684,9 +684,7 @@ impl ModuleExports { items = nominal_map .value_groups() .map(|(_, value_group)| { - // FIXME: use interned names for ValueGroup - let name = NameRef::from_raw(db.interner().intern(&value_group.name)); - ExportItem::ExportValue(name) + ExportItem::ExportValue(NameRef::from(Name::clone(&value_group.name))) }) .collect(); explicit = false; diff --git a/crates/analyzer/src/surface/trees.rs b/crates/analyzer/src/surface/trees.rs index fa327b9d..ee46baab 100644 --- a/crates/analyzer/src/surface/trees.rs +++ b/crates/analyzer/src/surface/trees.rs @@ -150,13 +150,13 @@ impl DataDeclaration { #[derive(Debug, PartialEq, Eq)] pub struct DataConstructor { - pub name: SmolStr, + pub name: Name, pub fields: Vec, } #[derive(Debug, PartialEq, Eq)] pub struct DataGroup { - pub name: SmolStr, + pub name: Name, pub annotation: Option, pub declaration: DataDeclaration, } @@ -174,7 +174,7 @@ pub struct ValueEquation { #[derive(Debug, PartialEq, Eq)] pub struct ValueGroup { - pub name: SmolStr, + pub name: Name, pub annotation: Option, pub equations: FxHashMap, ValueEquation>, }