aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Ramine <[email protected]>2015-03-25 13:59:26 +0100
committerAnthony Ramine <[email protected]>2015-03-26 12:13:30 +0100
commitd8fa79149a1339b2359ecc981f992bd53e5a9d18 (patch)
tree51f62da658ea6699454f6577c53521e3ebf8c68b
parent07abc92d5c763cee81bf69695e35a658ddc961dc (diff)
downloadotp-d8fa79149a1339b2359ecc981f992bd53e5a9d18.tar.gz
otp-d8fa79149a1339b2359ecc981f992bd53e5a9d18.tar.bz2
otp-d8fa79149a1339b2359ecc981f992bd53e5a9d18.zip
Properly report unknown parse transforms
We don't want undef errors coming from the parse transform itself to be confused with undef errors caused by the absence of the parse transform. Reported-by: Klas Johansson
-rw-r--r--lib/compiler/src/compile.erl51
-rw-r--r--lib/compiler/test/error_SUITE.erl12
2 files changed, 39 insertions, 24 deletions
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index c7d91070f6..60311ef002 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -906,28 +906,35 @@ transform_module(#compile{options=Opt,code=Code0}=St0) ->
foldl_transform(St, [T|Ts]) ->
Name = "transform " ++ atom_to_list(T),
- Fun = fun(S) -> T:parse_transform(S#compile.code, S#compile.options) end,
- Run = case member(time, St#compile.options) of
- true -> fun run_tc/2;
- false -> fun({_Name,F}, S) -> catch F(S) end
- end,
- case Run({Name, Fun}, St) of
- {error,Es,Ws} ->
- {error,St#compile{warnings=St#compile.warnings ++ Ws,
- errors=St#compile.errors ++ Es}};
- {'EXIT',{undef,_}} ->
- Es = [{St#compile.ifile,[{none,compile,
- {undef_parse_transform,T}}]}],
- {error,St#compile{errors=St#compile.errors ++ Es}};
- {'EXIT',R} ->
- Es = [{St#compile.ifile,[{none,compile,{parse_transform,T,R}}]}],
- {error,St#compile{errors=St#compile.errors ++ Es}};
- {warning, Forms, Ws} ->
- foldl_transform(
- St#compile{code=Forms,
- warnings=St#compile.warnings ++ Ws}, Ts);
- Forms ->
- foldl_transform(St#compile{code=Forms}, Ts)
+ case code:ensure_loaded(T) =:= {module,T} andalso
+ erlang:function_exported(T, parse_transform, 2) of
+ true ->
+ Fun = fun(S) ->
+ T:parse_transform(S#compile.code, S#compile.options)
+ end,
+ Run = case member(time, St#compile.options) of
+ true -> fun run_tc/2;
+ false -> fun({_Name,F}, S) -> catch F(S) end
+ end,
+ case Run({Name, Fun}, St) of
+ {error,Es,Ws} ->
+ {error,St#compile{warnings=St#compile.warnings ++ Ws,
+ errors=St#compile.errors ++ Es}};
+ {'EXIT',R} ->
+ Es = [{St#compile.ifile,[{none,compile,
+ {parse_transform,T,R}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}};
+ {warning, Forms, Ws} ->
+ foldl_transform(
+ St#compile{code=Forms,
+ warnings=St#compile.warnings ++ Ws}, Ts);
+ Forms ->
+ foldl_transform(St#compile{code=Forms}, Ts)
+ end;
+ false ->
+ Es = [{St#compile.ifile,[{none,compile,
+ {undef_parse_transform,T}}]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
end;
foldl_transform(St, []) -> {ok,St}.
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index bd877bb528..8e79b88821 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -235,10 +235,18 @@ transforms(Config) ->
">>,
{error,[{none,compile,{parse_transform,?MODULE,{too_bad,_}}}],[]} =
run_test(Ts2, test_filename(Config), [], dont_write_beam),
+ Ts3 = <<"
+ -compile({parse_transform,",?MODULE_STRING,"}).
+ ">>,
+ {error,[{none,compile,{parse_transform,?MODULE,{undef,_}}}],[]} =
+ run_test(Ts3, test_filename(Config), [call_undef], dont_write_beam),
ok.
-parse_transform(_, _) ->
- error(too_bad).
+parse_transform(_, Opts) ->
+ case lists:member(call_undef, Opts) of
+ false -> error(too_bad);
+ true -> camembert:délicieux()
+ end.
forbidden_maps(Config) when is_list(Config) ->