If there is a compile error, Kernel.ParallelCompiler raises
`** (UndefinedFunctionError) function List.Chars.to_charlist/1 is
undefined (module List.Chars is not available)`.
Before this patch, we could have slightly different
AST while compiling modules in parallel, depending
if modules were recompiled or not. Now we always
recompile Kernel before compiling the whole stdlib.
We used this opportunity to simplify bootstrap by
breaking it two steps. The first step is the minimal
necessary to compile Kernel itself. The second step
contains the whole compiler.
Closes#10000.
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
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.
This speeds up the Elixir compiler from 5-10% as we no
longer do duplicate work on erl_lint and expand_records.
We also avoid the copying of messages by controlling
exactly when the compiler spawns new processes.
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.
Erlang's typespecs define only cover_compiled and preloaded
as valid atoms and uses an empty list for generated code.
So we should follow Erlang's rules until we can officially
relax them.
Note a field named safe_by_default has been added so we don't
warn on variables defined inside EXPR in "case EXPR, do: ...".
The proper solution would be to convert && and || into special
forms and they would be free of the warning. However,
safe_by_default is a welcome temporary solution until we see
how the warning will fare on actual applications.