Repository navigation
impl show file ref in safe delete #2415 - #2663
asukaminato0721 wants to merge 6 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the safe-delete file feature (from #2415) by adding two new code actions when a file has import usages: "Find usages of file ..." (which opens a reference list via a client command) and "Delete file ... anyway" (which performs the delete regardless of usages). It also includes the corresponding VS Code extension handler for the pyrefly.findFileUsages command and updates tests.
Changes:
- Refactored
safe_delete_file_code_actionintosafe_delete_file_code_actionsto return multiple actions, adding "Find usages" and "Delete anyway" options when imports are found - Implemented
collect_import_usage_locationsto gather exact reference locations (file URI + range) instead of just detecting presence of usages - Added VS Code extension command handler (
pyrefly.findFileUsages) to display references usingeditor.action.showReferences
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pyrefly/lib/lsp/non_wasm/safe_delete_file.rs | Refactored to return multiple code actions and collect usage locations with ranges |
| pyrefly/lib/lsp/non_wasm/server.rs | Updated import and call site for renamed function returning Vec |
| pyrefly/lib/test/lsp/lsp_interaction/safe_delete_file.rs | Updated tests to verify new "Find usages" and "Delete anyway" actions |
| lsp/src/extension.ts | Added pyrefly.findFileUsages command handler to show references |
| lsp/package.json | Registered pyrefly.findFileUsages command in extension manifest |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| CodeActionOrCommand::CodeAction(CodeAction { | ||
| title: title.clone(), | ||
| command: Some(Command { | ||
| title, | ||
| command: "pyrefly.findFileUsages".to_owned(), | ||
| arguments: Some(vec![json!({ | ||
| "uri": uri, | ||
| "locations": locations, | ||
| })]), | ||
| }), | ||
| ..Default::default() | ||
| }) |
There was a problem hiding this comment.
The find_usages_code_action is missing a kind field (defaults to None). Every other code action in this codebase sets a kind (e.g., refactor.delete, refactor.move, quickfix, source.fixAll). While kind is optional per the LSP spec, some clients use CodeActionContext.only to filter actions by kind. Actions without a kind may be unexpectedly hidden or shown depending on the client's filtering logic. Consider setting a kind here, such as CodeActionKind::new("refactor.delete") to be consistent with the sibling "delete anyway" action, or another appropriate kind.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
1eac488 to
40a285b
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
stroxler
left a comment
There was a problem hiding this comment.
I think there are issues here where the feature can misbehave:
- Incomplete references: indexed-but-closed importers have no retained AST, so they’re skipped. I reproduced this: 0 locations instead of 1. Path deduplication can also discard an open importer’s usable in-memory AST.
- Client integration: the server offers a VS Code-only command without negotiating support, and its missing
kindhides “Find usages” from VS Code’s Refactor menu. - Incorrect locations: notebook references bypass cell-URI mapping; attribute imports can also be mistaken for submodule usages.
One suggestion from an AI reviewer: make discovery on-demand, prefer current in-memory contents, and route locations through the server’s existing conversion helpers. The dependency graph still prevents these omissions from producing a false "Safe delete" action.
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
stroxler
left a comment
There was a problem hiding this comment.
Thanks! This is looking better.
Unfortunately it's a big PR, so the first round didn't find all concerns. I think there are still some things worth addressing based on another round of AI review:
-
Package re-exports can hide both new actions.
Withpkg/__init__.pycontainingfrom . import target, requesting actions onpkg/target.pyreturns neither “Find usages” nor “Delete anyway.” The [export matching]() treatspyrefly/pyrefly/lib/lsp/non_wasm/safe_delete_file.rs
Lines 250 to 269 in a2b90b0
OtherModule(pkg, …)as the final destination, missing the actual submodule. This is a regression from the previous revision. Follow the solver’s self-import/submodule semantics rather than comparing only the first export edge. -
Removing an import in an unsaved buffer still reports its old disk location.
I indexedconsumer.pycontainingimport target, opened it, then sentdidChangereplacing its contents withanswer = 123. “Find usages” still returned the old import at line 0. The [memory-first sorting]() cannot help when the current memory handle no longer depends on the target and therefore isn’t inpyrefly/pyrefly/lib/lsp/non_wasm/safe_delete_file.rs
Lines 170 to 189 in a2b90b0
rdeps. Consult current open-buffer contents independently of whether that handle remains a dependent. -
Unsupported clients still reparse every importer.
[Collection precedes the capability check](). With 50 importers of roughly 4,000 lines each, warm requests took about 34 ms even withpyrefly/pyrefly/lib/lsp/non_wasm/safe_delete_file.rs
Lines 98 to 115 in a2b90b0
findFileUsages: false, versus 0.16 ms for an unused file. Prefer on-demand location collection; at minimum, short-circuit unsupported clients and reuse retained ASTs.
The closed-file, capability/kind, and notebook-mapping fixes otherwise look good. The open-buffer test uses IndexingMode::None, so it misses the indexed disk/buffer collision above.
Summary
Fixes #2415
Added two unsafe-delete actions for files: Find usages of file ...(opens a reference list via a client command) and Delete file
...anyway.Implemented import-usage collection to provide exact reference locations for the new command.
Updated the VS Code extension to handle pyrefly.findFileUsages and show the references list.
Test Plan
Adjusted LSP interaction tests to expect the new actions.