Skip to content

Commit 8c522b6

Browse files
authored
Merge pull request #21832 from Shourya742/2026-03-04-add-mapping-to-constructor-method
Add mapping to syntax factory constructor methods
2 parents 0cf3e8a + f332632 commit 8c522b6

2 files changed

Lines changed: 182 additions & 24 deletions

File tree

crates/ide-assists/src/handlers/convert_bool_to_enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ fn make_bool_enum(make_pub: bool, make: &SyntaxFactory) -> ast::Enum {
533533
],
534534
),
535535
));
536-
make.enum_(
536+
make.item_enum(
537537
[derive_eq],
538538
if make_pub { Some(make.visibility_pub()) } else { None },
539539
make.name("Bool"),

crates/syntax/src/ast/syntax_factory/constructors.rs

Lines changed: 181 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,47 @@ impl SyntaxFactory {
104104
generic_param_list: Option<ast::GenericParamList>,
105105
field_list: ast::FieldList,
106106
) -> ast::Struct {
107-
make::struct_(visibility, strukt_name, generic_param_list, field_list).clone_for_update()
108-
}
107+
let ast = make::struct_(
108+
visibility.clone(),
109+
strukt_name.clone(),
110+
generic_param_list.clone(),
111+
field_list.clone(),
112+
)
113+
.clone_for_update();
109114

110-
pub fn enum_(
111-
&self,
112-
attrs: impl IntoIterator<Item = ast::Attr>,
113-
visibility: Option<ast::Visibility>,
114-
enum_name: ast::Name,
115-
generic_param_list: Option<ast::GenericParamList>,
116-
where_clause: Option<ast::WhereClause>,
117-
variant_list: ast::VariantList,
118-
) -> ast::Enum {
119-
make::enum_(attrs, visibility, enum_name, generic_param_list, where_clause, variant_list)
120-
.clone_for_update()
115+
if let Some(mut mapping) = self.mappings() {
116+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
117+
if let Some(visibility) = visibility {
118+
builder.map_node(
119+
visibility.syntax().clone(),
120+
ast.visibility().unwrap().syntax().clone(),
121+
);
122+
}
123+
builder.map_node(strukt_name.syntax().clone(), ast.name().unwrap().syntax().clone());
124+
if let Some(generic_param_list) = generic_param_list {
125+
builder.map_node(
126+
generic_param_list.syntax().clone(),
127+
ast.generic_param_list().unwrap().syntax().clone(),
128+
);
129+
}
130+
builder
131+
.map_node(field_list.syntax().clone(), ast.field_list().unwrap().syntax().clone());
132+
builder.finish(&mut mapping);
133+
}
134+
135+
ast
121136
}
122137

123138
pub fn unnamed_param(&self, ty: ast::Type) -> ast::Param {
124-
make::unnamed_param(ty).clone_for_update()
139+
let ast = make::unnamed_param(ty.clone()).clone_for_update();
140+
141+
if let Some(mut mapping) = self.mappings() {
142+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
143+
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
144+
builder.finish(&mut mapping);
145+
}
146+
147+
ast
125148
}
126149

127150
pub fn ty_fn_ptr<I: Iterator<Item = Param>>(
@@ -131,26 +154,89 @@ impl SyntaxFactory {
131154
params: I,
132155
ret_type: Option<ast::RetType>,
133156
) -> ast::FnPtrType {
134-
make::ty_fn_ptr(is_unsafe, abi, params, ret_type).clone_for_update()
157+
let (params, params_input) = iterator_input(params);
158+
let ast = make::ty_fn_ptr(is_unsafe, abi.clone(), params.into_iter(), ret_type.clone())
159+
.clone_for_update();
160+
161+
if let Some(mut mapping) = self.mappings() {
162+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
163+
if let Some(abi) = abi {
164+
builder.map_node(abi.syntax().clone(), ast.abi().unwrap().syntax().clone());
165+
}
166+
builder.map_children(
167+
params_input,
168+
ast.param_list().unwrap().params().map(|p| p.syntax().clone()),
169+
);
170+
if let Some(ret_type) = ret_type {
171+
builder
172+
.map_node(ret_type.syntax().clone(), ast.ret_type().unwrap().syntax().clone());
173+
}
174+
builder.finish(&mut mapping);
175+
}
176+
177+
ast
135178
}
136179

137180
pub fn where_pred(
138181
&self,
139182
path: Either<ast::Lifetime, ast::Type>,
140183
bounds: impl IntoIterator<Item = ast::TypeBound>,
141184
) -> ast::WherePred {
142-
make::where_pred(path, bounds).clone_for_update()
185+
let (bounds, bounds_input) = iterator_input(bounds);
186+
let ast = make::where_pred(path.clone(), bounds).clone_for_update();
187+
188+
if let Some(mut mapping) = self.mappings() {
189+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
190+
match &path {
191+
Either::Left(lifetime) => {
192+
builder.map_node(
193+
lifetime.syntax().clone(),
194+
ast.lifetime().unwrap().syntax().clone(),
195+
);
196+
}
197+
Either::Right(ty) => {
198+
builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
199+
}
200+
}
201+
if let Some(type_bound_list) = ast.type_bound_list() {
202+
builder.map_children(
203+
bounds_input,
204+
type_bound_list.bounds().map(|b| b.syntax().clone()),
205+
);
206+
}
207+
builder.finish(&mut mapping);
208+
}
209+
210+
ast
143211
}
144212

145213
pub fn where_clause(
146214
&self,
147215
predicates: impl IntoIterator<Item = ast::WherePred>,
148216
) -> ast::WhereClause {
149-
make::where_clause(predicates).clone_for_update()
217+
let (predicates, input) = iterator_input(predicates);
218+
let ast = make::where_clause(predicates).clone_for_update();
219+
220+
if let Some(mut mapping) = self.mappings() {
221+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
222+
builder.map_children(input, ast.predicates().map(|p| p.syntax().clone()));
223+
builder.finish(&mut mapping);
224+
}
225+
226+
ast
150227
}
151228

152229
pub fn impl_trait_type(&self, bounds: ast::TypeBoundList) -> ast::ImplTraitType {
153-
make::impl_trait_type(bounds).clone_for_update()
230+
let ast = make::impl_trait_type(bounds.clone()).clone_for_update();
231+
232+
if let Some(mut mapping) = self.mappings() {
233+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
234+
builder
235+
.map_node(bounds.syntax().clone(), ast.type_bound_list().unwrap().syntax().clone());
236+
builder.finish(&mut mapping);
237+
}
238+
239+
ast
154240
}
155241

156242
pub fn expr_field(&self, receiver: ast::Expr, field: &str) -> ast::FieldExpr {
@@ -348,15 +434,53 @@ impl SyntaxFactory {
348434
name_ref: ast::NameRef,
349435
generic_args: impl IntoIterator<Item = ast::GenericArg>,
350436
) -> ast::PathSegment {
351-
make::generic_ty_path_segment(name_ref, generic_args).clone_for_update()
437+
let (generic_args, input) = iterator_input(generic_args);
438+
let ast = make::generic_ty_path_segment(name_ref.clone(), generic_args).clone_for_update();
439+
440+
if let Some(mut mapping) = self.mappings() {
441+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
442+
builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone());
443+
builder.map_children(
444+
input,
445+
ast.generic_arg_list().unwrap().generic_args().map(|a| a.syntax().clone()),
446+
);
447+
builder.finish(&mut mapping);
448+
}
449+
450+
ast
352451
}
353452

354453
pub fn tail_only_block_expr(&self, tail_expr: ast::Expr) -> ast::BlockExpr {
355-
make::tail_only_block_expr(tail_expr)
454+
let ast = make::tail_only_block_expr(tail_expr.clone()).clone_for_update();
455+
456+
if let Some(mut mapping) = self.mappings() {
457+
let stmt_list = ast.stmt_list().unwrap();
458+
let mut builder = SyntaxMappingBuilder::new(stmt_list.syntax().clone());
459+
builder.map_node(
460+
tail_expr.syntax().clone(),
461+
stmt_list.tail_expr().unwrap().syntax().clone(),
462+
);
463+
builder.finish(&mut mapping);
464+
}
465+
466+
ast
356467
}
357468

358469
pub fn expr_bin_op(&self, lhs: ast::Expr, op: ast::BinaryOp, rhs: ast::Expr) -> ast::Expr {
359-
make::expr_bin_op(lhs, op, rhs)
470+
let ast::Expr::BinExpr(ast) =
471+
make::expr_bin_op(lhs.clone(), op, rhs.clone()).clone_for_update()
472+
else {
473+
unreachable!()
474+
};
475+
476+
if let Some(mut mapping) = self.mappings() {
477+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
478+
builder.map_node(lhs.syntax().clone(), ast.lhs().unwrap().syntax().clone());
479+
builder.map_node(rhs.syntax().clone(), ast.rhs().unwrap().syntax().clone());
480+
builder.finish(&mut mapping);
481+
}
482+
483+
ast.into()
360484
}
361485

362486
pub fn ty_placeholder(&self) -> ast::Type {
@@ -393,7 +517,23 @@ impl SyntaxFactory {
393517
visibility: Option<ast::Visibility>,
394518
use_tree: ast::UseTree,
395519
) -> ast::Use {
396-
make::use_(attrs, visibility, use_tree).clone_for_update()
520+
let (attrs, attrs_input) = iterator_input(attrs);
521+
let ast = make::use_(attrs, visibility.clone(), use_tree.clone()).clone_for_update();
522+
523+
if let Some(mut mapping) = self.mappings() {
524+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
525+
builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone()));
526+
if let Some(visibility) = visibility {
527+
builder.map_node(
528+
visibility.syntax().clone(),
529+
ast.visibility().unwrap().syntax().clone(),
530+
);
531+
}
532+
builder.map_node(use_tree.syntax().clone(), ast.use_tree().unwrap().syntax().clone());
533+
builder.finish(&mut mapping);
534+
}
535+
536+
ast
397537
}
398538

399539
pub fn use_tree(
@@ -403,7 +543,25 @@ impl SyntaxFactory {
403543
alias: Option<ast::Rename>,
404544
add_star: bool,
405545
) -> ast::UseTree {
406-
make::use_tree(path, use_tree_list, alias, add_star).clone_for_update()
546+
let ast = make::use_tree(path.clone(), use_tree_list.clone(), alias.clone(), add_star)
547+
.clone_for_update();
548+
549+
if let Some(mut mapping) = self.mappings() {
550+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
551+
builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
552+
if let Some(use_tree_list) = use_tree_list {
553+
builder.map_node(
554+
use_tree_list.syntax().clone(),
555+
ast.use_tree_list().unwrap().syntax().clone(),
556+
);
557+
}
558+
if let Some(alias) = alias {
559+
builder.map_node(alias.syntax().clone(), ast.rename().unwrap().syntax().clone());
560+
}
561+
builder.finish(&mut mapping);
562+
}
563+
564+
ast
407565
}
408566

409567
pub fn path_unqualified(&self, segment: ast::PathSegment) -> ast::Path {

0 commit comments

Comments
 (0)