-
Notifications
You must be signed in to change notification settings - Fork 223
flag deprecated exports in autoimport and move to bottom
#1694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hi @DanielNoord! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at [email protected]. Thanks! |
|
For the reviewer, I also found: pyrefly/pyrefly/lib/state/lsp.rs Lines 2226 to 2230 in c0ebd8c
There is a difference between completions and code actions, I guess? I'm not quite sure what the difference between them is, but I think the code on Do we need to address this drift? And if so, how? |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the change! I like the small change with lots of tests.
Do we need to address this drift? And if so, how?
I'm not especially concerned about the drift right now. from what I see, completion autoimports use a fuzzy search and quick fixes don't. that makes sense to me: I don't want a quick fix changing the identifier - I only want it adding imports.
if I were to work on this, I'd likely change search_exports_exact's API to return some notion of deprecated as well and use that metadata to format the quick fixes with some type of warning similar to imports (along with downranking them if you want)
but then the bigger question of "how do we sort these correctly" is still unanswered.... I'll comment on the original task for that
pyrefly/lib/state/lsp.rs
Outdated
| // Ignore deprecated exports in autoimport suggestions | ||
| if export.deprecation.is_some() { | ||
| return Vec::new(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can add metadata making it clear that these are deprecated instead of ignoring these (lots of people might still want to use them).
- completion items are the most likely to be accidentally imported, but they have the tag called
deprecatedthat formats it as strikethrough. maybe the next step in improving this is deranking them with sortText? - quick fix code actions are more of an opt-in action, so I'm not too concerned about people accidentally importing deprecated functionality. it might make sense to instead format it with a strike-through or write
(deprecated)next to it. what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know if IDEs take the deprecated into consideration when sorting completions? To me it feels more of a concern of the IDE (or whatever is taking in the LSP output) than of the LSP itself. We already provide all "necessary" data for the sorting algorithm to decide (by indicating it as being deprecated).
For quick fix I think adding (deprecated) makes the most sense?
However, perhaps that should be tackled in a follow up (related to the linked issue). It seems we want more things to be taken into consideration when sorting, which might influence the type of "metadata"/context we show for the action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know if IDEs take the deprecated into consideration when sorting completions? To me it feels more of a concern of the IDE (or whatever is taking in the LSP output) than of the LSP itself. We already provide all "necessary" data for the sorting algorithm to decide (by indicating it as being deprecated).
Since we provide sortText, I doubt they'd push these results to the bottom out of sortText order. It seems like language servers should decide this.
For quick fix I think adding (deprecated) makes the most sense?
agreed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kinto0 Could you provide some pointers on the datastructure to return and where to define it?
I'm not too experienced with larger rust codebases like these. I thought of maybe combining Handle and ExportLocation in the a `struct? But perhaps that is not efficient enough.
Very open to any kind of feedback/tips :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I were you I'd scope this as follows:
- this PR: add
deprecatedwarning on autoimport - another PR: sort
deprecatedto the bottom
in order to do these, I might start by changing search_exports_exact to return a Vec<(Handle, bool (representing is_deprecated)>. then you can reuse is_deprecated upstream in sorting / text.
This is also what I struggle with. I'm scared of overscoping this PR but am not sure what you're preferred course of action is. If this already provides value in your opinion I would merge it, but can also understand if you first want to answer the bigger question :) |
I think this provides value if it adds the (deprecated) field. But I think removing quick fixes might not be what some users want. Let me look into how pyright sorts / filters these completion items.... |
751f8f2 to
d2d5ba9
Compare
| code_actions.sort_by(|(title1, _, _, _), (title2, _, _, _)| { | ||
| match (title1.contains("deprecated"), title2.contains("deprecated")) { | ||
| (true, false) => Ordering::Greater, | ||
| (false, true) => Ordering::Less, | ||
| _ => title1.cmp(title2), | ||
| } | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also feels very non-idiomatic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we sort within this function, we should rename it to local_quickfix_code_actions_sorted so callers know not to re-sort (I think most other state functions return unsorted items). keeping it in here is probably the simplest thing to do.
maybe instead of this sort, we add a sort_key to code_actions. when we notice deprecated and add it, we put a sort-key that will put it at the bottom. then in this function, we can just sort by key once at the end. this will let us add other things to sort by in the future. we don't need to return the sort_key, so we can map it out after/during sorting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did the rename!
I'm not quite sure how to implement the sort_key. I grepped the code base but could only find examples in Python code. Do you have an example of an idiomatic rust implementation of such a property/attribute/whatever?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the code_actions.sort_by call, we would do something like this:
code_actions.sort_by_key(|(_, _, _, _, sort_key)| sort_key)
// remove sort key
code_actions.map(|(a, b, c, d, _)| (a, b, c, d));
this means all the logic of sorting can be confined to when we add the code action:
if (export.deprecation.is_some()) {
let title = format!(
"Insert import: `{}`",
insert_text.trim(),
);
code_actions.push((title, module_info.dupe(), range, insert_text, ""));
} else {
let title = format!(
"Insert import: `{}` (deprecated)",
insert_text.trim(),
);
code_actions.push((title, module_info.dupe(), range, insert_text, "zzzz"));
}
(sorry this removes the other suggestion of insert import deduplication unless you can figure out a clean way to keep it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm not sure how to do this cleanly. Because you'll also still want to sort by title itself so you'd get "zzzz - {}", title as the sort_key. It also doesn't feel very extensible to other sorting considerations?
If you think it is better to use the sort_key I can change it of course, but I'd probably keep as is for now so and come up with a better datastructure for all of our sorting needs in the rest of the linked issue.
|
@kinto0 I have changed the test and code. It now shows we prefer the import from |
kinto0
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the clean code and comments! a few small suggestions but otherwise looks great
| code_actions.sort_by(|(title1, _, _, _), (title2, _, _, _)| { | ||
| match (title1.contains("deprecated"), title2.contains("deprecated")) { | ||
| (true, false) => Ordering::Greater, | ||
| (false, true) => Ordering::Less, | ||
| _ => title1.cmp(title2), | ||
| } | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we sort within this function, we should rename it to local_quickfix_code_actions_sorted so callers know not to re-sort (I think most other state functions return unsorted items). keeping it in here is probably the simplest thing to do.
maybe instead of this sort, we add a sort_key to code_actions. when we notice deprecated and add it, we put a sort-key that will put it at the bottom. then in this function, we can just sort by key once at the end. this will let us add other things to sort by in the future. we don't need to return the sort_key, so we can map it out after/during sorting.
deprecated exports in autoimportdeprecated exports in autoimport and move to bottom
|
@kinto0 Is there anything left to do here? If possible I'd like to avoid future merge conflicts 😄 |
sorry!!! not sure how I missed this. I swear I imported it when I renamed it. oh well, thanks for fixing the conflicts. |
yangdanny97
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review automatically exported from Phabricator review in Meta.
Summary
References #1685
This implements one of the improvements discussed in the issue: taking into account deprecations when checking exports for autoimport.
I have added two tests. One tests whether we suggest imports from the stdlib. It doesn't seem we test this yet and I was figuring out how the tests worked and came up with this. I can remove it, but since I wrote it I thought I might as well keep it? It also shows an improvement we should make (
typingoverast).The second test covers the change I make in the PR. It is pretty simple really.
Test Plan
See above. Added two tests.
Also tried to run the CI on my local fork in DanielNoord#1 but it seems the setup is quite different from the checks I see running on other PRs in this repository.
I did. There are quite a lot of warnings about unused lint ignores and unused exports, but my changes seem okay? Let me know if I missed anything.