josefs/Gradualizer

exclude option in rebar.config does not work

jesperes opened this issue · 11 comments

I'm trying to exclude files from being analyzed, as they are causing problems, but the exclude option in rebar.config does not seem to work:

{gradualizer_opts, [{exclude, ["**/opsgenie.*"]}]}.

I still get warnings like this:

/home/jespereskilson/dev/kred/_build/test/lib/opsgenie/ebin/opsgenie.beam: The variable on line 85 is expected to have type #{any() => any()} but it has type error() | uri_map()

        _ ->
            UriMap0 = uri_string:parse(Endpoint),
            Path = maps:get(path, UriMap0) ++
                                  ^^^^^^^

Am I using the option incorrectly? The documentation is very scarce about how to use it, so if the option actually works, maybe some examples would be good to clarify how it should be used?

The same as #468?

It is marked as solved by #470 but apparently the rebar3 plugin doesn't pass on the option to this new code, so I guess it's not solved.

Ah, yes this might well be duplicate of #468.

Also, if I try to run without --use_beams, I get a truckload of missing includes, which seems like a bug to me. Should I report it?

The option I added is exclude_modules and it takes a list of module names, not a regex.

**/opsgenie.* is a filelib wildcard, not a regexp. But a module list works for me.

Do you have a branch for me to test?

Thanks @tsloughter for clarifying.

Also, if I try to run without --use_beams, I get a truckload of missing includes, which seems like a bug to me. Should I report it?

@jesperes You can pass -I to gradualizer, just like you can pass -I to erlc, to specify where the include dirs are. If you have a complex project with lots of include files in different places, it becomes hard for gradualizer to guess where they are. Therefore, it's often easier to run on beams.

However, when using the rebar3 plugin, it would be good if it could use the same include dirs as rebar3 does for compiling. You can open an issue for this or submit a PR. (Tristan knows if it's easy to get this from rebar3.) 😄

Why does the gradualizer provider not just rely on rebar3's compilation? I get it needs some internal compilation to work without rebar3 but in the case the user is calling the rebar3 plugin it shouldn't need to do any compilation.

Gradualizer doesn't need to compile source files, but when typechecking source files, it uses the lexer, parser and preprocessor (epp) before typechecking the parse tree, and for this it needs to resolve include files (-include and -include_lib).

In any project where compilation works, gradualizer also works if it has access to the same include dirs as is used during compilation of the project, i.e. what rebar3 compile passes as {i, Dir} to the compiler.

There is some default, I'm guessing [".", "../include"] (relative the src dir where the erl file is located). On top of that, it appears to be possible to add {i, Dir} in the rebar.config:

{erl_opts, [{i, "myinclude"}]}.

The gradualizer rebar3 plugin would need, in order to find the same include dirs as rebar3 compile, to pick up this form erl_opts and use the same defaults and logic to determine the include dirs as rebar3 compile does.

Aaah.

I'd have to refresh my memory of the compiler to see if you can access that in rebar3 easily. I don't think we build it up until its time to compile the app, so it may not be possible without compiling, which would make it useless here.

But then what is the reason for using src instead of beam? I assumed it was speed, but is it that much slower to compile than to parse and preprocess?

The reason for not using beams is apparently that include and exclude with pattern only doesnt work with use_beams