aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-05-08 12:09:37 +0200
committerBjörn Gustavsson <[email protected]>2015-05-08 12:09:37 +0200
commit0bdb747b4b0572bfe30bf7d974e32d05c0e2df66 (patch)
tree8d846fec1a4b0a910fd2099a89b9e15b1a10191b
parent40980940e866a9fe8f7055d7499df8bf604f11d4 (diff)
parentd8fa79149a1339b2359ecc981f992bd53e5a9d18 (diff)
downloadotp-0bdb747b4b0572bfe30bf7d974e32d05c0e2df66.tar.gz
otp-0bdb747b4b0572bfe30bf7d974e32d05c0e2df66.tar.bz2
otp-0bdb747b4b0572bfe30bf7d974e32d05c0e2df66.zip
Merge branch 'nox/compiler/parse_transform-undef/OTP-12723'
* nox/compiler/parse_transform-undef/OTP-12723: Properly report unknown parse transforms
-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 b54d125774..22810c910c 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -920,28 +920,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 0d23f12fb5..acd785cc5a 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.
maps_warnings(Config) when is_list(Config) ->