From e42f9627664cc3c44094e1c4f985270fbfd592b1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 Nov 2019 11:27:47 +0300 Subject: Encapsulate Attrs --- crates/ra_hir/src/code_model/attrs.rs | 16 ++++++----- crates/ra_hir/src/db.rs | 4 +-- crates/ra_hir_def/src/attr.rs | 36 ++++++++++++++++++++---- crates/ra_hir_def/src/nameres/collector.rs | 20 ++++++------- crates/ra_hir_def/src/nameres/raw.rs | 18 +++++------- crates/ra_ide_api/src/completion/presentation.rs | 5 +--- 6 files changed, 57 insertions(+), 42 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs index 9e304217c..9923cde81 100644 --- a/crates/ra_hir/src/code_model/attrs.rs +++ b/crates/ra_hir/src/code_model/attrs.rs @@ -8,7 +8,6 @@ use crate::{ use hir_def::attr::Attr; use hir_expand::hygiene::Hygiene; use ra_syntax::ast; -use std::sync::Arc; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum AttrDef { @@ -38,16 +37,19 @@ impl_froms!( ); pub trait Attrs { - fn attrs(&self, db: &impl HirDatabase) -> Option>; + fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs; } pub(crate) fn attributes_query( db: &(impl DefDatabase + AstDatabase), def: AttrDef, -) -> Option> { +) -> hir_def::attr::Attrs { match def { AttrDef::Module(it) => { - let src = it.declaration_source(db)?; + let src = match it.declaration_source(db) { + Some(it) => it, + None => return hir_def::attr::Attrs::default(), + }; let hygiene = Hygiene::new(db, src.file_id); Attr::from_attrs_owner(&src.value, &hygiene) } @@ -57,7 +59,7 @@ pub(crate) fn attributes_query( let hygiene = Hygiene::new(db, src.file_id); Attr::from_attrs_owner(&named, &hygiene) } - FieldSource::Pos(..) => None, + FieldSource::Pos(..) => hir_def::attr::Attrs::default(), }, AttrDef::Adt(it) => match it { Adt::Struct(it) => attrs_from_ast(it, db), @@ -74,7 +76,7 @@ pub(crate) fn attributes_query( } } -fn attrs_from_ast(node: T, db: &D) -> Option> +fn attrs_from_ast(node: T, db: &D) -> hir_def::attr::Attrs where T: HasSource, T::Ast: ast::AttrsOwner, @@ -86,7 +88,7 @@ where } impl + Copy> Attrs for T { - fn attrs(&self, db: &impl HirDatabase) -> Option> { + fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs { db.attrs((*self).into()) } } diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index ed0d68001..1f63be3b9 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use hir_def::attr::Attr; +use hir_def::attr::Attrs; use ra_db::salsa; use ra_syntax::SmolStr; @@ -61,7 +61,7 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { fn documentation(&self, def: crate::DocDef) -> Option; #[salsa::invoke(crate::code_model::attrs::attributes_query)] - fn attrs(&self, def: crate::AttrDef) -> Option>; + fn attrs(&self, def: crate::AttrDef) -> Attrs; } #[salsa::query_group(HirDatabaseStorage)] diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 0e961ca12..7a9d0fdf4 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -1,6 +1,6 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. -use std::sync::Arc; +use std::{ops, sync::Arc}; use hir_expand::hygiene::Hygiene; use mbe::ast_to_token_tree; @@ -13,6 +13,28 @@ use tt::Subtree; use crate::path::Path; +#[derive(Default, Debug, Clone, PartialEq, Eq)] +pub struct Attrs { + entries: Option>, +} + +impl ops::Deref for Attrs { + type Target = [Attr]; + + fn deref(&self) -> &[Attr] { + match &self.entries { + Some(it) => &*it, + None => &[], + } + } +} + +impl Attrs { + pub fn has_atom(&self, atom: &str) -> bool { + self.iter().any(|it| it.is_simple_atom(atom)) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Attr { pub(crate) path: Path, @@ -43,13 +65,15 @@ impl Attr { Some(Attr { path, input }) } - pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Option> { + pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { let mut attrs = owner.attrs().peekable(); - if attrs.peek().is_none() { + let entries = if attrs.peek().is_none() { // Avoid heap allocation - return None; - } - Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) + None + } else { + Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) + }; + Attrs { entries } } pub fn is_simple_atom(&self, name: &str) -> bool { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index aae3dcadf..7902293e8 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -12,7 +12,7 @@ use rustc_hash::FxHashMap; use test_utils::tested_by; use crate::{ - attr::Attr, + attr::Attrs, db::DefDatabase2, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, @@ -549,7 +549,7 @@ where // `#[macro_use] extern crate` is hoisted to imports macros before collecting // any other items. for item in items { - if self.is_cfg_enabled(item.attrs()) { + if self.is_cfg_enabled(&item.attrs) { if let raw::RawItemKind::Import(import_id) = item.kind { let import = self.raw_items[import_id].clone(); if import.is_extern_crate && import.is_macro_use { @@ -560,10 +560,10 @@ where } for item in items { - if self.is_cfg_enabled(item.attrs()) { + if self.is_cfg_enabled(&item.attrs) { match item.kind { raw::RawItemKind::Module(m) => { - self.collect_module(&self.raw_items[m], item.attrs()) + self.collect_module(&self.raw_items[m], &item.attrs) } raw::RawItemKind::Import(import_id) => self .def_collector @@ -585,9 +585,9 @@ where } } - fn collect_module(&mut self, module: &raw::ModuleData, attrs: &[Attr]) { + fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { let path_attr = self.path_attr(attrs); - let is_macro_use = self.is_macro_use(attrs); + let is_macro_use = attrs.has_atom("macro_use"); match module { // inline module, just recurse raw::ModuleData::Definition { name, items, ast_id } => { @@ -779,17 +779,13 @@ where } } - fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { + 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 [Attr]) -> Option<&'a SmolStr> { + fn path_attr<'a>(&self, attrs: &'a Attrs) -> Option<&'a SmolStr> { attrs.iter().find_map(|attr| attr.as_path()) } - - fn is_macro_use<'a>(&self, attrs: &'a [Attr]) -> bool { - attrs.iter().any(|attr| attr.is_simple_atom("macro_use")) - } } fn is_macro_rules(path: &Path) -> bool { diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 7c68fd638..55a9634f8 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -16,7 +16,12 @@ use ra_syntax::{ }; use test_utils::tested_by; -use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, ModuleSource, Source}; +use crate::{ + attr::{Attr, Attrs}, + db::DefDatabase2, + path::Path, + FileAstId, HirFileId, ModuleSource, Source, +}; /// `RawItems` is a set of top-level items in a file (except for impls). /// @@ -129,21 +134,12 @@ impl Index for RawItems { } } -// Avoid heap allocation on items without attributes. -type Attrs = Option>; - #[derive(Debug, PartialEq, Eq, Clone)] pub(super) struct RawItem { - attrs: Attrs, + pub(super) attrs: Attrs, pub(super) kind: RawItemKind, } -impl RawItem { - pub(super) fn attrs(&self) -> &[Attr] { - self.attrs.as_ref().map_or(&[], |it| &*it) - } -} - #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(super) enum RawItemKind { Module(Module), diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index b20329459..cbaf169bf 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -286,10 +286,7 @@ impl Completions { } fn is_deprecated(node: impl Attrs, db: &impl HirDatabase) -> bool { - match node.attrs(db) { - None => false, - Some(attrs) => attrs.iter().any(|x| x.is_simple_atom("deprecated")), - } + node.attrs(db).has_atom("deprecated") } fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { -- cgit v1.2.3 From a87e9145a67634a5ea8a893ab8b52b3c07108a13 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 Nov 2019 11:36:14 +0300 Subject: Rename Atts trait --- crates/ra_hir/src/code_model/attrs.rs | 21 +++++++++------------ crates/ra_hir/src/lib.rs | 2 +- crates/ra_ide_api/src/completion/presentation.rs | 4 ++-- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs index 9923cde81..96da8c88c 100644 --- a/crates/ra_hir/src/code_model/attrs.rs +++ b/crates/ra_hir/src/code_model/attrs.rs @@ -5,7 +5,7 @@ use crate::{ Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, Union, }; -use hir_def::attr::Attr; +use hir_def::attr::{Attr, Attrs}; use hir_expand::hygiene::Hygiene; use ra_syntax::ast; @@ -36,19 +36,16 @@ impl_froms!( MacroDef ); -pub trait Attrs { - fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs; +pub trait HasAttrs { + fn attrs(&self, db: &impl HirDatabase) -> Attrs; } -pub(crate) fn attributes_query( - db: &(impl DefDatabase + AstDatabase), - def: AttrDef, -) -> hir_def::attr::Attrs { +pub(crate) fn attributes_query(db: &(impl DefDatabase + AstDatabase), def: AttrDef) -> Attrs { match def { AttrDef::Module(it) => { let src = match it.declaration_source(db) { Some(it) => it, - None => return hir_def::attr::Attrs::default(), + None => return Attrs::default(), }; let hygiene = Hygiene::new(db, src.file_id); Attr::from_attrs_owner(&src.value, &hygiene) @@ -59,7 +56,7 @@ pub(crate) fn attributes_query( let hygiene = Hygiene::new(db, src.file_id); Attr::from_attrs_owner(&named, &hygiene) } - FieldSource::Pos(..) => hir_def::attr::Attrs::default(), + FieldSource::Pos(..) => Attrs::default(), }, AttrDef::Adt(it) => match it { Adt::Struct(it) => attrs_from_ast(it, db), @@ -76,7 +73,7 @@ pub(crate) fn attributes_query( } } -fn attrs_from_ast(node: T, db: &D) -> hir_def::attr::Attrs +fn attrs_from_ast(node: T, db: &D) -> Attrs where T: HasSource, T::Ast: ast::AttrsOwner, @@ -87,8 +84,8 @@ where Attr::from_attrs_owner(&src.value, &hygiene) } -impl + Copy> Attrs for T { - fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs { +impl + Copy> HasAttrs for T { + fn attrs(&self, db: &impl HirDatabase) -> Attrs { db.attrs((*self).into()) } } diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 8c6834392..915ca46fb 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -52,7 +52,7 @@ mod marks; pub use crate::{ code_model::{ - attrs::{AttrDef, Attrs}, + attrs::{AttrDef, HasAttrs}, docs::{DocDef, Docs, Documentation}, src::{HasBodySource, HasSource}, Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index cbaf169bf..bd464d193 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -1,6 +1,6 @@ //! This modules takes care of rendering various definitions as completion items. -use hir::{db::HirDatabase, Attrs, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; +use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; use join_to_string::join; use ra_syntax::ast::NameOwner; use test_utils::tested_by; @@ -285,7 +285,7 @@ impl Completions { } } -fn is_deprecated(node: impl Attrs, db: &impl HirDatabase) -> bool { +fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { node.attrs(db).has_atom("deprecated") } -- cgit v1.2.3