diff options
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r-- | lib/stdlib/src/edlin_expand.erl | 8 | ||||
-rw-r--r-- | lib/stdlib/src/erl_eval.erl | 30 | ||||
-rw-r--r-- | lib/stdlib/src/erl_lint.erl | 21 | ||||
-rw-r--r-- | lib/stdlib/src/erl_pp.erl | 19 | ||||
-rw-r--r-- | lib/stdlib/src/lists.erl | 15 | ||||
-rw-r--r-- | lib/stdlib/src/re.erl | 3 | ||||
-rw-r--r-- | lib/stdlib/src/supervisor.erl | 5 | ||||
-rw-r--r-- | lib/stdlib/src/supervisor_bridge.erl | 11 |
8 files changed, 89 insertions, 23 deletions
diff --git a/lib/stdlib/src/edlin_expand.erl b/lib/stdlib/src/edlin_expand.erl index 516c0aa30b..0033010dce 100644 --- a/lib/stdlib/src/edlin_expand.erl +++ b/lib/stdlib/src/edlin_expand.erl @@ -89,7 +89,13 @@ match(Prefix, Alts, Extra) -> {yes, Remain, []} end; {complete, Str} -> - {yes, nthtail(Len, Str) ++ Extra, []}; + {_, Arity} = lists:keyfind(Str, 1, Matches), + case {Arity, Extra} of + {0, "("} -> + {yes, nthtail(Len, Str) ++ "()", []}; + _ -> + {yes, nthtail(Len, Str) ++ Extra, []} + end; no -> {no, [], []} end. diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl index 5f96795d92..63e7be4b74 100644 --- a/lib/stdlib/src/erl_eval.erl +++ b/lib/stdlib/src/erl_eval.erl @@ -241,23 +241,15 @@ expr({record,_,_,Name,_}, _Bs, _Lf, _Ef, _RBs) -> erlang:raise(error, {undef_record,Name}, stacktrace()); %% map -expr({map_field_assoc,_,EK, EV}, Bs0, Lf, Ef, RBs) -> - {value,K,Bs1} = expr(EK, Bs0, Lf, Ef, none), - {value,V,Bs2} = expr(EV, Bs0, Lf, Ef, none), - ret_expr({map_assoc,K,V}, merge_bindings(Bs1,Bs2), RBs); -expr({map_field_exact,_,EK, EV}, Bs0, Lf, Ef, RBs) -> - {value,K,Bs1} = expr(EK, Bs0, Lf, Ef, none), - {value,V,Bs2} = expr(EV, Bs0, Lf, Ef, none), - ret_expr({map_exact,K,V}, merge_bindings(Bs1,Bs2), RBs); expr({map,_, Binding,Es}, Bs0, Lf, Ef, RBs) -> {value, Map0, Bs1} = expr(Binding, Bs0, Lf, Ef, RBs), - {Vs,Bs} = expr_list(Es, Bs1, Lf, Ef), + {Vs,Bs} = eval_map_fields(Es, Bs1, Lf, Ef), ret_expr(lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi); ({map_exact,K,V}, Mi) -> maps:update(K,V,Mi) end, Map0, Vs), Bs, RBs); expr({map,_,Es}, Bs0, Lf, Ef, RBs) -> - {Vs,Bs} = expr_list(Es, Bs0, Lf, Ef), + {Vs,Bs} = eval_map_fields(Es, Bs0, Lf, Ef), ret_expr(lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi) end, maps:new(), Vs), Bs, RBs); @@ -749,6 +741,24 @@ eval_filter(F, Bs0, Lf, Ef, CompFun, Acc) -> end end. +%% eval_map_fields([Field], Bindings, LocalFunctionHandler, +%% ExternalFuncHandler) -> +%% {[{map_assoc | map_exact,Key,Value}],Bindings} + +eval_map_fields(Fs, Bs, Lf, Ef) -> + eval_map_fields(Fs, Bs, Lf, Ef, []). + +eval_map_fields([{map_field_assoc,_,K0,V0}|Fs], Bs0, Lf, Ef, Acc) -> + {value,K1,Bs1} = expr(K0, Bs0, Lf, Ef, none), + {value,V1,Bs2} = expr(V0, Bs1, Lf, Ef, none), + eval_map_fields(Fs, Bs2, Lf, Ef, [{map_assoc,K1,V1}|Acc]); +eval_map_fields([{map_field_exact,_,K0,V0}|Fs], Bs0, Lf, Ef, Acc) -> + {value,K1,Bs1} = expr(K0, Bs0, Lf, Ef, none), + {value,V1,Bs2} = expr(V0, Bs1, Lf, Ef, none), + eval_map_fields(Fs, Bs2, Lf, Ef, [{map_exact,K1,V1}|Acc]); +eval_map_fields([], Bs, _Lf, _Ef, Acc) -> + {lists:reverse(Acc),Bs}. + %% RBs is the bindings to return when the evalution of a function %% (fun) has finished. If RBs =:= none, then the evalution took place diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index f630db6032..0c6f41f594 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -100,7 +100,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) -> compile=[], %Compile flags records=dict:new() :: dict(), %Record definitions locals=gb_sets:empty() :: gb_set(), %All defined functions (prescanned) - no_auto=gb_sets:empty() :: gb_set(), %Functions explicitly not autoimported + no_auto=gb_sets:empty() :: gb_set() | 'all', %Functions explicitly not autoimported defined=gb_sets:empty() :: gb_set(), %Defined fuctions on_load=[] :: [fa()], %On-load function on_load_line=0 :: line(), %Line for on_load @@ -3648,15 +3648,22 @@ is_imported_from_erlang(ImportSet,{Func,Arity}) -> {ok,erlang} -> true; _ -> false end. -%% Build set of functions where auto-import is explicitly supressed +%% Build set of functions where auto-import is explicitly suppressed auto_import_suppressed(CompileFlags) -> - L0 = [ X || {no_auto_import,X} <- CompileFlags ], - L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ], - gb_sets:from_list(L1). -%% Predicate to find out if autoimport is explicitly supressed for a function + case lists:member(no_auto_import, CompileFlags) of + true -> + all; + false -> + L0 = [ X || {no_auto_import,X} <- CompileFlags ], + L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ], + gb_sets:from_list(L1) + end. +%% Predicate to find out if autoimport is explicitly suppressed for a function +is_autoimport_suppressed(all,{_Func,_Arity}) -> + true; is_autoimport_suppressed(NoAutoSet,{Func,Arity}) -> gb_sets:is_element({Func,Arity},NoAutoSet). -%% Predicate to find out if a function specific bif-clash supression (old deprecated) is present +%% Predicate to find out if a function specific bif-clash suppression (old deprecated) is present bif_clash_specifically_disabled(St,{F,A}) -> Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile), lists:member({F,A},Nowarn). diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl index 8a1d8e0440..9dbe89da91 100644 --- a/lib/stdlib/src/erl_pp.erl +++ b/lib/stdlib/src/erl_pp.erl @@ -479,6 +479,15 @@ lexpr({record_field, _, Rec, F}, Prec, Opts) -> {L,P,R} = inop_prec('.'), El = [lexpr(Rec, L, Opts),$.,lexpr(F, R, Opts)], maybe_paren(P, Prec, El); +lexpr({map, _, Fs}, Prec, Opts) -> + {P,_R} = preop_prec('#'), + El = {first,leaf("#"),map_fields(Fs, Opts)}, + maybe_paren(P, Prec, El); +lexpr({map, _, Map, Fs}, Prec, Opts) -> + {L,P,_R} = inop_prec('#'), + Rl = lexpr(Map, L, Opts), + El = {first,[Rl,leaf("#")],map_fields(Fs, Opts)}, + maybe_paren(P, Prec, El); lexpr({block,_,Es}, _, Opts) -> {list,[{step,'begin',body(Es, Opts)},'end']}; lexpr({'if',_,Cs}, _, Opts) -> @@ -671,6 +680,16 @@ record_field({typed_record_field,Field,Type}, Opts) -> record_field({record_field,_,F}, Opts) -> lexpr(F, 0, Opts). +map_fields(Fs, Opts) -> + tuple(Fs, fun map_field/2, Opts). + +map_field({map_field_assoc,_,K,V}, Opts) -> + Pl = lexpr(K, 0, Opts), + {list,[{step,[Pl,leaf(" =>")],lexpr(V, 0, Opts)}]}; +map_field({map_field_exact,_,K,V}, Opts) -> + Pl = lexpr(K, 0, Opts), + {list,[{step,[Pl,leaf(" :=")],lexpr(V, 0, Opts)}]}. + list({cons,_,H,T}, Es, Opts) -> list(T, [H|Es], Opts); list({nil,_}, Es, Opts) -> diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index d6a9f4645d..6303465d3d 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -22,7 +22,7 @@ -compile({no_auto_import,[min/2]}). -export([append/2, append/1, subtract/2, reverse/1, - nth/2, nthtail/2, prefix/2, suffix/2, last/1, + nth/2, nthtail/2, prefix/2, suffix/2, droplast/1, last/1, seq/2, seq/3, sum/1, duplicate/2, min/1, max/1, sublist/2, sublist/3, delete/2, unzip/1, unzip3/1, zip/2, zip3/3, zipwith/3, zipwith3/4, @@ -203,6 +203,19 @@ suffix(Suffix, List) -> Delta = length(List) - length(Suffix), Delta >= 0 andalso nthtail(Delta, List) =:= Suffix. +%% droplast(List) returns the list dropping its last element + +-spec droplast(List) -> InitList when + List :: [T, ...], + InitList :: [T], + T :: term(). + +%% This is the simple recursive implementation +%% reverse(tl(reverse(L))) is faster on average, +%% but creates more garbage. +droplast([_T]) -> []; +droplast([H|T]) -> [H|droplast(T)]. + %% last(List) returns the last element in a list. -spec last(List) -> Last when diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl index afc63496d0..7f3cd8f592 100644 --- a/lib/stdlib/src/re.erl +++ b/lib/stdlib/src/re.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2012. All Rights Reserved. +%% Copyright Ericsson AB 2008-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -19,7 +19,6 @@ -module(re). -export([grun/3,urun/3,ucompile/2,replace/3,replace/4,split/2,split/3]). -%-opaque mp() :: {re_pattern, _, _, _, _}. -type mp() :: {re_pattern, _, _, _, _}. -type nl_spec() :: cr | crlf | lf | anycrlf | any. diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index d18387568d..974583bc28 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -45,10 +45,13 @@ -type restart() :: 'permanent' | 'transient' | 'temporary'. -type shutdown() :: 'brutal_kill' | timeout(). -type worker() :: 'worker' | 'supervisor'. --type sup_name() :: {'local', Name :: atom()} | {'global', Name :: atom()}. +-type sup_name() :: {'local', Name :: atom()} + | {'global', Name :: atom()} + | {'via', Module :: module(), Name :: any()}. -type sup_ref() :: (Name :: atom()) | {Name :: atom(), Node :: node()} | {'global', Name :: atom()} + | {'via', Module :: module(), Name :: any()} | pid(). -type child_spec() :: {Id :: child_id(), StartFunc :: mfargs(), diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl index e8405ab9a4..ff4502f0b9 100644 --- a/lib/stdlib/src/supervisor_bridge.erl +++ b/lib/stdlib/src/supervisor_bridge.erl @@ -101,7 +101,16 @@ handle_cast(_, State) -> {noreply, State}. handle_info({'EXIT', Pid, Reason}, State) when State#state.pid =:= Pid -> - report_error(child_terminated, Reason, State), + case Reason of + normal -> + ok; + shutdown -> + ok; + {shutdown, _Term} -> + ok; + _ -> + report_error(child_terminated, Reason, State) + end, {stop, Reason, State#state{pid = undefined}}; handle_info(_, State) -> {noreply, State}. |