diff options
18 files changed, 260 insertions, 276 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 983029587..85c23e4d9 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -26,9 +26,8 @@ use std::{ | |||
26 | use libsyntax2::{ | 26 | use libsyntax2::{ |
27 | TextUnit, | 27 | TextUnit, |
28 | ast::{self, AstNode}, | 28 | ast::{self, AstNode}, |
29 | algo::{find_leaf_at_offset, ancestors}, | ||
30 | }; | 29 | }; |
31 | use libeditor::{LineIndex, FileSymbol}; | 30 | use libeditor::{LineIndex, FileSymbol, find_node}; |
32 | 31 | ||
33 | use self::symbol_index::FileSymbols; | 32 | use self::symbol_index::FileSymbols; |
34 | pub use self::symbol_index::Query; | 33 | pub use self::symbol_index::Query; |
@@ -123,13 +122,7 @@ impl World { | |||
123 | let file = self.file_syntax(id)?; | 122 | let file = self.file_syntax(id)?; |
124 | let syntax = file.syntax(); | 123 | let syntax = file.syntax(); |
125 | let syntax = syntax.as_ref(); | 124 | let syntax = syntax.as_ref(); |
126 | let name_ref = | 125 | let name_ref = find_node::<ast::NameRef<_>>(syntax, offset); |
127 | find_leaf_at_offset(syntax, offset) | ||
128 | .left_biased() | ||
129 | .into_iter() | ||
130 | .flat_map(|node| ancestors(node)) | ||
131 | .flat_map(ast::NameRef::cast) | ||
132 | .next(); | ||
133 | let name = match name_ref { | 126 | let name = match name_ref { |
134 | None => return Ok(vec![]), | 127 | None => return Ok(vec![]), |
135 | Some(name_ref) => name_ref.text(), | 128 | Some(name_ref) => name_ref.text(), |
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 88c348436..4987964d2 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs | |||
@@ -66,7 +66,7 @@ fn find_non_trivia_leaf(syntax: SyntaxNodeRef, offset: TextUnit) -> Option<Synta | |||
66 | .find(|leaf| !leaf.kind().is_trivia()) | 66 | .find(|leaf| !leaf.kind().is_trivia()) |
67 | } | 67 | } |
68 | 68 | ||
69 | fn find_node<'a, N: AstNode<&'a SyntaxRoot>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> { | 69 | pub fn find_node<'a, N: AstNode<&'a SyntaxRoot>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> { |
70 | let leaf = find_non_trivia_leaf(syntax, offset)?; | 70 | let leaf = find_non_trivia_leaf(syntax, offset)?; |
71 | ancestors(leaf) | 71 | ancestors(leaf) |
72 | .filter_map(N::cast) | 72 | .filter_map(N::cast) |
diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index 28da457d1..76cb4d028 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs | |||
@@ -21,7 +21,10 @@ pub use self::{ | |||
21 | extend_selection::extend_selection, | 21 | extend_selection::extend_selection, |
22 | symbols::{StructureNode, file_structure, FileSymbol, file_symbols}, | 22 | symbols::{StructureNode, file_structure, FileSymbol, file_symbols}, |
23 | edit::{EditBuilder, Edit, AtomEdit}, | 23 | edit::{EditBuilder, Edit, AtomEdit}, |
24 | code_actions::{flip_comma, add_derive, ActionResult, CursorPosition}, | 24 | code_actions::{ |
25 | ActionResult, CursorPosition, find_node, | ||
26 | flip_comma, add_derive, | ||
27 | }, | ||
25 | }; | 28 | }; |
26 | 29 | ||
27 | #[derive(Debug)] | 30 | #[derive(Debug)] |
@@ -59,9 +62,7 @@ pub fn matching_brace(file: &ast::File, offset: TextUnit) -> Option<TextUnit> { | |||
59 | L_PAREN, R_PAREN, | 62 | L_PAREN, R_PAREN, |
60 | L_ANGLE, R_ANGLE, | 63 | L_ANGLE, R_ANGLE, |
61 | ]; | 64 | ]; |
62 | let syntax = file.syntax(); | 65 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax_ref(), offset) |
63 | let syntax = syntax.as_ref(); | ||
64 | let (brace_node, brace_idx) = find_leaf_at_offset(syntax, offset) | ||
65 | .filter_map(|node| { | 66 | .filter_map(|node| { |
66 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; | 67 | let idx = BRACES.iter().position(|&brace| brace == node.kind())?; |
67 | Some((node, idx)) | 68 | Some((node, idx)) |
@@ -75,9 +76,8 @@ pub fn matching_brace(file: &ast::File, offset: TextUnit) -> Option<TextUnit> { | |||
75 | } | 76 | } |
76 | 77 | ||
77 | pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> { | 78 | pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> { |
78 | let syntax = file.syntax(); | ||
79 | let mut res = Vec::new(); | 79 | let mut res = Vec::new(); |
80 | for node in walk::preorder(syntax.as_ref()) { | 80 | for node in walk::preorder(file.syntax_ref()) { |
81 | let tag = match node.kind() { | 81 | let tag = match node.kind() { |
82 | ERROR => "error", | 82 | ERROR => "error", |
83 | COMMENT | DOC_COMMENT => "comment", | 83 | COMMENT | DOC_COMMENT => "comment", |
@@ -99,10 +99,9 @@ pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> { | |||
99 | } | 99 | } |
100 | 100 | ||
101 | pub fn diagnostics(file: &ast::File) -> Vec<Diagnostic> { | 101 | pub fn diagnostics(file: &ast::File) -> Vec<Diagnostic> { |
102 | let syntax = file.syntax(); | ||
103 | let mut res = Vec::new(); | 102 | let mut res = Vec::new(); |
104 | 103 | ||
105 | for node in walk::preorder(syntax.as_ref()) { | 104 | for node in walk::preorder(file.syntax_ref()) { |
106 | if node.kind() == ERROR { | 105 | if node.kind() == ERROR { |
107 | res.push(Diagnostic { | 106 | res.push(Diagnostic { |
108 | range: node.range(), | 107 | range: node.range(), |
diff --git a/crates/libeditor/src/symbols.rs b/crates/libeditor/src/symbols.rs index 6f8853770..2585d9579 100644 --- a/crates/libeditor/src/symbols.rs +++ b/crates/libeditor/src/symbols.rs | |||
@@ -26,8 +26,7 @@ pub struct FileSymbol { | |||
26 | } | 26 | } |
27 | 27 | ||
28 | pub fn file_symbols(file: &ast::File) -> Vec<FileSymbol> { | 28 | pub fn file_symbols(file: &ast::File) -> Vec<FileSymbol> { |
29 | let syntax = file.syntax(); | 29 | preorder(file.syntax_ref()) |
30 | preorder(syntax.as_ref()) | ||
31 | .filter_map(to_symbol) | 30 | .filter_map(to_symbol) |
32 | .collect() | 31 | .collect() |
33 | } | 32 | } |
@@ -57,9 +56,8 @@ fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { | |||
57 | pub fn file_structure(file: &ast::File) -> Vec<StructureNode> { | 56 | pub fn file_structure(file: &ast::File) -> Vec<StructureNode> { |
58 | let mut res = Vec::new(); | 57 | let mut res = Vec::new(); |
59 | let mut stack = Vec::new(); | 58 | let mut stack = Vec::new(); |
60 | let syntax = file.syntax(); | ||
61 | 59 | ||
62 | for event in walk(syntax.as_ref()) { | 60 | for event in walk(file.syntax_ref()) { |
63 | match event { | 61 | match event { |
64 | WalkEvent::Enter(node) => { | 62 | WalkEvent::Enter(node) => { |
65 | match structure_node(node) { | 63 | match structure_node(node) { |
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 | ||
24 | impl<R: TreeRoot> ArrayType<R> {} | 24 | impl<R: TreeRoot> ArrayType<R> {} |
25 | 25 | ||
26 | // Attr | ||
27 | #[derive(Debug, Clone, Copy)] | ||
28 | pub struct Attr<R: TreeRoot = Arc<SyntaxRoot>> { | ||
29 | syntax: SyntaxNode<R>, | ||
30 | } | ||
31 | |||
32 | impl<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 | |||
42 | impl<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)] |
28 | pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> { | 53 | pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> { |
@@ -40,6 +65,7 @@ impl<R: TreeRoot> AstNode<R> for ConstDef<R> { | |||
40 | } | 65 | } |
41 | 66 | ||
42 | impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {} | 67 | impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {} |
68 | impl<R: TreeRoot> ast::AttrsOwner<R> for ConstDef<R> {} | ||
43 | impl<R: TreeRoot> ConstDef<R> {} | 69 | impl<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 | ||
79 | impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {} | 105 | impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {} |
106 | impl<R: TreeRoot> ast::AttrsOwner<R> for EnumDef<R> {} | ||
80 | impl<R: TreeRoot> EnumDef<R> {} | 107 | impl<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 | ||
122 | impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {} | 149 | impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {} |
150 | impl<R: TreeRoot> ast::AttrsOwner<R> for FnDef<R> {} | ||
123 | impl<R: TreeRoot> FnDef<R> {} | 151 | impl<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 | ||
213 | impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {} | 241 | impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {} |
242 | impl<R: TreeRoot> ast::AttrsOwner<R> for Module<R> {} | ||
214 | impl<R: TreeRoot> Module<R> {} | 243 | impl<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 | ||
268 | impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {} | 297 | impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {} |
298 | impl<R: TreeRoot> ast::AttrsOwner<R> for NamedField<R> {} | ||
269 | impl<R: TreeRoot> NamedField<R> {} | 299 | impl<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 | ||
438 | impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {} | 468 | impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {} |
469 | impl<R: TreeRoot> ast::AttrsOwner<R> for StaticDef<R> {} | ||
439 | impl<R: TreeRoot> StaticDef<R> {} | 470 | impl<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 | ||
457 | impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {} | 488 | impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {} |
489 | impl<R: TreeRoot> ast::AttrsOwner<R> for StructDef<R> {} | ||
458 | impl<R: TreeRoot> StructDef<R> { | 490 | impl<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)] | ||
500 | pub struct TokenTree<R: TreeRoot = Arc<SyntaxRoot>> { | ||
501 | syntax: SyntaxNode<R>, | ||
502 | } | ||
503 | |||
504 | impl<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 | |||
514 | impl<R: TreeRoot> TokenTree<R> {} | ||
515 | |||
466 | // TraitDef | 516 | // TraitDef |
467 | #[derive(Debug, Clone, Copy)] | 517 | #[derive(Debug, Clone, Copy)] |
468 | pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> { | 518 | pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> { |
@@ -480,6 +530,7 @@ impl<R: TreeRoot> AstNode<R> for TraitDef<R> { | |||
480 | } | 530 | } |
481 | 531 | ||
482 | impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {} | 532 | impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {} |
533 | impl<R: TreeRoot> ast::AttrsOwner<R> for TraitDef<R> {} | ||
483 | impl<R: TreeRoot> TraitDef<R> {} | 534 | impl<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 | ||
519 | impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {} | 570 | impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {} |
571 | impl<R: TreeRoot> ast::AttrsOwner<R> for TypeDef<R> {} | ||
520 | impl<R: TreeRoot> TypeDef<R> {} | 572 | impl<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 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use itertools::Itertools; | ||
5 | use smol_str::SmolStr; | 6 | use smol_str::SmolStr; |
6 | 7 | ||
7 | use { | 8 | use { |
8 | SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, | 9 | SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError, |
9 | SyntaxKind::*, | 10 | SyntaxKind::*, |
10 | }; | 11 | }; |
11 | pub use self::generated::*; | 12 | pub 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 | ||
19 | pub trait NameOwner<R: TreeRoot>: AstNode<R> { | 23 | pub trait NameOwner<R: TreeRoot>: AstNode<R> { |
@@ -25,6 +29,14 @@ pub trait NameOwner<R: TreeRoot>: AstNode<R> { | |||
25 | } | 29 | } |
26 | } | 30 | } |
27 | 31 | ||
32 | pub 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 | |||
28 | impl File<Arc<SyntaxRoot>> { | 40 | impl 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 | ||
40 | impl<R: TreeRoot> FnDef<R> { | 52 | impl<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) => { | 61 | fn 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 | |||
32 | fn 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 | |||
52 | fn 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 | ||
58 | pub(super) const ITEM_FIRST: TokenSet = | ||
59 | token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND]; | ||
60 | |||
61 | pub(super) enum MaybeItem { | 58 | pub(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 | ||
325 | fn token_tree(p: &mut Parser) { | 322 | pub(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 | } |
diff --git a/crates/libsyntax2/tests/data/parser/err/0005_attribute_recover.txt b/crates/libsyntax2/tests/data/parser/err/0005_attribute_recover.txt index 219352859..12451c892 100644 --- a/crates/libsyntax2/tests/data/parser/err/0005_attribute_recover.txt +++ b/crates/libsyntax2/tests/data/parser/err/0005_attribute_recover.txt | |||
@@ -2,25 +2,20 @@ FILE@[0; 54) | |||
2 | FN_DEF@[0; 31) | 2 | FN_DEF@[0; 31) |
3 | ATTR@[0; 18) | 3 | ATTR@[0; 18) |
4 | POUND@[0; 1) | 4 | POUND@[0; 1) |
5 | L_BRACK@[1; 2) | 5 | TOKEN_TREE@[1; 18) |
6 | META_ITEM@[2; 17) | 6 | L_BRACK@[1; 2) |
7 | IDENT@[2; 5) "foo" | 7 | IDENT@[2; 5) "foo" |
8 | L_PAREN@[5; 6) | 8 | TOKEN_TREE@[5; 17) |
9 | META_ITEM@[6; 9) | 9 | L_PAREN@[5; 6) |
10 | IDENT@[6; 9) "foo" | 10 | IDENT@[6; 9) "foo" |
11 | COMMA@[9; 10) | 11 | COMMA@[9; 10) |
12 | WHITESPACE@[10; 11) | 12 | WHITESPACE@[10; 11) |
13 | err: `expected attribute` | ||
14 | ERROR@[11; 12) | ||
15 | PLUS@[11; 12) | 13 | PLUS@[11; 12) |
16 | err: `expected attribute` | ||
17 | ERROR@[12; 13) | ||
18 | COMMA@[12; 13) | 14 | COMMA@[12; 13) |
19 | WHITESPACE@[13; 14) | 15 | WHITESPACE@[13; 14) |
20 | LITERAL@[14; 16) | ||
21 | INT_NUMBER@[14; 16) "92" | 16 | INT_NUMBER@[14; 16) "92" |
22 | R_PAREN@[16; 17) | 17 | R_PAREN@[16; 17) |
23 | R_BRACK@[17; 18) | 18 | R_BRACK@[17; 18) |
24 | WHITESPACE@[18; 19) | 19 | WHITESPACE@[18; 19) |
25 | FN_KW@[19; 21) | 20 | FN_KW@[19; 21) |
26 | WHITESPACE@[21; 22) | 21 | WHITESPACE@[21; 22) |
@@ -35,26 +30,26 @@ FILE@[0; 54) | |||
35 | WHITESPACE@[29; 30) | 30 | WHITESPACE@[29; 30) |
36 | R_CURLY@[30; 31) | 31 | R_CURLY@[30; 31) |
37 | WHITESPACE@[31; 34) | 32 | WHITESPACE@[31; 34) |
38 | FN_DEF@[34; 53) | 33 | ATTR@[34; 53) |
39 | ATTR@[34; 40) | 34 | POUND@[34; 35) |
40 | POUND@[34; 35) | 35 | TOKEN_TREE@[35; 53) |
41 | L_BRACK@[35; 36) | 36 | L_BRACK@[35; 36) |
42 | META_ITEM@[36; 40) | 37 | IDENT@[36; 39) "foo" |
43 | IDENT@[36; 39) "foo" | 38 | TOKEN_TREE@[39; 53) |
44 | L_PAREN@[39; 40) | 39 | L_PAREN@[39; 40) |
45 | err: `expected attribute` | 40 | WHITESPACE@[40; 41) |
46 | err: `expected R_BRACK` | 41 | FN_KW@[41; 43) |
47 | WHITESPACE@[40; 41) | 42 | WHITESPACE@[43; 44) |
48 | FN_KW@[41; 43) | 43 | IDENT@[44; 47) "foo" |
49 | WHITESPACE@[43; 44) | 44 | TOKEN_TREE@[47; 49) |
50 | NAME@[44; 47) | 45 | L_PAREN@[47; 48) |
51 | IDENT@[44; 47) "foo" | 46 | R_PAREN@[48; 49) |
52 | PARAM_LIST@[47; 49) | 47 | WHITESPACE@[49; 50) |
53 | L_PAREN@[47; 48) | 48 | TOKEN_TREE@[50; 53) |
54 | R_PAREN@[48; 49) | 49 | L_CURLY@[50; 51) |
55 | WHITESPACE@[49; 50) | 50 | WHITESPACE@[51; 52) |
56 | BLOCK_EXPR@[50; 53) | 51 | R_CURLY@[52; 53) |
57 | L_CURLY@[50; 51) | 52 | err: `expected R_PAREN` |
58 | WHITESPACE@[51; 52) | 53 | err: `expected R_BRACK` |
59 | R_CURLY@[52; 53) | 54 | err: `expected an item` |
60 | WHITESPACE@[53; 54) | 55 | WHITESPACE@[53; 54) |
diff --git a/crates/libsyntax2/tests/data/parser/err/0008_item_block_recovery.txt b/crates/libsyntax2/tests/data/parser/err/0008_item_block_recovery.txt index 5b46be079..68f2b8aa5 100644 --- a/crates/libsyntax2/tests/data/parser/err/0008_item_block_recovery.txt +++ b/crates/libsyntax2/tests/data/parser/err/0008_item_block_recovery.txt | |||
@@ -19,9 +19,10 @@ FILE@[0; 95) | |||
19 | NAME_REF@[14; 17) | 19 | NAME_REF@[14; 17) |
20 | IDENT@[14; 17) "bar" | 20 | IDENT@[14; 17) "bar" |
21 | err: `expected EXCL` | 21 | err: `expected EXCL` |
22 | L_PAREN@[17; 18) | 22 | TOKEN_TREE@[17; 19) |
23 | R_PAREN@[18; 19) | 23 | L_PAREN@[17; 18) |
24 | err: `expected SEMI` | 24 | R_PAREN@[18; 19) |
25 | err: `expected SEMI` | ||
25 | WHITESPACE@[19; 20) | 26 | WHITESPACE@[19; 20) |
26 | err: `expected an item` | 27 | err: `expected an item` |
27 | ERROR@[20; 80) | 28 | ERROR@[20; 80) |
diff --git a/crates/libsyntax2/tests/data/parser/inline/0039_path_expr.txt b/crates/libsyntax2/tests/data/parser/inline/0039_path_expr.txt index 876dd068c..629a8ec9b 100644 --- a/crates/libsyntax2/tests/data/parser/inline/0039_path_expr.txt +++ b/crates/libsyntax2/tests/data/parser/inline/0039_path_expr.txt | |||
@@ -86,8 +86,9 @@ FILE@[0; 91) | |||
86 | NAME_REF@[78; 84) | 86 | NAME_REF@[78; 84) |
87 | IDENT@[78; 84) "format" | 87 | IDENT@[78; 84) "format" |
88 | EXCL@[84; 85) | 88 | EXCL@[84; 85) |
89 | L_PAREN@[85; 86) | 89 | TOKEN_TREE@[85; 87) |
90 | R_PAREN@[86; 87) | 90 | L_PAREN@[85; 86) |
91 | R_PAREN@[86; 87) | ||
91 | SEMI@[87; 88) | 92 | SEMI@[87; 88) |
92 | WHITESPACE@[88; 89) | 93 | WHITESPACE@[88; 89) |
93 | R_CURLY@[89; 90) | 94 | R_CURLY@[89; 90) |
diff --git a/crates/libsyntax2/tests/data/parser/inline/0078_mod_contents.txt b/crates/libsyntax2/tests/data/parser/inline/0078_mod_contents.txt index c6be58e75..696695eba 100644 --- a/crates/libsyntax2/tests/data/parser/inline/0078_mod_contents.txt +++ b/crates/libsyntax2/tests/data/parser/inline/0078_mod_contents.txt | |||
@@ -21,8 +21,9 @@ FILE@[0; 70) | |||
21 | WHITESPACE@[24; 25) | 21 | WHITESPACE@[24; 25) |
22 | IDENT@[25; 28) "foo" | 22 | IDENT@[25; 28) "foo" |
23 | WHITESPACE@[28; 29) | 23 | WHITESPACE@[28; 29) |
24 | L_CURLY@[29; 30) | 24 | TOKEN_TREE@[29; 31) |
25 | R_CURLY@[30; 31) | 25 | L_CURLY@[29; 30) |
26 | R_CURLY@[30; 31) | ||
26 | WHITESPACE@[31; 32) | 27 | WHITESPACE@[31; 32) |
27 | MACRO_CALL@[32; 44) | 28 | MACRO_CALL@[32; 44) |
28 | PATH@[32; 40) | 29 | PATH@[32; 40) |
@@ -35,8 +36,9 @@ FILE@[0; 70) | |||
35 | NAME_REF@[37; 40) | 36 | NAME_REF@[37; 40) |
36 | IDENT@[37; 40) "bar" | 37 | IDENT@[37; 40) "bar" |
37 | EXCL@[40; 41) | 38 | EXCL@[40; 41) |
38 | L_PAREN@[41; 42) | 39 | TOKEN_TREE@[41; 43) |
39 | R_PAREN@[42; 43) | 40 | L_PAREN@[41; 42) |
41 | R_PAREN@[42; 43) | ||
40 | SEMI@[43; 44) | 42 | SEMI@[43; 44) |
41 | WHITESPACE@[44; 45) | 43 | WHITESPACE@[44; 45) |
42 | MACRO_CALL@[45; 59) | 44 | MACRO_CALL@[45; 59) |
@@ -50,8 +52,9 @@ FILE@[0; 70) | |||
50 | IDENT@[52; 55) "baz" | 52 | IDENT@[52; 55) "baz" |
51 | EXCL@[55; 56) | 53 | EXCL@[55; 56) |
52 | WHITESPACE@[56; 57) | 54 | WHITESPACE@[56; 57) |
53 | L_CURLY@[57; 58) | 55 | TOKEN_TREE@[57; 59) |
54 | R_CURLY@[58; 59) | 56 | L_CURLY@[57; 58) |
57 | R_CURLY@[58; 59) | ||
55 | WHITESPACE@[59; 60) | 58 | WHITESPACE@[59; 60) |
56 | STRUCT_DEF@[60; 69) | 59 | STRUCT_DEF@[60; 69) |
57 | STRUCT_KW@[60; 66) | 60 | STRUCT_KW@[60; 66) |
diff --git a/crates/libsyntax2/tests/data/parser/ok/0006_inner_attributes.txt b/crates/libsyntax2/tests/data/parser/ok/0006_inner_attributes.txt index 562c8d917..d5a170144 100644 --- a/crates/libsyntax2/tests/data/parser/ok/0006_inner_attributes.txt +++ b/crates/libsyntax2/tests/data/parser/ok/0006_inner_attributes.txt | |||
@@ -2,175 +2,163 @@ FILE@[0; 236) | |||
2 | ATTR@[0; 8) | 2 | ATTR@[0; 8) |
3 | POUND@[0; 1) | 3 | POUND@[0; 1) |
4 | EXCL@[1; 2) | 4 | EXCL@[1; 2) |
5 | L_BRACK@[2; 3) | 5 | TOKEN_TREE@[2; 8) |
6 | META_ITEM@[3; 7) | 6 | L_BRACK@[2; 3) |
7 | IDENT@[3; 7) "attr" | 7 | IDENT@[3; 7) "attr" |
8 | R_BRACK@[7; 8) | 8 | R_BRACK@[7; 8) |
9 | WHITESPACE@[8; 9) | 9 | WHITESPACE@[8; 9) |
10 | ATTR@[9; 23) | 10 | ATTR@[9; 23) |
11 | POUND@[9; 10) | 11 | POUND@[9; 10) |
12 | EXCL@[10; 11) | 12 | EXCL@[10; 11) |
13 | L_BRACK@[11; 12) | 13 | TOKEN_TREE@[11; 23) |
14 | META_ITEM@[12; 22) | 14 | L_BRACK@[11; 12) |
15 | IDENT@[12; 16) "attr" | 15 | IDENT@[12; 16) "attr" |
16 | L_PAREN@[16; 17) | 16 | TOKEN_TREE@[16; 22) |
17 | LITERAL@[17; 21) | 17 | L_PAREN@[16; 17) |
18 | TRUE_KW@[17; 21) | 18 | TRUE_KW@[17; 21) |
19 | R_PAREN@[21; 22) | 19 | R_PAREN@[21; 22) |
20 | R_BRACK@[22; 23) | 20 | R_BRACK@[22; 23) |
21 | WHITESPACE@[23; 24) | 21 | WHITESPACE@[23; 24) |
22 | ATTR@[24; 39) | 22 | ATTR@[24; 39) |
23 | POUND@[24; 25) | 23 | POUND@[24; 25) |
24 | EXCL@[25; 26) | 24 | EXCL@[25; 26) |
25 | L_BRACK@[26; 27) | 25 | TOKEN_TREE@[26; 39) |
26 | META_ITEM@[27; 38) | 26 | L_BRACK@[26; 27) |
27 | IDENT@[27; 31) "attr" | 27 | IDENT@[27; 31) "attr" |
28 | L_PAREN@[31; 32) | 28 | TOKEN_TREE@[31; 38) |
29 | META_ITEM@[32; 37) | 29 | L_PAREN@[31; 32) |
30 | IDENT@[32; 37) "ident" | 30 | IDENT@[32; 37) "ident" |
31 | R_PAREN@[37; 38) | 31 | R_PAREN@[37; 38) |
32 | R_BRACK@[38; 39) | 32 | R_BRACK@[38; 39) |
33 | WHITESPACE@[39; 40) | 33 | WHITESPACE@[39; 40) |
34 | ATTR@[40; 116) | 34 | ATTR@[40; 116) |
35 | POUND@[40; 41) | 35 | POUND@[40; 41) |
36 | EXCL@[41; 42) | 36 | EXCL@[41; 42) |
37 | L_BRACK@[42; 43) | 37 | TOKEN_TREE@[42; 116) |
38 | META_ITEM@[43; 115) | 38 | L_BRACK@[42; 43) |
39 | IDENT@[43; 47) "attr" | 39 | IDENT@[43; 47) "attr" |
40 | L_PAREN@[47; 48) | 40 | TOKEN_TREE@[47; 115) |
41 | META_ITEM@[48; 53) | 41 | L_PAREN@[47; 48) |
42 | IDENT@[48; 53) "ident" | 42 | IDENT@[48; 53) "ident" |
43 | COMMA@[53; 54) | 43 | COMMA@[53; 54) |
44 | WHITESPACE@[54; 55) | 44 | WHITESPACE@[54; 55) |
45 | LITERAL@[55; 58) | ||
46 | INT_NUMBER@[55; 58) "100" | 45 | INT_NUMBER@[55; 58) "100" |
47 | COMMA@[58; 59) | 46 | COMMA@[58; 59) |
48 | WHITESPACE@[59; 60) | 47 | WHITESPACE@[59; 60) |
49 | LITERAL@[60; 64) | ||
50 | TRUE_KW@[60; 64) | 48 | TRUE_KW@[60; 64) |
51 | COMMA@[64; 65) | 49 | COMMA@[64; 65) |
52 | WHITESPACE@[65; 66) | 50 | WHITESPACE@[65; 66) |
53 | LITERAL@[66; 72) | ||
54 | STRING@[66; 72) | 51 | STRING@[66; 72) |
55 | COMMA@[72; 73) | 52 | COMMA@[72; 73) |
56 | WHITESPACE@[73; 74) | 53 | WHITESPACE@[73; 74) |
57 | META_ITEM@[74; 85) | ||
58 | IDENT@[74; 79) "ident" | 54 | IDENT@[74; 79) "ident" |
59 | WHITESPACE@[79; 80) | 55 | WHITESPACE@[79; 80) |
60 | EQ@[80; 81) | 56 | EQ@[80; 81) |
61 | WHITESPACE@[81; 82) | 57 | WHITESPACE@[81; 82) |
62 | LITERAL@[82; 85) | 58 | INT_NUMBER@[82; 85) "100" |
63 | INT_NUMBER@[82; 85) "100" | 59 | COMMA@[85; 86) |
64 | COMMA@[85; 86) | 60 | WHITESPACE@[86; 87) |
65 | WHITESPACE@[86; 87) | ||
66 | META_ITEM@[87; 102) | ||
67 | IDENT@[87; 92) "ident" | 61 | IDENT@[87; 92) "ident" |
68 | WHITESPACE@[92; 93) | 62 | WHITESPACE@[92; 93) |
69 | EQ@[93; 94) | 63 | EQ@[93; 94) |
70 | WHITESPACE@[94; 95) | 64 | WHITESPACE@[94; 95) |
71 | LITERAL@[95; 102) | 65 | STRING@[95; 102) |
72 | STRING@[95; 102) | 66 | COMMA@[102; 103) |
73 | COMMA@[102; 103) | 67 | WHITESPACE@[103; 104) |
74 | WHITESPACE@[103; 104) | ||
75 | META_ITEM@[104; 114) | ||
76 | IDENT@[104; 109) "ident" | 68 | IDENT@[104; 109) "ident" |
77 | L_PAREN@[109; 110) | 69 | TOKEN_TREE@[109; 114) |
78 | LITERAL@[110; 113) | 70 | L_PAREN@[109; 110) |
79 | INT_NUMBER@[110; 113) "100" | 71 | INT_NUMBER@[110; 113) "100" |
80 | R_PAREN@[113; 114) | 72 | R_PAREN@[113; 114) |
81 | R_PAREN@[114; 115) | 73 | R_PAREN@[114; 115) |
82 | R_BRACK@[115; 116) | 74 | R_BRACK@[115; 116) |
83 | WHITESPACE@[116; 117) | 75 | WHITESPACE@[116; 117) |
84 | ATTR@[117; 130) | 76 | ATTR@[117; 130) |
85 | POUND@[117; 118) | 77 | POUND@[117; 118) |
86 | EXCL@[118; 119) | 78 | EXCL@[118; 119) |
87 | L_BRACK@[119; 120) | 79 | TOKEN_TREE@[119; 130) |
88 | META_ITEM@[120; 129) | 80 | L_BRACK@[119; 120) |
89 | IDENT@[120; 124) "attr" | 81 | IDENT@[120; 124) "attr" |
90 | L_PAREN@[124; 125) | 82 | TOKEN_TREE@[124; 129) |
91 | LITERAL@[125; 128) | 83 | L_PAREN@[124; 125) |
92 | INT_NUMBER@[125; 128) "100" | 84 | INT_NUMBER@[125; 128) "100" |
93 | R_PAREN@[128; 129) | 85 | R_PAREN@[128; 129) |
94 | R_BRACK@[129; 130) | 86 | R_BRACK@[129; 130) |
95 | WHITESPACE@[130; 131) | 87 | WHITESPACE@[130; 131) |
96 | ATTR@[131; 155) | 88 | ATTR@[131; 155) |
97 | POUND@[131; 132) | 89 | POUND@[131; 132) |
98 | EXCL@[132; 133) | 90 | EXCL@[132; 133) |
99 | L_BRACK@[133; 134) | 91 | TOKEN_TREE@[133; 155) |
100 | META_ITEM@[134; 154) | 92 | L_BRACK@[133; 134) |
101 | IDENT@[134; 138) "attr" | 93 | IDENT@[134; 138) "attr" |
102 | L_PAREN@[138; 139) | 94 | TOKEN_TREE@[138; 154) |
103 | META_ITEM@[139; 153) | 95 | L_PAREN@[138; 139) |
104 | IDENT@[139; 146) "enabled" | 96 | IDENT@[139; 146) "enabled" |
105 | WHITESPACE@[146; 147) | 97 | WHITESPACE@[146; 147) |
106 | EQ@[147; 148) | 98 | EQ@[147; 148) |
107 | WHITESPACE@[148; 149) | 99 | WHITESPACE@[148; 149) |
108 | LITERAL@[149; 153) | 100 | TRUE_KW@[149; 153) |
109 | TRUE_KW@[149; 153) | 101 | R_PAREN@[153; 154) |
110 | R_PAREN@[153; 154) | 102 | R_BRACK@[154; 155) |
111 | R_BRACK@[154; 155) | ||
112 | WHITESPACE@[155; 156) | 103 | WHITESPACE@[155; 156) |
113 | ATTR@[156; 173) | 104 | ATTR@[156; 173) |
114 | POUND@[156; 157) | 105 | POUND@[156; 157) |
115 | EXCL@[157; 158) | 106 | EXCL@[157; 158) |
116 | L_BRACK@[158; 159) | 107 | TOKEN_TREE@[158; 173) |
117 | META_ITEM@[159; 172) | 108 | L_BRACK@[158; 159) |
118 | IDENT@[159; 166) "enabled" | 109 | IDENT@[159; 166) "enabled" |
119 | L_PAREN@[166; 167) | 110 | TOKEN_TREE@[166; 172) |
120 | LITERAL@[167; 171) | 111 | L_PAREN@[166; 167) |
121 | TRUE_KW@[167; 171) | 112 | TRUE_KW@[167; 171) |
122 | R_PAREN@[171; 172) | 113 | R_PAREN@[171; 172) |
123 | R_BRACK@[172; 173) | 114 | R_BRACK@[172; 173) |
124 | WHITESPACE@[173; 174) | 115 | WHITESPACE@[173; 174) |
125 | ATTR@[174; 191) | 116 | ATTR@[174; 191) |
126 | POUND@[174; 175) | 117 | POUND@[174; 175) |
127 | EXCL@[175; 176) | 118 | EXCL@[175; 176) |
128 | L_BRACK@[176; 177) | 119 | TOKEN_TREE@[176; 191) |
129 | META_ITEM@[177; 190) | 120 | L_BRACK@[176; 177) |
130 | IDENT@[177; 181) "attr" | 121 | IDENT@[177; 181) "attr" |
131 | L_PAREN@[181; 182) | 122 | TOKEN_TREE@[181; 190) |
132 | LITERAL@[182; 189) | 123 | L_PAREN@[181; 182) |
133 | STRING@[182; 189) | 124 | STRING@[182; 189) |
134 | R_PAREN@[189; 190) | 125 | R_PAREN@[189; 190) |
135 | R_BRACK@[190; 191) | 126 | R_BRACK@[190; 191) |
136 | WHITESPACE@[191; 192) | 127 | WHITESPACE@[191; 192) |
137 | ATTR@[192; 214) | 128 | ATTR@[192; 214) |
138 | POUND@[192; 193) | 129 | POUND@[192; 193) |
139 | EXCL@[193; 194) | 130 | EXCL@[193; 194) |
140 | L_BRACK@[194; 195) | 131 | TOKEN_TREE@[194; 214) |
141 | META_ITEM@[195; 213) | 132 | L_BRACK@[194; 195) |
142 | IDENT@[195; 199) "repr" | 133 | IDENT@[195; 199) "repr" |
143 | L_PAREN@[199; 200) | 134 | TOKEN_TREE@[199; 213) |
144 | META_ITEM@[200; 201) | 135 | L_PAREN@[199; 200) |
145 | IDENT@[200; 201) "C" | 136 | IDENT@[200; 201) "C" |
146 | COMMA@[201; 202) | 137 | COMMA@[201; 202) |
147 | WHITESPACE@[202; 203) | 138 | WHITESPACE@[202; 203) |
148 | META_ITEM@[203; 212) | ||
149 | IDENT@[203; 208) "align" | 139 | IDENT@[203; 208) "align" |
150 | WHITESPACE@[208; 209) | 140 | WHITESPACE@[208; 209) |
151 | EQ@[209; 210) | 141 | EQ@[209; 210) |
152 | WHITESPACE@[210; 211) | 142 | WHITESPACE@[210; 211) |
153 | LITERAL@[211; 212) | 143 | INT_NUMBER@[211; 212) "4" |
154 | INT_NUMBER@[211; 212) "4" | 144 | R_PAREN@[212; 213) |
155 | R_PAREN@[212; 213) | 145 | R_BRACK@[213; 214) |
156 | R_BRACK@[213; 214) | ||
157 | WHITESPACE@[214; 215) | 146 | WHITESPACE@[214; 215) |
158 | ATTR@[215; 236) | 147 | ATTR@[215; 236) |
159 | POUND@[215; 216) | 148 | POUND@[215; 216) |
160 | EXCL@[216; 217) | 149 | EXCL@[216; 217) |
161 | L_BRACK@[217; 218) | 150 | TOKEN_TREE@[217; 236) |
162 | META_ITEM@[218; 235) | 151 | L_BRACK@[217; 218) |
163 | IDENT@[218; 222) "repr" | 152 | IDENT@[218; 222) "repr" |
164 | L_PAREN@[222; 223) | 153 | TOKEN_TREE@[222; 235) |
165 | META_ITEM@[223; 224) | 154 | L_PAREN@[222; 223) |
166 | IDENT@[223; 224) "C" | 155 | IDENT@[223; 224) "C" |
167 | COMMA@[224; 225) | 156 | COMMA@[224; 225) |
168 | WHITESPACE@[225; 226) | 157 | WHITESPACE@[225; 226) |
169 | META_ITEM@[226; 234) | ||
170 | IDENT@[226; 231) "align" | 158 | IDENT@[226; 231) "align" |
171 | L_PAREN@[231; 232) | 159 | TOKEN_TREE@[231; 234) |
172 | LITERAL@[232; 233) | 160 | L_PAREN@[231; 232) |
173 | INT_NUMBER@[232; 233) "4" | 161 | INT_NUMBER@[232; 233) "4" |
174 | R_PAREN@[233; 234) | 162 | R_PAREN@[233; 234) |
175 | R_PAREN@[234; 235) | 163 | R_PAREN@[234; 235) |
176 | R_BRACK@[235; 236) | 164 | R_BRACK@[235; 236) |
diff --git a/crates/libsyntax2/tests/data/parser/ok/0008_mod_item.txt b/crates/libsyntax2/tests/data/parser/ok/0008_mod_item.txt index abd2f8d61..54fe69baf 100644 --- a/crates/libsyntax2/tests/data/parser/ok/0008_mod_item.txt +++ b/crates/libsyntax2/tests/data/parser/ok/0008_mod_item.txt | |||
@@ -60,10 +60,10 @@ FILE@[0; 118) | |||
60 | ATTR@[79; 87) | 60 | ATTR@[79; 87) |
61 | POUND@[79; 80) | 61 | POUND@[79; 80) |
62 | EXCL@[80; 81) | 62 | EXCL@[80; 81) |
63 | L_BRACK@[81; 82) | 63 | TOKEN_TREE@[81; 87) |
64 | META_ITEM@[82; 86) | 64 | L_BRACK@[81; 82) |
65 | IDENT@[82; 86) "attr" | 65 | IDENT@[82; 86) "attr" |
66 | R_BRACK@[86; 87) | 66 | R_BRACK@[86; 87) |
67 | WHITESPACE@[87; 92) | 67 | WHITESPACE@[87; 92) |
68 | MODULE@[92; 98) | 68 | MODULE@[92; 98) |
69 | MOD_KW@[92; 95) | 69 | MOD_KW@[92; 95) |
diff --git a/crates/libsyntax2/tests/data/parser/ok/0011_outer_attribute.txt b/crates/libsyntax2/tests/data/parser/ok/0011_outer_attribute.txt index eae432fe2..24647fb06 100644 --- a/crates/libsyntax2/tests/data/parser/ok/0011_outer_attribute.txt +++ b/crates/libsyntax2/tests/data/parser/ok/0011_outer_attribute.txt | |||
@@ -2,21 +2,21 @@ FILE@[0; 35) | |||
2 | FN_DEF@[0; 34) | 2 | FN_DEF@[0; 34) |
3 | ATTR@[0; 12) | 3 | ATTR@[0; 12) |
4 | POUND@[0; 1) | 4 | POUND@[0; 1) |
5 | L_BRACK@[1; 2) | 5 | TOKEN_TREE@[1; 12) |
6 | META_ITEM@[2; 11) | 6 | L_BRACK@[1; 2) |
7 | IDENT@[2; 5) "cfg" | 7 | IDENT@[2; 5) "cfg" |
8 | L_PAREN@[5; 6) | 8 | TOKEN_TREE@[5; 11) |
9 | META_ITEM@[6; 10) | 9 | L_PAREN@[5; 6) |
10 | IDENT@[6; 10) "test" | 10 | IDENT@[6; 10) "test" |
11 | R_PAREN@[10; 11) | 11 | R_PAREN@[10; 11) |
12 | R_BRACK@[11; 12) | 12 | R_BRACK@[11; 12) |
13 | WHITESPACE@[12; 13) | 13 | WHITESPACE@[12; 13) |
14 | ATTR@[13; 22) | 14 | ATTR@[13; 22) |
15 | POUND@[13; 14) | 15 | POUND@[13; 14) |
16 | L_BRACK@[14; 15) | 16 | TOKEN_TREE@[14; 22) |
17 | META_ITEM@[15; 21) | 17 | L_BRACK@[14; 15) |
18 | IDENT@[15; 21) "ignore" | 18 | IDENT@[15; 21) "ignore" |
19 | R_BRACK@[21; 22) | 19 | R_BRACK@[21; 22) |
20 | WHITESPACE@[22; 23) | 20 | WHITESPACE@[22; 23) |
21 | FN_KW@[23; 25) | 21 | FN_KW@[23; 25) |
22 | WHITESPACE@[25; 26) | 22 | WHITESPACE@[25; 26) |
diff --git a/crates/libsyntax2/tests/data/parser/ok/0017_attr_trailing_comma.txt b/crates/libsyntax2/tests/data/parser/ok/0017_attr_trailing_comma.txt index 993cdcdec..6acd842c6 100644 --- a/crates/libsyntax2/tests/data/parser/ok/0017_attr_trailing_comma.txt +++ b/crates/libsyntax2/tests/data/parser/ok/0017_attr_trailing_comma.txt | |||
@@ -2,15 +2,15 @@ FILE@[0; 23) | |||
2 | FN_DEF@[0; 22) | 2 | FN_DEF@[0; 22) |
3 | ATTR@[0; 10) | 3 | ATTR@[0; 10) |
4 | POUND@[0; 1) | 4 | POUND@[0; 1) |
5 | L_BRACK@[1; 2) | 5 | TOKEN_TREE@[1; 10) |
6 | META_ITEM@[2; 9) | 6 | L_BRACK@[1; 2) |
7 | IDENT@[2; 5) "foo" | 7 | IDENT@[2; 5) "foo" |
8 | L_PAREN@[5; 6) | 8 | TOKEN_TREE@[5; 9) |
9 | META_ITEM@[6; 7) | 9 | L_PAREN@[5; 6) |
10 | IDENT@[6; 7) "a" | 10 | IDENT@[6; 7) "a" |
11 | COMMA@[7; 8) | 11 | COMMA@[7; 8) |
12 | R_PAREN@[8; 9) | 12 | R_PAREN@[8; 9) |
13 | R_BRACK@[9; 10) | 13 | R_BRACK@[9; 10) |
14 | WHITESPACE@[10; 11) | 14 | WHITESPACE@[10; 11) |
15 | FN_KW@[11; 13) | 15 | FN_KW@[11; 13) |
16 | WHITESPACE@[13; 14) | 16 | WHITESPACE@[13; 14) |
diff --git a/crates/libsyntax2/tests/test/main.rs b/crates/libsyntax2/tests/test/main.rs index 6b0a44d0c..802dba0e9 100644 --- a/crates/libsyntax2/tests/test/main.rs +++ b/crates/libsyntax2/tests/test/main.rs | |||
@@ -70,19 +70,19 @@ fn assert_equal_text(expected: &str, actual: &str, path: &Path) { | |||
70 | return; | 70 | return; |
71 | } | 71 | } |
72 | let dir = project_dir(); | 72 | let dir = project_dir(); |
73 | let path = path.strip_prefix(&dir).unwrap_or_else(|_| path); | 73 | let pretty_path = path.strip_prefix(&dir).unwrap_or_else(|_| path); |
74 | if expected.trim() == actual.trim() { | 74 | if expected.trim() == actual.trim() { |
75 | println!("whitespace difference, rewriting"); | 75 | println!("whitespace difference, rewriting"); |
76 | println!("file: {}\n", path.display()); | 76 | println!("file: {}\n", pretty_path.display()); |
77 | fs::write(path, actual).unwrap(); | 77 | fs::write(path, actual).unwrap(); |
78 | return; | 78 | return; |
79 | } | 79 | } |
80 | if REWRITE { | 80 | if REWRITE { |
81 | println!("rewriting {}", path.display()); | 81 | println!("rewriting {}", pretty_path.display()); |
82 | fs::write(path, actual).unwrap(); | 82 | fs::write(path, actual).unwrap(); |
83 | return; | 83 | return; |
84 | } | 84 | } |
85 | assert_eq_text!(expected, actual, "file: {}", path.display()); | 85 | assert_eq_text!(expected, actual, "file: {}", pretty_path.display()); |
86 | } | 86 | } |
87 | 87 | ||
88 | fn collect_tests(paths: &[&str]) -> Vec<PathBuf> { | 88 | fn collect_tests(paths: &[&str]) -> Vec<PathBuf> { |