Open erszcz opened 3 years ago
Some notes on hypothetical Gradient integration with ElixirLS.
ElixirLS comes with a Dialyzer integration - it's a natural starting point:
10:45:00 erszcz @ x6 : ~/work/elixir-lsp/elixir-ls (gradient *%)
$ rg -l Dialyzer apps/language_server/
apps/language_server/lib/language_server/dialyzer.ex
apps/language_server/lib/language_server/server.ex
apps/language_server/lib/language_server/dialyzer/success_typings.ex
apps/language_server/lib/language_server/dialyzer/utils.ex
apps/language_server/lib/language_server/dialyzer/manifest.ex
apps/language_server/lib/language_server/providers/code_lens.ex
apps/language_server/lib/language_server/dialyzer/analyzer.ex
apps/language_server/lib/language_server/dialyzer/supervisor.ex
apps/language_server/lib/language_server/providers/code_lens/type_spec.ex
apps/language_server/test/dialyzer_test.exs
apps/language_server/test/fixtures/umbrella_dialyzer/mix.exs
apps/language_server/test/fixtures/dialyzer/mix.exs
However, at this stage we're not that interested in the integration details, but rather in the integration points with the main language server framework. This seems to happen in apps/language_server/lib/language_server/server.ex
:
$ rg Dialyzer apps/language_server/lib/language_server/server.ex
20: alias ElixirLS.LanguageServer.{SourceFile, Build, Protocol, JsonRpc, Dialyzer, Diagnostics}
142: {:reply, Dialyzer.suggest_contracts([abs_path]), state}
971: Dialyzer.analyze(state.build_ref, warn_opts, dialyzer_default_format(state))
1030: Logger.info("Dialyzer analysis is up to date")
1041: |> Dialyzer.suggest_contracts()
1063: Dialyzer.check_support() == :ok and build_enabled?(state) and state.dialyzer_sup != nil
1103: case Dialyzer.check_support() do
1113: Dialyzer.check_support() == :ok && Map.get(settings, "dialyzerEnabled", true)
1160: {:ok, pid} = Dialyzer.Supervisor.start_link(state.project_dir)
Specifically, the most interesting point in the above results seems to be handle_build_result
, where Dialyzer analysis is started. Another interesting point is handle_dialyzer_result
, which shows that Dialyzer results are received asynchronously. We could follow the same pattern with Gradient integration. On the other hand, Gradient is reasonably fast on single files, so an initial prototype could just be invoked synchronously from handle_build_result
and the diagnostics published together with build result diagnostics.
https://github.com/elixir-lsp/elixir-ls