-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support rich compiler error messages #2783
Conversation
0b15d9a
to
5c768be
Compare
Nice, much more straightforward than I expected. |
Do you think it's worth driving this forward as-is or we'd like to have fancier output? I also imagine we'll need a switch for machine parsing to reuse the old context-free messages |
07df8f2
to
73ba8c4
Compare
4a4e3c8
to
e650b56
Compare
c44d29a
to
415a2ab
Compare
Has there been any consideration using more fancy box drawing or unicode characters? Rust uses carets for the whole error column range:
I think that looks slightly better and it is easier to see what exactly is marked as a problem. |
Here's an example with box drawing characters (looks even better in a terminal):
|
I could use box drawing chars easily, but I wouldn't use the carets for the whole expression, only because I have no width information about the error, just the column it starts on. The Color highlight is done with a sort of messy regex trick, and it's unlikely to carry well to other compilers we support. If the Color is a bit wrong but the arrow is good, it sort of limits the scope of error. I'll update the PR to use the fancier characters. |
This is rather straightforward as an implementation: given any error message that contains column information, read the source file and find that line. Display it, and indent a cursor underneath it that points to the column. Then we can just show the same error message as before. In practice, given the module: -module(rebar_fake). -export([diagnostic/1]). diagnostic(A) -> X = add(5 / 0), {X,X}. add(X) -> X. add(X, Y) -> X + Y. Calling rebar3 compile yields: ... ===> Compiling rebar ===> Compiling apps/rebar/src/rebar_fake.erl failed apps/rebar/src/rebar_fake.erl:5:12: diagnostic(A) -> ^-- variable 'A' is unused apps/rebar/src/rebar_fake.erl:6:15: X = add(5 / 0), ^-- evaluation of operator '/'/2 will fail with a 'badarith' exception apps/rebar/src/rebar_fake.erl:11:1: add(X, Y) -> X + Y. ^-- function add/2 is unused This is friendlier than what we had before for sure. Adding color could be an extension to this if we find the format useful. The rebar compiler output richness is conditional and configurable, and we default to the minimal normal one to make sure it won't break all sorts of tooling. Rich errors also happen to support to xrl and yrl compilers
This will help testability and to better self-contain the implementation
This now looks like: ... ===> Compiling apps/rebar/src/fake_mod.erl failed ┌─ apps/rebar/src/fake_mod.erl: │ 5 │ diagnostic(A) -> │ ╰── variable 'A' is unused ┌─ apps/rebar/src/fake_mod.erl: │ 6 │ X = add(5 / 0), │ ╰── evaluation of operator '/'/2 will fail with a 'badarith' exception ┌─ apps/rebar/src/fake_mod.erl: │ 11 │ add(X, Y) -> X + Y. │ ╰── function add/2 is unused And supports colors with a weak heuristic based on regexes that I expect we'll need to fix and expand later to cover more compiler-specific rules.
0039235
to
dbbb73a
Compare
This is rather straightforward as an implementation: given any error message that contains column information, read the source file and find that line. Display it, and indent a cursor underneath it that points to the column.
Then we can just show the same error message as before.
In practice, given the module:
Calling rebar3 compile yields:
and in a terminal supporting color output:
This is friendlier than what we had before for sure. Adding color could be an extension to this if we find the format useful.
By default, this format is turned off, but can be turned on optionally by configuring values with
Compilers that want to support it must switch their calls from
rebar_compiler:error_tuple(Source, Errors, Warnings, Opts)
torebar_compiler:error_tuple(Source, Errors, Warnings, Config, Opts)
, which allows the configuration to work and go for non-default values.The intent of this PR is to put the initial scaffolding in place to gradually get nicer and richer error formats for users, without necessarily harming the ability of tools to still work with them (via config switches).