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 introduces five new metadata nodes:
* `do` - contains metadata about do location in a function call with
`do/end` blocks
* `end` - contains metadata about end location in a function call with
`do/end` blocks
* `closing` - contains metadata about the closing pair, such as a `}`
in a tuple or in a map, or such as the closing `)` in a function call
with parens
* `eol` - is set to true when the opening pair, such as `{` or `(`, are
followed by the end of the line
* `delimiter` - contains the opening for sigils (such as `"{"`, `"/"`,
etc)
Regexes are precompiled to binary values during code compilation.
These binary values may be incompatible between different PCRE versions
and OS endianness. This makes code less portable to achieve slight
performance improvement.
PCRE version and endianness are parts of Regex structure and may be
checked in runtime.
This commit adds this check and makes regex execution fall back
to binary matching if versions are incompatible.
This slightly reduces performance (around 5% for simple regexes) for
compatible versions because there is an additional version read.
Also for incompatible versions it's as fast as binary matching.
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.
When you are working on large files and you add new code,
you may forget to add a `do` or an `end`. In those cases,
the error message usually points to the first `do` or the
last `end` in the file, which are usually far away from
the source of the error.
This pull request adds a simple heuristic based on the
indentation of the tokens, to try to provide hints of
where the source may be. Those hints are not deterministic
but they may be able to point users to the source of the
problem.
For example, in this case:
defmodule MyApp do
def one do
# end
def two do
end
end
we know that we now that `def two do` is happening on the
same indentation as `def one do`, which may mean that
`def one do` was not closed properly. We store this as a
hint in case the terminators do not match later.
Similarly, in the case below:
defmodule MyApp do
def one
end
def two do
end
end
The `end` on line 3 will end-up closing the defmodule `do`,
on line 1. Because their indentation do not match, it may
be that there is a missing `do`, where the `end` was supposed
to align.
Some basic testing show those heuristics work on the majority
of the cases, but we will only be sure when we have enough
feedback from the community.
This touches only messages directed to the end user,
so comments are ignored.
This is important, specially for newcomers, who may be confused
by the interchangeable use of Erlang and OTP.
The expressions used consistenly across the documentation are:
- Erlang/OTP version
- Erlang/OTP 20+
- Erlang/OTP release,
- Erlang/OTP documentation
- Erlang process
- Erlang project
- Erlang's error logger
- Erlang log message
- OTP application
- OTP behaviour
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.
Currently there is no way to compile a file without leaving
footprints on the system. Plus, the term load_file/2 is very
confusing as loaded is the notation used by modules.
This commit focuses the whole loaded aspect of files exclusively
on require_file/2 (and renames two functions accordingly) and
introduces compile_file/2 which is semantically simpler than
load_file/2.