From e0b06cb672b7aae770fea24e4a5efdbec8cbf5c6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Nov 2019 15:13:56 +0300 Subject: Switch to StaticLoc for statics --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/code_model/src.rs | 2 +- crates/ra_hir/src/from_source.rs | 15 ++++++++++-- crates/ra_hir/src/source_binder.rs | 12 ++++------ crates/ra_hir/src/ty/tests.rs | 2 -- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/body.rs | 3 ++- crates/ra_hir_def/src/data.rs | 2 +- crates/ra_hir_def/src/db.rs | 5 ++-- crates/ra_hir_def/src/docs.rs | 2 +- crates/ra_hir_def/src/lib.rs | 37 ++++++++++++++++++++++++++---- crates/ra_hir_def/src/nameres/collector.rs | 7 ++++-- crates/ra_hir_def/src/resolver.rs | 2 +- 13 files changed, 65 insertions(+), 28 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 36ea8d8bf..905bb5bcb 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -734,7 +734,7 @@ pub struct Static { impl Static { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.module(db) } + Module { id: self.id.lookup(db).module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 59cda2e89..b9d21bdd7 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -88,7 +88,7 @@ impl HasSource for Const { impl HasSource for Static { type Ast = ast::StaticDef; fn source(self, db: &impl DefDatabase) -> Source { - self.id.source(db) + self.id.lookup(db).source(db) } } impl HasSource for Trait { diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index c3c3b05ed..e6eefcace 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -104,10 +104,21 @@ impl FromSource for Const { impl FromSource for Static { type Ast = ast::StaticDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id = from_source(db, src)?; - Some(Static { id }) + let module = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Module(it) => it, + Container::Trait(_) | Container::ImplBlock(_) => return None, + }; + module + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::Static(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) } } + impl FromSource for TypeAlias { type Ast = ast::TypeAliasDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 0a836c913..cfc4bd326 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -11,7 +11,7 @@ use hir_def::{ expr::{ExprId, PatId}, path::known, resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, - DefWithBodyId, LocationCtx, + DefWithBodyId, }; use hir_expand::{ name::AsName, AstId, HirFileId, MacroCallId, MacroCallLoc, MacroFileKind, Source, @@ -28,8 +28,8 @@ use crate::{ expr::{BodySourceMap, ExprScopes, ScopeId}, ty::method_resolution::{self, implements_trait}, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, - GenericParam, HasBody, Local, MacroDef, Module, Name, Path, ScopeDef, Static, Struct, Trait, - Ty, TypeAlias, + GenericParam, HasBody, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, + TypeAlias, }; fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { @@ -68,16 +68,12 @@ fn def_with_body_from_child_node( db: &impl HirDatabase, child: Source<&SyntaxNode>, ) -> Option { - let module_source = crate::ModuleSource::from_child_node(db, child); - let module = Module::from_definition(db, Source::new(child.file_id, module_source))?; - let ctx = LocationCtx::new(db, module.id, child.file_id); - child.value.ancestors().find_map(|node| { match_ast! { match node { ast::FnDef(def) => { return Function::from_source(db, child.with_value(def)).map(DefWithBody::from); }, ast::ConstDef(def) => { return Const::from_source(db, child.with_value(def)).map(DefWithBody::from); }, - ast::StaticDef(def) => { Some(Static { id: ctx.to_def(&def) }.into()) }, + ast::StaticDef(def) => { return Static::from_source(db, child.with_value(def)).map(DefWithBody::from); }, _ => { None }, } } diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 17a50cf74..3209c66bd 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -2550,8 +2550,6 @@ fn test() { [233; 246) 'GLOBAL_STATIC': u32 [256; 257) 'w': u32 [260; 277) 'GLOBAL...IC_MUT': u32 - [118; 120) '99': u32 - [161; 163) '99': u32 "### ); } diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 48ce8cd93..87f411599 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -63,11 +63,11 @@ impl Attrs { AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), }, - AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 225638b42..1589085b5 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -17,7 +17,7 @@ use crate::{ expr::{Expr, ExprId, Pat, PatId}, nameres::CrateDefMap, path::Path, - AstItemDef, DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, + DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, }; pub struct Expander { @@ -160,6 +160,7 @@ impl Body { (src.file_id, c.module(db), src.value.body()) } DefWithBodyId::StaticId(s) => { + let s = s.lookup(db); let src = s.source(db); (src.file_id, s.module(db), src.value.body()) } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index f0b3e198a..81a8ec18d 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -204,7 +204,7 @@ impl ConstData { } pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc { - let node = konst.source(db).value; + let node = konst.lookup(db).source(db).value; const_data_for(&node) } } diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 7fec2e8c0..32adb11bd 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -18,7 +18,8 @@ use crate::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ItemLoc, ModuleId, StaticId, StructOrUnionId, TraitId, TypeAliasId, TypeAliasLoc, + ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructOrUnionId, TraitId, TypeAliasId, + TypeAliasLoc, }; #[salsa::query_group(InternDatabaseStorage)] @@ -32,7 +33,7 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_const(&self, loc: ConstLoc) -> ConstId; #[salsa::interned] - fn intern_static(&self, loc: ItemLoc) -> StaticId; + fn intern_static(&self, loc: StaticLoc) -> StaticId; #[salsa::interned] fn intern_trait(&self, loc: ItemLoc) -> TraitId; #[salsa::interned] diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 69846fd1b..225511428 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -52,10 +52,10 @@ impl Documentation { let src = it.parent.child_source(db); docs_from_ast(&src.value[it.local_id]) } - AttrDefId::StaticId(it) => docs_from_ast(&it.source(db).value), AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value), AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id.to_node(db)), AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value), + AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::FunctionId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::TypeAliasId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::ImplId(_) => None, diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index b063530c2..89f1ceb58 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -245,12 +245,24 @@ impl Lookup for ConstId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticId(salsa::InternId); impl_intern_key!(StaticId); -impl AstItemDef for StaticId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_static(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StaticLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for StaticLoc { + type ID = StaticId; + fn intern(self, db: &impl db::DefDatabase) -> StaticId { + db.intern_static(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_static(self) +} + +impl Lookup for StaticId { + type Data = StaticLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc { + db.lookup_intern_static(*self) } } @@ -481,6 +493,12 @@ impl HasModule for ConstLoc { } } +impl HasModule for StaticLoc { + fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { + self.container + } +} + pub trait HasSource { type Value; fn source(&self, db: &impl db::DefDatabase) -> Source; @@ -513,6 +531,15 @@ impl HasSource for ConstLoc { } } +impl HasSource for StaticLoc { + type Value = ast::StaticDef; + + fn source(&self, db: &impl db::DefDatabase) -> Source { + let node = self.ast_id.to_node(db); + Source::new(self.ast_id.file_id(), node) + } +} + pub trait HasChildSource { type ChildId; type Value; diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 1d004b6a6..7b2487999 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -21,7 +21,7 @@ use crate::{ path::{Path, PathKind}, per_ns::PerNs, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, - Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, + Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, StructOrUnionId, TraitId, TypeAliasLoc, UnionId, }; @@ -715,7 +715,10 @@ where PerNs::values(def.into()) } raw::DefKind::Static(ast_id) => { - PerNs::values(StaticId::from_ast_id(ctx, ast_id).into()) + let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + + PerNs::values(def.into()) } raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), raw::DefKind::TypeAlias(ast_id) => { diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index b56de44dd..4ff0a091b 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -540,7 +540,7 @@ impl HasResolver for ConstId { impl HasResolver for StaticId { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db).resolver(db) + self.lookup(db).container.resolver(db) } } -- cgit v1.2.3 From 151180057b0304ee4dee75401e8f1aaa7aaaec21 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Nov 2019 15:20:59 +0300 Subject: Simplify --- crates/ra_hir/src/from_source.rs | 4 +++- crates/ra_hir_def/src/lib.rs | 15 --------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index e6eefcace..f506bba70 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -282,7 +282,9 @@ where let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); let module = Module::from_definition(db, Source::new(src.file_id, module_src))?; let ctx = LocationCtx::new(db, module.id, src.file_id); - Some(DEF::from_ast(ctx, &src.value)) + let items = db.ast_id_map(src.file_id); + let item_id = items.ast_id(&src.value); + Some(DEF::from_ast_id(ctx, item_id)) } enum Container { diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 89f1ceb58..f60feb5fa 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -94,25 +94,10 @@ impl<'a, DB> LocationCtx<&'a DB> { } } -impl<'a, DB: AstDatabase + InternDatabase> LocationCtx<&'a DB> { - pub fn to_def(self, ast: &N) -> DEF - where - N: AstNode, - DEF: AstItemDef, - { - DEF::from_ast(self, ast) - } -} - pub trait AstItemDef: salsa::InternKey + Clone { fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self; fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc; - fn from_ast(ctx: LocationCtx<&(impl AstDatabase + InternDatabase)>, ast: &N) -> Self { - let items = ctx.db.ast_id_map(ctx.file_id); - let item_id = items.ast_id(ast); - Self::from_ast_id(ctx, item_id) - } fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId) -> Self { let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) }; Self::intern(ctx.db, loc) -- cgit v1.2.3 From 8e36cb586038e2c12e6eceae57f7a95684fc6c6d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Nov 2019 15:28:45 +0300 Subject: Simplify --- crates/ra_hir_def/src/attr.rs | 12 +----------- crates/ra_hir_def/src/nameres/collector.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 87f411599..7d8f0d915 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -144,17 +144,7 @@ impl Attr { } } - pub fn as_path(&self) -> Option<&SmolStr> { - if !self.is_simple_atom("path") { - return None; - } - match &self.input { - Some(AttrInput::Literal(it)) => Some(it), - _ => None, - } - } - - pub fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option { + pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option { cfg_options.is_cfg_enabled(self.as_cfg()?) } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 7b2487999..15941a1cb 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -7,7 +7,7 @@ use hir_expand::{ }; use ra_cfg::CfgOptions; use ra_db::{CrateId, FileId}; -use ra_syntax::{ast, SmolStr}; +use ra_syntax::ast; use rustc_hash::{FxHashMap, FxHashSet}; use test_utils::tested_by; @@ -599,7 +599,7 @@ where } fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { - let path_attr = self.path_attr(attrs); + let path_attr = attrs.find_string_value("path"); let is_macro_use = attrs.has_atom("macro_use"); match module { // inline module, just recurse @@ -612,7 +612,7 @@ where module_id, file_id: self.file_id, raw_items: self.raw_items, - mod_dir: self.mod_dir.descend_into_definition(name, path_attr), + mod_dir: self.mod_dir.descend_into_definition(name, path_attr.as_ref()), } .collect(&*items); if is_macro_use { @@ -626,7 +626,7 @@ where self.def_collector.db, self.file_id, name, - path_attr, + path_attr.as_ref(), ) { Ok((file_id, mod_dir)) => { let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); @@ -798,10 +798,6 @@ where fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) } - - fn path_attr<'a>(&self, attrs: &'a Attrs) -> Option<&'a SmolStr> { - attrs.iter().find_map(|attr| attr.as_path()) - } } fn is_macro_rules(path: &Path) -> bool { -- cgit v1.2.3 From 1956d57ed4896bb29dfcfaed2a5291ec69251f52 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Nov 2019 15:50:45 +0300 Subject: Slightly reduce code duplication --- crates/ra_hir_def/src/attr.rs | 54 ++++++++++++++++++------------------ crates/ra_hir_def/src/lang_item.rs | 2 +- crates/ra_hir_def/src/nameres/raw.rs | 7 ++--- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 7d8f0d915..5c1b151f7 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -2,7 +2,7 @@ use std::{ops, sync::Arc}; -use hir_expand::{either::Either, hygiene::Hygiene, AstId}; +use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; use mbe::ast_to_token_tree; use ra_cfg::CfgOptions; use ra_syntax::{ @@ -40,23 +40,19 @@ impl Attrs { Some(it) => it, None => return Attrs::default(), }; - let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(&src.value, &hygiene) + Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } AttrDefId::StructFieldId(it) => { let src = it.parent.child_source(db); match &src.value[it.local_id] { Either::A(_tuple) => Attrs::default(), - Either::B(record) => { - let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(record, &hygiene) - } + Either::B(record) => Attrs::from_attrs_owner(db, src.with_value(record)), } } - AttrDefId::EnumVariantId(it) => { - let src = it.parent.child_source(db); - let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) + AttrDefId::EnumVariantId(var_id) => { + let src = var_id.parent.child_source(db); + let src = src.as_ref().map(|it| &it[var_id.local_id]); + Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) } AttrDefId::AdtId(it) => match it { AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), @@ -73,6 +69,22 @@ impl Attrs { } } + fn from_attrs_owner(db: &impl DefDatabase, owner: Source<&dyn AttrsOwner>) -> Attrs { + let hygiene = Hygiene::new(db, owner.file_id); + Attrs::new(owner.value, &hygiene) + } + + pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { + let mut attrs = owner.attrs().peekable(); + let entries = if attrs.peek().is_none() { + // Avoid heap allocation + None + } else { + Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) + }; + Attrs { entries } + } + pub fn has_atom(&self, atom: &str) -> bool { self.iter().any(|it| it.is_simple_atom(atom)) } @@ -100,7 +112,7 @@ pub enum AttrInput { } impl Attr { - pub(crate) fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option { + fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option { let path = Path::from_src(ast.path()?, hygiene)?; let input = match ast.input() { None => None, @@ -117,17 +129,6 @@ impl Attr { Some(Attr { path, input }) } - pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { - let mut attrs = owner.attrs().peekable(); - let entries = if attrs.peek().is_none() { - // Avoid heap allocation - None - } else { - Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) - }; - Attrs { entries } - } - pub fn is_simple_atom(&self, name: &str) -> bool { // FIXME: Avoid cloning self.path.as_ident().map_or(false, |s| s.to_string() == name) @@ -154,8 +155,8 @@ where N: ast::AttrsOwner, D: DefDatabase, { - let hygiene = Hygiene::new(db, src.file_id()); - Attr::from_attrs_owner(&src.to_node(db), &hygiene) + let src = Source::new(src.file_id(), src.to_node(db)); + Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } fn attrs_from_loc(node: T, db: &D) -> Attrs @@ -165,6 +166,5 @@ where D: DefDatabase, { let src = node.source(db); - let hygiene = Hygiene::new(db, src.file_id); - Attr::from_attrs_owner(&src.value, &hygiene) + Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index df951c533..69d7bf21a 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -114,7 +114,7 @@ impl LangItems { { let attrs = db.attrs(item.into()); if let Some(lang_item_name) = attrs.find_string_value("lang") { - self.items.entry(lang_item_name).or_insert_with(|| constructor(item)); + self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); } } } diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 552cbe544..198578753 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -17,10 +17,7 @@ use ra_syntax::{ use test_utils::tested_by; use crate::{ - attr::{Attr, Attrs}, - db::DefDatabase, - path::Path, - FileAstId, HirFileId, LocalImportId, Source, + attr::Attrs, db::DefDatabase, path::Path, FileAstId, HirFileId, LocalImportId, Source, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -407,6 +404,6 @@ impl RawItemsCollector { } fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { - Attr::from_attrs_owner(item, &self.hygiene) + Attrs::new(item, &self.hygiene) } } -- cgit v1.2.3 From 4b74fb1d896ce5a1c8c4c4bf73ad2940fb86abc5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Nov 2019 16:03:02 +0300 Subject: Nicer API for attrs --- crates/ra_hir_def/src/attr.rs | 52 ++++++++++++------------ crates/ra_hir_def/src/lang_item.rs | 2 +- crates/ra_hir_def/src/nameres/collector.rs | 14 ++++--- crates/ra_ide_api/src/completion/presentation.rs | 2 +- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 5c1b151f7..53456fc08 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -4,7 +4,6 @@ use std::{ops, sync::Arc}; use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; use mbe::ast_to_token_tree; -use ra_cfg::CfgOptions; use ra_syntax::{ ast::{self, AstNode, AttrsOwner}, SmolStr, @@ -85,17 +84,8 @@ impl Attrs { Attrs { entries } } - pub fn has_atom(&self, atom: &str) -> bool { - self.iter().any(|it| it.is_simple_atom(atom)) - } - - pub fn find_string_value(&self, key: &str) -> Option { - self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| { - match attr.input.as_ref()? { - AttrInput::Literal(it) => Some(it.clone()), - _ => None, - } - }) + pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { + AttrQuery { attrs: self, key } } } @@ -128,25 +118,37 @@ impl Attr { Some(Attr { path, input }) } +} + +pub struct AttrQuery<'a> { + attrs: &'a Attrs, + key: &'static str, +} - pub fn is_simple_atom(&self, name: &str) -> bool { - // FIXME: Avoid cloning - self.path.as_ident().map_or(false, |s| s.to_string() == name) +impl<'a> AttrQuery<'a> { + pub fn tt_values(self) -> impl Iterator { + self.attrs().filter_map(|attr| match attr.input.as_ref()? { + AttrInput::TokenTree(it) => Some(it), + _ => None, + }) } - // FIXME: handle cfg_attr :-) - pub fn as_cfg(&self) -> Option<&Subtree> { - if !self.is_simple_atom("cfg") { - return None; - } - match &self.input { - Some(AttrInput::TokenTree(subtree)) => Some(subtree), + pub fn string_value(self) -> Option<&'a SmolStr> { + self.attrs().find_map(|attr| match attr.input.as_ref()? { + AttrInput::Literal(it) => Some(it), _ => None, - } + }) + } + + pub fn exists(self) -> bool { + self.attrs().next().is_some() } - pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option { - cfg_options.is_cfg_enabled(self.as_cfg()?) + fn attrs(self) -> impl Iterator { + let key = self.key; + self.attrs + .iter() + .filter(move |attr| attr.path.as_ident().map_or(false, |s| s.to_string() == key)) } } diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index 69d7bf21a..3b9fb0328 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -113,7 +113,7 @@ impl LangItems { T: Into + Copy, { let attrs = db.attrs(item.into()); - if let Some(lang_item_name) = attrs.find_string_value("lang") { + if let Some(lang_item_name) = attrs.by_key("lang").string_value() { self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 15941a1cb..7a5f90327 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -599,8 +599,8 @@ where } fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { - let path_attr = attrs.find_string_value("path"); - let is_macro_use = attrs.has_atom("macro_use"); + let path_attr = attrs.by_key("path").string_value(); + let is_macro_use = attrs.by_key("macro_use").exists(); match module { // inline module, just recurse raw::ModuleData::Definition { name, items, ast_id } => { @@ -612,7 +612,7 @@ where module_id, file_id: self.file_id, raw_items: self.raw_items, - mod_dir: self.mod_dir.descend_into_definition(name, path_attr.as_ref()), + mod_dir: self.mod_dir.descend_into_definition(name, path_attr), } .collect(&*items); if is_macro_use { @@ -626,7 +626,7 @@ where self.def_collector.db, self.file_id, name, - path_attr.as_ref(), + path_attr, ) { Ok((file_id, mod_dir)) => { let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); @@ -796,7 +796,11 @@ where } fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { - attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) + // FIXME: handle cfg_attr :-) + attrs + .by_key("cfg") + .tt_values() + .all(|tt| self.def_collector.cfg_options.is_cfg_enabled(tt) != Some(false)) } } diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 896ad1517..bac3f7582 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -288,7 +288,7 @@ impl Completions { } fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { - node.attrs(db).has_atom("deprecated") + node.attrs(db).by_key("deprecated").exists() } fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { -- cgit v1.2.3