diff options
Diffstat (limited to 'crates/ra_hir/src/attr.rs')
-rw-r--r-- | crates/ra_hir/src/attr.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/crates/ra_hir/src/attr.rs b/crates/ra_hir/src/attr.rs new file mode 100644 index 000000000..19be6de32 --- /dev/null +++ b/crates/ra_hir/src/attr.rs | |||
@@ -0,0 +1,58 @@ | |||
1 | use mbe::ast_to_token_tree; | ||
2 | use ra_syntax::{ | ||
3 | ast::{self, AstNode}, | ||
4 | SmolStr, | ||
5 | }; | ||
6 | use tt::Subtree; | ||
7 | |||
8 | use crate::{db::AstDatabase, path::Path, Source}; | ||
9 | |||
10 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
11 | pub(crate) struct Attr { | ||
12 | pub(crate) path: Path, | ||
13 | pub(crate) input: Option<AttrInput>, | ||
14 | } | ||
15 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
17 | pub enum AttrInput { | ||
18 | Literal(SmolStr), | ||
19 | TokenTree(Subtree), | ||
20 | } | ||
21 | |||
22 | impl Attr { | ||
23 | pub(crate) fn from_src( | ||
24 | Source { file_id, ast }: Source<ast::Attr>, | ||
25 | db: &impl AstDatabase, | ||
26 | ) -> Option<Attr> { | ||
27 | let path = Path::from_src(Source { file_id, ast: ast.path()? }, db)?; | ||
28 | let input = match ast.input() { | ||
29 | None => None, | ||
30 | Some(ast::AttrInput::Literal(lit)) => { | ||
31 | // FIXME: escape? raw string? | ||
32 | let value = lit.syntax().first_token()?.text().trim_matches('"').into(); | ||
33 | Some(AttrInput::Literal(value)) | ||
34 | } | ||
35 | Some(ast::AttrInput::TokenTree(tt)) => { | ||
36 | Some(AttrInput::TokenTree(ast_to_token_tree(&tt)?.0)) | ||
37 | } | ||
38 | }; | ||
39 | |||
40 | Some(Attr { path, input }) | ||
41 | } | ||
42 | |||
43 | pub(crate) fn is_simple_atom(&self, name: &str) -> bool { | ||
44 | // FIXME: Avoid cloning | ||
45 | self.path.as_ident().map_or(false, |s| s.to_string() == name) | ||
46 | } | ||
47 | |||
48 | pub(crate) fn as_cfg(&self) -> Option<&Subtree> { | ||
49 | if self.is_simple_atom("cfg") { | ||
50 | match &self.input { | ||
51 | Some(AttrInput::TokenTree(subtree)) => Some(subtree), | ||
52 | _ => None, | ||
53 | } | ||
54 | } else { | ||
55 | None | ||
56 | } | ||
57 | } | ||
58 | } | ||