Current section

Files

Jump to
ephp src ephp_ns.erl
Raw

src/ephp_ns.erl

%% @doc This module stores handle the way to use namespaces. The namespaces
%% are needed mainly during parsing (compilation-time) but dynamically
%% it's sometimes needed as well.
%% @end
-module(ephp_ns).
-author('manuel@altenwald.com').
-compile([warnings_as_errors]).
-include("ephp.hrl").
-export([
normalize/1,
join/2,
split/1,
to_bin/1,
to_bin/2,
parse/1,
find/2,
translate/3
]).
-spec normalize(namespace()) -> namespace().
%% @doc normalize namespace removing initial empty (absolute) if any.
normalize([<<>>|NS]) -> NS;
normalize(NS) -> NS.
-spec join(namespace(), namespace()) -> namespace().
%% @doc join two namespaces to generate only one, checking for absolute and relative.
join(_BaseNS, [<<>>|RelativeNS]) -> RelativeNS;
join(BaseNS, RelativeNS) -> BaseNS ++ RelativeNS.
-spec split(namespace()) -> {namespace(), binary()}.
%% @doc retrieve last part of the namespace.
split([Name]) -> {[], Name};
split(NS) when is_list(NS) andalso length(NS) > 1 ->
{lists:droplast(NS), lists:last(NS)}.
-spec to_bin(namespace()) -> binary().
%% @doc converts a namespace to the string representation.
to_bin(NS) ->
ephp_string:join(NS, <<"\\">>).
-spec to_bin(namespace(), class_name()) -> binary().
%% @doc converts a namespace and class or function name to the string representation.
to_bin(NS, <<>>) ->
to_bin(NS);
to_bin(NS, ClassName) ->
to_bin(NS ++ [ClassName]).
-spec parse(binary()) -> {namespace(), class_name()}.
%% @doc converts a string into a 2-tuple: namespace and class name.
parse(Str) ->
case binary:split(Str, <<"\\">>, [global]) of
[ClassName] -> {[], ClassName};
Parts -> {lists:droplast(Parts), lists:last(Parts)}
end.
-spec find(namespace(), [{namespace(), namespace()}]) -> {namespace(), namespace()} | false.
%% @doc find a matching namespace based on the initial match.
find(NS, NSList) ->
lists:foldl(fun({MatchNS, RealNS}, false) ->
case lists:prefix(MatchNS, NS) of
true -> {MatchNS, RealNS};
false -> false
end;
(_, Acc) -> Acc
end, false, NSList).
-spec translate(Source :: namespace(), Match :: namespace(), Target :: namespace()) -> namespace().
%% @doc translate a namespace into another based on match one.
translate(Source, Match, Target) ->
MatchSize = length(Match),
Suffix = lists:sublist(Source, MatchSize + 1, length(Source) - MatchSize),
Target ++ Suffix.