mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
minor: Add item_enum
constructor to SyntaxFactory
I recursively added all constructors it depends on. I also changed the old `make::` constructors to support more of the grammar.
This commit is contained in:
parent
7b4b83ba91
commit
c70bf568bb
5 changed files with 242 additions and 9 deletions
|
@ -512,9 +512,11 @@ fn make_bool_enum(make_pub: bool) -> ast::Enum {
|
||||||
let enum_def = make::enum_(
|
let enum_def = make::enum_(
|
||||||
if make_pub { Some(make::visibility_pub()) } else { None },
|
if make_pub { Some(make::visibility_pub()) } else { None },
|
||||||
make::name("Bool"),
|
make::name("Bool"),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
make::variant_list(vec![
|
make::variant_list(vec![
|
||||||
make::variant(make::name("True"), None),
|
make::variant(None, make::name("True"), None, None),
|
||||||
make::variant(make::name("False"), None),
|
make::variant(None, make::name("False"), None, None),
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
.clone_for_update();
|
.clone_for_update();
|
||||||
|
|
|
@ -137,7 +137,7 @@ fn make_variant(
|
||||||
parent: PathParent,
|
parent: PathParent,
|
||||||
) -> ast::Variant {
|
) -> ast::Variant {
|
||||||
let field_list = parent.make_field_list(ctx);
|
let field_list = parent.make_field_list(ctx);
|
||||||
make::variant(make::name(&name_ref.text()), field_list)
|
make::variant(None, make::name(&name_ref.text()), field_list, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_record_field_list(
|
fn make_record_field_list(
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_variant_to_empty_enum() {
|
fn add_variant_to_empty_enum() {
|
||||||
let variant = make::variant(make::name("Bar"), None).clone_for_update();
|
let variant = make::variant(None, make::name("Bar"), None, None).clone_for_update();
|
||||||
|
|
||||||
check_add_variant(
|
check_add_variant(
|
||||||
r#"
|
r#"
|
||||||
|
@ -1190,7 +1190,7 @@ enum Foo {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_variant_to_non_empty_enum() {
|
fn add_variant_to_non_empty_enum() {
|
||||||
let variant = make::variant(make::name("Baz"), None).clone_for_update();
|
let variant = make::variant(None, make::name("Baz"), None, None).clone_for_update();
|
||||||
|
|
||||||
check_add_variant(
|
check_add_variant(
|
||||||
r#"
|
r#"
|
||||||
|
@ -1211,10 +1211,12 @@ enum Foo {
|
||||||
#[test]
|
#[test]
|
||||||
fn add_variant_with_tuple_field_list() {
|
fn add_variant_with_tuple_field_list() {
|
||||||
let variant = make::variant(
|
let variant = make::variant(
|
||||||
|
None,
|
||||||
make::name("Baz"),
|
make::name("Baz"),
|
||||||
Some(ast::FieldList::TupleFieldList(make::tuple_field_list(std::iter::once(
|
Some(ast::FieldList::TupleFieldList(make::tuple_field_list(std::iter::once(
|
||||||
make::tuple_field(None, make::ty("bool")),
|
make::tuple_field(None, make::ty("bool")),
|
||||||
)))),
|
)))),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.clone_for_update();
|
.clone_for_update();
|
||||||
|
|
||||||
|
@ -1237,10 +1239,12 @@ enum Foo {
|
||||||
#[test]
|
#[test]
|
||||||
fn add_variant_with_record_field_list() {
|
fn add_variant_with_record_field_list() {
|
||||||
let variant = make::variant(
|
let variant = make::variant(
|
||||||
|
None,
|
||||||
make::name("Baz"),
|
make::name("Baz"),
|
||||||
Some(ast::FieldList::RecordFieldList(make::record_field_list(std::iter::once(
|
Some(ast::FieldList::RecordFieldList(make::record_field_list(std::iter::once(
|
||||||
make::record_field(None, make::name("x"), make::ty("bool")),
|
make::record_field(None, make::name("x"), make::ty("bool")),
|
||||||
)))),
|
)))),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.clone_for_update();
|
.clone_for_update();
|
||||||
|
|
||||||
|
|
|
@ -1053,7 +1053,17 @@ pub fn variant_list(variants: impl IntoIterator<Item = ast::Variant>) -> ast::Va
|
||||||
ast_from_text(&format!("enum f {{ {variants} }}"))
|
ast_from_text(&format!("enum f {{ {variants} }}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Variant {
|
pub fn variant(
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
name: ast::Name,
|
||||||
|
field_list: Option<ast::FieldList>,
|
||||||
|
discriminant: Option<ast::Expr>,
|
||||||
|
) -> ast::Variant {
|
||||||
|
let visibility = match visibility {
|
||||||
|
None => String::new(),
|
||||||
|
Some(it) => format!("{it} "),
|
||||||
|
};
|
||||||
|
|
||||||
let field_list = match field_list {
|
let field_list = match field_list {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(it) => match it {
|
Some(it) => match it {
|
||||||
|
@ -1061,7 +1071,12 @@ pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Vari
|
||||||
ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
|
ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ast_from_text(&format!("enum f {{ {name}{field_list} }}"))
|
|
||||||
|
let discriminant = match discriminant {
|
||||||
|
Some(it) => format!(" = {it}"),
|
||||||
|
None => String::new(),
|
||||||
|
};
|
||||||
|
ast_from_text(&format!("enum f {{ {visibility}{name}{field_list}{discriminant} }}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_(
|
pub fn fn_(
|
||||||
|
@ -1122,6 +1137,8 @@ pub fn struct_(
|
||||||
pub fn enum_(
|
pub fn enum_(
|
||||||
visibility: Option<ast::Visibility>,
|
visibility: Option<ast::Visibility>,
|
||||||
enum_name: ast::Name,
|
enum_name: ast::Name,
|
||||||
|
generic_param_list: Option<ast::GenericParamList>,
|
||||||
|
where_clause: Option<ast::WhereClause>,
|
||||||
variant_list: ast::VariantList,
|
variant_list: ast::VariantList,
|
||||||
) -> ast::Enum {
|
) -> ast::Enum {
|
||||||
let visibility = match visibility {
|
let visibility = match visibility {
|
||||||
|
@ -1129,7 +1146,12 @@ pub fn enum_(
|
||||||
Some(it) => format!("{it} "),
|
Some(it) => format!("{it} "),
|
||||||
};
|
};
|
||||||
|
|
||||||
ast_from_text(&format!("{visibility}enum {enum_name} {variant_list}"))
|
let generic_params = generic_param_list.map(|it| it.to_string()).unwrap_or_default();
|
||||||
|
let where_clause = where_clause.map(|it| format!(" {it}")).unwrap_or_default();
|
||||||
|
|
||||||
|
ast_from_text(&format!(
|
||||||
|
"{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}"
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attr_outer(meta: ast::Meta) -> ast::Attr {
|
pub fn attr_outer(meta: ast::Meta) -> ast::Attr {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, make, HasName, HasTypeBounds},
|
ast::{self, make, HasGenericParams, HasName, HasTypeBounds, HasVisibility},
|
||||||
syntax_editor::SyntaxMappingBuilder,
|
syntax_editor::SyntaxMappingBuilder,
|
||||||
AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken,
|
AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken,
|
||||||
};
|
};
|
||||||
|
@ -169,6 +169,211 @@ impl SyntaxFactory {
|
||||||
ast
|
ast
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn record_field_list(
|
||||||
|
&self,
|
||||||
|
fields: impl IntoIterator<Item = ast::RecordField>,
|
||||||
|
) -> ast::RecordFieldList {
|
||||||
|
let fields: Vec<ast::RecordField> = fields.into_iter().collect();
|
||||||
|
let input: Vec<_> = fields.iter().map(|it| it.syntax().clone()).collect();
|
||||||
|
let ast = make::record_field_list(fields).clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
||||||
|
builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_field(
|
||||||
|
&self,
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
name: ast::Name,
|
||||||
|
ty: ast::Type,
|
||||||
|
) -> ast::RecordField {
|
||||||
|
let ast =
|
||||||
|
make::record_field(visibility.clone(), name.clone(), ty.clone()).clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
if let Some(visibility) = visibility {
|
||||||
|
builder.map_node(
|
||||||
|
visibility.syntax().clone(),
|
||||||
|
ast.visibility().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
|
||||||
|
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple_field_list(
|
||||||
|
&self,
|
||||||
|
fields: impl IntoIterator<Item = ast::TupleField>,
|
||||||
|
) -> ast::TupleFieldList {
|
||||||
|
let fields: Vec<ast::TupleField> = fields.into_iter().collect();
|
||||||
|
let input: Vec<_> = fields.iter().map(|it| it.syntax().clone()).collect();
|
||||||
|
let ast = make::tuple_field_list(fields).clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
||||||
|
builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tuple_field(
|
||||||
|
&self,
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
ty: ast::Type,
|
||||||
|
) -> ast::TupleField {
|
||||||
|
let ast = make::tuple_field(visibility.clone(), ty.clone()).clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
if let Some(visibility) = visibility {
|
||||||
|
builder.map_node(
|
||||||
|
visibility.syntax().clone(),
|
||||||
|
ast.visibility().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn item_enum(
|
||||||
|
&self,
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
name: ast::Name,
|
||||||
|
generic_param_list: Option<ast::GenericParamList>,
|
||||||
|
where_clause: Option<ast::WhereClause>,
|
||||||
|
variant_list: ast::VariantList,
|
||||||
|
) -> ast::Enum {
|
||||||
|
let ast = make::enum_(
|
||||||
|
visibility.clone(),
|
||||||
|
name.clone(),
|
||||||
|
generic_param_list.clone(),
|
||||||
|
where_clause.clone(),
|
||||||
|
variant_list.clone(),
|
||||||
|
)
|
||||||
|
.clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
if let Some(visibility) = visibility {
|
||||||
|
builder.map_node(
|
||||||
|
visibility.syntax().clone(),
|
||||||
|
ast.visibility().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
|
||||||
|
|
||||||
|
if let Some(generic_param_list) = generic_param_list {
|
||||||
|
builder.map_node(
|
||||||
|
generic_param_list.syntax().clone(),
|
||||||
|
ast.generic_param_list().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(where_clause) = where_clause {
|
||||||
|
builder.map_node(
|
||||||
|
where_clause.syntax().clone(),
|
||||||
|
ast.where_clause().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.map_node(
|
||||||
|
variant_list.syntax().clone(),
|
||||||
|
ast.variant_list().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variant_list(
|
||||||
|
&self,
|
||||||
|
variants: impl IntoIterator<Item = ast::Variant>,
|
||||||
|
) -> ast::VariantList {
|
||||||
|
let variants: Vec<ast::Variant> = variants.into_iter().collect();
|
||||||
|
let input: Vec<_> = variants.iter().map(|it| it.syntax().clone()).collect();
|
||||||
|
let ast = make::variant_list(variants).clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
|
||||||
|
builder.map_children(input.into_iter(), ast.variants().map(|it| it.syntax().clone()));
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variant(
|
||||||
|
&self,
|
||||||
|
visibility: Option<ast::Visibility>,
|
||||||
|
name: ast::Name,
|
||||||
|
field_list: Option<ast::FieldList>,
|
||||||
|
discriminant: Option<ast::Expr>,
|
||||||
|
) -> ast::Variant {
|
||||||
|
let ast = make::variant(
|
||||||
|
visibility.clone(),
|
||||||
|
name.clone(),
|
||||||
|
field_list.clone(),
|
||||||
|
discriminant.clone(),
|
||||||
|
)
|
||||||
|
.clone_for_update();
|
||||||
|
|
||||||
|
if let Some(mut mapping) = self.mappings() {
|
||||||
|
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
|
||||||
|
if let Some(visibility) = visibility {
|
||||||
|
builder.map_node(
|
||||||
|
visibility.syntax().clone(),
|
||||||
|
ast.visibility().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
|
||||||
|
|
||||||
|
if let Some(field_list) = field_list {
|
||||||
|
builder.map_node(
|
||||||
|
field_list.syntax().clone(),
|
||||||
|
ast.field_list().unwrap().syntax().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(discriminant) = discriminant {
|
||||||
|
builder
|
||||||
|
.map_node(discriminant.syntax().clone(), ast.expr().unwrap().syntax().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.finish(&mut mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast
|
||||||
|
}
|
||||||
|
|
||||||
pub fn token_tree(
|
pub fn token_tree(
|
||||||
&self,
|
&self,
|
||||||
delimiter: SyntaxKind,
|
delimiter: SyntaxKind,
|
||||||
|
|
Loading…
Reference in a new issue