diff options
author | Aleksey Kladov <[email protected]> | 2020-07-30 13:06:04 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-07-30 13:06:39 +0100 |
commit | 35e7966ebeee70ca2c15b5139b5c1918d9ef4086 (patch) | |
tree | 884d3e034699c6d6bd389fa05bb4999fefcbcf73 | |
parent | be803efb7c7ba257716fcc97c57ecfd07e278b07 (diff) |
Add comma list to use tree
-rw-r--r-- | crates/ra_syntax/src/ast/generated/nodes.rs | 155 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 35 | ||||
-rw-r--r-- | xtask/src/codegen/rust.ungram | 25 |
3 files changed, 126 insertions, 89 deletions
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 3fd761367..9d8127a3d 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs | |||
@@ -268,6 +268,36 @@ pub struct Rename { | |||
268 | impl ast::NameOwner for Rename {} | 268 | impl ast::NameOwner for Rename {} |
269 | impl Rename { | 269 | impl Rename { |
270 | pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) } | 270 | pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) } |
271 | pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) } | ||
272 | } | ||
273 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
274 | pub struct UseTree { | ||
275 | pub(crate) syntax: SyntaxNode, | ||
276 | } | ||
277 | impl UseTree { | ||
278 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | ||
279 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } | ||
280 | pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) } | ||
281 | pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) } | ||
282 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } | ||
283 | } | ||
284 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
285 | pub struct Path { | ||
286 | pub(crate) syntax: SyntaxNode, | ||
287 | } | ||
288 | impl Path { | ||
289 | pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) } | ||
290 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } | ||
291 | pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) } | ||
292 | } | ||
293 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
294 | pub struct UseTreeList { | ||
295 | pub(crate) syntax: SyntaxNode, | ||
296 | } | ||
297 | impl UseTreeList { | ||
298 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } | ||
299 | pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) } | ||
300 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } | ||
271 | } | 301 | } |
272 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 302 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
273 | pub struct Abi { | 303 | pub struct Abi { |
@@ -433,15 +463,6 @@ impl PathType { | |||
433 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | 463 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } |
434 | } | 464 | } |
435 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 465 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
436 | pub struct Path { | ||
437 | pub(crate) syntax: SyntaxNode, | ||
438 | } | ||
439 | impl Path { | ||
440 | pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) } | ||
441 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } | ||
442 | pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) } | ||
443 | } | ||
444 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
445 | pub struct PointerType { | 466 | pub struct PointerType { |
446 | pub(crate) syntax: SyntaxNode, | 467 | pub(crate) syntax: SyntaxNode, |
447 | } | 468 | } |
@@ -1178,26 +1199,6 @@ impl Param { | |||
1178 | pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) } | 1199 | pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) } |
1179 | } | 1200 | } |
1180 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1201 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1181 | pub struct UseTree { | ||
1182 | pub(crate) syntax: SyntaxNode, | ||
1183 | } | ||
1184 | impl UseTree { | ||
1185 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | ||
1186 | pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } | ||
1187 | pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) } | ||
1188 | pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) } | ||
1189 | pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) } | ||
1190 | } | ||
1191 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1192 | pub struct UseTreeList { | ||
1193 | pub(crate) syntax: SyntaxNode, | ||
1194 | } | ||
1195 | impl UseTreeList { | ||
1196 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } | ||
1197 | pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) } | ||
1198 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } | ||
1199 | } | ||
1200 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1201 | pub struct PathSegment { | 1202 | pub struct PathSegment { |
1202 | pub(crate) syntax: SyntaxNode, | 1203 | pub(crate) syntax: SyntaxNode, |
1203 | } | 1204 | } |
@@ -1627,6 +1628,39 @@ impl AstNode for Rename { | |||
1627 | } | 1628 | } |
1628 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1629 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1629 | } | 1630 | } |
1631 | impl AstNode for UseTree { | ||
1632 | fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE } | ||
1633 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1634 | if Self::can_cast(syntax.kind()) { | ||
1635 | Some(Self { syntax }) | ||
1636 | } else { | ||
1637 | None | ||
1638 | } | ||
1639 | } | ||
1640 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1641 | } | ||
1642 | impl AstNode for Path { | ||
1643 | fn can_cast(kind: SyntaxKind) -> bool { kind == PATH } | ||
1644 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1645 | if Self::can_cast(syntax.kind()) { | ||
1646 | Some(Self { syntax }) | ||
1647 | } else { | ||
1648 | None | ||
1649 | } | ||
1650 | } | ||
1651 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1652 | } | ||
1653 | impl AstNode for UseTreeList { | ||
1654 | fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST } | ||
1655 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1656 | if Self::can_cast(syntax.kind()) { | ||
1657 | Some(Self { syntax }) | ||
1658 | } else { | ||
1659 | None | ||
1660 | } | ||
1661 | } | ||
1662 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1663 | } | ||
1630 | impl AstNode for Abi { | 1664 | impl AstNode for Abi { |
1631 | fn can_cast(kind: SyntaxKind) -> bool { kind == ABI } | 1665 | fn can_cast(kind: SyntaxKind) -> bool { kind == ABI } |
1632 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 1666 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -1825,17 +1859,6 @@ impl AstNode for PathType { | |||
1825 | } | 1859 | } |
1826 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1860 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1827 | } | 1861 | } |
1828 | impl AstNode for Path { | ||
1829 | fn can_cast(kind: SyntaxKind) -> bool { kind == PATH } | ||
1830 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1831 | if Self::can_cast(syntax.kind()) { | ||
1832 | Some(Self { syntax }) | ||
1833 | } else { | ||
1834 | None | ||
1835 | } | ||
1836 | } | ||
1837 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1838 | } | ||
1839 | impl AstNode for PointerType { | 1862 | impl AstNode for PointerType { |
1840 | fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE } | 1863 | fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE } |
1841 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 1864 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -2672,28 +2695,6 @@ impl AstNode for Param { | |||
2672 | } | 2695 | } |
2673 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2696 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2674 | } | 2697 | } |
2675 | impl AstNode for UseTree { | ||
2676 | fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE } | ||
2677 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2678 | if Self::can_cast(syntax.kind()) { | ||
2679 | Some(Self { syntax }) | ||
2680 | } else { | ||
2681 | None | ||
2682 | } | ||
2683 | } | ||
2684 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2685 | } | ||
2686 | impl AstNode for UseTreeList { | ||
2687 | fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST } | ||
2688 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2689 | if Self::can_cast(syntax.kind()) { | ||
2690 | Some(Self { syntax }) | ||
2691 | } else { | ||
2692 | None | ||
2693 | } | ||
2694 | } | ||
2695 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2696 | } | ||
2697 | impl AstNode for PathSegment { | 2698 | impl AstNode for PathSegment { |
2698 | fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT } | 2699 | fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT } |
2699 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 2700 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -3560,6 +3561,21 @@ impl std::fmt::Display for Rename { | |||
3560 | std::fmt::Display::fmt(self.syntax(), f) | 3561 | std::fmt::Display::fmt(self.syntax(), f) |
3561 | } | 3562 | } |
3562 | } | 3563 | } |
3564 | impl std::fmt::Display for UseTree { | ||
3565 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3566 | std::fmt::Display::fmt(self.syntax(), f) | ||
3567 | } | ||
3568 | } | ||
3569 | impl std::fmt::Display for Path { | ||
3570 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3571 | std::fmt::Display::fmt(self.syntax(), f) | ||
3572 | } | ||
3573 | } | ||
3574 | impl std::fmt::Display for UseTreeList { | ||
3575 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3576 | std::fmt::Display::fmt(self.syntax(), f) | ||
3577 | } | ||
3578 | } | ||
3563 | impl std::fmt::Display for Abi { | 3579 | impl std::fmt::Display for Abi { |
3564 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 3580 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3565 | std::fmt::Display::fmt(self.syntax(), f) | 3581 | std::fmt::Display::fmt(self.syntax(), f) |
@@ -3650,11 +3666,6 @@ impl std::fmt::Display for PathType { | |||
3650 | std::fmt::Display::fmt(self.syntax(), f) | 3666 | std::fmt::Display::fmt(self.syntax(), f) |
3651 | } | 3667 | } |
3652 | } | 3668 | } |
3653 | impl std::fmt::Display for Path { | ||
3654 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3655 | std::fmt::Display::fmt(self.syntax(), f) | ||
3656 | } | ||
3657 | } | ||
3658 | impl std::fmt::Display for PointerType { | 3669 | impl std::fmt::Display for PointerType { |
3659 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 3670 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3660 | std::fmt::Display::fmt(self.syntax(), f) | 3671 | std::fmt::Display::fmt(self.syntax(), f) |
@@ -4035,16 +4046,6 @@ impl std::fmt::Display for Param { | |||
4035 | std::fmt::Display::fmt(self.syntax(), f) | 4046 | std::fmt::Display::fmt(self.syntax(), f) |
4036 | } | 4047 | } |
4037 | } | 4048 | } |
4038 | impl std::fmt::Display for UseTree { | ||
4039 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4040 | std::fmt::Display::fmt(self.syntax(), f) | ||
4041 | } | ||
4042 | } | ||
4043 | impl std::fmt::Display for UseTreeList { | ||
4044 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4045 | std::fmt::Display::fmt(self.syntax(), f) | ||
4046 | } | ||
4047 | } | ||
4048 | impl std::fmt::Display for PathSegment { | 4049 | impl std::fmt::Display for PathSegment { |
4049 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 4050 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
4050 | std::fmt::Display::fmt(self.syntax(), f) | 4051 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index 9b49712c1..c77fc8a8d 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -543,6 +543,10 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> { | |||
543 | } | 543 | } |
544 | 544 | ||
545 | fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { | 545 | fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { |
546 | if lower_comma_list(acc, grammar, rule) { | ||
547 | return; | ||
548 | } | ||
549 | |||
546 | match rule { | 550 | match rule { |
547 | Rule::Node(node) => { | 551 | Rule::Node(node) => { |
548 | let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand }; | 552 | let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand }; |
@@ -595,6 +599,37 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { | |||
595 | } | 599 | } |
596 | } | 600 | } |
597 | 601 | ||
602 | // (T (',' T)* ','?)? | ||
603 | fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool { | ||
604 | let rule = match rule { | ||
605 | Rule::Opt(it) => it, | ||
606 | _ => return false, | ||
607 | }; | ||
608 | let rule = match &**rule { | ||
609 | Rule::Seq(it) => it, | ||
610 | _ => return false, | ||
611 | }; | ||
612 | let (node, repeat, trailing_comma) = match rule.as_slice() { | ||
613 | [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => { | ||
614 | (node, repeat, trailing_comma) | ||
615 | } | ||
616 | _ => return false, | ||
617 | }; | ||
618 | let repeat = match &**repeat { | ||
619 | Rule::Seq(it) => it, | ||
620 | _ => return false, | ||
621 | }; | ||
622 | match repeat.as_slice() { | ||
623 | [comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (), | ||
624 | _ => return false, | ||
625 | } | ||
626 | let name = grammar[*node].name.clone(); | ||
627 | let label = pluralize(&to_lower_snake_case(&name)); | ||
628 | let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) }; | ||
629 | acc.push(field); | ||
630 | true | ||
631 | } | ||
632 | |||
598 | fn deduplicate_fields(ast: &mut AstSrc) { | 633 | fn deduplicate_fields(ast: &mut AstSrc) { |
599 | for node in &mut ast.nodes { | 634 | for node in &mut ast.nodes { |
600 | let mut i = 0; | 635 | let mut i = 0; |
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram index e6e7c7518..2ba68457f 100644 --- a/xtask/src/codegen/rust.ungram +++ b/xtask/src/codegen/rust.ungram | |||
@@ -29,6 +29,19 @@ ItemList = | |||
29 | ExternCrate = | 29 | ExternCrate = |
30 | Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';' | 30 | Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';' |
31 | 31 | ||
32 | Rename = | ||
33 | 'as' (Name | '_') | ||
34 | |||
35 | UseItem = | ||
36 | Attr* Visibility? 'use' UseTree ';' | ||
37 | |||
38 | UseTree = | ||
39 | (Path? '::')? ('*' | UseTreeList ) | ||
40 | | Path Rename? | ||
41 | |||
42 | UseTreeList = | ||
43 | '{' (UseTree (',' UseTree)* ','?)? '}' | ||
44 | |||
32 | FnDef = | 45 | FnDef = |
33 | Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList? | 46 | Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList? |
34 | ParamList RetType? | 47 | ParamList RetType? |
@@ -395,18 +408,6 @@ Param = | |||
395 | Attr* Pat (':' ascribed_type:TypeRef) | 408 | Attr* Pat (':' ascribed_type:TypeRef) |
396 | | '...' | 409 | | '...' |
397 | 410 | ||
398 | UseItem = | ||
399 | Attr* Visibility? 'use' UseTree ';' | ||
400 | |||
401 | UseTree = | ||
402 | Path ('::' ('*' | UseTreeList)) Rename? | ||
403 | |||
404 | UseTreeList = | ||
405 | '{' UseTree* '}' | ||
406 | |||
407 | Rename = | ||
408 | 'as' Name | ||
409 | |||
410 | Path = | 411 | Path = |
411 | (qualifier:Path '::')? segment:PathSegment | 412 | (qualifier:Path '::')? segment:PathSegment |
412 | 413 | ||