aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs66
-rw-r--r--crates/ra_syntax/src/ast/generated.rs3
-rw-r--r--crates/ra_syntax/src/ast/traits.rs2
-rw-r--r--crates/ra_syntax/src/grammar.ron2
4 files changed, 26 insertions, 47 deletions
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 8c5ece65d..a7b886457 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -1,10 +1,8 @@
1//! Various extension methods to ast Nodes, which are hard to code-generate. 1//! Various extension methods to ast Nodes, which are hard to code-generate.
2//! Extensions for various expressions live in a sibling `expr_extensions` module. 2//! Extensions for various expressions live in a sibling `expr_extensions` module.
3 3
4use itertools::Itertools;
5
6use crate::{ 4use crate::{
7 ast::{self, child_opt, children, AstChildren, AstNode, SyntaxNode}, 5 ast::{self, child_opt, children, AstChildren, AstNode, AttrInput, SyntaxNode},
8 SmolStr, SyntaxElement, 6 SmolStr, SyntaxElement,
9 SyntaxKind::*, 7 SyntaxKind::*,
10 SyntaxToken, T, 8 SyntaxToken, T,
@@ -39,12 +37,7 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
39 37
40impl ast::Attr { 38impl ast::Attr {
41 pub fn is_inner(&self) -> bool { 39 pub fn is_inner(&self) -> bool {
42 let tt = match self.value() { 40 let prev = match self.syntax().prev_sibling() {
43 None => return false,
44 Some(tt) => tt,
45 };
46
47 let prev = match tt.syntax().prev_sibling() {
48 None => return false, 41 None => return false,
49 Some(prev) => prev, 42 Some(prev) => prev,
50 }; 43 };
@@ -52,48 +45,37 @@ impl ast::Attr {
52 prev.kind() == T![!] 45 prev.kind() == T![!]
53 } 46 }
54 47
55 pub fn as_atom(&self) -> Option<SmolStr> { 48 pub fn as_simple_atom(&self) -> Option<SmolStr> {
56 let tt = self.value()?; 49 match self.input() {
57 let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; 50 None => self.simple_name(),
58 if attr.kind() == IDENT { 51 Some(_) => None,
59 Some(attr.as_token()?.text().clone())
60 } else {
61 None
62 } 52 }
63 } 53 }
64 54
65 pub fn as_call(&self) -> Option<(SmolStr, ast::TokenTree)> { 55 pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
66 let tt = self.value()?; 56 match self.input() {
67 let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; 57 Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
68 let args = ast::TokenTree::cast(args.as_node()?.clone())?; 58 _ => None,
69 if attr.kind() == IDENT {
70 Some((attr.as_token()?.text().clone(), args))
71 } else {
72 None
73 } 59 }
74 } 60 }
75 61
76 pub fn as_named(&self) -> Option<SmolStr> { 62 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
77 let tt = self.value()?; 63 match self.input() {
78 let attr = tt.syntax().children_with_tokens().nth(1)?; 64 Some(AttrInput::Literal(lit)) => {
79 if attr.kind() == IDENT { 65 let key = self.simple_name()?;
80 Some(attr.as_token()?.text().clone()) 66 // FIXME: escape? raw string?
81 } else { 67 let value = lit.syntax().first_token()?.text().trim_matches('"').into();
82 None 68 Some((key, value))
69 }
70 _ => None,
83 } 71 }
84 } 72 }
85 73
86 pub fn as_key_value(&self) -> Option<(SmolStr, SmolStr)> { 74 pub fn simple_name(&self) -> Option<SmolStr> {
87 let tt = self.value()?; 75 let path = self.path()?;
88 let tt_node = tt.syntax(); 76 match (path.segment(), path.qualifier()) {
89 let attr = tt_node.children_with_tokens().nth(1)?; 77 (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
90 if attr.kind() == IDENT { 78 _ => None,
91 let key = attr.as_token()?.text().clone();
92 let val_node = tt_node.children_with_tokens().find(|t| t.kind() == STRING)?;
93 let val = val_node.as_token()?.text().trim_start_matches('"').trim_end_matches('"');
94 Some((key, SmolStr::new(val)))
95 } else {
96 None
97 } 79 }
98 } 80 }
99} 81}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 408449fd6..aaf03ce3f 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -172,9 +172,6 @@ impl Attr {
172 pub fn input(&self) -> Option<AttrInput> { 172 pub fn input(&self) -> Option<AttrInput> {
173 AstChildren::new(&self.syntax).next() 173 AstChildren::new(&self.syntax).next()
174 } 174 }
175 pub fn value(&self) -> Option<TokenTree> {
176 AstChildren::new(&self.syntax).next()
177 }
178} 175}
179#[derive(Debug, Clone, PartialEq, Eq, Hash)] 176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
180pub enum AttrInput { 177pub enum AttrInput {
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index c3e676d4c..f275a4955 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -99,7 +99,7 @@ pub trait AttrsOwner: AstNode {
99 children(self) 99 children(self)
100 } 100 }
101 fn has_atom_attr(&self, atom: &str) -> bool { 101 fn has_atom_attr(&self, atom: &str) -> bool {
102 self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom) 102 self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)
103 } 103 }
104} 104}
105 105
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 8cb45f394..30328f59f 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -577,7 +577,7 @@ Grammar(
577 options: [ "TokenTree", "Path" ], 577 options: [ "TokenTree", "Path" ],
578 ), 578 ),
579 "AttrInput": ( enum: [ "Literal", "TokenTree" ] ), 579 "AttrInput": ( enum: [ "Literal", "TokenTree" ] ),
580 "Attr": ( options: [ "Path", [ "input", "AttrInput" ], [ "value", "TokenTree" ] ] ), 580 "Attr": ( options: [ "Path", [ "input", "AttrInput" ] ] ),
581 "TokenTree": (), 581 "TokenTree": (),
582 "TypeParamList": ( 582 "TypeParamList": (
583 collections: [ 583 collections: [