aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-07-30 13:06:04 +0100
committerAleksey Kladov <[email protected]>2020-07-30 13:06:39 +0100
commit35e7966ebeee70ca2c15b5139b5c1918d9ef4086 (patch)
tree884d3e034699c6d6bd389fa05bb4999fefcbcf73
parentbe803efb7c7ba257716fcc97c57ecfd07e278b07 (diff)
Add comma list to use tree
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs155
-rw-r--r--xtask/src/codegen/gen_syntax.rs35
-rw-r--r--xtask/src/codegen/rust.ungram25
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 {
268impl ast::NameOwner for Rename {} 268impl ast::NameOwner for Rename {}
269impl Rename { 269impl 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)]
274pub struct UseTree {
275 pub(crate) syntax: SyntaxNode,
276}
277impl 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)]
285pub struct Path {
286 pub(crate) syntax: SyntaxNode,
287}
288impl 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)]
294pub struct UseTreeList {
295 pub(crate) syntax: SyntaxNode,
296}
297impl 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)]
273pub struct Abi { 303pub 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)]
436pub struct Path {
437 pub(crate) syntax: SyntaxNode,
438}
439impl 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)]
445pub struct PointerType { 466pub 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)]
1181pub struct UseTree {
1182 pub(crate) syntax: SyntaxNode,
1183}
1184impl 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)]
1192pub struct UseTreeList {
1193 pub(crate) syntax: SyntaxNode,
1194}
1195impl 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)]
1201pub struct PathSegment { 1202pub 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}
1631impl 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}
1642impl 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}
1653impl 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}
1630impl AstNode for Abi { 1664impl 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}
1828impl 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}
1839impl AstNode for PointerType { 1862impl 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}
2675impl 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}
2686impl 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}
2697impl AstNode for PathSegment { 2698impl 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}
3564impl 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}
3569impl 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}
3574impl 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}
3563impl std::fmt::Display for Abi { 3579impl 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}
3653impl 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}
3658impl std::fmt::Display for PointerType { 3669impl 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}
4038impl 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}
4043impl 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}
4048impl std::fmt::Display for PathSegment { 4049impl 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
545fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { 545fn 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)* ','?)?
603fn 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
598fn deduplicate_fields(ast: &mut AstSrc) { 633fn 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 =
29ExternCrate = 29ExternCrate =
30 Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';' 30 Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';'
31 31
32Rename =
33 'as' (Name | '_')
34
35UseItem =
36 Attr* Visibility? 'use' UseTree ';'
37
38UseTree =
39 (Path? '::')? ('*' | UseTreeList )
40| Path Rename?
41
42UseTreeList =
43 '{' (UseTree (',' UseTree)* ','?)? '}'
44
32FnDef = 45FnDef =
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
398UseItem =
399 Attr* Visibility? 'use' UseTree ';'
400
401UseTree =
402 Path ('::' ('*' | UseTreeList)) Rename?
403
404UseTreeList =
405 '{' UseTree* '}'
406
407Rename =
408 'as' Name
409
410Path = 411Path =
411 (qualifier:Path '::')? segment:PathSegment 412 (qualifier:Path '::')? segment:PathSegment
412 413