Skip to content
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

Added skipDestructiveCodeActions argument to organize imports server command #43184

Conversation

JoshuaKGoldberg
Copy link
Contributor

Fixes #43051

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Mar 10, 2021
@JoshuaKGoldberg JoshuaKGoldberg marked this pull request as ready for review March 10, 2021 20:02
@DanielRosenwasser
Copy link
Member

I think this is probably okay, but part of me feels like there's a difference between a user-specified import cleanup and one that was triggered incidentally by organize-imports-on-save.

@JoshuaKGoldberg
Copy link
Contributor Author

Err, does such a preference exist in the services API? I don't see anything in src/compiler/types.ts but could add it that consideration if available.

@andrewbranch
Copy link
Member

The combination of codefixes on save and save on blur is so horrifying to me; to pick up on Daniel’s point, I think it merits a broader discussion about what kinds of actions should be allowed through that sequence. My feeling is we should never run anything that deletes code without an explicit user action, and blurring your editor tab doesn’t count as an explicit user action.

@jessetrinity
Copy link
Contributor

Doesn't "do X on save" require that the use take explicit action in the first place (add the configuration to vscode settings.json)?

@andrewbranch
Copy link
Member

Yeah, but I’m talking about direct synchronous action. I’m not saying “this is dangerous so it needs to be opt-in”; I’m saying “we should not have a feature that deletes code when users aren’t looking, no matter how badly they think they want it.”

@andrewbranch
Copy link
Member

And to clarify, I’m not talking about codefixes-on-save alone. That’s ok because the direct causal action is Ctrl+S. If it messes up, you’re actively observing the mistake and you can undo it. The problem is save-on-blur triggering codefixes-on-save. Because in that case, the you’re explicitly moving your attention away from the place where we’re performing the edits. Anything done via that chain reaction needs to be totally non-destructive (e.g., formatting).

@jessetrinity
Copy link
Contributor

jessetrinity commented Apr 5, 2021

Thanks for the clarification. Does this make sense as a user preference, something like "remove unused imports when organizing imports" (only for the explicitly requested case)?

@jessetrinity
Copy link
Contributor

@JoshuaKGoldberg we discussed this a bit with VSCode and we think it makes sense to add a user preference to control if code is deleted on save.

I propose allowDestructiveCodeActions?: boolean. Default would be true to keep the current behavior. 'false' would short circuit in the same way as your syntax fix. VSCode could decide whether to pass true or false based on how the code action is triggered.

The syntax error would then be checked after this option.

@JoshuaKGoldberg
Copy link
Contributor Author

Super. Is that something I'd be well positioned to fix? I'm wary of taking on big projects that are still in early stages cross-team as an external contributor, but if you have a solid vision I could contribute to that'd make me very happy.

@jessetrinity
Copy link
Contributor

jessetrinity commented Apr 7, 2021

The work on our (TypeScript) side should be pretty simple. You would just need to add the option to the existing UserPreferences in src\compiler\types.ts and src\server\protocol.ts. organizeImports already takes a UserPreferences argument, so you would just need to then check the new option in the code removal logic. I think you would also need to change the fourslash method to test the new behavior.

You don't necessarily need to make changes on the vscode side to get this change in but you're welcome to try. If you're not comfortable doing that we can just let them know about the new option. I'm not familiar enough with the vscode side logic to give you pointers anyway 😅.

@andrewbranch
Copy link
Member

Note that UserPreferences are changed in a separate Configure request, so I’m not sure that (by itself) actually plays well with the idea of letting VS Code change it on the fly depending on how a command is triggered. We might need to add it as an argument to other commands.

@jessetrinity
Copy link
Contributor

Oh right. So for this particular issue, OrganizeImportsRequestArgs.

@JoshuaKGoldberg
Copy link
Contributor Author

Thanks! 3a61904 adds the option here. I've dabbled in VS Code before; it'd be fun to try to add it there too. 😄

@JoshuaKGoldberg JoshuaKGoldberg changed the title Stopped removing unused imports in files with syntactic errors Added allowDestructiveCodeActions argument to organize imports server command Apr 13, 2021
@JoshuaKGoldberg JoshuaKGoldberg force-pushed the organize-imports-skip-syntax-errors branch from 7fd22f8 to 1637e1a Compare April 13, 2021 02:06
@JoshuaKGoldberg
Copy link
Contributor Author

Btw, I realized that 3a61904 (which added the allowDestructiveCodeActions argument) is a breaking change by nesting the scope part of the args. So in 7fd22f8 1637e1a I switched the change to be an extension, not a nesting.

@andrewbranch
Copy link
Member

Thanks @JoshuaKGoldberg! Let’s get a review from @jessetrinity too.

Copy link
Contributor

@jessetrinity jessetrinity left a comment

Choose a reason for hiding this comment

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

nit: a word

src/harness/harnessLanguageService.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@jessetrinity jessetrinity left a comment

Choose a reason for hiding this comment

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

Looks good. We should make a separate issue for adding a UserPreference for cases in which the command is explicitly requested.

@andrewbranch
Copy link
Member

Why didn’t @typescript-bot issue the pinging-everyone-because-you-changed-protocol.ts comment?

Copy link
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

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

Seems like a breaking change to the protocol? Am I missing something?

src/server/protocol.ts Outdated Show resolved Hide resolved
export interface OrganizeImportsRequestArgs {
scope: OrganizeImportsScope;
export interface OrganizeImportsRequestArgs extends OrganizeImportsScope {
allowDestructiveCodeActions?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

To confirm, we expect the editor to want to make this decision per-request and that's why it's not a UserPreference?

Copy link
Member

Choose a reason for hiding this comment

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

Also i would name this flag as skipDestructiveCodeActions so that you would need to check only for truthiness instead of defaults when not set..

Copy link
Contributor

@jessetrinity jessetrinity Apr 16, 2021

Choose a reason for hiding this comment

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

To confirm, we expect the editor to want to make this decision per-request and that's why it's not a UserPreference?

Yes, the editor would need to specify the option based on whether the command was sent as a part of compileOnSave or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

dacfd7e renames to skipDestructiveCodeActions and defaults it to falsy.

@amcasey
Copy link
Member

amcasey commented Apr 16, 2021

Btw, I realized that 3a61904 (which added the allowDestructiveCodeActions argument) is a breaking change by nesting the scope part of the args. So in 7fd22f8 1637e1a I switched the change to be an extension, not a nesting.

I'm definitely missing something in this comment.

@JoshuaKGoldberg JoshuaKGoldberg requested a review from amcasey April 17, 2021 16:30
@JoshuaKGoldberg JoshuaKGoldberg changed the title Added allowDestructiveCodeActions argument to organize imports server command Added skipDestructiveCodeActions argument to organize imports server command Apr 17, 2021
Copy link
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

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

I'd like to get a second opinion on the flag name, but LGTM otherwise.

@@ -681,6 +681,7 @@ namespace ts.server.protocol {

export interface OrganizeImportsRequestArgs {
scope: OrganizeImportsScope;
skipDestructiveCodeActions?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we have an actual convention, but it looks like we have a pattern of using positive names and, if necessary, treating undefined as true. e.g. UserPreferences.includeAutomaticOptionalChainCompletions or CompilerOptions.AllowUnreachableCode. I think @andrewbranch has also found this frustrating and might have suggestions?

Copy link
Member

Choose a reason for hiding this comment

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

No, I don’t really have a preference here. This looks fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

source.organizeImports should not remove imports if file contains errors.
7 participants