diff options
-rw-r--r-- | lib/elixir/src/elixir.hrl | 2 | ||||
-rw-r--r-- | lib/elixir/src/elixir_bitstring.erl | 10 | ||||
-rw-r--r-- | lib/elixir/src/elixir_clauses.erl | 44 | ||||
-rw-r--r-- | lib/elixir/src/elixir_def.erl | 9 | ||||
-rw-r--r-- | lib/elixir/src/elixir_def_defaults.erl | 8 | ||||
-rw-r--r-- | lib/elixir/src/elixir_errors.erl | 1 | ||||
-rw-r--r-- | lib/elixir/src/elixir_fn.erl | 6 | ||||
-rw-r--r-- | lib/elixir/src/elixir_for.erl | 182 | ||||
-rw-r--r-- | lib/elixir/src/elixir_map.erl | 26 | ||||
-rw-r--r-- | lib/elixir/src/elixir_quote.erl | 8 | ||||
-rw-r--r-- | lib/elixir/src/elixir_rewrite.erl | 25 | ||||
-rw-r--r-- | lib/elixir/src/elixir_scope.erl | 22 | ||||
-rw-r--r-- | lib/elixir/src/elixir_translator.erl | 46 | ||||
-rw-r--r-- | lib/elixir/src/elixir_try.erl | 6 | ||||
-rw-r--r-- | lib/elixir/src/elixir_utils.erl | 28 |
15 files changed, 218 insertions, 205 deletions
diff --git a/lib/elixir/src/elixir.hrl b/lib/elixir/src/elixir.hrl index cdfaa2b13..00b33b421 100644 --- a/lib/elixir/src/elixir.hrl +++ b/lib/elixir/src/elixir.hrl @@ -1,5 +1,7 @@ -define(m(M, K), maps:get(K, M)). +-define(ann(Opts), elixir_utils:get_ann(Opts)). -define(line(Opts), elixir_utils:get_line(Opts)). +-define(generated, [{generated, true}, {location, 0}]). -record(elixir_scope, { context=nil, %% can be match, guards or nil diff --git a/lib/elixir/src/elixir_bitstring.erl b/lib/elixir/src/elixir_bitstring.erl index a2a2fafc4..56aaa8e74 100644 --- a/lib/elixir/src/elixir_bitstring.erl +++ b/lib/elixir/src/elixir_bitstring.erl @@ -147,7 +147,7 @@ translate(Meta, Args, S) -> build_bitstr(Fun, Exprs, Meta, S) -> {Final, FinalS} = build_bitstr_each(Fun, Exprs, Meta, S, []), - {{bin, ?line(Meta), lists:reverse(Final)}, FinalS}. + {{bin, ?ann(Meta), lists:reverse(Final)}, FinalS}. build_bitstr_each(_Fun, [], _Meta, S, Acc) -> {Acc, S}; @@ -165,11 +165,11 @@ build_bitstr_each(Fun, T, Meta, S, Acc, H, default, Types) when is_binary(H) -> true -> %% See explanation in elixir_utils:elixir_to_erl/1 to know %% why we can simply convert the binary to a list. - {bin_element, ?line(Meta), {string, 0, binary_to_list(H)}, default, default}; + {bin_element, ?ann(Meta), {string, 0, binary_to_list(H)}, default, default}; false -> case types_require_conversion(Types) of true -> - {bin_element, ?line(Meta), {string, 0, elixir_utils:characters_to_list(H)}, default, Types}; + {bin_element, ?ann(Meta), {string, 0, elixir_utils:characters_to_list(H)}, default, Types}; false -> elixir_errors:compile_error(Meta, S#elixir_scope.file, "invalid types for literal string in <<>>. " "Accepted types are: little, big, utf8, utf16, utf32, bits, bytes, binary, bitstring") @@ -192,10 +192,10 @@ build_bitstr_each(Fun, T, Meta, S, Acc, H, Size, Types) -> {bin, _, Elements} -> case (Size == default) andalso types_allow_splice(Types, Elements) of true -> build_bitstr_each(Fun, T, Meta, NS, lists:reverse(Elements, Acc)); - false -> build_bitstr_each(Fun, T, Meta, NS, [{bin_element, ?line(Meta), Expr, Size, Types}|Acc]) + false -> build_bitstr_each(Fun, T, Meta, NS, [{bin_element, ?ann(Meta), Expr, Size, Types}|Acc]) end; _ -> - build_bitstr_each(Fun, T, Meta, NS, [{bin_element, ?line(Meta), Expr, Size, Types}|Acc]) + build_bitstr_each(Fun, T, Meta, NS, [{bin_element, ?ann(Meta), Expr, Size, Types}|Acc]) end. types_require_conversion([End|T]) when End == little; End == big -> types_require_conversion(T); diff --git a/lib/elixir/src/elixir_clauses.erl b/lib/elixir/src/elixir_clauses.erl index 63c9cd352..7267d4284 100644 --- a/lib/elixir/src/elixir_clauses.erl +++ b/lib/elixir/src/elixir_clauses.erl @@ -1,7 +1,7 @@ %% Handle code related to args, guard and -> matching for case, %% fn, receive and friends. try is handled in elixir_try. -module(elixir_clauses). --export([match/3, clause/6, clauses/3, guards/4, get_pairs/3, get_pairs/4, +-export([match/3, clause/6, clauses/3, guards/3, get_pairs/3, get_pairs/4, extract_splat_guards/1, extract_guards/1]). -include("elixir.hrl"). @@ -31,26 +31,26 @@ match(Fun, Args, S) -> Fun(Args, S). %% Translate clauses with args, guards and expressions -clause(Line, Fun, Args, Expr, Guards, S) when is_integer(Line) -> +clause(Meta, Fun, Args, Expr, Guards, S) when is_list(Meta) -> {TArgs, SA} = match(Fun, Args, S#elixir_scope{extra_guards=[]}), {TExpr, SE} = elixir_translator:translate(Expr, SA#elixir_scope{extra_guards=nil}), Extra = SA#elixir_scope.extra_guards, - TGuards = guards(Line, Guards, Extra, SA), - {{clause, Line, TArgs, TGuards, unblock(TExpr)}, SE}. + TGuards = guards(Guards, Extra, SA), + {{clause, ?ann(Meta), TArgs, TGuards, unblock(TExpr)}, SE}. % Translate/Extract guards from the given expression. -guards(Line, Guards, Extra, S) -> +guards(Guards, Extra, S) -> SG = S#elixir_scope{context=guard, extra_guards=nil}, case Guards of [] -> case Extra of [] -> []; _ -> [Extra] end; - _ -> [translate_guard(Line, Guard, Extra, SG) || Guard <- Guards] + _ -> [translate_guard(Guard, Extra, SG) || Guard <- Guards] end. -translate_guard(Line, Guard, Extra, S) -> - [element(1, elixir_translator:translate(elixir_quote:linify(Line, Guard), S))|Extra]. +translate_guard(Guard, Extra, S) -> + [element(1, elixir_translator:translate(Guard, S))|Extra]. extract_guards({'when', _, [Left, Right]}) -> {Left, extract_or_guards(Right)}; extract_guards(Else) -> {Else, []}. @@ -101,14 +101,14 @@ do_clauses(Meta, DecoupledClauses, S) -> % Expand all clauses by adding a match operation at the end % that defines variables missing in one clause to the others. - expand_clauses(?line(Meta), TClauses, CV, FinalVars, [], FS). + expand_clauses(?ann(Meta), TClauses, CV, FinalVars, [], FS). -expand_clauses(Line, [Clause|T], [ClauseVars|V], FinalVars, Acc, S) -> +expand_clauses(Ann, [Clause|T], [ClauseVars|V], FinalVars, Acc, S) -> case generate_match_vars(FinalVars, ClauseVars, [], []) of {[], []} -> - expand_clauses(Line, T, V, FinalVars, [Clause|Acc], S); + expand_clauses(Ann, T, V, FinalVars, [Clause|Acc], S); {Left, Right} -> - MatchExpr = generate_match(Line, Left, Right), + MatchExpr = generate_match(Ann, Left, Right), ClauseExprs = element(5, Clause), [Final|RawClauseExprs] = lists:reverse(ClauseExprs), @@ -122,8 +122,8 @@ expand_clauses(Line, [Clause|T], [ClauseVars|V], FinalVars, Acc, S) -> {[UserVar, MatchExpr, Final|RawClauseExprs], S}; _ -> {VarName, _, SS} = elixir_scope:build_var('_', S), - StorageVar = {var, Line, VarName}, - StorageExpr = {match, Line, StorageVar, Final}, + StorageVar = {var, Ann, VarName}, + StorageExpr = {match, Ann, StorageVar, Final}, {[StorageVar, MatchExpr, StorageExpr|RawClauseExprs], SS} end; false -> @@ -131,10 +131,10 @@ expand_clauses(Line, [Clause|T], [ClauseVars|V], FinalVars, Acc, S) -> end, FinalClause = setelement(5, Clause, lists:reverse(FinalClauseExprs)), - expand_clauses(Line, T, V, FinalVars, [FinalClause|Acc], FS) + expand_clauses(Ann, T, V, FinalVars, [FinalClause|Acc], FS) end; -expand_clauses(_Line, [], [], _FinalVars, Acc, S) -> +expand_clauses(_Ann, [], [], _FinalVars, Acc, S) -> {lists:reverse(Acc), S}. % Handle each key/value clause pair and translate them accordingly. @@ -142,12 +142,12 @@ expand_clauses(_Line, [], [], _FinalVars, Acc, S) -> each_clause(Export, {match, Meta, [Condition], Expr}, S) -> Fun = wrap_export_fun(Export, fun elixir_translator:translate_args/2), {Arg, Guards} = extract_guards(Condition), - clause(?line(Meta), Fun, [Arg], Expr, Guards, S); + clause(Meta, Fun, [Arg], Expr, Guards, S); each_clause(Export, {expr, Meta, [Condition], Expr}, S) -> {TCondition, SC} = (wrap_export_fun(Export, fun elixir_translator:translate/2))(Condition, S), {TExpr, SB} = elixir_translator:translate(Expr, SC), - {{clause, ?line(Meta), [TCondition], [], unblock(TExpr)}, SB}. + {{clause, ?ann(Meta), [TCondition], [], unblock(TExpr)}, SB}. wrap_export_fun(Meta, Fun) -> case lists:keyfind(export_head, 1, Meta) of @@ -216,11 +216,11 @@ generate_match_vars([{Key, Value, Expr}|T], ClauseVars, Left, Right) -> generate_match_vars([], _ClauseVars, Left, Right) -> {Left, Right}. -generate_match(Line, [Left], [Right]) -> - {match, Line, Left, Right}; +generate_match(Ann, [Left], [Right]) -> + {match, Ann, Left, Right}; -generate_match(Line, LeftVars, RightVars) -> - {match, Line, {tuple, Line, LeftVars}, {tuple, Line, RightVars}}. +generate_match(Ann, LeftVars, RightVars) -> + {match, Ann, {tuple, Ann, LeftVars}, {tuple, Ann, RightVars}}. unblock({'block', _, Exprs}) -> Exprs; unblock(Exprs) -> [Exprs]. diff --git a/lib/elixir/src/elixir_def.erl b/lib/elixir/src/elixir_def.erl index 4447dcfe6..0d60817a7 100644 --- a/lib/elixir/src/elixir_def.erl +++ b/lib/elixir/src/elixir_def.erl @@ -34,7 +34,7 @@ delete_definition(Module, Tuple) -> % Invoked by the wrap definition with the function abstract tree. % Each function is then added to the function table. -store_definition(Line, Kind, CheckClauses, Call, Body, Pos) -> +store_definition(Line, Kind, CheckClauses, Call, Body, Pos) when is_integer(Line) -> E = (elixir_locals:get_cached_env(Pos))#{line := Line}, {NameAndArgs, Guards} = elixir_clauses:extract_guards(Call), @@ -156,7 +156,10 @@ translate_definition(Kind, Line, Name, Args, Guards, Body, E) when is_integer(Li {EArgs, EGuards, EBody, _} = elixir_exp_clauses:def(fun elixir_def_defaults:expand/2, Args, Guards, expr_from_body(Line, Body), E), - Body == nil andalso check_args_for_bodyless_clause(Line, EArgs, E), + case Body of + nil -> check_args_for_bodyless_clause(Line, EArgs, E); + _ -> ok + end, S = elixir_env:env_to_scope(E), {Unpacked, Defaults} = elixir_def_defaults:unpack(Kind, Name, EArgs, S), @@ -170,7 +173,7 @@ translate_clause(nil, _Line, _Kind, _Args, [], _Body, _S) -> translate_clause(nil, Line, Kind, _Args, _Guards, _Body, #elixir_scope{file=File}) -> elixir_errors:form_error([{line, Line}], File, ?MODULE, {missing_do, Kind}); translate_clause(_, Line, Kind, Args, Guards, Body, S) -> - {TClause, TS} = elixir_clauses:clause(Line, + {TClause, TS} = elixir_clauses:clause([{line, Line}], fun elixir_translator:translate_args/2, Args, Body, Guards, S), FClause = case is_macro(Kind) of diff --git a/lib/elixir/src/elixir_def_defaults.erl b/lib/elixir/src/elixir_def_defaults.erl index 874ca38cb..cf57f178a 100644 --- a/lib/elixir/src/elixir_def_defaults.erl +++ b/lib/elixir/src/elixir_def_defaults.erl @@ -29,14 +29,14 @@ unpack_each(Kind, Name, [{'\\\\', DefMeta, [Expr, _]}|T] = List, Acc, Clauses, S {DefArgs, SA} = elixir_clauses:match(fun elixir_translator:translate_args/2, Base ++ Args, S), {DefInvoke, _} = elixir_translator:translate_args(Base ++ Invoke, SA), - Line = ?line(DefMeta), + Ann = ?ann(DefMeta), - Call = {call, Line, - {atom, Line, name_for_kind(Kind, Name)}, + Call = {call, Ann, + {atom, Ann, name_for_kind(Kind, Name)}, DefInvoke }, - Clause = {clause, Line, DefArgs, [], [Call]}, + Clause = {clause, Ann, DefArgs, [], [Call]}, unpack_each(Kind, Name, T, [Expr|Acc], [Clause|Clauses], S); unpack_each(Kind, Name, [H|T], Acc, Clauses, S) -> diff --git a/lib/elixir/src/elixir_errors.erl b/lib/elixir/src/elixir_errors.erl index 43505099d..6b7f6cc85 100644 --- a/lib/elixir/src/elixir_errors.erl +++ b/lib/elixir/src/elixir_errors.erl @@ -99,7 +99,6 @@ parse_erl_term(Term) -> {ok, Parsed} = erl_parse:parse_term(Tokens ++ [{dot, 1}]), Parsed. - %% Handle warnings and errors from Erlang land (called during module compilation) %% Ignore on bootstrap diff --git a/lib/elixir/src/elixir_fn.erl b/lib/elixir/src/elixir_fn.erl index 4d26d9e2a..2286526c6 100644 --- a/lib/elixir/src/elixir_fn.erl +++ b/lib/elixir/src/elixir_fn.erl @@ -6,8 +6,8 @@ translate(Meta, Clauses, S) -> Transformer = fun({'->', CMeta, [ArgsWithGuards, Expr]}, Acc) -> {Args, Guards} = elixir_clauses:extract_splat_guards(ArgsWithGuards), - {TClause, TS } = elixir_clauses:clause(?line(CMeta), fun translate_fn_match/2, - Args, Expr, Guards, Acc), + {TClause, TS } = elixir_clauses:clause(CMeta, fun translate_fn_match/2, + Args, Expr, Guards, Acc), {TClause, elixir_scope:mergef(S, TS)} end, @@ -16,7 +16,7 @@ translate(Meta, Clauses, S) -> case lists:usort(Arities) of [_] -> - {{'fun', ?line(Meta), {clauses, TClauses}}, NS}; + {{'fun', ?ann(Meta), {clauses, TClauses}}, NS}; _ -> compile_error(Meta, S#elixir_scope.file, "cannot mix clauses with different arities in function definition") diff --git a/lib/elixir/src/elixir_for.erl b/lib/elixir/src/elixir_for.erl index d2893cf69..636b12d90 100644 --- a/lib/elixir/src/elixir_for.erl +++ b/lib/elixir/src/elixir_for.erl @@ -53,16 +53,16 @@ translate(Meta, Args, Return, S) -> {AccName, _, SA} = elixir_scope:build_var('_', S), {VarName, _, SV} = elixir_scope:build_var('_', SA), - Line = ?line(Meta), - Acc = {var, Line, AccName}, - Var = {var, Line, VarName}, + Ann = ?ann(Meta), + Acc = {var, Ann, AccName}, + Var = {var, Ann, VarName}, {Cases, [{do, Expr}|Opts]} = elixir_utils:split_last(Args), {TInto, SI} = case lists:keyfind(into, 1, Opts) of {into, Into} -> elixir_translator:translate(Into, SV); - false when Return -> {{nil, Line}, SV}; + false when Return -> {{nil, Ann}, SV}; false -> {false, SV} end, @@ -72,9 +72,9 @@ translate(Meta, Args, Return, S) -> case comprehension_expr(TInto, TExpr) of {inline, TIntoExpr} -> - {build_inline(Line, TCases, TIntoExpr, TInto, Var, Acc, SE), SF}; + {build_inline(Ann, TCases, TIntoExpr, TInto, Var, Acc, SE), SF}; {into, TIntoExpr} -> - build_into(Line, TCases, TIntoExpr, TInto, Var, Acc, SF) + build_into(Ann, TCases, TIntoExpr, TInto, Var, Acc, SF) end. translate_gen(ForMeta, [{'<-', Meta, [Left, Right]}|T], Acc, S) -> @@ -125,56 +125,56 @@ collect_filters([H|T], Acc) -> collect_filters([], Acc) -> {Acc, []}. -build_inline(Line, Clauses, Expr, Into, _Var, Acc, S) -> +build_inline(Ann, Clauses, Expr, Into, _Var, Acc, S) -> case lists:all(fun(Clause) -> element(1, Clause) == bin end, Clauses) of - true -> build_comprehension(Line, Clauses, Expr, Into); + true -> build_comprehension(Ann, Clauses, Expr, Into); false -> build_reduce(Clauses, Expr, Into, Acc, S) end. -build_into(Line, Clauses, Expr, Into, Fun, Acc, S) -> - {Kind, SK} = build_var(Line, S), - {Reason, SR} = build_var(Line, SK), - {Stack, ST} = build_var(Line, SR), - {Done, SD} = build_var(Line, ST), +build_into(Ann, Clauses, Expr, Into, Fun, Acc, S) -> + {Kind, SK} = build_var(Ann, S), + {Reason, SR} = build_var(Ann, SK), + {Stack, ST} = build_var(Ann, SR), + {Done, SD} = build_var(Ann, ST), - IntoExpr = {call, Line, Fun, [Acc, pair(Line, cont, Expr)]}, - MatchExpr = {match, Line, - {tuple, Line, [Acc, Fun]}, - elixir_utils:erl_call(Line, 'Elixir.Collectable', into, [Into]) + IntoExpr = {call, Ann, Fun, [Acc, pair(Ann, cont, Expr)]}, + MatchExpr = {match, Ann, + {tuple, Ann, [Acc, Fun]}, + elixir_utils:erl_call(Ann, 'Elixir.Collectable', into, [Into]) }, TryExpr = - {'try', Line, + {'try', Ann, [build_reduce_clause(Clauses, IntoExpr, Acc, Acc, SD)], - [{clause, Line, + [{clause, Ann, [Done], [], - [{call, Line, Fun, [Done, {atom, Line, done}]}]}], - [{clause, Line, - [{tuple, Line, [Kind, Reason, {var, Line, '_'}]}], + [{call, Ann, Fun, [Done, {atom, Ann, done}]}]}], + [{clause, Ann, + [{tuple, Ann, [Kind, Reason, {var, Ann, '_'}]}], [], - [{match, Line, Stack, elixir_utils:erl_call(Line, erlang, get_stacktrace, [])}, - {call, Line, Fun, [Acc, {atom, Line, halt}]}, - elixir_utils:erl_call(Line, erlang, raise, [Kind, Reason, Stack])]}], + [{match, Ann, Stack, elixir_utils:erl_call(Ann, erlang, get_stacktrace, [])}, + {call, Ann, Fun, [Acc, {atom, Ann, halt}]}, + elixir_utils:erl_call(Ann, erlang, raise, [Kind, Reason, Stack])]}], []}, - {{block, Line, [MatchExpr, TryExpr]}, SD}. + {{block, Ann, [MatchExpr, TryExpr]}, SD}. %% Helpers build_reduce(Clauses, Expr, false, Acc, S) -> build_reduce_clause(Clauses, Expr, {nil, 0}, Acc, S); -build_reduce(Clauses, Expr, {nil, Line} = Into, Acc, S) -> - ListExpr = {cons, Line, Expr, Acc}, - elixir_utils:erl_call(Line, lists, reverse, +build_reduce(Clauses, Expr, {nil, Ann} = Into, Acc, S) -> + ListExpr = {cons, Ann, Expr, Acc}, + elixir_utils:erl_call(Ann, lists, reverse, [build_reduce_clause(Clauses, ListExpr, Into, Acc, S)]); build_reduce(Clauses, Expr, {bin, _, _} = Into, Acc, S) -> - {bin, Line, Elements} = Expr, - BinExpr = {bin, Line, [{bin_element, Line, Acc, default, [bitstring]}|Elements]}, + {bin, Ann, Elements} = Expr, + BinExpr = {bin, Ann, [{bin_element, Ann, Acc, default, [bitstring]}|Elements]}, build_reduce_clause(Clauses, BinExpr, Into, Acc, S). build_reduce_clause([{enum, Meta, Left, Right, Filters}|T], Expr, Arg, Acc, S) -> - Line = ?line(Meta), + Ann = ?ann(Meta), True = build_reduce_clause(T, Expr, Acc, Acc, S), False = Acc, @@ -182,23 +182,23 @@ build_reduce_clause([{enum, Meta, Left, Right, Filters}|T], Expr, Arg, Acc, S) - case is_var(Left) of true -> []; false -> - [{clause, -1, - [{var, Line, '_'}, Acc], [], + [{clause, ?generated, + [{var, Ann, '_'}, Acc], [], [False]}] end, Clauses1 = - [{clause, Line, + [{clause, Ann, [Left, Acc], [], - [join_filters(Line, Filters, True, False)]}|Clauses0], + [join_filters(Ann, Filters, True, False)]}|Clauses0], - Args = [Right, Arg, {'fun', Line, {clauses, Clauses1}}], - elixir_utils:erl_call(Line, 'Elixir.Enum', reduce, Args); + Args = [Right, Arg, {'fun', Ann, {clauses, Clauses1}}], + elixir_utils:erl_call(Ann, 'Elixir.Enum', reduce, Args); build_reduce_clause([{bin, Meta, Left, Right, Filters}|T], Expr, Arg, Acc, S) -> - Line = ?line(Meta), - {Tail, ST} = build_var(Line, S), - {Fun, SF} = build_var(Line, ST), + Ann = ?ann(Meta), + {Tail, ST} = build_var(Ann, S), + {Fun, SF} = build_var(Ann, ST), True = build_reduce_clause(T, Expr, Acc, Acc, SF), False = Acc, @@ -206,26 +206,26 @@ build_reduce_clause([{bin, Meta, Left, Right, Filters}|T], Expr, Arg, Acc, S) -> {bin, _, Elements} = Left, BinMatch = - {bin, Line, Elements ++ [{bin_element, Line, Tail, default, [bitstring]}]}, + {bin, Ann, Elements ++ [{bin_element, Ann, Tail, default, [bitstring]}]}, NoVarMatch = - {bin, Line, no_var(Elements) ++ [{bin_element, Line, Tail, default, [bitstring]}]}, + {bin, Ann, no_var(Elements) ++ [{bin_element, Ann, Tail, default, [bitstring]}]}, Clauses = - [{clause, Line, + [{clause, Ann, [BinMatch, Acc], [], - [{call, Line, Fun, [Tail, join_filters(Line, Filters, True, False)]}]}, - {clause, -1, + [{call, Ann, Fun, [Tail, join_filters(Ann, Filters, True, False)]}]}, + {clause, ?generated, [NoVarMatch, Acc], [], - [{call, Line, Fun, [Tail, False]}]}, - {clause, -1, - [{bin, Line, []}, Acc], [], + [{call, Ann, Fun, [Tail, False]}]}, + {clause, ?generated, + [{bin, Ann, []}, Acc], [], [Acc]}, - {clause, -1, - [Tail, {var, Line, '_'}], [], - [elixir_utils:erl_call(Line, erlang, error, [pair(Line, badarg, Tail)])]}], + {clause, ?generated, + [Tail, {var, Ann, '_'}], [], + [elixir_utils:erl_call(Ann, erlang, error, [pair(Ann, badarg, Tail)])]}], - {call, Line, - {named_fun, Line, element(3, Fun), Clauses}, + {call, Ann, + {named_fun, Ann, element(3, Fun), Clauses}, [Right, Arg]}; build_reduce_clause([], Expr, _Arg, _Acc, _S) -> @@ -234,31 +234,31 @@ build_reduce_clause([], Expr, _Arg, _Acc, _S) -> is_var({var, _, _}) -> true; is_var(_) -> false. -pair(Line, Atom, Arg) -> - {tuple, Line, [{atom, Line, Atom}, Arg]}. +pair(Ann, Atom, Arg) -> + {tuple, Ann, [{atom, Ann, Atom}, Arg]}. -build_var(Line, S) -> +build_var(Ann, S) -> {Name, _, ST} = elixir_scope:build_var('_', S), - {{var, Line, Name}, ST}. + {{var, Ann, Name}, ST}. no_var(Elements) -> - [{bin_element, Line, no_var_expr(Expr), Size, Types} || - {bin_element, Line, Expr, Size, Types} <- Elements]. -no_var_expr({var, Line, _}) -> - {var, Line, '_'}. - -build_comprehension(Line, Clauses, Expr, false) -> - {block, Line, [ - build_comprehension(Line, Clauses, Expr, {nil, Line}), - {nil, Line} + [{bin_element, Ann, no_var_expr(Expr), Size, Types} || + {bin_element, Ann, Expr, Size, Types} <- Elements]. +no_var_expr({var, Ann, _}) -> + {var, Ann, '_'}. + +build_comprehension(Ann, Clauses, Expr, false) -> + {block, Ann, [ + build_comprehension(Ann, Clauses, Expr, {nil, Ann}), + {nil, Ann} ]}; -build_comprehension(Line, Clauses, Expr, Into) -> - {comprehension_kind(Into), Line, Expr, comprehension_clause(Clauses)}. +build_comprehension(Ann, Clauses, Expr, Into) -> + {comprehension_kind(Into), Ann, Expr, comprehension_clause(Clauses)}. comprehension_clause([{Kind, Meta, Left, Right, Filters}|T]) -> - Line = ?line(Meta), - [{comprehension_generator(Kind), Line, Left, Right}] ++ - comprehension_filter(Line, Filters) ++ + Ann = ?ann(Meta), + [{comprehension_generator(Kind), Ann, Left, Right}] ++ + comprehension_filter(Ann, Filters) ++ comprehension_clause(T); comprehension_clause([]) -> []. @@ -271,8 +271,8 @@ comprehension_generator(bin) -> b_generate. comprehension_expr({bin, _, []}, {bin, _, _} = Expr) -> {inline, Expr}; -comprehension_expr({bin, Line, []}, Expr) -> - BinExpr = {bin, Line, [{bin_element, Line, Expr, default, [bitstring]}]}, +comprehension_expr({bin, Ann, []}, Expr) -> + BinExpr = {bin, Ann, [{bin_element, Ann, Expr, default, [bitstring]}]}, {inline, BinExpr}; comprehension_expr({nil, _}, Expr) -> {inline, Expr}; @@ -281,29 +281,29 @@ comprehension_expr(false, Expr) -> comprehension_expr(_, Expr) -> {into, Expr}. -comprehension_filter(Line, Filters) -> - [join_filter(Line, Filter, {atom, Line, true}, {atom, Line, false}) || +comprehension_filter(Ann, Filters) -> + [join_filter(Ann, Filter, {atom, Ann, true}, {atom, Ann, false}) || Filter <- lists:reverse(Filters)]. -join_filters(_Line, [], True, _False) -> +join_filters(_Ann, [], True, _False) -> True; -join_filters(Line, [H|T], True, False) -> +join_filters(Ann, [H|T], True, False) -> lists:foldl(fun(Filter, Acc) -> - join_filter(Line, Filter, Acc, False) - end, join_filter(Line, H, True, False), T). + join_filter(Ann, Filter, Acc, False) + end, join_filter(Ann, H, True, False), T). -join_filter(Line, {nil, Filter}, True, False) -> - {'case', Line, Filter, [ - {clause, Line, [{atom, Line, true}], [], [True]}, - {clause, Line, [{atom, Line, false}], [], [False]} +join_filter(Ann, {nil, Filter}, True, False) -> + {'case', Ann, Filter, [ + {clause, Ann, [{atom, Ann, true}], [], [True]}, + {clause, Ann, [{atom, Ann, false}], [], [False]} ]}; -join_filter(Line, {Var, Filter}, True, False) -> +join_filter(Ann, {Var, Filter}, True, False) -> Guard = - {op, Line, 'orelse', - {op, Line, '==', Var, {atom, Line, false}}, - {op, Line, '==', Var, {atom, Line, nil}}}, + {op, Ann, 'orelse', + {op, Ann, '==', Var, {atom, Ann, false}}, + {op, Ann, '==', Var, {atom, Ann, nil}}}, - {'case', Line, Filter, [ - {clause, Line, [Var], [[Guard]], [False]}, - {clause, Line, [{var, Line, '_'}], [], [True]} + {'case', Ann, Filter, [ + {clause, Ann, [Var], [[Guard]], [False]}, + {clause, Ann, [{var, Ann, '_'}], [], [True]} ]}. diff --git a/lib/elixir/src/elixir_map.erl b/lib/elixir/src/elixir_map.erl index 2371cba81..43a186a66 100644 --- a/lib/elixir/src/elixir_map.erl +++ b/lib/elixir/src/elixir_map.erl @@ -67,20 +67,20 @@ translate_struct(Meta, Name, {'%{}', MapMeta, Args}, S) -> if TUpdate /= nil -> - Line = ?line(Meta), + Ann = ?ann(Meta), {VarName, _, VS} = elixir_scope:build_var('_', US), - Var = {var, Line, VarName}, - Map = {map, Line, [{map_field_exact, Line, {atom, Line, '__struct__'}, {atom, Line, Name}}]}, + Var = {var, Ann, VarName}, + Map = {map, Ann, [{map_field_exact, Ann, {atom, Ann, '__struct__'}, {atom, Ann, Name}}]}, - Match = {match, Line, Var, Map}, - Error = {tuple, Line, [{atom, Line, badstruct}, {atom, Line, Name}, Var]}, + Match = {match, Ann, Var, Map}, + Error = {tuple, Ann, [{atom, Ann, badstruct}, {atom, Ann, Name}, Var]}, {TMap, TS} = translate_map(MapMeta, Assocs, Var, VS), - {{'case', Line, TUpdate, [ - {clause, Line, [Match], [], [TMap]}, - {clause, Line, [Var], [], [elixir_utils:erl_call(Line, erlang, error, [Error])]} + {{'case', Ann, TUpdate, [ + {clause, Ann, [Match], [], [TMap]}, + {clause, Ann, [Var], [], [elixir_utils:erl_call(Ann, erlang, error, [Error])]} ]}, TS}; S#elixir_scope.context == match -> translate_map(MapMeta, Assocs ++ [{'__struct__', Name}], nil, US); @@ -151,15 +151,15 @@ wait_for_struct(Module) -> translate_map(Meta, Assocs, TUpdate, #elixir_scope{extra=Extra} = S) -> {Op, KeyFun, ValFun} = extract_key_val_op(TUpdate, S), - Line = ?line(Meta), + Ann = ?ann(Meta), {TArgs, SA} = lists:mapfoldl(fun({Key, Value}, Acc) -> {TKey, Acc1} = KeyFun(Key, Acc), {TValue, Acc2} = ValFun(Value, Acc1#elixir_scope{extra=Extra}), - {{Op, ?line(Meta), TKey, TValue}, Acc2} + {{Op, ?ann(Meta), TKey, TValue}, Acc2} end, S, Assocs), - build_map(Line, TUpdate, TArgs, SA). + build_map(Ann, TUpdate, TArgs, SA). extract_assoc_update([{'|', _Meta, [Update, Args]}], S) -> {TArg, SA} = elixir_translator:translate_arg(Update, S, S), @@ -177,8 +177,8 @@ extract_key_val_op(TUpdate, S) -> fun(X, Acc) -> elixir_translator:translate_arg(X, Acc, KS) end, fun(X, Acc) -> elixir_translator:translate_arg(X, Acc, S) end}. -build_map(Line, nil, TArgs, SA) -> {{map, Line, TArgs}, SA}; -build_map(Line, TUpdate, TArgs, SA) -> {{map, Line, TUpdate, TArgs}, SA}. +build_map(Ann, nil, TArgs, SA) -> {{map, Ann, TArgs}, SA}; +build_map(Ann, TUpdate, TArgs, SA) -> {{map, Ann, TUpdate, TArgs}, SA}. assert_struct_keys(Meta, Name, Struct, Assocs, S) -> [begin diff --git a/lib/elixir/src/elixir_quote.erl b/lib/elixir/src/elixir_quote.erl index 9f723c963..91587239d 100644 --- a/lib/elixir/src/elixir_quote.erl +++ b/lib/elixir/src/elixir_quote.erl @@ -52,10 +52,10 @@ do_linify_meta(Line, line, Meta) -> _ -> keystore(line, Meta, Line) end; -do_linify_meta(Line, Key, Meta) -> - case keyfind(Key, Meta) of - {Key, Int} when is_integer(Int), Int /= 0 -> - keyreplace(Key, Meta, {line, Int}); +do_linify_meta(Line, keep, Meta) -> + case keyfind(keep, Meta) of + {keep, Int} when is_integer(Int), Int /= 0 -> + keyreplace(keep, keydelete(line, Meta), {line, Int}); _ -> do_linify_meta(Line, line, Meta) end. diff --git a/lib/elixir/src/elixir_rewrite.erl b/lib/elixir/src/elixir_rewrite.erl index 0ea55d6f2..d37099bf9 100644 --- a/lib/elixir/src/elixir_rewrite.erl +++ b/lib/elixir/src/elixir_rewrite.erl @@ -1,10 +1,9 @@ -module(elixir_rewrite). -export([rewrite/5, inline/3]). +-include("elixir.hrl"). %% Convenience variables --define(hidden, [{line, -1}]). - -define(atom, 'Elixir.Atom'). -define(enum, 'Elixir.Enum'). -define(float, 'Elixir.Float'). @@ -160,27 +159,27 @@ inline(_, _, _) -> false. rewrite(?string_chars, _DotMeta, 'to_string', _Meta, [String]) when is_binary(String) -> String; rewrite(?string_chars, DotMeta, 'to_string', Meta, [String]) -> - Var = {'rewrite', Meta, 'Elixir'}, - Guard = {{'.', Meta, [erlang, is_binary]}, Meta, [Var]}, + Var = {'rewrite', ?generated, 'Elixir'}, + Guard = {{'.', ?generated, [erlang, is_binary]}, ?generated, [Var]}, Slow = remote(?string_chars, DotMeta, 'to_string', Meta, [Var]), Fast = Var, - {'case', ?hidden, [String, [{do, - [{'->', ?hidden, [[{'when', Meta, [Var, Guard]}], Fast]}, - {'->', ?hidden, [[Var], Slow]}] + {'case', ?generated, [String, [{do, + [{'->', ?generated, [[{'when', ?generated, [Var, Guard]}], Fast]}, + {'->', ?generated, [[Var], Slow]}] }]]}; rewrite(?enum, DotMeta, 'reverse', Meta, [List]) when is_list(List) -> remote(lists, DotMeta, 'reverse', Meta, [List]); rewrite(?enum, DotMeta, 'reverse', Meta, [List]) -> - Var = {'rewrite', Meta, 'Elixir'}, - Guard = {{'.', Meta, [erlang, is_list]}, Meta, [Var]}, + Var = {'rewrite', ?generated, 'Elixir'}, + Guard = {{'.', ?generated, [erlang, is_list]}, ?generated, [Var]}, Slow = remote(?enum, DotMeta, 'reverse', Meta, [Var]), - Fast = remote(lists, Meta, 'reverse', Meta, [Var]), + Fast = remote(lists, DotMeta, 'reverse', Meta, [Var]), - {'case', ?hidden, [List, [{do, - [{'->', ?hidden, [[{'when', Meta, [Var, Guard]}], Fast]}, - {'->', ?hidden, [[Var], Slow]}] + {'case', ?generated, [List, [{do, + [{'->', ?generated, [[{'when', ?generated, [Var, Guard]}], Fast]}, + {'->', ?generated, [[Var], Slow]}] }]]}; rewrite(Receiver, DotMeta, Right, Meta, Args) -> diff --git a/lib/elixir/src/elixir_scope.erl b/lib/elixir/src/elixir_scope.erl index c27debb71..71a684b2a 100644 --- a/lib/elixir/src/elixir_scope.erl +++ b/lib/elixir/src/elixir_scope.erl @@ -11,9 +11,9 @@ %% VAR HANDLING translate_var(Meta, Name, Kind, S) when is_atom(Kind); is_integer(Kind) -> - Line = ?line(Meta), + Ann = ?ann(Meta), Tuple = {Name, Kind}, - Vars = S#elixir_scope.vars, + Vars = S#elixir_scope.vars, case orddict:find({Name, Kind}, Vars) of {ok, {Current, _}} -> Exists = true; @@ -26,8 +26,8 @@ translate_var(Meta, Name, Kind, S) when is_atom(Kind); is_integer(Kind) -> case Exists andalso ordsets:is_element(Tuple, MatchVars) of true -> - warn_underscored_var_repeat(Line, Meta, S#elixir_scope.file, Name, Kind), - {{var, Line, Current}, S}; + warn_underscored_var_repeat(Meta, S#elixir_scope.file, Name, Kind), + {{var, Ann, Current}, S}; false -> %% We attempt to give vars a nice name because we %% still use the unused vars warnings from erl_lint. @@ -51,11 +51,11 @@ translate_var(Meta, Name, Kind, S) when is_atom(Kind); is_integer(Kind) -> end }, - {{var, Line, NewVar}, FS} + {{var, Ann, NewVar}, FS} end; _ when Exists -> - warn_underscored_var_access(Line, Meta, S#elixir_scope.file, Name), - {{var, Line, Current}, S} + warn_underscored_var_access(Meta, S#elixir_scope.file, Name), + {{var, Ann, Current}, S} end. build_var(Key, S) -> @@ -66,24 +66,24 @@ build_var(Key, S) -> context_info(Kind) when Kind == nil; is_integer(Kind) -> ""; context_info(Kind) -> io_lib:format(" (context ~ts)", [elixir_aliases:inspect(Kind)]). -warn_underscored_var_repeat(Line, Meta, File, Name, Kind) -> +warn_underscored_var_repeat(Meta, File, Name, Kind) -> Warn = should_warn(Meta), case atom_to_list(Name) of "_@" ++ _ -> ok; %% Automatically generated variables "_" ++ _ when Warn -> - elixir_errors:form_warn([{line, Line}], File, ?MODULE, {unused_match, Name, Kind}); + elixir_errors:form_warn(Meta, File, ?MODULE, {unused_match, Name, Kind}); _ -> ok end. -warn_underscored_var_access(Line, Meta, File, Name) -> +warn_underscored_var_access(Meta, File, Name) -> Warn = should_warn(Meta), case atom_to_list(Name) of "_@" ++ _ -> ok; %% Automatically generated variables "_" ++ _ when Warn -> - elixir_errors:form_warn([{line, Line}], File, ?MODULE, {underscore_var_access, Name}); + elixir_errors:form_warn(Meta, File, ?MODULE, {underscore_var_access, Name}); _ -> ok end. diff --git a/lib/elixir/src/elixir_translator.erl b/lib/elixir/src/elixir_translator.erl index 145aa9c1b..ef90da531 100644 --- a/lib/elixir/src/elixir_translator.erl +++ b/lib/elixir/src/elixir_translator.erl @@ -10,18 +10,18 @@ translate({'=', Meta, [{'_', _, Atom}, Right]}, S) when is_atom(Atom) -> {TRight, SR} = translate(Right, S), - {{match, ?line(Meta), {var, ?line(Meta), '_'}, TRight}, SR}; + {{match, ?ann(Meta), {var, ?ann(Meta), '_'}, TRight}, SR}; translate({'=', Meta, [Left, Right]}, S) -> {TRight, SR} = translate(Right, S), {TLeft, SL} = elixir_clauses:match(fun translate/2, Left, SR), - {{match, ?line(Meta), TLeft, TRight}, SL}; + {{match, ?ann(Meta), TLeft, TRight}, SL}; %% Containers translate({'{}', Meta, Args}, S) when is_list(Args) -> {TArgs, SE} = translate_args(Args, S), - {{tuple, ?line(Meta), TArgs}, SE}; + {{tuple, ?ann(Meta), TArgs}, SE}; translate({'%{}', Meta, Args}, S) when is_list(Args) -> elixir_map:translate_map(Meta, Args, S); @@ -36,17 +36,17 @@ translate({'<<>>', Meta, Args}, S) when is_list(Args) -> translate({'__block__', Meta, Args}, S) when is_list(Args) -> {TArgs, SA} = translate_block(Args, [], S), - {{block, ?line(Meta), TArgs}, SA}; + {{block, ?ann(Meta), TArgs}, SA}; %% Erlang op translate({{'.', _, [erlang, 'andalso']}, Meta, [Left, Right]}, S) -> {[TLeft, TRight], NS} = translate_args([Left, Right], S), - {{op, ?line(Meta), 'andalso', TLeft, TRight}, NS}; + {{op, ?ann(Meta), 'andalso', TLeft, TRight}, NS}; translate({{'.', _, [erlang, 'orelse']}, Meta, [Left, Right]}, S) -> {[TLeft, TRight], NS} = translate_args([Left, Right], S), - {{op, ?line(Meta), 'orelse', TLeft, TRight}, NS}; + {{op, ?ann(Meta), 'orelse', TLeft, TRight}, NS}; %% Lexical @@ -56,13 +56,13 @@ translate({Lexical, _, [_, _]}, S) when Lexical == import; Lexical == alias; Lex %% Pseudo variables translate({'__CALLER__', Meta, Atom}, S) when is_atom(Atom) -> - {{var, ?line(Meta), '__CALLER__'}, S#elixir_scope{caller=true}}; + {{var, ?ann(Meta), '__CALLER__'}, S#elixir_scope{caller=true}}; %% Functions translate({'&', Meta, [{'/', [], [{Fun, [], Atom}, Arity]}]}, S) when is_atom(Fun), is_atom(Atom), is_integer(Arity) -> - {{'fun', ?line(Meta), {function, Fun, Arity}}, S}; + {{'fun', ?ann(Meta), {function, Fun, Arity}}, S}; translate({'&', Meta, [Arg]}, S) when is_integer(Arg) -> compile_error(Meta, S#elixir_scope.file, "unhandled &~B outside of a capture", [Arg]); @@ -95,7 +95,7 @@ translate({'case', Meta, [Expr, KV]}, S) -> Clauses = elixir_clauses:get_pairs(do, KV, match), {TExpr, NS} = translate(Expr, S), {TClauses, TS} = elixir_clauses:clauses(Meta, Clauses, NS), - {{'case', ?line(Meta), TExpr, TClauses}, TS}; + {{'case', ?ann(Meta), TExpr, TClauses}, TS}; %% Try @@ -119,7 +119,7 @@ translate({'try', Meta, [Clauses]}, RS) -> {TElse, SE} = elixir_clauses:clauses(Meta, Else, mergec(S, SA)), SF = (mergec(S, SE))#elixir_scope{noname=RS#elixir_scope.noname}, - {{'try', ?line(Meta), unblock(TDo), TElse, TCatch, TAfter}, SF}; + {{'try', ?ann(Meta), unblock(TDo), TElse, TCatch, TAfter}, SF}; %% Receive @@ -129,13 +129,13 @@ translate({'receive', Meta, [KV]}, S) -> case lists:keyfind('after', 1, KV) of false -> {TClauses, SC} = elixir_clauses:clauses(Meta, Do, S), - {{'receive', ?line(Meta), TClauses}, SC}; + {{'receive', ?ann(Meta), TClauses}, SC}; _ -> After = elixir_clauses:get_pairs('after', KV, expr), {TClauses, SC} = elixir_clauses:clauses(Meta, Do ++ After, S), {FClauses, TAfter} = elixir_utils:split_last(TClauses), {_, _, [FExpr], _, FAfter} = TAfter, - {{'receive', ?line(Meta), FClauses, FExpr, FAfter}, SC} + {{'receive', ?ann(Meta), FClauses, FExpr, FAfter}, SC} end; %% Comprehensions @@ -161,7 +161,7 @@ translate({super, Meta, Args}, S) when is_list(Args) -> end, Super = elixir_def_overridable:name(Module, Function), - {{call, ?line(Meta), {atom, ?line(Meta), Super}, TArgs}, TS#elixir_scope{super=true}}; + {{call, ?ann(Meta), {atom, ?ann(Meta), Super}, TArgs}, TS#elixir_scope{super=true}}; %% Variables @@ -169,13 +169,13 @@ translate({'^', Meta, [{Name, VarMeta, Kind}]}, #elixir_scope{context=match} = S Tuple = {Name, var_kind(VarMeta, Kind)}, case orddict:find(Tuple, S#elixir_scope.backup_vars) of {ok, {Value, _Counter}} -> - {{var, ?line(Meta), Value}, S}; + {{var, ?ann(Meta), Value}, S}; error -> compile_error(Meta, S#elixir_scope.file, "unbound variable ^~ts", [Name]) end; translate({'_', Meta, Kind}, #elixir_scope{context=match} = S) when is_atom(Kind) -> - {{var, ?line(Meta), '_'}, S}; + {{var, ?ann(Meta), '_'}, S}; translate({'_', Meta, Kind}, S) when is_atom(Kind) -> compile_error(Meta, S#elixir_scope.file, "unbound variable _"); @@ -203,7 +203,7 @@ translate({Name, Meta, Args}, S) when is_atom(Name), is_list(Meta), is_list(Args [Name, Arity]) end; true -> - Line = ?line(Meta), + Line = ?ann(Meta), {TArgs, NS} = translate_args(Args, S), {{call, Line, {atom, Line, Name}, TArgs}, NS} end; @@ -217,7 +217,7 @@ translate({{'.', _, [Left, Right]}, Meta, []}, S) {TLeft, SL} = translate(Left, S), {Var, _, SV} = elixir_scope:build_var('_', SL), - Line = ?line(Meta), + Line = ?ann(Meta), TRight = {atom, Line, Right}, %% TODO: Consider making this {badkey, _} error @@ -236,16 +236,16 @@ translate({{'.', _, [Left, Right]}, Meta, []}, S) {atom, Line, term}, TVar}]}, - {{'case', -1, TLeft, [ - {clause, -1, + {{'case', ?generated, TLeft, [ + {clause, ?generated, [{map, Line, [{map_field_exact, Line, TRight, TVar}]}], [], [TVar]}, - {clause, -1, + {clause, ?generated, [{match, Line, TVar, {map, Line, []}}], [], [elixir_utils:erl_call(Line, erlang, error, [TMap])]}, - {clause, -1, + {clause, ?generated, [TVar], [], [{call, Line, {remote, Line, TVar, TRight}, []}]} @@ -256,7 +256,7 @@ translate({{'.', _, [Left, Right]}, Meta, Args}, S) {TLeft, SL} = translate(Left, S), {TArgs, SA} = translate_args(Args, mergec(S, SL)), - Line = ?line(Meta), + Line = ?ann(Meta), Arity = length(Args), TRight = {atom, Line, Right}, SC = mergev(SL, SA), @@ -279,7 +279,7 @@ translate({{'.', _, [Left, Right]}, Meta, Args}, S) translate({{'.', _, [Expr]}, Meta, Args}, S) when is_list(Args) -> {TExpr, SE} = translate(Expr, S), {TArgs, SA} = translate_args(Args, mergec(S, SE)), - {{call, ?line(Meta), TExpr, TArgs}, mergev(SE, SA)}; + {{call, ?ann(Meta), TExpr, TArgs}, mergev(SE, SA)}; %% Literals diff --git a/lib/elixir/src/elixir_try.erl b/lib/elixir/src/elixir_try.erl index ce2081e54..6b4b48604 100644 --- a/lib/elixir/src/elixir_try.erl +++ b/lib/elixir/src/elixir_try.erl @@ -22,7 +22,7 @@ each_clause({'catch', Meta, Raw, Expr}, S) -> end, Condition = [{'{}', Meta, Final}], - {TC, TS} = elixir_clauses:clause(?line(Meta), fun elixir_translator:translate_args/2, + {TC, TS} = elixir_clauses:clause(Meta, fun elixir_translator:translate_args/2, Condition, Expr, Guards, S), {[TC], TS}; @@ -58,13 +58,13 @@ build_rescue(Meta, Parts, Body, S) -> Matches = [Match || {Match, _} <- Parts], {{clause, Line, TMatches, _, TBody}, TS} = - elixir_clauses:clause(?line(Meta), fun elixir_translator:translate_args/2, + elixir_clauses:clause(Meta, fun elixir_translator:translate_args/2, Matches, Body, [], S), TClauses = [begin TArgs = [{tuple, Line, [{atom, Line, error}, TMatch, {var, Line, '_'}]}], - TGuards = elixir_clauses:guards(Line, Guards, [], TS), + TGuards = elixir_clauses:guards(Guards, [], TS), {clause, Line, TArgs, TGuards, TBody} end || {TMatch, {_, Guards}} <- lists:zip(TMatches, Parts)], diff --git a/lib/elixir/src/elixir_utils.erl b/lib/elixir/src/elixir_utils.erl index cae39fef9..772543729 100644 --- a/lib/elixir/src/elixir_utils.erl +++ b/lib/elixir/src/elixir_utils.erl @@ -1,11 +1,11 @@ %% Convenience functions used throughout elixir source code %% for ast manipulation and querying. -module(elixir_utils). --export([elixir_to_erl/1, get_line/1, split_last/1, meta_location/1, +-export([elixir_to_erl/1, get_ann/1, get_line/1, split_last/1, characters_to_list/1, characters_to_binary/1, macro_name/1, convert_to_boolean/4, returns_boolean/1, atom_concat/1, read_file_type/1, read_link_type/1, relative_to_cwd/1, - change_universal_time/2, erl_call/4]). + change_universal_time/2, erl_call/4, meta_location/1]). -include("elixir.hrl"). -include_lib("kernel/include/file.hrl"). @@ -15,9 +15,9 @@ macro_name(Macro) -> atom_concat(Atoms) -> list_to_atom(lists:concat(Atoms)). -erl_call(Line, Module, Function, Args) -> - {call, Line, - {remote, Line, {atom, Line, Module}, {atom, Line, Function}}, +erl_call(Ann, Module, Function, Args) -> + {call, Ann, + {remote, Ann, {atom, Ann, Module}, {atom, Ann, Function}}, Args }. @@ -27,6 +27,15 @@ get_line(Opts) when is_list(Opts) -> false -> 0 end. +get_ann(Opts) when is_list(Opts) -> + get_ann(Opts, [], 0). + +get_ann([{generated,Gen}|T], Acc, Line) -> get_ann(T, [{generated,Gen}|Acc], Line); +get_ann([{line,Line}|T], Acc, _) -> get_ann(T, Acc, Line); +get_ann([_|T], Acc, Line) -> get_ann(T, Acc, Line); +get_ann([], [], Line) -> Line; +get_ann([], Acc, Line) -> [{location,Line}|Acc]. + split_last([]) -> {[], []}; split_last(List) -> split_last(List, []). split_last([H], Acc) -> {lists:reverse(Acc), H}; @@ -83,10 +92,11 @@ characters_to_binary(Data) -> meta_location(Meta) -> case lists:keyfind(file, 1, Meta) of {file, MetaFile} when is_binary(MetaFile) -> - case lists:keyfind(keep, 1, Meta) of - {keep, MetaLine} when is_integer(MetaLine) -> ok; - _ -> MetaLine = 0 - end, + MetaLine = + case lists:keyfind(keep, 1, Meta) of + {keep, Keep} when is_integer(Keep) -> Keep; + _ -> 0 + end, {MetaFile, MetaLine}; _ -> nil |