Skip to content

Commit 3bc26ba

Browse files
committed
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.
1 parent 95670ac commit 3bc26ba

File tree

5 files changed

+242
-9
lines changed

5 files changed

+242
-9
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/bool_to_enum.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,11 @@ fn make_bool_enum(make_pub: bool) -> ast::Enum {
512512
let enum_def = make::enum_(
513513
if make_pub { Some(make::visibility_pub()) } else { None },
514514
make::name("Bool"),
515+
None,
516+
None,
515517
make::variant_list(vec![
516-
make::variant(make::name("True"), None),
517-
make::variant(make::name("False"), None),
518+
make::variant(None, make::name("True"), None, None),
519+
make::variant(None, make::name("False"), None, None),
518520
]),
519521
)
520522
.clone_for_update();

src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_enum_variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn make_variant(
137137
parent: PathParent,
138138
) -> ast::Variant {
139139
let field_list = parent.make_field_list(ctx);
140-
make::variant(make::name(&name_ref.text()), field_list)
140+
make::variant(None, make::name(&name_ref.text()), field_list, None)
141141
}
142142

143143
fn make_record_field_list(

src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ mod tests {
11731173

11741174
#[test]
11751175
fn add_variant_to_empty_enum() {
1176-
let variant = make::variant(make::name("Bar"), None).clone_for_update();
1176+
let variant = make::variant(None, make::name("Bar"), None, None).clone_for_update();
11771177

11781178
check_add_variant(
11791179
r#"
@@ -1190,7 +1190,7 @@ enum Foo {
11901190

11911191
#[test]
11921192
fn add_variant_to_non_empty_enum() {
1193-
let variant = make::variant(make::name("Baz"), None).clone_for_update();
1193+
let variant = make::variant(None, make::name("Baz"), None, None).clone_for_update();
11941194

11951195
check_add_variant(
11961196
r#"
@@ -1211,10 +1211,12 @@ enum Foo {
12111211
#[test]
12121212
fn add_variant_with_tuple_field_list() {
12131213
let variant = make::variant(
1214+
None,
12141215
make::name("Baz"),
12151216
Some(ast::FieldList::TupleFieldList(make::tuple_field_list(std::iter::once(
12161217
make::tuple_field(None, make::ty("bool")),
12171218
)))),
1219+
None,
12181220
)
12191221
.clone_for_update();
12201222

@@ -1237,10 +1239,12 @@ enum Foo {
12371239
#[test]
12381240
fn add_variant_with_record_field_list() {
12391241
let variant = make::variant(
1242+
None,
12401243
make::name("Baz"),
12411244
Some(ast::FieldList::RecordFieldList(make::record_field_list(std::iter::once(
12421245
make::record_field(None, make::name("x"), make::ty("bool")),
12431246
)))),
1247+
None,
12441248
)
12451249
.clone_for_update();
12461250

src/tools/rust-analyzer/crates/syntax/src/ast/make.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,15 +1053,30 @@ pub fn variant_list(variants: impl IntoIterator<Item = ast::Variant>) -> ast::Va
10531053
ast_from_text(&format!("enum f {{ {variants} }}"))
10541054
}
10551055

1056-
pub fn variant(name: ast::Name, field_list: Option<ast::FieldList>) -> ast::Variant {
1056+
pub fn variant(
1057+
visibility: Option<ast::Visibility>,
1058+
name: ast::Name,
1059+
field_list: Option<ast::FieldList>,
1060+
discriminant: Option<ast::Expr>,
1061+
) -> ast::Variant {
1062+
let visibility = match visibility {
1063+
None => String::new(),
1064+
Some(it) => format!("{it} "),
1065+
};
1066+
10571067
let field_list = match field_list {
10581068
None => String::new(),
10591069
Some(it) => match it {
10601070
ast::FieldList::RecordFieldList(record) => format!(" {record}"),
10611071
ast::FieldList::TupleFieldList(tuple) => format!("{tuple}"),
10621072
},
10631073
};
1064-
ast_from_text(&format!("enum f {{ {name}{field_list} }}"))
1074+
1075+
let discriminant = match discriminant {
1076+
Some(it) => format!(" = {it}"),
1077+
None => String::new(),
1078+
};
1079+
ast_from_text(&format!("enum f {{ {visibility}{name}{field_list}{discriminant} }}"))
10651080
}
10661081

10671082
pub fn fn_(
@@ -1122,14 +1137,21 @@ pub fn struct_(
11221137
pub fn enum_(
11231138
visibility: Option<ast::Visibility>,
11241139
enum_name: ast::Name,
1140+
generic_param_list: Option<ast::GenericParamList>,
1141+
where_clause: Option<ast::WhereClause>,
11251142
variant_list: ast::VariantList,
11261143
) -> ast::Enum {
11271144
let visibility = match visibility {
11281145
None => String::new(),
11291146
Some(it) => format!("{it} "),
11301147
};
11311148

1132-
ast_from_text(&format!("{visibility}enum {enum_name} {variant_list}"))
1149+
let generic_params = generic_param_list.map(|it| it.to_string()).unwrap_or_default();
1150+
let where_clause = where_clause.map(|it| format!(" {it}")).unwrap_or_default();
1151+
1152+
ast_from_text(&format!(
1153+
"{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}"
1154+
))
11331155
}
11341156

11351157
pub fn attr_outer(meta: ast::Meta) -> ast::Attr {

src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use itertools::Itertools;
33

44
use crate::{
5-
ast::{self, make, HasName, HasTypeBounds},
5+
ast::{self, make, HasGenericParams, HasName, HasTypeBounds, HasVisibility},
66
syntax_editor::SyntaxMappingBuilder,
77
AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken,
88
};
@@ -169,6 +169,211 @@ impl SyntaxFactory {
169169
ast
170170
}
171171

172+
pub fn record_field_list(
173+
&self,
174+
fields: impl IntoIterator<Item = ast::RecordField>,
175+
) -> ast::RecordFieldList {
176+
let fields: Vec<ast::RecordField> = fields.into_iter().collect();
177+
let input: Vec<_> = fields.iter().map(|it| it.syntax().clone()).collect();
178+
let ast = make::record_field_list(fields).clone_for_update();
179+
180+
if let Some(mut mapping) = self.mappings() {
181+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
182+
183+
builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
184+
185+
builder.finish(&mut mapping);
186+
}
187+
188+
ast
189+
}
190+
191+
pub fn record_field(
192+
&self,
193+
visibility: Option<ast::Visibility>,
194+
name: ast::Name,
195+
ty: ast::Type,
196+
) -> ast::RecordField {
197+
let ast =
198+
make::record_field(visibility.clone(), name.clone(), ty.clone()).clone_for_update();
199+
200+
if let Some(mut mapping) = self.mappings() {
201+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
202+
if let Some(visibility) = visibility {
203+
builder.map_node(
204+
visibility.syntax().clone(),
205+
ast.visibility().unwrap().syntax().clone(),
206+
);
207+
}
208+
209+
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
210+
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
211+
212+
builder.finish(&mut mapping);
213+
}
214+
215+
ast
216+
}
217+
218+
pub fn tuple_field_list(
219+
&self,
220+
fields: impl IntoIterator<Item = ast::TupleField>,
221+
) -> ast::TupleFieldList {
222+
let fields: Vec<ast::TupleField> = fields.into_iter().collect();
223+
let input: Vec<_> = fields.iter().map(|it| it.syntax().clone()).collect();
224+
let ast = make::tuple_field_list(fields).clone_for_update();
225+
226+
if let Some(mut mapping) = self.mappings() {
227+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
228+
229+
builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
230+
231+
builder.finish(&mut mapping);
232+
}
233+
234+
ast
235+
}
236+
237+
pub fn tuple_field(
238+
&self,
239+
visibility: Option<ast::Visibility>,
240+
ty: ast::Type,
241+
) -> ast::TupleField {
242+
let ast = make::tuple_field(visibility.clone(), ty.clone()).clone_for_update();
243+
244+
if let Some(mut mapping) = self.mappings() {
245+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
246+
if let Some(visibility) = visibility {
247+
builder.map_node(
248+
visibility.syntax().clone(),
249+
ast.visibility().unwrap().syntax().clone(),
250+
);
251+
}
252+
253+
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
254+
255+
builder.finish(&mut mapping);
256+
}
257+
258+
ast
259+
}
260+
261+
pub fn item_enum(
262+
&self,
263+
visibility: Option<ast::Visibility>,
264+
name: ast::Name,
265+
generic_param_list: Option<ast::GenericParamList>,
266+
where_clause: Option<ast::WhereClause>,
267+
variant_list: ast::VariantList,
268+
) -> ast::Enum {
269+
let ast = make::enum_(
270+
visibility.clone(),
271+
name.clone(),
272+
generic_param_list.clone(),
273+
where_clause.clone(),
274+
variant_list.clone(),
275+
)
276+
.clone_for_update();
277+
278+
if let Some(mut mapping) = self.mappings() {
279+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
280+
if let Some(visibility) = visibility {
281+
builder.map_node(
282+
visibility.syntax().clone(),
283+
ast.visibility().unwrap().syntax().clone(),
284+
);
285+
}
286+
287+
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
288+
289+
if let Some(generic_param_list) = generic_param_list {
290+
builder.map_node(
291+
generic_param_list.syntax().clone(),
292+
ast.generic_param_list().unwrap().syntax().clone(),
293+
);
294+
}
295+
296+
if let Some(where_clause) = where_clause {
297+
builder.map_node(
298+
where_clause.syntax().clone(),
299+
ast.where_clause().unwrap().syntax().clone(),
300+
);
301+
}
302+
303+
builder.map_node(
304+
variant_list.syntax().clone(),
305+
ast.variant_list().unwrap().syntax().clone(),
306+
);
307+
308+
builder.finish(&mut mapping);
309+
}
310+
311+
ast
312+
}
313+
314+
pub fn variant_list(
315+
&self,
316+
variants: impl IntoIterator<Item = ast::Variant>,
317+
) -> ast::VariantList {
318+
let variants: Vec<ast::Variant> = variants.into_iter().collect();
319+
let input: Vec<_> = variants.iter().map(|it| it.syntax().clone()).collect();
320+
let ast = make::variant_list(variants).clone_for_update();
321+
322+
if let Some(mut mapping) = self.mappings() {
323+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
324+
325+
builder.map_children(input.into_iter(), ast.variants().map(|it| it.syntax().clone()));
326+
327+
builder.finish(&mut mapping);
328+
}
329+
330+
ast
331+
}
332+
333+
pub fn variant(
334+
&self,
335+
visibility: Option<ast::Visibility>,
336+
name: ast::Name,
337+
field_list: Option<ast::FieldList>,
338+
discriminant: Option<ast::Expr>,
339+
) -> ast::Variant {
340+
let ast = make::variant(
341+
visibility.clone(),
342+
name.clone(),
343+
field_list.clone(),
344+
discriminant.clone(),
345+
)
346+
.clone_for_update();
347+
348+
if let Some(mut mapping) = self.mappings() {
349+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
350+
if let Some(visibility) = visibility {
351+
builder.map_node(
352+
visibility.syntax().clone(),
353+
ast.visibility().unwrap().syntax().clone(),
354+
);
355+
}
356+
357+
builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
358+
359+
if let Some(field_list) = field_list {
360+
builder.map_node(
361+
field_list.syntax().clone(),
362+
ast.field_list().unwrap().syntax().clone(),
363+
);
364+
}
365+
366+
if let Some(discriminant) = discriminant {
367+
builder
368+
.map_node(discriminant.syntax().clone(), ast.expr().unwrap().syntax().clone());
369+
}
370+
371+
builder.finish(&mut mapping);
372+
}
373+
374+
ast
375+
}
376+
172377
pub fn token_tree(
173378
&self,
174379
delimiter: SyntaxKind,

0 commit comments

Comments
 (0)