erlang-ls / erlang_ls

The Erlang Language Server
https://erlang-ls.github.io/
Apache License 2.0
627 stars 136 forks source link

Getting dialyzer to work with a rebar3 project #573

Open Vagabond opened 4 years ago

Vagabond commented 4 years ago

Describe the bug

When trying to enable dialyzer on a rebar3 project, I did the following:

plt_path: "/home/andrew/.cache/rebar3/rebar3_22.2.7_plt"

This caused errors like the following to appear in the ELS log:

2020-03-15 05:44:29.025 [error] <0.279.0>@els_dialyzer_diagnostics:diagnostics:40 Error while running dialyzer [type=throw] [error={dialyzer_error,"Analysis failed with error:\nCould not scan the following file(s):\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:113: can't find include file \"logger.hrl\"\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:644: undefined macro 'LOG_WARNING/2'\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:889: undefined macro 'LOG_ERROR/2'\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:388: function try_dispatch/4 undefined\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:631: function try_dispatch/4 undefined\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:633: function try_dispatch/4 undefined\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:861: function error_info/7 undefined\n/usr/lib/erlang/lib/stdlib-3.11.2/src/gen_server.erl:869: function error_info/7 undefined\n\nLast messages in the log cache:\n  Reading files and computing callgraph... "}]

So I added the following to my els config:

deps_dirs:
  ...
  - "/usr/lib/erlang/lib/*"
include_dirs:
  ...
  - "/usr/lib/erlang/lib"
  - "/usr/lib/erlang/lib/*/include"

This appears to have silenced the error, but dialyzer still doesn't report any intentional errors I add to the source file.

To Reproduce Steps to reproduce the behavior: try to enable dialyzer on a rebar3 project.

Expected behavior Dialyzer should be able to analyze the source files in my project and report errors.

Actual behavior Dialyzer appears to do nothing. rebar3 dialyzer does report errors.

Context

jfacorro commented 4 years ago

I think the issue you are seeing is not because the project is a rebar3 project but because the specific module you are working with implements the gen_server behaviour.

The current implementation for Dialyzer diagnostics tries to include some (but not all) files that are relevant for the analysis. A module that uses implements a gen_server behaviour, for example, requires the callback information specified in gen_server.erl.

The resolution of relevant files is currently simple and quite shallow (see els_diagnostics_utils:dependencies/1). The reason is that we want the Dialyzer diagnostic to finish in a reasonable amount of time. If the resolution fetched as many files and information as necessary we risk the situation weree it bring half of OTP, which shouldn't happen often though.

A possible approach would be to fetch dependencies up to a depth, which would require some work.

@onno-vos-dev Any thoughts on this?

moritzploss commented 3 years ago

Just to bring this up again, I'm seeing the same problem for modules implementing the statem behaviour. In my erlang_ls.config I point to the project's plt generated by rebar3:

...
plt_path: "./_build/default/rebar3_23.1.5_plt"
...

It works fine for modules that don't implement statem or gen_server behaviours. I'd be happy to help, but I'm totally unfamiliar with the project and have no idea where to start.

josephDunne commented 2 years ago

the problem is that the dialyzer run command does not include otp include directories :-( So I end up with erlang_ls.config files with the otp include dirs hard coded:

deps_dirs:
  - "deps"
include_dirs:
  - "lib"
  - "lib/*/include"
  - "deps"
  - "deps/*/include"
  - "/usr/local/Cellar/erlang/24.1.2/lib/erlang/lib/*/include"

it doesn't matter wether I specify the otp_path or not. you have to specify the otp include dirs manually

robertoaloi commented 2 years ago

@Vagabond @josephDunne may I ask you to provide a minimal example reproducing the issue? This could be a dummy repo with a new rebar3 project and an intentional dialyzer error. That will help us troubleshooting the issue and hopefully coming with the proper fix.

expelledboy commented 1 year ago

Hey @josephDunne :) I see you still coding in Erlang!

Did you manage to get dialyzer working via erlang_ls in a rebar3 project.