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 ast::NameOwner for Rename {}
|
||||||
impl Rename {
|
impl Rename {
|
||||||
pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Abi {
|
pub struct Abi {
|
||||||
|
@ -433,15 +463,6 @@ impl PathType {
|
||||||
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
|
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[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 struct PointerType {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
}
|
}
|
||||||
|
@ -1178,26 +1199,6 @@ impl Param {
|
||||||
pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
|
pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[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 struct PathSegment {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
}
|
}
|
||||||
|
@ -1627,6 +1628,39 @@ impl AstNode for Rename {
|
||||||
}
|
}
|
||||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
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 {
|
impl AstNode for Abi {
|
||||||
fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
|
fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
|
||||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
@ -1825,17 +1859,6 @@ impl AstNode for PathType {
|
||||||
}
|
}
|
||||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
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 {
|
impl AstNode for PointerType {
|
||||||
fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE }
|
fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE }
|
||||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
@ -2672,28 +2695,6 @@ impl AstNode for Param {
|
||||||
}
|
}
|
||||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
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 {
|
impl AstNode for PathSegment {
|
||||||
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT }
|
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT }
|
||||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
@ -3560,6 +3561,21 @@ impl std::fmt::Display for Rename {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
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 {
|
impl std::fmt::Display for Abi {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
@ -3650,11 +3666,6 @@ impl std::fmt::Display for PathType {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
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 {
|
impl std::fmt::Display for PointerType {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
@ -4035,16 +4046,6 @@ impl std::fmt::Display for Param {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
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 {
|
impl std::fmt::Display for PathSegment {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
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) {
|
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
|
||||||
|
if lower_comma_list(acc, grammar, rule) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
match rule {
|
match rule {
|
||||||
Rule::Node(node) => {
|
Rule::Node(node) => {
|
||||||
let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand };
|
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) {
|
fn deduplicate_fields(ast: &mut AstSrc) {
|
||||||
for node in &mut ast.nodes {
|
for node in &mut ast.nodes {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
|
@ -29,6 +29,19 @@ ItemList =
|
||||||
ExternCrate =
|
ExternCrate =
|
||||||
Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';'
|
Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';'
|
||||||
|
|
||||||
|
Rename =
|
||||||
|
'as' (Name | '_')
|
||||||
|
|
||||||
|
UseItem =
|
||||||
|
Attr* Visibility? 'use' UseTree ';'
|
||||||
|
|
||||||
|
UseTree =
|
||||||
|
(Path? '::')? ('*' | UseTreeList )
|
||||||
|
| Path Rename?
|
||||||
|
|
||||||
|
UseTreeList =
|
||||||
|
'{' (UseTree (',' UseTree)* ','?)? '}'
|
||||||
|
|
||||||
FnDef =
|
FnDef =
|
||||||
Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
|
Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
|
||||||
ParamList RetType?
|
ParamList RetType?
|
||||||
|
@ -395,18 +408,6 @@ Param =
|
||||||
Attr* Pat (':' ascribed_type:TypeRef)
|
Attr* Pat (':' ascribed_type:TypeRef)
|
||||||
| '...'
|
| '...'
|
||||||
|
|
||||||
UseItem =
|
|
||||||
Attr* Visibility? 'use' UseTree ';'
|
|
||||||
|
|
||||||
UseTree =
|
|
||||||
Path ('::' ('*' | UseTreeList)) Rename?
|
|
||||||
|
|
||||||
UseTreeList =
|
|
||||||
'{' UseTree* '}'
|
|
||||||
|
|
||||||
Rename =
|
|
||||||
'as' Name
|
|
||||||
|
|
||||||
Path =
|
Path =
|
||||||
(qualifier:Path '::')? segment:PathSegment
|
(qualifier:Path '::')? segment:PathSegment
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue