Packages
sourceror
0.8.1
1.12.2
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.2
1.8.0
1.7.1
1.7.0
1.6.0
1.5.0
1.4.0
1.3.0
1.2.1
1.2.0
1.1.0
1.0.3
1.0.2
1.0.1
1.0.0
0.14.1
0.14.0
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.2.2
Utilities to work with Elixir source code.
Current section
Files
Jump to
Current section
Files
src/sourceror_elixir.erl
%% Main entry point for Elixir functions. All of those functions are
%% private to the Elixir compiler and reserved to be used by Elixir only.
-module(sourceror_elixir).
-export([string_to_tokens/5, tokens_to_quoted/3, 'string_to_quoted!'/5]).
-include("sourceror_elixir.hrl").
-define(system, 'Elixir.System').
%% Top level types
%% TODO: Remove char_list type on v2.0
-export_type([charlist/0, char_list/0, nonempty_charlist/0, struct/0, as_boolean/1, keyword/0, keyword/1]).
-type charlist() :: string().
-type char_list() :: string().
-type nonempty_charlist() :: nonempty_string().
-type as_boolean(T) :: T.
-type keyword() :: [{atom(), any()}].
-type keyword(T) :: [{atom(), T}].
-type struct() :: #{'__struct__' := atom(), atom() => any()}.
%% Converts a given string (charlist) into quote expression
string_to_tokens(String, StartLine, StartColumn, File, Opts) when is_integer(StartLine), is_binary(File) ->
case sourceror_elixir_tokenizer:tokenize(String, StartLine, StartColumn, [{file, File} | Opts]) of
{ok, _Tokens} = Ok ->
Ok;
{error, {Line, Column, {ErrorPrefix, ErrorSuffix}, Token}, _Rest, _SoFar} ->
Location = [{line, Line}, {column, Column}],
{error, {Location, {to_binary(ErrorPrefix), to_binary(ErrorSuffix)}, to_binary(Token)}};
{error, {Line, Column, Error, Token}, _Rest, _SoFar} ->
Location = [{line, Line}, {column, Column}],
{error, {Location, to_binary(Error), to_binary(Token)}}
end.
tokens_to_quoted(Tokens, File, Opts) ->
handle_parsing_opts(File, Opts),
try sourceror_elixir_parser:parse(Tokens) of
{ok, Forms} ->
{ok, Forms};
{error, {Line, _, [{ErrorPrefix, ErrorSuffix}, Token]}} ->
{error, {parser_location(Line), {to_binary(ErrorPrefix), to_binary(ErrorSuffix)}, to_binary(Token)}};
{error, {Line, _, [Error, Token]}} ->
{error, {parser_location(Line), to_binary(Error), to_binary(Token)}}
after
erase(elixir_parser_file),
erase(elixir_parser_columns),
erase(elixir_token_metadata),
erase(elixir_literal_encoder)
end.
parser_location({Line, Column, _}) ->
[{line, Line}, {column, Column}];
parser_location(Meta) ->
Line =
case lists:keyfind(line, 1, Meta) of
{line, L} -> L;
false -> 0
end,
case lists:keyfind(column, 1, Meta) of
{column, C} -> [{line, Line}, {column, C}];
false -> [{line, Line}]
end.
'string_to_quoted!'(String, StartLine, StartColumn, File, Opts) ->
case string_to_tokens(String, StartLine, StartColumn, File, Opts) of
{ok, Tokens} ->
case tokens_to_quoted(Tokens, File, Opts) of
{ok, Forms} ->
Forms;
{error, {Line, Error, Token}} ->
elixir_errors:parse_error(Line, File, Error, Token)
end;
{error, {Line, Error, Token}} ->
elixir_errors:parse_error(Line, File, Error, Token)
end.
to_binary(List) when is_list(List) -> elixir_utils:characters_to_binary(List);
to_binary(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8).
handle_parsing_opts(File, Opts) ->
LiteralEncoder =
case lists:keyfind(literal_encoder, 1, Opts) of
{literal_encoder, Fun} -> Fun;
false -> false
end,
TokenMetadata = lists:keyfind(token_metadata, 1, Opts) == {token_metadata, true},
Columns = lists:keyfind(columns, 1, Opts) == {columns, true},
put(elixir_parser_file, File),
put(elixir_parser_columns, Columns),
put(elixir_token_metadata, TokenMetadata),
put(elixir_literal_encoder, LiteralEncoder).