Skip to content

Conversation

@AtharvGhumtane
Copy link

@AtharvGhumtane AtharvGhumtane commented Jan 20, 2026

Summary

This PR addresses the root cause of Java refactoring edits being lost during file rename/move operations in Theia.
Specifically, it ensures that workspace/willRenameFiles edits produced by language servers are properly propagated through the plugin-ext pipeline instead of being discarded.

Note: This PR does not fully fix #16748. It provides the missing infrastructure needed for a complete solution, but does not yet apply the returned edits to the workspace.


Problem

When renaming or moving Java files in Theia:

  • The willRenameFiles event is correctly triggered
  • The Java language server generates refactoring edits
  • The edits are discarded before reaching the file system participant
  • No refactoring is applied (class names, packages, imports remain unchanged)

Evidence from logs:

[LanguagesMain] File rename detected!
[LanguagesExt] willRenameFiles called: { files: [...] }
[LanguagesExt] Workspace edits returned (array): []


Root Cause

The plugin-ext file operation handler collected workspace edits from _fireWillEvent(...) but did not return them back to the main thread. As a result, the propagated result was always an empty array.


What this PR changes

  • Returns the collected workspace edits from $onWillRunFileOperation
  • Ensures edits from willRenameFiles handlers are propagated correctly
  • Removes unused yarn.lock
  • Reduces duplicate workspace edit merging logic
  • Improves typing of the return value

Testing

Manual testing performed:

  • Renamed Java class files → edits are now returned
  • Moved Java files across packages → edits are now returned
  • Verified non-empty workspace edit arrays in logs

Limitations / Follow-ups

This PR does not yet:

  • Apply the returned workspace edits
  • Handle multi-file text edit application
  • Show user confirmation dialogs

These are required to fully resolve #16748 and will be addressed in follow-up work.


Related

Progress toward: #16748

@github-project-automation github-project-automation bot moved this to Waiting on reviewers in PR Backlog Jan 20, 2026
Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

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

Hey @AtharvGhumtane, thanks for the contribution.

As far as I can tell from the description, this does not actually fix #16748, right? Please update the description to no longer read "Fixes", because that would close the issue as soon as this PR is merged.

Aside from that, I'm a bit hesitant to review this PR since it's not clear whether this is the correct way forward. It makes sense to update the $onWillRunFileOperation to collect the edits, but the other changes - especially to the LanguagesExt - seem rather experimental. Looking at VSCode's interface, it also doesn't seem like they handle this feature through the Languages proxy.

If possible, I would kindly request from you to finish the feature implementation to verify that this is actually going to help fix the issue.

Also, please sign the Eclipse Contributor Agreement (ECA) with the same email that was used to create the commit. Otherwise, we won't be able to accept your changes. Thank you!

Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: We don't use yarn anymore in this project. Please remove this.

Comment on lines +226 to +230
if (renameEdits && renameEdits.length > 0) {
const mergedEdit = this.mergeWorkspaceEdits(renameEdits);
console.log('[LanguagesExt] Merged workspace edit:', mergedEdit);
return typeConverter.fromWorkspaceEdit(mergedEdit);
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: This merging is happening in all branches, can we remove the redundancy?

};
}

async $onWillRunFileOperation(operation: FileOperation, target: UriComponents, source: UriComponents | undefined, timeout: number, token: CancellationToken): Promise<any> {
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: Can we improve the typing of the return promise? Now that we return actual values here, using any is quite unsafe.

@AtharvGhumtane
Copy link
Author

Thanks for the detailed review and for pointing this out.

You’re right — this PR does not fully fix #16748. It only addresses the root cause by ensuring willRenameFiles workspace edits are propagated correctly through the plugin-ext pipeline.

I will update the description to remove “Fixes #16748” and clarify that this is a foundational step toward a full solution.

I’ll also:

  • remove yarn.lock
  • refactor the duplicate merge logic
  • improve the return type of $onWillRunFileOperation

And I’ll continue working on applying the returned edits so the refactoring actually takes effect end-to-end.

Additionally, I’d really appreciate some guidance on the intended architecture for this feature:

  1. Should workspace edits be converted and applied in plugin-ext, or on the main thread side?
  2. Is there a specific component in Theia that should own the application of willRenameFiles edits (similar to VS Code’s design)?
  3. What would be the preferred return type for $onWillRunFileOperation?

I’d like to align the next steps with Theia’s intended design rather than guessing.

Thanks again for the guidance.

@msujew
Copy link
Member

msujew commented Jan 21, 2026

Should workspace edits be converted and applied in plugin-ext, or on the main thread side?

Whereever it makes sense - when possible it's best to keep them local to the plugin process, but that's not always possible. I would recommend to take a look at how VS Code is solving this issue.

Is there a specific component in Theia that should own the application of willRenameFiles edits (similar to VS Code’s design)?

It would be best to keep things similar to VS Code's design, as it makes future work easier.

What would be the preferred return type for $onWillRunFileOperation?

Whatever it actually returns. Before your changes, it always returned undefined, so it didn't matter. Now, it actually returns something - which should indicate what its return type is.

@AtharvGhumtane AtharvGhumtane changed the title LSP: propagate willRenameFiles workspace edits during file rename (fixes Java refactoring) LSP: propagate willRenameFiles workspace edits during file rename (Java refactoring groundwork) Jan 21, 2026
@AtharvGhumtane
Copy link
Author

Thanks a lot for the guidance, this is very helpful.

I’ll take a closer look at how VS Code handles willRenameFiles end-to-end and try to align Theia’s design accordingly, especially regarding where workspace edits are converted and applied.

From an initial look, it seems VS Code keeps most of the edit handling within the extension host / workspace edit infrastructure rather than routing it through the Languages proxy, so I’ll re-evaluate my current approach in that direction.

Regarding ownership: I’ll investigate whether the edit application should live in the plugin-ext filesystem event service, the languages main thread side, or a dedicated workspace edit application component similar to VS Code’s implementation.

For the return type of $onWillRunFileOperation, agreed — now that it returns actual data, I’ll replace Promise<any> with the concrete type that is propagated (likely the workspace edit DTO or an optional variant).

I’ll push an update once I’ve aligned the implementation with VS Code’s model.

Thanks again for the review and direction.

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

Labels

None yet

Projects

Status: Waiting on reviewers

Development

Successfully merging this pull request may close these issues.

Refactoring (moving/renaming) class files in Java does not adapt file contents

2 participants