aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src')
-rw-r--r--crates/libsyntax2/src/ast/generated.rs52
-rw-r--r--crates/libsyntax2/src/ast/mod.rs53
-rw-r--r--crates/libsyntax2/src/grammar.ron20
-rw-r--r--crates/libsyntax2/src/grammar/attributes.rs56
-rw-r--r--crates/libsyntax2/src/grammar/items/mod.rs7
5 files changed, 97 insertions, 91 deletions
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs
index 1ec05c950..c575e15df 100644
--- a/crates/libsyntax2/src/ast/generated.rs
+++ b/crates/libsyntax2/src/ast/generated.rs
@@ -23,6 +23,31 @@ impl<R: TreeRoot> AstNode<R> for ArrayType<R> {
23 23
24impl<R: TreeRoot> ArrayType<R> {} 24impl<R: TreeRoot> ArrayType<R> {}
25 25
26// Attr
27#[derive(Debug, Clone, Copy)]
28pub struct Attr<R: TreeRoot = Arc<SyntaxRoot>> {
29 syntax: SyntaxNode<R>,
30}
31
32impl<R: TreeRoot> AstNode<R> for Attr<R> {
33 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
34 match syntax.kind() {
35 ATTR => Some(Attr { syntax }),
36 _ => None,
37 }
38 }
39 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
40}
41
42impl<R: TreeRoot> Attr<R> {
43 pub fn value(&self) -> Option<TokenTree<R>> {
44 self.syntax()
45 .children()
46 .filter_map(TokenTree::cast)
47 .next()
48 }
49}
50
26// ConstDef 51// ConstDef
27#[derive(Debug, Clone, Copy)] 52#[derive(Debug, Clone, Copy)]
28pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> { 53pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> {
@@ -40,6 +65,7 @@ impl<R: TreeRoot> AstNode<R> for ConstDef<R> {
40} 65}
41 66
42impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {} 67impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {}
68impl<R: TreeRoot> ast::AttrsOwner<R> for ConstDef<R> {}
43impl<R: TreeRoot> ConstDef<R> {} 69impl<R: TreeRoot> ConstDef<R> {}
44 70
45// DynTraitType 71// DynTraitType
@@ -77,6 +103,7 @@ impl<R: TreeRoot> AstNode<R> for EnumDef<R> {
77} 103}
78 104
79impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {} 105impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {}
106impl<R: TreeRoot> ast::AttrsOwner<R> for EnumDef<R> {}
80impl<R: TreeRoot> EnumDef<R> {} 107impl<R: TreeRoot> EnumDef<R> {}
81 108
82// File 109// File
@@ -120,6 +147,7 @@ impl<R: TreeRoot> AstNode<R> for FnDef<R> {
120} 147}
121 148
122impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {} 149impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {}
150impl<R: TreeRoot> ast::AttrsOwner<R> for FnDef<R> {}
123impl<R: TreeRoot> FnDef<R> {} 151impl<R: TreeRoot> FnDef<R> {}
124 152
125// FnPointerType 153// FnPointerType
@@ -211,6 +239,7 @@ impl<R: TreeRoot> AstNode<R> for Module<R> {
211} 239}
212 240
213impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {} 241impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {}
242impl<R: TreeRoot> ast::AttrsOwner<R> for Module<R> {}
214impl<R: TreeRoot> Module<R> {} 243impl<R: TreeRoot> Module<R> {}
215 244
216// Name 245// Name
@@ -266,6 +295,7 @@ impl<R: TreeRoot> AstNode<R> for NamedField<R> {
266} 295}
267 296
268impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {} 297impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {}
298impl<R: TreeRoot> ast::AttrsOwner<R> for NamedField<R> {}
269impl<R: TreeRoot> NamedField<R> {} 299impl<R: TreeRoot> NamedField<R> {}
270 300
271// NeverType 301// NeverType
@@ -436,6 +466,7 @@ impl<R: TreeRoot> AstNode<R> for StaticDef<R> {
436} 466}
437 467
438impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {} 468impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {}
469impl<R: TreeRoot> ast::AttrsOwner<R> for StaticDef<R> {}
439impl<R: TreeRoot> StaticDef<R> {} 470impl<R: TreeRoot> StaticDef<R> {}
440 471
441// StructDef 472// StructDef
@@ -455,6 +486,7 @@ impl<R: TreeRoot> AstNode<R> for StructDef<R> {
455} 486}
456 487
457impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {} 488impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {}
489impl<R: TreeRoot> ast::AttrsOwner<R> for StructDef<R> {}
458impl<R: TreeRoot> StructDef<R> { 490impl<R: TreeRoot> StructDef<R> {
459 pub fn fields<'a>(&'a self) -> impl Iterator<Item = NamedField<R>> + 'a { 491 pub fn fields<'a>(&'a self) -> impl Iterator<Item = NamedField<R>> + 'a {
460 self.syntax() 492 self.syntax()
@@ -463,6 +495,24 @@ impl<R: TreeRoot> StructDef<R> {
463 } 495 }
464} 496}
465 497
498// TokenTree
499#[derive(Debug, Clone, Copy)]
500pub struct TokenTree<R: TreeRoot = Arc<SyntaxRoot>> {
501 syntax: SyntaxNode<R>,
502}
503
504impl<R: TreeRoot> AstNode<R> for TokenTree<R> {
505 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
506 match syntax.kind() {
507 TOKEN_TREE => Some(TokenTree { syntax }),
508 _ => None,
509 }
510 }
511 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
512}
513
514impl<R: TreeRoot> TokenTree<R> {}
515
466// TraitDef 516// TraitDef
467#[derive(Debug, Clone, Copy)] 517#[derive(Debug, Clone, Copy)]
468pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> { 518pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> {
@@ -480,6 +530,7 @@ impl<R: TreeRoot> AstNode<R> for TraitDef<R> {
480} 530}
481 531
482impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {} 532impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {}
533impl<R: TreeRoot> ast::AttrsOwner<R> for TraitDef<R> {}
483impl<R: TreeRoot> TraitDef<R> {} 534impl<R: TreeRoot> TraitDef<R> {}
484 535
485// TupleType 536// TupleType
@@ -517,6 +568,7 @@ impl<R: TreeRoot> AstNode<R> for TypeDef<R> {
517} 568}
518 569
519impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {} 570impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {}
571impl<R: TreeRoot> ast::AttrsOwner<R> for TypeDef<R> {}
520impl<R: TreeRoot> TypeDef<R> {} 572impl<R: TreeRoot> TypeDef<R> {}
521 573
522// TypeRef 574// TypeRef
diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs
index 679e292a2..fe8f91d15 100644
--- a/crates/libsyntax2/src/ast/mod.rs
+++ b/crates/libsyntax2/src/ast/mod.rs
@@ -2,10 +2,11 @@ mod generated;
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use itertools::Itertools;
5use smol_str::SmolStr; 6use smol_str::SmolStr;
6 7
7use { 8use {
8 SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, 9 SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError,
9 SyntaxKind::*, 10 SyntaxKind::*,
10}; 11};
11pub use self::generated::*; 12pub use self::generated::*;
@@ -14,6 +15,9 @@ pub trait AstNode<R: TreeRoot> {
14 fn cast(syntax: SyntaxNode<R>) -> Option<Self> 15 fn cast(syntax: SyntaxNode<R>) -> Option<Self>
15 where Self: Sized; 16 where Self: Sized;
16 fn syntax(&self) -> &SyntaxNode<R>; 17 fn syntax(&self) -> &SyntaxNode<R>;
18 fn syntax_ref<'a>(&'a self) -> SyntaxNodeRef<'a> where R: 'a {
19 self.syntax().as_ref()
20 }
17} 21}
18 22
19pub trait NameOwner<R: TreeRoot>: AstNode<R> { 23pub trait NameOwner<R: TreeRoot>: AstNode<R> {
@@ -25,6 +29,14 @@ pub trait NameOwner<R: TreeRoot>: AstNode<R> {
25 } 29 }
26} 30}
27 31
32pub trait AttrsOwner<R: TreeRoot>: AstNode<R> {
33 fn attrs<'a>(&'a self) -> Box<Iterator<Item=Attr<R>> + 'a> where R: 'a {
34 let it = self.syntax().children()
35 .filter_map(Attr::cast);
36 Box::new(it)
37 }
38}
39
28impl File<Arc<SyntaxRoot>> { 40impl File<Arc<SyntaxRoot>> {
29 pub fn parse(text: &str) -> Self { 41 pub fn parse(text: &str) -> Self {
30 File::cast(::parse(text)).unwrap() 42 File::cast(::parse(text)).unwrap()
@@ -39,31 +51,20 @@ impl<R: TreeRoot> File<R> {
39 51
40impl<R: TreeRoot> FnDef<R> { 52impl<R: TreeRoot> FnDef<R> {
41 pub fn has_atom_attr(&self, atom: &str) -> bool { 53 pub fn has_atom_attr(&self, atom: &str) -> bool {
42 self.syntax() 54 self.attrs()
43 .children() 55 .filter_map(|x| x.value())
44 .filter(|node| node.kind() == ATTR) 56 .filter_map(|x| as_atom(x))
45 .any(|attr| { 57 .any(|x| x == atom)
46 let mut metas = attr.children().filter(|node| node.kind() == META_ITEM); 58 }
47 let meta = match metas.next() { 59}
48 None => return false, 60
49 Some(meta) => { 61fn as_atom<R: TreeRoot>(tt: TokenTree<R>) -> Option<SmolStr> {
50 if metas.next().is_some() { 62 let syntax = tt.syntax_ref();
51 return false; 63 let (_bra, attr, _ket) = syntax.children().collect_tuple()?;
52 } 64 if attr.kind() == IDENT {
53 meta 65 Some(attr.leaf_text().unwrap())
54 } 66 } else {
55 }; 67 None
56 let mut children = meta.children();
57 match children.next() {
58 None => false,
59 Some(child) => {
60 if children.next().is_some() {
61 return false;
62 }
63 child.kind() == IDENT && child.text() == atom
64 }
65 }
66 })
67 } 68 }
68} 69}
69 70
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index aa28ab922..4e523da9a 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -221,24 +221,26 @@ Grammar(
221 ["functions", "FnDef"] 221 ["functions", "FnDef"]
222 ] 222 ]
223 ), 223 ),
224 "FnDef": ( traits: ["NameOwner"] ), 224 "FnDef": ( traits: ["NameOwner", "AttrsOwner"] ),
225 "StructDef": ( 225 "StructDef": (
226 traits: ["NameOwner"], 226 traits: ["NameOwner", "AttrsOwner"],
227 collections: [ 227 collections: [
228 ["fields", "NamedField"] 228 ["fields", "NamedField"]
229 ] 229 ]
230 ), 230 ),
231 "NamedField": ( traits: ["NameOwner"] ), 231 "NamedField": ( traits: ["NameOwner", "AttrsOwner"] ),
232 "EnumDef": ( traits: ["NameOwner"] ), 232 "EnumDef": ( traits: ["NameOwner", "AttrsOwner"] ),
233 "TraitDef": ( traits: ["NameOwner"] ), 233 "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ),
234 "Module": ( traits: ["NameOwner"] ), 234 "Module": ( traits: ["NameOwner", "AttrsOwner"] ),
235 "ConstDef": ( traits: ["NameOwner"] ), 235 "ConstDef": ( traits: ["NameOwner", "AttrsOwner"] ),
236 "StaticDef": ( traits: ["NameOwner"] ), 236 "StaticDef": ( traits: ["NameOwner", "AttrsOwner"] ),
237 "TypeDef": ( traits: ["NameOwner"] ), 237 "TypeDef": ( traits: ["NameOwner", "AttrsOwner"] ),
238 "ImplItem": (), 238 "ImplItem": (),
239 239
240 "Name": (), 240 "Name": (),
241 "NameRef": (), 241 "NameRef": (),
242 "Attr": ( options: [ ["value", "TokenTree"] ] ),
243 "TokenTree": (),
242 244
243 "ParenType": (), 245 "ParenType": (),
244 "TupleType": (), 246 "TupleType": (),
diff --git a/crates/libsyntax2/src/grammar/attributes.rs b/crates/libsyntax2/src/grammar/attributes.rs
index c411d4d7f..cd30e8a45 100644
--- a/crates/libsyntax2/src/grammar/attributes.rs
+++ b/crates/libsyntax2/src/grammar/attributes.rs
@@ -22,58 +22,10 @@ fn attribute(p: &mut Parser, inner: bool) {
22 p.bump(); 22 p.bump();
23 } 23 }
24 24
25 if p.expect(L_BRACK) { 25 if p.at(L_BRACK) {
26 meta_item(p); 26 items::token_tree(p);
27 p.expect(R_BRACK);
28 }
29 attr.complete(p, ATTR);
30}
31
32fn meta_item(p: &mut Parser) {
33 if p.at(IDENT) {
34 let meta_item = p.start();
35 p.bump();
36 match p.current() {
37 EQ => {
38 p.bump();
39 if expressions::literal(p).is_none() {
40 p.error("expected literal");
41 }
42 }
43 L_PAREN => meta_item_arg_list(p),
44 _ => (),
45 }
46 meta_item.complete(p, META_ITEM);
47 } else { 27 } else {
48 p.error("expected attribute value"); 28 p.error("expected `[`");
49 }
50}
51
52fn meta_item_arg_list(p: &mut Parser) {
53 assert!(p.at(L_PAREN));
54 p.bump();
55 loop {
56 match p.current() {
57 EOF | R_PAREN => break,
58 IDENT => meta_item(p),
59 c => if expressions::literal(p).is_none() {
60 let message = "expected attribute";
61
62 if items::ITEM_FIRST.contains(c) {
63 p.error(message);
64 return;
65 }
66
67 let err = p.start();
68 p.error(message);
69 p.bump();
70 err.complete(p, ERROR);
71 continue;
72 },
73 }
74 if !p.at(R_PAREN) {
75 p.expect(COMMA);
76 }
77 } 29 }
78 p.expect(R_PAREN); 30 attr.complete(p, ATTR);
79} 31}
diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs
index fc02f0c5c..84cb47748 100644
--- a/crates/libsyntax2/src/grammar/items/mod.rs
+++ b/crates/libsyntax2/src/grammar/items/mod.rs
@@ -55,9 +55,6 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
55 } 55 }
56} 56}
57 57
58pub(super) const ITEM_FIRST: TokenSet =
59 token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND];
60
61pub(super) enum MaybeItem { 58pub(super) enum MaybeItem {
62 None, 59 None,
63 Item(SyntaxKind), 60 Item(SyntaxKind),
@@ -322,13 +319,14 @@ pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
322 flavor 319 flavor
323} 320}
324 321
325fn token_tree(p: &mut Parser) { 322pub(super) fn token_tree(p: &mut Parser) {
326 let closing_paren_kind = match p.current() { 323 let closing_paren_kind = match p.current() {
327 L_CURLY => R_CURLY, 324 L_CURLY => R_CURLY,
328 L_PAREN => R_PAREN, 325 L_PAREN => R_PAREN,
329 L_BRACK => R_BRACK, 326 L_BRACK => R_BRACK,
330 _ => unreachable!(), 327 _ => unreachable!(),
331 }; 328 };
329 let m = p.start();
332 p.bump(); 330 p.bump();
333 while !p.at(EOF) && !p.at(closing_paren_kind) { 331 while !p.at(EOF) && !p.at(closing_paren_kind) {
334 match p.current() { 332 match p.current() {
@@ -338,4 +336,5 @@ fn token_tree(p: &mut Parser) {
338 } 336 }
339 }; 337 };
340 p.expect(closing_paren_kind); 338 p.expect(closing_paren_kind);
339 m.complete(p, TOKEN_TREE);
341} 340}