WhatsApp / erlfmt

An automated code formatter for Erlang
Apache License 2.0
407 stars 51 forks source link

Formatting fails with binary pattern match macro #357

Open eproxus opened 3 weeks ago

eproxus commented 3 weeks ago

When formatting a module containing a macro with an argument that is put inside a binary, a compilation error is generated:

-module(my_module).

-export([func/2]).

-define(BIN(Arg), <<Arg>>).

func(uuid, ?BIN(A:8)) -> A.

Running rebar3 fmt on this file generates the following error:

$ rebar3 fmt src/my_module.erl
===> Analyzing applications...
===> Compiling erlfmt
src/my_module.erl:7:18: syntax error before: ':'

Erlang / Rebar 3 itself can compile the file just fine:

$ rebar3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling my_app
Erlang/OTP 27 [erts-15.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Eshell V15.0.1 (press Ctrl+G to abort, type help(). for help)
1> my_module:func(<<"A">>).
65

erlfmt version: 1.3.0 and latest main Erlang/OTP: 27.0.1 Rebar 3: 3.23.0

michalmuskala commented 3 weeks ago

This is somewhat expected - erlfmt generally expects macro definitions and arguments to be valid Erlang AST, with some extensions - this is not true of a stand-alone A:8 expression.

It might be possible to extend the grammar to accept this as a stand-alone expression, but I'm not sure. This is primarily because parsing of : is already one of the most complex parts of the parser - given it has completely different precedence in all 3 places: when used as a remote call marker, in binaries, and in catch clauses.