Skip to content

internal: migrate extract_module to SyntaxEditor#21868

Open
itang06 wants to merge 13 commits intorust-lang:masterfrom
itang06:feature/US-18285-extract-module-syntax-editor
Open

internal: migrate extract_module to SyntaxEditor#21868
itang06 wants to merge 13 commits intorust-lang:masterfrom
itang06:feature/US-18285-extract-module-syntax-editor

Conversation

@itang06
Copy link
Copy Markdown

@itang06 itang06 commented Mar 25, 2026

Part of #18285

Migrates all ted:: calls in crates/ide-assists/src/handlers/extract_module.rs to the new SyntaxEditor/SyntaxFactory abstraction

Changes:

  • generate_module_def: replaced ted:: with SyntaxEditor/SyntaxFactory
  • expand_and_group_usages_file_wise: replaced ted::replace with SyntaxEditor
  • change_visibility: replaced ted::insert (via add_change_vis helper) with SyntaxEditor::insert_all; removes the add_change_vis function entirely

AI assistance was used for this contribution

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 25, 2026
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please migrate remaining make::* usages to SyntaxFactory APIs

continue;
}

let mut editor = SyntaxEditor::new(body_item.syntax().clone());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new SyntaxEditor instance and .finish() call on it necessary? Couldn't it be done by passing the mutable reference of existing one from the assist entrance function as a parameter of this function instead?

Copy link
Copy Markdown
Author

@itang06 itang06 Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the items here are detached clone_subtree() nodes, so the editor from the entry point can't reach them. I can use SyntaxFactory::without_mappings() locally to get rid of the .clone_for_update() calls instead, does that work?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yeah, I guess it could be still uplifted to the root SyntaxEditor but that would require more involved refactoring, so I think this is fine as is for now

})
.collect();
if !replacements.is_empty() {
let mut editor = SyntaxEditor::new(entry.syntax().clone());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, too

@@ -18,8 +18,10 @@ use syntax::{
self, HasVisibility,
edit::{AstNodeEdit, IndentLevel},
make,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kindly replace use of make with SyntaxFactory

let assoc_item_list = make::assoc_item_list(Some(assoc_items)).clone_for_update();
let impl_ = impl_.reset_indent();
ted::replace(impl_.get_or_create_assoc_item_list().syntax(), assoc_item_list.syntax());
let impl_detached = ast::Impl::cast(impl_.syntax().clone_subtree()).unwrap();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unwraps

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


let (mut replacements, record_field_parents, impls) =
get_replacements_for_visibility_change(&mut self.body_items, false);
get_replacements_for_visibility_change(&mut self.body_items, true);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Copy Markdown
Author

@itang06 itang06 Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was a workaround because of the local SyntaxEditor approach, was an incorrect change


let mut editor = SyntaxEditor::new(body_item.syntax().clone());
for target in insert_targets {
let pub_crate_vis = make::visibility_pub_crate().clone_for_update();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be removed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix, good catch

Some((
seg.syntax().parent()?,
make::path_from_text(&format!("{mod_name}::{seg}"))
.clone_for_update(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i missed that this should use SyntaxFactory, will replace it

@ChayimFriedman2
Copy link
Copy Markdown
Contributor

@itang06 What's the status of this?

@itang06
Copy link
Copy Markdown
Author

itang06 commented Apr 9, 2026

@itang06 What's the status of this?

i addressed the unwrap issue. waiting for ShoyuVanilla's response to my question about using SyntaxFactory::without_mappings() locally in the helpers instead of passing the file-level editor since they operate on detached nodes

@itang06 itang06 force-pushed the feature/US-18285-extract-module-syntax-editor branch from 11ff3da to fbf2dfa Compare April 11, 2026 08:14
@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@itang06 itang06 force-pushed the feature/US-18285-extract-module-syntax-editor branch from fbf2dfa to a9d2246 Compare April 11, 2026 08:31
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 11, 2026

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

.entry(use_.syntax().text_range().start())
.or_insert_with(|| use_.clone_subtree().clone_for_update());
for seg in use_
.or_insert_with(|| use_.clone_subtree());
Copy link
Copy Markdown
Member

@Shourya742 Shourya742 Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

remove clone_subtree

let assoc_item_list = make::assoc_item_list(Some(assoc_items)).clone_for_update();
let impl_ = impl_.reset_indent();
ted::replace(impl_.get_or_create_assoc_item_list().syntax(), assoc_item_list.syntax());
let impl_detached = ast::Impl::cast(impl_.syntax().clone_subtree()).unwrap();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

],
);
}
*body_item = ast::Item::cast(editor.finish().new_root().clone_subtree()).unwrap();
Copy link
Copy Markdown
Member

@Shourya742 Shourya742 Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

Suggested change
*body_item = ast::Item::cast(editor.finish().new_root().clone_subtree()).unwrap();
*body_item = ast::Item::cast(editor.finish().new_root()).unwrap();

Comment on lines +435 to +437
for item in &mut self.body_items {
*item = ast::Item::cast(item.reset_indent().syntax().clone_subtree()).unwrap();
}
Copy link
Copy Markdown
Member

@Shourya742 Shourya742 Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

No need to call clone_subtree here anymore. SyntaxEditor manages this internally

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried removing the clone_subtree() calls but found that 3 of the 4 calls require using the detached root returned by SyntaxEditor::new() instead of just dropping clone_subtree(). i think the 4th at line 436 has to stay because replacements is collected from body_items immediately after. is there something i'm missing or is there a different approach you had in mind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants