katana-code
katana-code copied to clipboard
ktn_code fails since ktn_dodger cannot parse macro functions in function clauses
Given the following module
-module(macros).
-define(MATCH_NAME(), #{name := "Per"}).
is_adult(?MATCH_NAME()) ->
false.
1> File = "path/to/macros.erl".
"path/to/macros.erl"
2> {ok, Dev} = file:open(File, [read]).
{ok, <0.328.0>}.
3> ktn_dodger:parse_form(Dev, 1, [{scan_opts, [text]}]).
{ok,{tree,attribute,
{attr,[{text,"module"},{location,1}],[],none},
{attribute,{tree,atom,
{attr,[{text,"module"},{location,1}],[],none},
module},
[{tree,atom,
{attr,[{text,"module"},{location,1}],[],none},
macros}]}},
2}
4> ktn_dodger:parse_form(Dev, 2, [{scan_opts, [text]}]).
{ok,{tree,attribute,
{attr,[{text,"define"},{location,2}],[],none},
{attribute,{atom,[{text,"define"},{location,2}],define},
[{tree,application,
{attr,[{text,"MATCH_NAME"},{location,2}],[],none},
{application,{var,[{text,"MATCH_NAME"},{location,2}],
'MATCH_NAME'},
[]}},
{tree,map_expr,
{attr,[{text,"#"},{location,2}],[],none},
{map_expr,none,
[{tree,map_field_exact,
{attr,[{text,"name"},{location,2}],[],none},
{map_field_exact,{atom,[{text,...},{...}],name},
{string,[{...}|...],[...]}}}]}}]}},
3}
5> ktn_dodger:parse_form(Dev, 2, [{scan_opts, [text]}]).
{error,{3,erl_parse,["syntax error before: ","?"]},5}
Problem seems to reside in ktn_dodger:scan_form which does not send correct thing to erl_parse:parse_form.
6> file:close(Dev), f(Dev), {ok, Dev} = file:open(File, [read]).
{ok, <0.333.0>}
7> c(ktn_dodger, [export_all]).
{ok, ktn_dodger}
8> {ok, Ts1, _} = io:scan_erl_form(Dev, "", 1, [{scan_opts, [text]}]).
{ok,[{'-',1},
{atom,1,module},
{'(',1},
{atom,1,macros},
{')',1},
{dot,1}],
2}
9> S1 = ktn_dodger:scan_form(Ts1, {opt, false}).
[{'-',1},
{atom,1,module},
{'(',1},
{atom,1,macros},
{')',1},
{dot,1}]
10> erl_parse:parse_form(S1).
{ok,{attribute,1,module,macros}}
11> {ok, Ts2, _} = io:scan_erl_form(Dev, "", 2, [{scan_opts, [text]}]).
{ok,[{'-',2},
{atom,2,define},
{'(',2},
{var,2,'MATCH_NAME'},
{'(',2},
{')',2},
{',',2},
{'#',2},
{'{',2},
{atom,2,name},
{':=',2},
{string,2,"Per"},
{'}',2},
{')',2},
{dot,2}],
3}
12> S2 = ktn_dodger:scan_form(Ts2, {opt, false}).
[{atom,2,'?preprocessor declaration?'},
{'(',2},
{')',2},
{'->',2},
{atom,2,define},
{'(',2},
{var,2,'MATCH_NAME'},
{'(',2},
{')',2},
{',',2},
{'#',2},
{'{',2},
{atom,2,name},
{':=',2},
{string,2,"Per"},
{'}',2},
{')',2},
{dot,2}]
13> erl_parse:parse_form(S2).
{ok,{function,2,'?preprocessor declaration?',0,
[{clause,2,[],[],
[{call,2,
{atom,2,define},
[{call,2,{var,2,'MATCH_NAME'},[]},
{map,2,
[{map_field_exact,2,{atom,2,...},{string,...}}]}]}]}]}}
14> {ok, Ts3, _} = io:scan_erl_form(Dev, "", 3, [{scan_opts, [text]}]).
{ok,[{atom,3,is_adult},
{'(',3},
{'?',3},
{var,3,'MATCH_NAME'},
{'(',3},
{')',3},
{')',3},
{'->',3},
{atom,4,false},
{dot,4}],
5}
15> S3 = ktn_dodger:scan_form(Ts3, {opt, false}).
[{atom,3,is_adult},
{'(',3},
{'(',0},
{atom,3,'? <macro> ('},
{'(',3},
{var,3,'MATCH_NAME'},
{')',3},
{')',0},
{')',3},
{'->',3},
{atom,4,false},
{dot,4}]
16> erl_parse:parse_form(S3).
{error,{3,erl_parse,["syntax error before: ","'('"]}}
You should try with ktn_dodger:parse_form(Dev, 1, [{scan_opts, [text]}, no_fail]).
haven't been able to look at it yet, but you suggest opening a PR changing this row?
https://github.com/inaka/katana-code/blob/9ae6f99ac8709f576bdf3f4a1ff638e307765f48/src/ktn_code.erl#L96
{ok, Forms} = ktn_dodger:parse( IoString
- , {1, 1}
+ , 1
, [{scan_opts, [text]}]
+ , no_fail
),
Yeah, exactly. Sorry I closed the issue, I thought the usage of ktn_dodger was from another library not this one.