Packages

Syntax extensions for Erlang

Current section

Files

Jump to
erlando src import_as.erl
Raw

src/import_as.erl

%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (the "License"); you may not use this file except in
%% compliance with the License. You may obtain a copy of the License
%% at http://www.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and
%% limitations under the License.
%%
%% The Original Code is Erlando.
%%
%% The Initial Developer of the Original Code is VMware, Inc.
%% Copyright (c) 2011-2013 VMware, Inc. All rights reserved.
%%
-module(import_as).
-export([parse_transform/2]).
parse_transform(Forms, _Options) ->
%% io:format("Before:~n~p~n~n", [Forms]),
{[], Forms1} = lists:foldl(fun import_as/2, {[], []}, Forms),
Forms2 = lists:reverse(Forms1),
%% io:format("After:~n~s~n~n",
%% [erl_prettypr:format(erl_syntax:form_list(Forms2))]),
Forms2.
import_as({attribute, Line, import_as, {Module, Aliases}}, Acc) ->
import_as({attribute, Line, import_as, [{Module, Aliases}]}, Acc);
import_as({attribute, Line, import_as, List}, {Funs, Acc})
when is_list(List) ->
Funs1 =
lists:foldl(
fun ({Module, Aliases}, Acc1) when is_list(Aliases) ->
[alias_fun(Module, Line, Alias) || Alias <- Aliases] ++ Acc1;
(WrongThing, Acc1) ->
[general_error_fun(Line, WrongThing) | Acc1]
end, Funs, List),
{Funs1, Acc};
import_as({attribute, Line, import_as, WrongThing}, {Funs, Acc}) ->
{Funs, [general_error(Line, WrongThing) | Acc]};
import_as({eof, Line}, {Funs, Acc}) ->
{Acc1, Line1} =
lists:foldl(
fun (Fun, {AccN, LineN}) -> {[Fun(LineN) | AccN], LineN + 1} end,
{Acc, Line}, Funs),
{[], [{eof, Line1} | Acc1]};
import_as(Other, {Funs, Acc}) ->
{Funs, [Other | Acc]}.
alias_fun(Module, _AttLine, {{Dest, Arity}, Alias}) when is_atom(Module) andalso
is_atom(Dest) andalso
is_atom(Alias) andalso
is_integer(Arity) ->
fun (Line) ->
Vars = [{var, Line, list_to_atom("Var_" ++ integer_to_list(N))} ||
N <- lists:seq(1, Arity)],
Body = {call, Line,
{remote, Line, {atom, Line, Module}, {atom, Line, Dest}},
Vars},
{function, Line, Alias, Arity, [{clause, Line, Vars, [], [Body]}]}
end;
alias_fun(_Module, AttLine, WrongThing) ->
fun (_Line) ->
Str = io_lib:format("~p", [WrongThing]),
{error, {AttLine, erl_parse,
["-import_as: Expected a pair of "
"{target_fun/arity, alias}, not: ", Str]}}
end.
general_error_fun(AttLine, WrongThing) ->
fun (_Line) -> general_error(AttLine, WrongThing) end.
general_error(AttLine, WrongThing) ->
Str = io_lib:format("~p", [WrongThing]),
{error, {AttLine, erl_parse, ["-import_as: invalid attribute value: ", Str]}}.