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

Add extract code actions #870

Merged
merged 6 commits into from
Jun 16, 2023
Merged

Add extract code actions #870

merged 6 commits into from
Jun 16, 2023

Conversation

jfeser
Copy link
Collaborator

@jfeser jfeser commented Oct 11, 2022

Adds two new code actions: Extract local and Extract function.

Extract local transforms:

let f x =  $x+1$ + 2

to

let f x = 
  let new_var = x + 1 in 
  new_var + 2

The new variable gets placed at the tightest enclosing binder of the extracted expression.

Extract function would transform the same code to:

let new_fun x = x + 1
let f x = new_fun x + 2

The new function will be inserted directly before the enclosing structure item. Any free variables in the expression will be passed as arguments.

Just wanted to get opinions on whether this is a useful feature, and whether these behaviors make sense.

TODO:

  • Should extract local move the expression to the loosest binder rather than the tightest?
  • Extract function doesn't handle free variables with nontrivial Longidents.
  • Add tests.

@rgrinberg
Copy link
Member

The feature looks useful to me.

Should extract local move the expression to the loosest binder rather than the tightest?

I would expect the tightest. But perhaps you could have two extract actions for the different behaviors.

Or perhaps we could have different refactorings for hoisting bindings up.

The new function will be inserted directly before the enclosing structure item.

I would expect it to stay close to the scope where it's being used personally.

@rgrinberg
Copy link
Member

Btw, can you try splitting this code action into a discovery/resolve phase and evaluate if it helps performance a little. I'm getting a little worried about all these code actions clogging up the server.

@ulugbekna
Copy link
Collaborator

I am working on a code actions “framework” within olsp that should batch merlin work into a single job and facilitate implementing code action resolve easily, so I would say it’s fine if we don’t have resolve implemented in this PR.

@jfeser
Copy link
Collaborator Author

jfeser commented Oct 19, 2022

I have a branch (https://github.com/jfeser/ocaml-lsp/tree/tracing) with some extra tracing. From the traces I've looked at, code actions aren't a performance concern. How have you been evaluating performance/where have you seen performance problems?

@rgrinberg
Copy link
Member

If you measured it and it's not a problem then let's leave it be.

I haven't measured anything but I've noticed that lsp gets stuck "thinking" sometimes and then fires off a bunch of responses. I do not know the source of the bottle neck though.

@coveralls
Copy link

coveralls commented Jun 13, 2023

Pull Request Test Coverage Report for Build 3872

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 99 of 117 (84.62%) changed or added relevant lines in 4 files are covered.
  • 821 unchanged lines in 19 files lost coverage.
  • Overall coverage increased (+0.05%) to 18.089%

Changes Missing Coverage Covered Lines Changed/Added Lines %
ocaml-lsp-server/src/document.ml 4 5 80.0%
ocaml-lsp-server/src/code_actions/action_mark_remove_unused.ml 0 5 0.0%
ocaml-lsp-server/src/code_actions/action_extract.ml 91 103 88.35%
Files with Coverage Reduction New Missed Lines %
lsp/src/cancel_request.ml 1 75.0%
lsp/src/position.ml 1 75.0%
ocaml-lsp-server/src/code_actions/diagnostic_util.ml 1 50.0%
ocaml-lsp-server/src/custom_requests/req_switch_impl_intf.ml 9 0.0%
ocaml-lsp-server/src/custom_requests/req_infer_intf.ml 13 0.0%
ocaml-lsp-server/src/document_text_command.ml 13 0.0%
lsp/src/array_view.ml 16 46.67%
ocaml-lsp-server/src/merlin_config_command.ml 19 0.0%
ocaml-lsp-server/src/custom_requests/req_typed_holes.ml 23 0.0%
ocaml-lsp-server/src/document_symbol.ml 29 0.0%
Totals Coverage Status
Change from base Build 3867: 0.05%
Covered Lines: 4257
Relevant Lines: 23533

💛 - Coveralls

@jfeser jfeser marked this pull request as ready for review June 13, 2023 15:20
@jfeser jfeser requested a review from rgrinberg June 14, 2023 00:58
let start_pos =
match String.index src '$' with
| Some x -> x
| None -> failwith "expected a selection opening mark"
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible the user can encounter this error?

  1. If yes, then it should be a Jsonrpc error.
  2. if not, it should it be a code error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is part of the test harness. It gets raised when the test input doesn't have $ markers for the selection. Do you want me to use a different exception?

Copy link
Member

Choose a reason for hiding this comment

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

Oh never mind. It's fine.

@rgrinberg rgrinberg added this to the 1.16.0 milestone Jun 15, 2023
@jfeser jfeser merged commit 6bc2627 into ocaml:master Jun 16, 2023
@3Rafal
Copy link
Collaborator

3Rafal commented Jun 16, 2023

Unit tests for this PR are broken. CI fails on 4/7 checks

@rgrinberg
Copy link
Member

@jfeser could you take a look?

rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Jun 18, 2023
CHANGES:

## Fixes

- Disable code lens by default. The support can be re-enabled by explicitly
  setting it in the configuration. (ocaml/ocaml-lsp#1134)

- Fix initilization of `ocamlformat-rpc` in some edge cases when ocamlformat is
  initialized concurrently (ocaml/ocaml-lsp#1132)

- Kill unnecessary `$ dune ocaml-merlin` with SIGTERM rather than SIGKILL
  (ocaml/ocaml-lsp#1124)

- Refactor comment parsing to use `odoc-parser` and `cmarkit` instead of
  `octavius` and `omd` (ocaml/ocaml-lsp#1088)

  This allows users who migrated to omd 2.X to install ocaml-lsp-server in the
  same opam switch.

  We also slightly improved markdown generation support and fixed a couple in
  the generation of inline heading and module types.

- Allow opening documents that were already open. This is a workaround for
  neovim's lsp client (ocaml/ocaml-lsp#1067)

- Disable type annotation for functions (ocaml/ocaml-lsp#1054)

- Respect codeActionLiteralSupport capability (ocaml/ocaml-lsp#1046)

- Fix a document syncing issue when utf-16 is the position encoding (ocaml/ocaml-lsp#1004)

- Disable "Type-annotate" action for code that is already annotated.
  ([ocaml/ocaml-lsp#1037](ocaml/ocaml-lsp#1037)), fixes
  [ocaml/ocaml-lsp#1036](ocaml/ocaml-lsp#1036)

- Fix semantic highlighting of long identifiers when using preprocessors
  ([ocaml/ocaml-lsp#1049](ocaml/ocaml-lsp#1049), fixes
  [ocaml/ocaml-lsp#1034](ocaml/ocaml-lsp#1034))

- Fix the type of DocumentSelector in cram document registration (ocaml/ocaml-lsp#1068)

- Accept the `--clientProcessId` command line argument. (ocaml/ocaml-lsp#1074)

- Accept `--port` as a synonym for `--socket`. (ocaml/ocaml-lsp#1075)

- Fix connecting to dune rpc on Windows. (ocaml/ocaml-lsp#1080)

## Features

- Add "Remove type annotation" code action. (ocaml/ocaml-lsp#1039)

- Support settings through `didChangeConfiguration` notification (ocaml/ocaml-lsp#1103)

- Add "Extract local" and "Extract function" code actions. (ocaml/ocaml-lsp#870)

- Depend directly on `merlin-lib` 4.9 (ocaml/ocaml-lsp#1070)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants