mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 20:43:21 +00:00
Add comma list to use tree
This commit is contained in:
parent
be803efb7c
commit
35e7966ebe
3 changed files with 126 additions and 89 deletions
|
@ -268,6 +268,36 @@ pub struct Rename {
|
|||
impl ast::NameOwner for Rename {}
|
||||
impl Rename {
|
||||
pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
|
||||
pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UseTree {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl UseTree {
|
||||
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
|
||||
pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
|
||||
pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Path {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl Path {
|
||||
pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UseTreeList {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl UseTreeList {
|
||||
pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
|
||||
pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
|
||||
pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Abi {
|
||||
|
@ -433,15 +463,6 @@ impl PathType {
|
|||
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Path {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl Path {
|
||||
pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct PointerType {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
|
@ -1178,26 +1199,6 @@ impl Param {
|
|||
pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UseTree {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl UseTree {
|
||||
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
|
||||
pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
|
||||
pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UseTreeList {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl UseTreeList {
|
||||
pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
|
||||
pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
|
||||
pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct PathSegment {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
|
@ -1627,6 +1628,39 @@ impl AstNode for Rename {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for UseTree {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for Path {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for UseTreeList {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for Abi {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
@ -1825,17 +1859,6 @@ impl AstNode for PathType {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for Path {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for PointerType {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
@ -2672,28 +2695,6 @@ impl AstNode for Param {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for UseTree {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for UseTreeList {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for PathSegment {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
@ -3560,6 +3561,21 @@ impl std::fmt::Display for Rename {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UseTree {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for Path {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UseTreeList {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for Abi {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
@ -3650,11 +3666,6 @@ impl std::fmt::Display for PathType {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for Path {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for PointerType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
@ -4035,16 +4046,6 @@ impl std::fmt::Display for Param {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UseTree {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UseTreeList {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for PathSegment {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
|
|
@ -543,6 +543,10 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
|
|||
}
|
||||
|
||||
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
|
||||
if lower_comma_list(acc, grammar, rule) {
|
||||
return;
|
||||
}
|
||||
|
||||
match rule {
|
||||
Rule::Node(node) => {
|
||||
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) {
|
|||
}
|
||||
}
|
||||
|
||||
// (T (',' T)* ','?)?
|
||||
fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool {
|
||||
let rule = match rule {
|
||||
Rule::Opt(it) => it,
|
||||
_ => return false,
|
||||
};
|
||||
let rule = match &**rule {
|
||||
Rule::Seq(it) => it,
|
||||
_ => return false,
|
||||
};
|
||||
let (node, repeat, trailing_comma) = match rule.as_slice() {
|
||||
[Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => {
|
||||
(node, repeat, trailing_comma)
|
||||
}
|
||||
_ => return false,
|
||||
};
|
||||
let repeat = match &**repeat {
|
||||
Rule::Seq(it) => it,
|
||||
_ => return false,
|
||||
};
|
||||
match repeat.as_slice() {
|
||||
[comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (),
|
||||
_ => return false,
|
||||
}
|
||||
let name = grammar[*node].name.clone();
|
||||
let label = pluralize(&to_lower_snake_case(&name));
|
||||
let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) };
|
||||
acc.push(field);
|
||||
true
|
||||
}
|
||||
|
||||
fn deduplicate_fields(ast: &mut AstSrc) {
|
||||
for node in &mut ast.nodes {
|
||||
let mut i = 0;
|
||||
|
|
|
@ -29,6 +29,19 @@ ItemList =
|
|||
ExternCrate =
|
||||
Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';'
|
||||
|
||||
Rename =
|
||||
'as' (Name | '_')
|
||||
|
||||
UseItem =
|
||||
Attr* Visibility? 'use' UseTree ';'
|
||||
|
||||
UseTree =
|
||||
(Path? '::')? ('*' | UseTreeList )
|
||||
| Path Rename?
|
||||
|
||||
UseTreeList =
|
||||
'{' (UseTree (',' UseTree)* ','?)? '}'
|
||||
|
||||
FnDef =
|
||||
Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
|
||||
ParamList RetType?
|
||||
|
@ -395,18 +408,6 @@ Param =
|
|||
Attr* Pat (':' ascribed_type:TypeRef)
|
||||
| '...'
|
||||
|
||||
UseItem =
|
||||
Attr* Visibility? 'use' UseTree ';'
|
||||
|
||||
UseTree =
|
||||
Path ('::' ('*' | UseTreeList)) Rename?
|
||||
|
||||
UseTreeList =
|
||||
'{' UseTree* '}'
|
||||
|
||||
Rename =
|
||||
'as' Name
|
||||
|
||||
Path =
|
||||
(qualifier:Path '::')? segment:PathSegment
|
||||
|
||||
|
|
Loading…
Reference in a new issue