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