aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/attr.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-24 12:50:45 +0000
committerAleksey Kladov <[email protected]>2019-11-24 12:50:45 +0000
commit1956d57ed4896bb29dfcfaed2a5291ec69251f52 (patch)
treec74e88db824e751818e7f1c4f80a9251732cf3a7 /crates/ra_hir_def/src/attr.rs
parent8e36cb586038e2c12e6eceae57f7a95684fc6c6d (diff)
Slightly reduce code duplication
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r--crates/ra_hir_def/src/attr.rs54
1 files changed, 27 insertions, 27 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 @@
2 2
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use hir_expand::{either::Either, hygiene::Hygiene, AstId}; 5use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source};
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_cfg::CfgOptions; 7use ra_cfg::CfgOptions;
8use ra_syntax::{ 8use ra_syntax::{
@@ -40,23 +40,19 @@ impl Attrs {
40 Some(it) => it, 40 Some(it) => it,
41 None => return Attrs::default(), 41 None => return Attrs::default(),
42 }; 42 };
43 let hygiene = Hygiene::new(db, src.file_id); 43 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
44 Attr::from_attrs_owner(&src.value, &hygiene)
45 } 44 }
46 AttrDefId::StructFieldId(it) => { 45 AttrDefId::StructFieldId(it) => {
47 let src = it.parent.child_source(db); 46 let src = it.parent.child_source(db);
48 match &src.value[it.local_id] { 47 match &src.value[it.local_id] {
49 Either::A(_tuple) => Attrs::default(), 48 Either::A(_tuple) => Attrs::default(),
50 Either::B(record) => { 49 Either::B(record) => Attrs::from_attrs_owner(db, src.with_value(record)),
51 let hygiene = Hygiene::new(db, src.file_id);
52 Attr::from_attrs_owner(record, &hygiene)
53 }
54 } 50 }
55 } 51 }
56 AttrDefId::EnumVariantId(it) => { 52 AttrDefId::EnumVariantId(var_id) => {
57 let src = it.parent.child_source(db); 53 let src = var_id.parent.child_source(db);
58 let hygiene = Hygiene::new(db, src.file_id); 54 let src = src.as_ref().map(|it| &it[var_id.local_id]);
59 Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) 55 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
60 } 56 }
61 AttrDefId::AdtId(it) => match it { 57 AttrDefId::AdtId(it) => match it {
62 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), 58 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
@@ -73,6 +69,22 @@ impl Attrs {
73 } 69 }
74 } 70 }
75 71
72 fn from_attrs_owner(db: &impl DefDatabase, owner: Source<&dyn AttrsOwner>) -> Attrs {
73 let hygiene = Hygiene::new(db, owner.file_id);
74 Attrs::new(owner.value, &hygiene)
75 }
76
77 pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
78 let mut attrs = owner.attrs().peekable();
79 let entries = if attrs.peek().is_none() {
80 // Avoid heap allocation
81 None
82 } else {
83 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect())
84 };
85 Attrs { entries }
86 }
87
76 pub fn has_atom(&self, atom: &str) -> bool { 88 pub fn has_atom(&self, atom: &str) -> bool {
77 self.iter().any(|it| it.is_simple_atom(atom)) 89 self.iter().any(|it| it.is_simple_atom(atom))
78 } 90 }
@@ -100,7 +112,7 @@ pub enum AttrInput {
100} 112}
101 113
102impl Attr { 114impl Attr {
103 pub(crate) fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> { 115 fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
104 let path = Path::from_src(ast.path()?, hygiene)?; 116 let path = Path::from_src(ast.path()?, hygiene)?;
105 let input = match ast.input() { 117 let input = match ast.input() {
106 None => None, 118 None => None,
@@ -117,17 +129,6 @@ impl Attr {
117 Some(Attr { path, input }) 129 Some(Attr { path, input })
118 } 130 }
119 131
120 pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
121 let mut attrs = owner.attrs().peekable();
122 let entries = if attrs.peek().is_none() {
123 // Avoid heap allocation
124 None
125 } else {
126 Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect())
127 };
128 Attrs { entries }
129 }
130
131 pub fn is_simple_atom(&self, name: &str) -> bool { 132 pub fn is_simple_atom(&self, name: &str) -> bool {
132 // FIXME: Avoid cloning 133 // FIXME: Avoid cloning
133 self.path.as_ident().map_or(false, |s| s.to_string() == name) 134 self.path.as_ident().map_or(false, |s| s.to_string() == name)
@@ -154,8 +155,8 @@ where
154 N: ast::AttrsOwner, 155 N: ast::AttrsOwner,
155 D: DefDatabase, 156 D: DefDatabase,
156{ 157{
157 let hygiene = Hygiene::new(db, src.file_id()); 158 let src = Source::new(src.file_id(), src.to_node(db));
158 Attr::from_attrs_owner(&src.to_node(db), &hygiene) 159 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
159} 160}
160 161
161fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs 162fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs
@@ -165,6 +166,5 @@ where
165 D: DefDatabase, 166 D: DefDatabase,
166{ 167{
167 let src = node.source(db); 168 let src = node.source(db);
168 let hygiene = Hygiene::new(db, src.file_id); 169 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
169 Attr::from_attrs_owner(&src.value, &hygiene)
170} 170}