diff options
author | Aleksey Kladov <[email protected]> | 2019-11-24 12:50:45 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-24 12:50:45 +0000 |
commit | 1956d57ed4896bb29dfcfaed2a5291ec69251f52 (patch) | |
tree | c74e88db824e751818e7f1c4f80a9251732cf3a7 /crates/ra_hir_def/src/attr.rs | |
parent | 8e36cb586038e2c12e6eceae57f7a95684fc6c6d (diff) |
Slightly reduce code duplication
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 54 |
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 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId}; | 5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; |
6 | use mbe::ast_to_token_tree; | 6 | use mbe::ast_to_token_tree; |
7 | use ra_cfg::CfgOptions; | 7 | use ra_cfg::CfgOptions; |
8 | use ra_syntax::{ | 8 | use 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 | ||
102 | impl Attr { | 114 | impl 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 | ||
161 | fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs | 162 | fn 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 | } |