Instead of incrementing the version for each variable individually we increment it globally for all variables. This means we can uniquely identify each variable assignment with only the version.
Currently the callbacks on :elixir_compiler are called before the warnings of unused aliases and imports are emitted, causing the messages to not consumed during the compilation. This commit changes `:elixir_lexical.run/2` to `:elixir_lexical.run/3` splitting the callback in two, one during the execution to evaluate the forms and another to be called after all the warnings are emitted.
Fixes#9440
* Make Module.open?/1 and family to match their docs.
* Cosmetics.
* Introduced internal not_closing state for modules.
It’s stored in a separate ETS and the last field of #elixir_code_server state to minimize impact.
* Use the same ETS for the state.
This feature allows IDEs and other tools wanting to
perform source code analysis to do so reliably without
a need to reimplement Elixir's compiler expansion and
without relying on Elixir's private APIs.
This commit also adds :parser_options to compiler
options, which allows developers to combine both options
to retrieve more accurate information, such as columns.
Prior to this patch, we would always compute the relative
path to the current working directory (CWD), but this meant
consolidated protocols would always get a full path since
they are always outside of their current working directory.
We address this by also storing the relative path in the
definition.
Closes#9095
This is part of an ongoing effort to forbid overriding macros
with functions and vice-versa. New checks will require the
overridable information to be stored more efficiently.
Unfortunately it is common to have macros that invokes macros
from other modules, leading to mixed quoted expressions causing
the counters to be mixed.
We would need to scope the counters to the caller.
This reverts commit f04f46c49d.
When the module is being compiled, we use deterministic counters instead
of random ones. This should help with most cases of undeterministic
source code or .beam files.
Closes#7955
Reason to add it is capturing functions when passing in module name,
function name and arity using variable, because the capture operator
can't handle them.
Done by delegating to `:erlang.make_fun(mod, f, arity)`, also exposed
some erlang functions for getting information for a function.
This avoids copying typespecs in and out of the table
every time there is a new entry.
We also make sure the Protocol module is only relying
on public APIs and not on inner typespec behaviour.
Previously we kept a Set table for attributes and a Bag table
for function definitions and clauses. This led to suboptimal
usage of ets tables.
With this commit, we start using both Bag and Set tables
to store function/macro definition information. In the next
commits we will continue generalizing the tables, storing
specs, docs and accumulated attributes in the Bag and keep
the remaining functionality in Set.
This gives us better control over when and how unused variables are printed.
As a result, we are able to emit unused variable warnings in situations
we could not before. This also opens up the way for us to remove a
dependency on erl_lint and track types information, which allows us to
speed up compilation times about 5% and allow us to emit more performant
code in some situations.