mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
Merge #5600
5600: Finalize structs grammar r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
2496628c56
4 changed files with 29 additions and 41 deletions
|
@ -422,7 +422,6 @@ pub struct TupleField {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
}
|
}
|
||||||
impl ast::AttrsOwner for TupleField {}
|
impl ast::AttrsOwner for TupleField {}
|
||||||
impl ast::NameOwner for TupleField {}
|
|
||||||
impl ast::VisibilityOwner for TupleField {}
|
impl ast::VisibilityOwner for TupleField {}
|
||||||
impl TupleField {
|
impl TupleField {
|
||||||
pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
|
pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
|
||||||
|
|
|
@ -242,11 +242,11 @@ pub(crate) struct AstNodeSrc {
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub(crate) enum Field {
|
pub(crate) enum Field {
|
||||||
Token(String),
|
Token(String),
|
||||||
Node { name: String, ty: String, valence: Valence },
|
Node { name: String, ty: String, cardinality: Cardinality },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub(crate) enum Valence {
|
pub(crate) enum Cardinality {
|
||||||
Optional,
|
Optional,
|
||||||
Many,
|
Many,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use quote::{format_ident, quote};
|
||||||
use ungrammar::{Grammar, Rule};
|
use ungrammar::{Grammar, Rule};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, KindsSrc, Valence, KINDS_SRC},
|
ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
|
||||||
codegen::{self, update, Mode},
|
codegen::{self, update, Mode},
|
||||||
project_root, Result,
|
project_root, Result,
|
||||||
};
|
};
|
||||||
|
@ -431,7 +431,7 @@ fn pluralize(s: &str) -> String {
|
||||||
|
|
||||||
impl Field {
|
impl Field {
|
||||||
fn is_many(&self) -> bool {
|
fn is_many(&self) -> bool {
|
||||||
matches!(self, Field::Node { valence: Valence::Many, .. })
|
matches!(self, Field::Node { cardinality: Cardinality::Many, .. })
|
||||||
}
|
}
|
||||||
fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
|
fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -509,7 +509,7 @@ fn lower(grammar: &Grammar) -> AstSrc {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut fields = Vec::new();
|
let mut fields = Vec::new();
|
||||||
lower_rule(&mut fields, grammar, rule);
|
lower_rule(&mut fields, grammar, None, rule);
|
||||||
res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
|
res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,19 +537,20 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
|
||||||
Some(variants)
|
Some(variants)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
|
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, rule: &Rule) {
|
||||||
if lower_comma_list(acc, grammar, rule) {
|
if lower_comma_list(acc, grammar, label, rule) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match rule {
|
match rule {
|
||||||
Rule::Node(node) => {
|
Rule::Node(node) => {
|
||||||
let ty = grammar[*node].name.clone();
|
let ty = grammar[*node].name.clone();
|
||||||
let name = to_lower_snake_case(&ty);
|
let name = label.cloned().unwrap_or_else(|| to_lower_snake_case(&ty));
|
||||||
let field = Field::Node { name, ty, valence: Valence::Optional };
|
let field = Field::Node { name, ty, cardinality: Cardinality::Optional };
|
||||||
acc.push(field);
|
acc.push(field);
|
||||||
}
|
}
|
||||||
Rule::Token(token) => {
|
Rule::Token(token) => {
|
||||||
|
assert!(label.is_none());
|
||||||
let mut name = grammar[*token].name.clone();
|
let mut name = grammar[*token].name.clone();
|
||||||
if name != "int_number" && name != "string" {
|
if name != "int_number" && name != "string" {
|
||||||
if "[]{}()".contains(&name) {
|
if "[]{}()".contains(&name) {
|
||||||
|
@ -562,44 +563,33 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
|
||||||
Rule::Rep(inner) => {
|
Rule::Rep(inner) => {
|
||||||
if let Rule::Node(node) = &**inner {
|
if let Rule::Node(node) = &**inner {
|
||||||
let ty = grammar[*node].name.clone();
|
let ty = grammar[*node].name.clone();
|
||||||
let name = pluralize(&to_lower_snake_case(&ty));
|
let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
|
||||||
let field = Field::Node { name, ty, valence: Valence::Many };
|
let field = Field::Node { name, ty, cardinality: Cardinality::Many };
|
||||||
acc.push(field);
|
acc.push(field);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
todo!("{:?}", rule)
|
todo!("{:?}", rule)
|
||||||
}
|
}
|
||||||
Rule::Labeled { label, rule } => {
|
Rule::Labeled { label: l, rule } => {
|
||||||
let node = match &**rule {
|
assert!(label.is_none());
|
||||||
Rule::Rep(inner) | Rule::Opt(inner) => match &**inner {
|
lower_rule(acc, grammar, Some(l), rule);
|
||||||
Rule::Node(node) => node,
|
|
||||||
_ => todo!("{:?}", rule),
|
|
||||||
},
|
|
||||||
Rule::Node(node) => node,
|
|
||||||
_ => todo!("{:?}", rule),
|
|
||||||
};
|
|
||||||
let ty = grammar[*node].name.clone();
|
|
||||||
let field = Field::Node {
|
|
||||||
name: label.clone(),
|
|
||||||
ty,
|
|
||||||
valence: match &**rule {
|
|
||||||
Rule::Rep(_) => Valence::Many,
|
|
||||||
_ => Valence::Optional,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
acc.push(field);
|
|
||||||
}
|
}
|
||||||
Rule::Seq(rules) | Rule::Alt(rules) => {
|
Rule::Seq(rules) | Rule::Alt(rules) => {
|
||||||
for rule in rules {
|
for rule in rules {
|
||||||
lower_rule(acc, grammar, rule)
|
lower_rule(acc, grammar, label, rule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rule::Opt(rule) => lower_rule(acc, grammar, rule),
|
Rule::Opt(rule) => lower_rule(acc, grammar, label, rule),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (T (',' T)* ','?)
|
// (T (',' T)* ','?)
|
||||||
fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool {
|
fn lower_comma_list(
|
||||||
|
acc: &mut Vec<Field>,
|
||||||
|
grammar: &Grammar,
|
||||||
|
label: Option<&String>,
|
||||||
|
rule: &Rule,
|
||||||
|
) -> bool {
|
||||||
let rule = match rule {
|
let rule = match rule {
|
||||||
Rule::Seq(it) => it,
|
Rule::Seq(it) => it,
|
||||||
_ => return false,
|
_ => return false,
|
||||||
|
@ -619,8 +609,8 @@ fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> boo
|
||||||
_ => return false,
|
_ => return false,
|
||||||
}
|
}
|
||||||
let ty = grammar[*node].name.clone();
|
let ty = grammar[*node].name.clone();
|
||||||
let name = pluralize(&to_lower_snake_case(&ty));
|
let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
|
||||||
let field = Field::Node { name, ty, valence: Valence::Many };
|
let field = Field::Node { name, ty, cardinality: Cardinality::Many };
|
||||||
acc.push(field);
|
acc.push(field);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -656,7 +646,7 @@ fn extract_enums(ast: &mut AstSrc) {
|
||||||
node.remove_field(to_remove);
|
node.remove_field(to_remove);
|
||||||
let ty = enm.name.clone();
|
let ty = enm.name.clone();
|
||||||
let name = to_lower_snake_case(&ty);
|
let name = to_lower_snake_case(&ty);
|
||||||
node.fields.push(Field::Node { name, ty, valence: Valence::Optional });
|
node.fields.push(Field::Node { name, ty, cardinality: Cardinality::Optional });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,22 +83,21 @@ StructDef =
|
||||||
)
|
)
|
||||||
|
|
||||||
RecordFieldList =
|
RecordFieldList =
|
||||||
'{' fields:RecordField* '}'
|
'{' fields:(RecordField (',' RecordField)* ','?)? '}'
|
||||||
|
|
||||||
RecordField =
|
RecordField =
|
||||||
Attr* Visibility? Name ':' ascribed_type:TypeRef
|
Attr* Visibility? Name ':' ascribed_type:TypeRef
|
||||||
|
|
||||||
TupleFieldList =
|
TupleFieldList =
|
||||||
'(' fields:TupleField* ')'
|
'(' fields:(TupleField (',' TupleField)* ','?)? ')'
|
||||||
|
|
||||||
TupleField =
|
TupleField =
|
||||||
Attr* Visibility? Name TypeRef
|
Attr* Visibility? TypeRef
|
||||||
|
|
||||||
FieldList =
|
FieldList =
|
||||||
RecordFieldList
|
RecordFieldList
|
||||||
| TupleFieldList
|
| TupleFieldList
|
||||||
|
|
||||||
|
|
||||||
UnionDef =
|
UnionDef =
|
||||||
Attr* Visibility? 'union' Name GenericParamList? WhereClause?
|
Attr* Visibility? 'union' Name GenericParamList? WhereClause?
|
||||||
RecordFieldList
|
RecordFieldList
|
||||||
|
|
Loading…
Reference in a new issue