aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r--lib/stdlib/src/beam_lib.erl9
-rw-r--r--lib/stdlib/src/dets.erl52
-rw-r--r--lib/stdlib/src/edlin.erl1
-rw-r--r--lib/stdlib/src/erl_eval.erl31
-rw-r--r--lib/stdlib/src/erl_lint.erl11
-rw-r--r--lib/stdlib/src/erl_parse.yrl439
-rw-r--r--lib/stdlib/src/ets.erl2
-rw-r--r--lib/stdlib/src/file_sorter.erl22
-rw-r--r--lib/stdlib/src/io.erl2
-rw-r--r--lib/stdlib/src/otp_internal.erl3
-rw-r--r--lib/stdlib/src/qlc.erl14
-rw-r--r--lib/stdlib/src/qlc_pt.erl34
-rw-r--r--lib/stdlib/src/stdlib.app.src2
13 files changed, 538 insertions, 84 deletions
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 6e00401dce..00cd1221fa 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -931,7 +931,10 @@ call_crypto_server(Req) ->
end.
call_crypto_server_1(Req) ->
- {ok, _} = gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []),
+ case gen_server:start({local,?CRYPTO_KEY_SERVER}, ?MODULE, [], []) of
+ {ok, _} -> ok;
+ {error, {already_started, _}} -> ok
+ end,
erlang:yield(),
call_crypto_server(Req).
@@ -972,9 +975,7 @@ handle_call({get_crypto_key, What}, From, #state{crypto_key_f=F}=S) ->
handle_call({crypto_key_fun, F}, {_,_} = From, S) ->
case S#state.crypto_key_f of
undefined ->
- %% Don't allow tuple funs here. (They weren't allowed before,
- %% so there is no reason to allow them now.)
- if is_function(F), is_function(F, 1) ->
+ if is_function(F, 1) ->
{Result, Fun, Reply} =
case catch F(init) of
ok ->
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 6d07f4018a..bf22949870 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -372,7 +372,7 @@ info(Tab) ->
Item :: 'access' | 'auto_save' | 'bchunk_format'
| 'hash' | 'file_size' | 'filename' | 'keypos' | 'memory'
| 'no_keys' | 'no_objects' | 'no_slots' | 'owner' | 'ram_file'
- | 'safe_fixed' | 'size' | 'type' | 'version',
+ | 'safe_fixed' | 'safe_fixed_monotonic_time' | 'size' | 'type' | 'version',
Value :: term().
info(Tab, owner) ->
@@ -1124,7 +1124,9 @@ repl({delayed_write, {Delay,Size} = C}, Defs)
Defs#open_args{delayed_write = C};
repl({estimated_no_objects, I}, Defs) ->
repl({min_no_slots, I}, Defs);
-repl({file, File}, Defs) ->
+repl({file, File}, Defs) when is_list(File) ->
+ Defs#open_args{file = File};
+repl({file, File}, Defs) when is_atom(File) ->
Defs#open_args{file = to_list(File)};
repl({keypos, P}, Defs) when is_integer(P), P > 0 ->
Defs#open_args{keypos =P};
@@ -1289,7 +1291,15 @@ init(Parent, Server) ->
open_file_loop(#head{parent = Parent, server = Server}).
open_file_loop(Head) ->
- open_file_loop(Head, 0).
+ %% The Dets server pretends the file is open before
+ %% internal_open() has been called, which means that unless the
+ %% internal_open message is applied first, other processes can
+ %% find the pid by calling dets_server:get_pid() and do things
+ %% before Head has been initialized properly.
+ receive
+ ?DETS_CALL(From, {internal_open, _Ref, _Args}=Op) ->
+ do_apply_op(Op, From, Head, 0)
+ end.
open_file_loop(Head, N) when element(1, Head#head.update_mode) =:= error ->
open_file_loop2(Head, N);
@@ -1964,7 +1974,9 @@ do_safe_fixtable(Head, Pid, true) ->
case Head#head.fixed of
false ->
link(Pid),
- Fixed = {utime_now(), [{Pid, 1}]},
+ MonTime = erlang:monotonic_time(),
+ TimeOffset = erlang:time_offset(),
+ Fixed = {{MonTime, TimeOffset}, [{Pid, 1}]},
Ftab = dets_utils:get_freelists(Head),
Head#head{fixed = Fixed, freelists = {Ftab, Ftab}};
{TimeStamp, Counters} ->
@@ -2091,7 +2103,22 @@ finfo(H, no_keys) ->
finfo(H, no_slots) -> {H, (H#head.mod):no_slots(H)};
finfo(H, pid) -> {H, self()};
finfo(H, ram_file) -> {H, H#head.ram_file};
-finfo(H, safe_fixed) -> {H, H#head.fixed};
+finfo(H, safe_fixed) ->
+ {H,
+ case H#head.fixed of
+ false ->
+ false;
+ {{FixMonTime, TimeOffset}, RefList} ->
+ {make_timestamp(FixMonTime, TimeOffset), RefList}
+ end};
+finfo(H, safe_fixed_monotonic_time) ->
+ {H,
+ case H#head.fixed of
+ false ->
+ false;
+ {{FixMonTime, _TimeOffset}, RefList} ->
+ {FixMonTime, RefList}
+ end};
finfo(H, size) ->
case catch write_cache(H) of
{H2, []} ->
@@ -3275,11 +3302,14 @@ err(Error) ->
time_now() ->
erlang:monotonic_time(1000000).
--compile({inline, [utime_now/0]}).
-utime_now() ->
- Time = time_now(),
- UniqueCounter = erlang:unique_integer([monotonic]),
- {Time, UniqueCounter}.
+make_timestamp(MonTime, TimeOffset) ->
+ ErlangSystemTime = erlang:convert_time_unit(MonTime+TimeOffset,
+ native,
+ micro_seconds),
+ MegaSecs = ErlangSystemTime div 1000000000000,
+ Secs = ErlangSystemTime div 1000000 - MegaSecs*1000000,
+ MicroSecs = ErlangSystemTime rem 1000000,
+ {MegaSecs, Secs, MicroSecs}.
%%%%%%%%%%%%%%%%% DEBUG functions %%%%%%%%%%%%%%%%
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 19444c0502..0e9c457de2 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -465,7 +465,6 @@ word_char(C) when C >= $a, C =< $z -> true;
word_char(C) when C >= $ß, C =< $ÿ, C =/= $÷ -> true;
word_char(C) when C >= $0, C =< $9 -> true;
word_char(C) when C =:= $_ -> true;
-word_char(C) when C =:= $. -> true; % accept dot-separated names
word_char(_) -> false.
%% over_white(Chars, InitialStack, InitialCount) ->
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 568eb1c852..40a34aa30f 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -415,7 +415,7 @@ expr({call,_,{atom,_,Func},As0}, Bs0, Lf, Ef, RBs) ->
{As,Bs} = expr_list(As0, Bs0, Lf, Ef),
bif(Func, As, Bs, Ef, RBs);
false ->
- local_func(Func, As0, Bs0, Lf, RBs)
+ local_func(Func, As0, Bs0, Lf, Ef, RBs)
end;
expr({call,_,Func0,As0}, Bs0, Lf, Ef, RBs) -> % function or {Mod,Fun}
{value,Func,Bs1} = expr(Func0, Bs0, Lf, Ef, none),
@@ -542,33 +542,34 @@ unhide_calls([E | Es], MaxLine, D) ->
unhide_calls(E, _MaxLine, _D) ->
E.
-%% local_func(Function, Arguments, Bindings, LocalFuncHandler, RBs) ->
+%% local_func(Function, Arguments, Bindings, LocalFuncHandler,
+%% ExternalFuncHandler, RBs) ->
%% {value,Value,Bindings} | Value when
%% LocalFuncHandler = {value,F} | {value,F,Eas} |
%% {eval,F} | {eval,F,Eas} | none.
-local_func(Func, As0, Bs0, {value,F}, value) ->
- {As1,_Bs1} = expr_list(As0, Bs0, {value,F}),
+local_func(Func, As0, Bs0, {value,F}, Ef, value) ->
+ {As1,_Bs1} = expr_list(As0, Bs0, {value,F}, Ef),
%% Make tail recursive calls when possible.
F(Func, As1);
-local_func(Func, As0, Bs0, {value,F}, RBs) ->
- {As1,Bs1} = expr_list(As0, Bs0, {value,F}),
+local_func(Func, As0, Bs0, {value,F}, Ef, RBs) ->
+ {As1,Bs1} = expr_list(As0, Bs0, {value,F}, Ef),
ret_expr(F(Func, As1), Bs1, RBs);
-local_func(Func, As0, Bs0, {value,F,Eas}, RBs) ->
+local_func(Func, As0, Bs0, {value,F,Eas}, Ef, RBs) ->
Fun = fun(Name, Args) -> apply(F, [Name,Args|Eas]) end,
- local_func(Func, As0, Bs0, {value, Fun}, RBs);
-local_func(Func, As, Bs, {eval,F}, RBs) ->
+ local_func(Func, As0, Bs0, {value, Fun}, Ef, RBs);
+local_func(Func, As, Bs, {eval,F}, _Ef, RBs) ->
local_func2(F(Func, As, Bs), RBs);
-local_func(Func, As, Bs, {eval,F,Eas}, RBs) ->
+local_func(Func, As, Bs, {eval,F,Eas}, _Ef, RBs) ->
local_func2(apply(F, [Func,As,Bs|Eas]), RBs);
%% These two clauses are for backwards compatibility.
-local_func(Func, As0, Bs0, {M,F}, RBs) ->
- {As1,Bs1} = expr_list(As0, Bs0, {M,F}),
+local_func(Func, As0, Bs0, {M,F}, Ef, RBs) ->
+ {As1,Bs1} = expr_list(As0, Bs0, {M,F}, Ef),
ret_expr(M:F(Func,As1), Bs1, RBs);
-local_func(Func, As, _Bs, {M,F,Eas}, RBs) ->
+local_func(Func, As, _Bs, {M,F,Eas}, _Ef, RBs) ->
local_func2(apply(M, F, [Func,As|Eas]), RBs);
%% Default unknown function handler to undefined function.
-local_func(Func, As0, _Bs0, none, _RBs) ->
+local_func(Func, As0, _Bs0, none, _Ef, _RBs) ->
erlang:raise(error, undef, [{erl_eval,Func,length(As0)}|stacktrace()]).
local_func2({value,V,Bs}, RBs) ->
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 3ce6abe752..9ef4acdf5f 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -96,7 +96,7 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%% 'called' and 'exports' contain {Line, {Function, Arity}},
%% the other function collections contain {Function, Arity}.
-record(lint, {state=start :: 'start' | 'attribute' | 'function',
- module=[], %Module
+ module='', %Module
behaviour=[], %Behaviour
exports=gb_sets:empty() :: gb_sets:set(fa()),%Exports
imports=[] :: [fa()], %Imports, an orddict()
@@ -696,7 +696,12 @@ set_form_file({function,L,N,A,C}, File) ->
set_form_file(Form, _File) ->
Form.
+set_file(Ts, File) when is_list(Ts) ->
+ [anno_set_file(T, File) || T <- Ts];
set_file(T, File) ->
+ anno_set_file(T, File).
+
+anno_set_file(T, File) ->
F = fun(Anno) -> erl_anno:set_file(File, Anno) end,
erl_parse:map_anno(F, T).
@@ -731,7 +736,7 @@ start_state(Form, St) ->
%% attribute_state(Form, State) ->
%% State'
-attribute_state({attribute,_L,module,_M}, #lint{module=[]}=St) ->
+attribute_state({attribute,_L,module,_M}, #lint{module=''}=St) ->
St;
attribute_state({attribute,L,module,_M}, St) ->
add_error(L, redefine_module, St);
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index e07ab2efc2..b1c574ea60 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2015. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -527,12 +527,418 @@ Erlang code.
-compile([{hipe,[{regalloc,linear_scan}]}]).
-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
- error_info/0]).
+ abstract_type/0, error_info/0]).
+
+%% Start of Abstract Format
+
+-type anno() :: erl_anno:anno().
+
+-type abstract_form() :: af_module()
+ | af_behavior()
+ | af_behaviour()
+ | af_export()
+ | af_import()
+ | af_export_type()
+ | af_optional_callbacks()
+ | af_compile()
+ | af_file()
+ | af_record_decl()
+ | af_type_decl()
+ | af_function_spec()
+ | af_wild_attribute()
+ | af_function_decl().
+
+-type af_module() :: {'attribute', anno(), 'module', module()}.
+
+-type af_behavior() :: {'attribute', anno(), 'behavior', behaviour()}.
+
+-type af_behaviour() :: {'attribute', anno(), 'behaviour', behaviour()}.
+
+-type behaviour() :: atom().
+
+-type af_export() :: {'attribute', anno(), 'export', af_fa_list()}.
+
+-type af_import() :: {'attribute', anno(), 'import', af_fa_list()}.
+
+-type af_fa_list() :: [{function_name(), arity()}].
+
+-type af_export_type() :: {'attribute', anno(), 'export_type', af_ta_list()}.
+
+-type af_ta_list() :: [{type_name(), arity()}].
+
+-type af_optional_callbacks() ::
+ {'attribute', anno(), 'optional_callbacks', af_fa_list()}.
+
+-type af_compile() :: {'attribute', anno(), 'compile', any()}.
+
+-type af_file() :: {'attribute', anno(), 'file', {string(), anno()}}.
+
+-type af_record_decl() ::
+ {'attribute', anno(), 'record', {record_name(), [af_field_decl()]}}.
+
+-type af_field_decl() :: af_typed_field() | af_field().
+
+-type af_typed_field() ::
+ {'typed_record_field', af_field(), abstract_type()}.
+
+-type af_field() :: {'record_field', anno(), af_field_name()}
+ | {'record_field', anno(), af_field_name(), abstract_expr()}.
+
+-type af_type_decl() :: {'attribute', anno(), type_attr(),
+ {type_name(), abstract_type(), [af_variable()]}}.
+
+-type type_attr() :: 'opaque' | 'type'.
+
+-type af_function_spec() :: {'attribute', anno(), spec_attr(),
+ {{function_name(), arity()},
+ af_function_type_list()}}
+ | {'attribute', anno(), 'spec',
+ {{module(), function_name(), arity()},
+ af_function_type_list()}}.
+
+-type spec_attr() :: 'callback' | 'spec'.
+
+-type af_wild_attribute() :: {'attribute', anno(), atom(), any()}.
+
+-type af_function_decl() ::
+ {'function', anno(), function_name(), arity(), af_clause_seq()}.
+
+-type abstract_expr() :: af_literal()
+ | af_match(abstract_expr())
+ | af_variable()
+ | af_tuple(abstract_expr())
+ | af_nil()
+ | af_cons(abstract_expr())
+ | af_bin(abstract_expr())
+ | af_binary_op(abstract_expr())
+ | af_unary_op(abstract_expr())
+ | af_record_access(abstract_expr())
+ | af_record_update(abstract_expr())
+ | af_record_index()
+ | af_record_field_access(abstract_expr())
+ | af_map_access(abstract_expr())
+ | af_map_update(abstract_expr())
+ | af_catch()
+ | af_local_call()
+ | af_remote_call()
+ | af_list_comprehension()
+ | af_binary_comprehension()
+ | af_block()
+ | af_if()
+ | af_case()
+ | af_try()
+ | af_receive()
+ | af_local_fun()
+ | af_remote_fun()
+ | af_fun()
+ | af_named_fun().
+
+-type af_record_update(T) :: {'record',
+ anno(),
+ abstract_expr(),
+ record_name(),
+ [af_record_field(T)]}.
+
+-type af_catch() :: {'catch', anno(), abstract_expr()}.
+
+-type af_local_call() :: {'call', anno(), af_local_function(), af_args()}.
+
+-type af_remote_call() :: {'call', anno(), af_remote_function(), af_args()}.
+
+-type af_args() :: [abstract_expr()].
+
+-type af_local_function() :: abstract_expr().
+
+-type af_remote_function() ::
+ {'remote', anno(), abstract_expr(), abstract_expr()}.
+
+-type af_list_comprehension() ::
+ {'lc', anno(), af_template(), af_qualifier_seq()}.
+
+-type af_binary_comprehension() ::
+ {'bc', anno(), af_template(), af_qualifier_seq()}.
+
+-type af_template() :: abstract_expr().
+
+-type af_qualifier_seq() :: [af_qualifier()].
+
+-type af_qualifier() :: af_generator() | af_filter().
+
+-type af_generator() :: {'generate', anno(), af_pattern(), abstract_expr()}
+ | {'b_generate', anno(), af_pattern(), abstract_expr()}.
+
+-type af_filter() :: abstract_expr().
+
+-type af_block() :: {'block', anno(), af_body()}.
+
+-type af_if() :: {'if', anno(), af_clause_seq()}.
+
+-type af_case() :: {'case', anno(), abstract_expr(), af_clause_seq()}.
+
+-type af_try() :: {'try',
+ anno(),
+ af_body() | [],
+ af_clause_seq() | [],
+ af_clause_seq() | [],
+ af_body() | []}.
+
+-type af_clause_seq() :: [af_clause(), ...].
+
+-type af_receive() ::
+ {'receive', anno(), af_clause_seq()}
+ | {'receive', anno(), af_clause_seq(), abstract_expr(), af_body()}.
+
+-type af_local_fun() ::
+ {'fun', anno(), {'function', function_name(), arity()}}.
+
+-type af_remote_fun() ::
+ {'fun', anno(), {'function', module(), function_name(), arity()}}
+ | {'fun', anno(), {'function', af_atom(), af_atom(), af_integer()}}.
+
+-type af_fun() :: {'fun', anno(), {'clauses', af_clause_seq()}}.
+
+-type af_named_fun() :: {'named_fun', anno(), fun_name(), af_clause_seq()}.
+
+-type fun_name() :: atom().
+
+-type abstract_clause() :: af_clause().
+
+-type af_clause() ::
+ {'clause', anno(), [af_pattern()], af_guard_seq(), af_body()}.
+
+-type af_body() :: [abstract_expr(), ...].
+
+-type af_guard_seq() :: [af_guard()].
+
+-type af_guard() :: [af_guard_test(), ...].
+
+-type af_guard_test() :: af_literal()
+ | af_variable()
+ | af_tuple(af_guard_test())
+ | af_nil()
+ | af_cons(af_guard_test())
+ | af_bin(af_guard_test())
+ | af_binary_op(af_guard_test())
+ | af_unary_op(af_guard_test())
+ | af_record_access(af_guard_test())
+ | af_record_index()
+ | af_record_field_access(af_guard_test())
+ | af_map_access(abstract_expr()) % FIXME
+ | af_map_update(abstract_expr()) % FIXME
+ | af_guard_call()
+ | af_remote_guard_call().
+
+-type af_record_field_access(T) ::
+ {'record_field', anno(), T, record_name(), af_field_name()}.
+
+-type af_map_access(T) :: {'map', anno(), [af_map_field(T)]}.
+
+-type af_map_update(T) :: {'map', anno(), T, [af_map_field(T)]}.
+
+-type af_map_field(T) :: af_map_field_assoc(T) | af_map_field_exact(T).
+
+-type af_map_field_assoc(T) :: {'map_field_assoc', anno(), T, T}.
+
+-type af_map_field_exact(T) :: {'map_field_exact', anno(), T, T}.
+
+-type af_guard_call() :: {'call', anno(), function_name(), [af_guard_test()]}.
+
+-type af_remote_guard_call() ::
+ {'call', anno(),
+ {'remote', anno(), af_lit_atom('erlang'), af_atom()},
+ [af_guard_test()]}.
+
+-type af_pattern() :: af_literal()
+ | af_match(af_pattern())
+ | af_variable()
+ | af_tuple(af_pattern())
+ | af_nil()
+ | af_cons(af_pattern())
+ | af_bin(af_pattern())
+ | af_binary_op(af_pattern())
+ | af_unary_op(af_pattern())
+ | af_record_access(af_pattern())
+ | af_record_index()
+ | af_map_pattern().
+
+-type af_record_index() ::
+ {'record_index', anno(), record_name(), af_field_name()}.
+
+-type af_record_access(T) ::
+ {'record', anno(), record_name(), [af_record_field(T)]}.
+
+-type af_record_field(T) :: {'record_field', anno(), af_field_name(), T}.
+
+-type af_map_pattern() ::
+ {'map', anno(), [af_map_field_exact(abstract_expr)]}. % FIXME?
+
+-type abstract_type() :: af_annotated_type()
+ | af_atom()
+ | af_bitstring_type()
+ | af_empty_list_type()
+ | af_fun_type()
+ | af_integer_range_type()
+ | af_map_type()
+ | af_predefined_type()
+ | af_record_type()
+ | af_remote_type()
+ | af_singleton_integer_type()
+ | af_tuple_type()
+ | af_type_union()
+ | af_type_variable()
+ | af_user_defined_type().
+
+-type af_annotated_type() ::
+ {'ann_type', anno(), [af_anno() | abstract_type()]}. % [Var, Type]
+
+-type af_anno() :: af_variable().
+
+-type af_bitstring_type() ::
+ {'type', anno(), 'binary', [af_singleton_integer_type()]}.
+
+-type af_empty_list_type() :: {'type', anno(), 'nil', []}.
+
+-type af_fun_type() :: {'type', anno(), 'fun', []}
+ | {'type', anno(), 'fun', [{'type', anno(), 'any'} |
+ abstract_type()]}
+ | {'type', anno(), 'fun', af_function_type()}.
+
+-type af_integer_range_type() ::
+ {'type', anno(), 'range', [af_singleton_integer_type()]}.
+
+-type af_map_type() :: {'type', anno(), 'map', 'any'}
+ | {'type', anno(), 'map', [af_map_pair_type()]}.
+
+-type af_map_pair_type() ::
+ {'type', anno(), 'map_field_assoc', [abstract_type()]}.
+
+-type af_predefined_type() ::
+ {'type', anno(), type_name(), [abstract_type()]}.
+
+-type af_record_type() ::
+ {'type', anno(), 'record', [(Name :: af_atom()) % [Name, T1, ... Tk]
+ | af_record_field_type()]}.
+
+-type af_record_field_type() ::
+ {'type', anno(), 'field_type', [(Name :: af_atom()) |
+ abstract_type()]}. % [Name, Type]
+
+-type af_remote_type() ::
+ {'remote_type', anno(), [(Module :: af_atom()) |
+ (TypeName :: af_atom()) |
+ [abstract_type()]]}. % [Module, Name, [T]]
+
+-type af_tuple_type() :: {'type', anno(), 'tuple', 'any'}
+ | {'type', anno(), 'tuple', [abstract_type()]}.
+
+-type af_type_union() :: {'type', anno(), 'union', [abstract_type()]}.
+
+-type af_type_variable() :: {'var', anno(), atom()}. % except '_'
+
+-type af_user_defined_type() ::
+ {'user_type', anno(), type_name(), [abstract_type()]}.
+
+-type af_function_type_list() :: [af_constrained_function_type() |
+ af_function_type()].
+
+-type af_constrained_function_type() ::
+ {'type', anno(), 'bounded_fun', [af_function_type() | % [Ft, Fc]
+ af_function_constraint()]}.
+
+-type af_function_type() ::
+ {'type', anno(), 'fun',
+ [{'type', anno(), 'product', [abstract_type()]} | abstract_type()]}.
+
+-type af_function_constraint() :: [af_constraint()].
+
+-type af_constraint() :: {'type', anno(), 'constraint',
+ af_lit_atom('is_subtype'),
+ [af_type_variable() | abstract_type()]}. % [V, T]
+
+-type af_singleton_integer_type() :: af_integer()
+ | af_unary_op(af_singleton_integer_type())
+ | af_binary_op(af_singleton_integer_type()).
+
+-type af_literal() :: af_atom() | af_integer() | af_float() | af_string().
+
+-type af_atom() :: af_lit_atom(atom()).
+
+-type af_lit_atom(A) :: {'atom', anno(), A}.
+
+-type af_integer() :: {'integer', anno(), non_neg_integer()}.
+
+-type af_float() :: {'float', anno(), float()}.
+
+-type af_string() :: {'string', anno(), string()}.
+
+-type af_match(T) :: {'match', anno(), af_pattern(), T}.
+
+-type af_variable() :: {'var', anno(), atom()}. % | af_anon_variable()
+
+%-type af_anon_variable() :: {'var', anno(), '_'}.
+
+-type af_tuple(T) :: {'tuple', anno(), [T]}.
+
+-type af_nil() :: {'nil', anno()}.
+
+-type af_cons(T) :: {'cons', anno(), T, T}.
+
+-type af_bin(T) :: {'bin', anno(), [af_binelement(T)]}.
+
+-type af_binelement(T) :: {'bin_element',
+ anno(),
+ T,
+ af_binelement_size(),
+ type_specifier_list()}.
+
+-type af_binelement_size() :: 'default' | abstract_expr().
+
+-type af_binary_op(T) :: {'op', anno(), binary_op(), T, T}.
+
+-type binary_op() :: '/' | '*' | 'div' | 'rem' | 'band' | 'and' | '+' | '-'
+ | 'bor' | 'bxor' | 'bsl' | 'bsr' | 'or' | 'xor' | '++'
+ | '--' | '==' | '/=' | '=<' | '<' | '>=' | '>' | '=:='
+ | '=/='.
+
+-type af_unary_op(T) :: {'op', anno(), unary_op(), T}.
+
+-type unary_op() :: '+' | '*' | 'bnot' | 'not'.
+
+%% See also lib/stdlib/{src/erl_bits.erl,include/erl_bits.hrl}.
+-type type_specifier_list() :: 'default' | [type_specifier(), ...].
+
+-type type_specifier() :: type()
+ | signedness()
+ | endianness()
+ | unit().
+
+-type type() :: 'integer'
+ | 'float'
+ | 'binary'
+ | 'bytes'
+ | 'bitstring'
+ | 'bits'
+ | 'utf8'
+ | 'utf16'
+ | 'utf32'.
+
+-type signedness() :: 'signed' | 'unsigned'.
+
+-type endianness() :: 'big' | 'little' | 'native'.
+
+-type unit() :: {'unit', 1..256}.
+
+-type record_name() :: atom().
+
+-type af_field_name() :: af_atom().
+
+-type function_name() :: atom().
+
+-type type_name() :: atom().
+
+%% End of Abstract Format
%% XXX. To be refined.
--type abstract_clause() :: term().
--type abstract_expr() :: term().
--type abstract_form() :: term().
-type error_description() :: term().
-type error_info() :: {erl_anno:line(), module(), error_description()}.
-type token() :: erl_scan:token().
@@ -1083,11 +1489,16 @@ type_preop_prec('-') -> {600,700};
type_preop_prec('bnot') -> {600,700};
type_preop_prec('#') -> {700,800}.
+-type erl_parse_tree() :: abstract_clause()
+ | abstract_expr()
+ | abstract_form()
+ | abstract_type().
+
-spec map_anno(Fun, Abstr) -> NewAbstr when
Fun :: fun((Anno) -> Anno),
Anno :: erl_anno:anno(),
- Abstr :: abstract_form() | abstract_expr(),
- NewAbstr :: abstract_form() | abstract_expr().
+ Abstr :: erl_parse_tree(),
+ NewAbstr :: erl_parse_tree().
map_anno(F0, Abstr) ->
F = fun(A, Acc) -> {F0(A), Acc} end,
@@ -1100,8 +1511,8 @@ map_anno(F0, Abstr) ->
Acc0 :: term(),
AccIn :: term(),
AccOut :: term(),
- Abstr :: abstract_form() | abstract_expr(),
- NewAbstr :: abstract_form() | abstract_expr().
+ Abstr :: erl_parse_tree(),
+ NewAbstr :: erl_parse_tree().
fold_anno(F0, Acc0, Abstr) ->
F = fun(A, Acc) -> {A, F0(A, Acc)} end,
@@ -1115,26 +1526,26 @@ fold_anno(F0, Acc0, Abstr) ->
Acc1 :: term(),
AccIn :: term(),
AccOut :: term(),
- Abstr :: abstract_form() | abstract_expr(),
- NewAbstr :: abstract_form() | abstract_expr().
+ Abstr :: erl_parse_tree(),
+ NewAbstr :: erl_parse_tree().
mapfold_anno(F, Acc0, Abstr) ->
modify_anno1(Abstr, Acc0, F).
-spec new_anno(Term) -> Abstr when
Term :: term(),
- Abstr :: abstract_form() | abstract_expr().
+ Abstr :: erl_parse_tree().
new_anno(Term) ->
map_anno(fun erl_anno:new/1, Term).
-spec anno_to_term(Abstr) -> term() when
- Abstr :: abstract_form() | abstract_expr().
+ Abstr :: erl_parse_tree().
anno_to_term(Abstract) ->
map_anno(fun erl_anno:to_term/1, Abstract).
--spec anno_from_term(Term) -> abstract_form() | abstract_expr() when
+-spec anno_from_term(Term) -> erl_parse_tree() when
Term :: term().
anno_from_term(Term) ->
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index 847def2fd8..1fca3624dc 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -146,7 +146,7 @@ info(_) ->
Tab :: tab(),
Item :: compressed | fixed | heir | keypos | memory
| name | named_table | node | owner | protection
- | safe_fixed | size | stats | type
+ | safe_fixed | safe_fixed_monotonic_time | size | stats | type
| write_concurrency | read_concurrency,
Value :: term().
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index 47adb133b0..aed857aa77 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -305,7 +305,6 @@ options(Option) ->
options([{format, Format} | L], Opts) when Format =:= binary;
Format =:= term;
- is_function(Format),
is_function(Format, 1) ->
options(L, Opts#opts{format = Format});
options([{format, binary_term} | L], Opts) ->
@@ -324,7 +323,7 @@ options([{tmpdir, Dir} | L], Opts) ->
FileName ->
options(L, Opts#opts{tmpdir = {dir, FileName}})
end;
-options([{order, Fun} | L], Opts) when is_function(Fun), is_function(Fun, 2) ->
+options([{order, Fun} | L], Opts) when is_function(Fun, 2) ->
options(L, Opts#opts{order = Fun});
options([{order, Order} | L], Opts) when Order =:= ascending;
Order =:= descending ->
@@ -409,7 +408,7 @@ merge_terms_fun(RFun) ->
case RFun(read) of
end_of_input ->
eof;
- {Objs, NRFun} when is_function(NRFun), is_function(NRFun, 1) ->
+ {Objs, NRFun} when is_function(NRFun, 1) ->
{_, [], Ts, _} = fun_objs(Objs, [], 0, ?MAXSIZE, I, W),
{{I, Ts, ?CHUNKSIZE}, merge_terms_fun(NRFun)};
Error ->
@@ -425,13 +424,12 @@ merge_bins_fun(FileName) ->
Fun(A)
end.
-wrap_output_terms(term, OutFun, _Z) when is_function(OutFun),
- is_function(OutFun, 1) ->
+wrap_output_terms(term, OutFun, _Z) when is_function(OutFun, 1) ->
{fun_wterms(OutFun), true};
wrap_output_terms(term, File, Z) when File =/= undefined ->
{file_wterms(name, File, Z++[write]), false};
wrap_output_terms(_Format, Output, _Z) ->
- {Output, is_function(Output) and is_function(Output, 1)}.
+ {Output, is_function(Output, 1)}.
binary_term_fun() ->
fun binary_to_term/1.
@@ -1309,8 +1307,7 @@ infun(W) ->
{end_of_input, W1};
{end_of_input, Value} ->
{end_of_input, W1#w{inout_value = {value, Value}}};
- {Objs, NFun} when is_function(NFun),
- is_function(NFun, 1),
+ {Objs, NFun} when is_function(NFun, 1),
is_list(Objs) ->
{cont, W#w{in = NFun}, Objs};
Error ->
@@ -1333,7 +1330,7 @@ outfun(A, W) ->
try (W#w.out)(A) of
Reply when A =:= close ->
Reply;
- NF when is_function(NF), is_function(NF, 1) ->
+ NF when is_function(NF, 1) ->
W#w{out = NF};
Error ->
error(Error, W1)
@@ -1358,7 +1355,7 @@ is_keyposs([Bad | _]) ->
is_keyposs(Bad) ->
{badarg, Bad}.
-is_input(Fun) when is_function(Fun), is_function(Fun, 1) ->
+is_input(Fun) when is_function(Fun, 1) ->
{true, Fun};
is_input(Files) ->
is_files(Files).
@@ -1378,7 +1375,7 @@ is_files([], L) ->
is_files(Bad, _L) ->
{badarg, Bad}.
-maybe_output(Fun) when is_function(Fun), is_function(Fun, 1) ->
+maybe_output(Fun) when is_function(Fun, 1) ->
{true, Fun};
maybe_output(File) ->
case read_file_info(File) of
@@ -1587,7 +1584,6 @@ fun_rterms(InFun) ->
(read) ->
case InFun(read) of
{Ts, NInFun} when is_list(Ts),
- is_function(NInFun),
is_function(NInFun, 1) ->
{to_bin(Ts, []), fun_rterms(NInFun)};
Else ->
@@ -1600,7 +1596,7 @@ fun_wterms(OutFun) ->
OutFun(close);
(L) ->
case OutFun(wterms_arg(L)) of
- NOutFun when is_function(NOutFun), is_function(NOutFun, 1) ->
+ NOutFun when is_function(NOutFun, 1) ->
fun_wterms(NOutFun);
Else ->
Else
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index 5dc8b4541e..f510f61e9f 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.erl
@@ -444,7 +444,7 @@ scan_erl_form(Io, Prompt, Pos0, Options) ->
%% Parsing Erlang code.
-type parse_ret() :: {'ok',
- ExprList :: erl_parse:abstract_expr(),
+ ExprList :: [erl_parse:abstract_expr()],
EndLocation :: location()}
| {'eof', EndLocation :: location()}
| {'error',
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index 960c70f255..bc70c296da 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -647,6 +647,9 @@ obsolete_1(random, _, _) ->
obsolete_1(code, rehash, 0) ->
{deprecated, "deprecated because the code path cache feature has been removed"};
+obsolete_1(overload, _, _) ->
+ {deprecated, "deprecated; will be removed in OTP 19"};
+
obsolete_1(_, _, _) ->
no.
diff --git a/lib/stdlib/src/qlc.erl b/lib/stdlib/src/qlc.erl
index 3ba3a88038..24e64efee7 100644
--- a/lib/stdlib/src/qlc.erl
+++ b/lib/stdlib/src/qlc.erl
@@ -808,21 +808,21 @@ options(Options0, [Key | Keys], L) when is_list(Options0) ->
{ok, U};
{pre_fun, U=undefined} ->
{ok, U};
- {info_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
+ {info_fun, Fun} when is_function(Fun, 1) ->
{ok, Fun};
- {pre_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
+ {pre_fun, Fun} when is_function(Fun, 1) ->
{ok, Fun};
- {post_fun, Fun} when is_function(Fun), is_function(Fun, 0) ->
+ {post_fun, Fun} when is_function(Fun, 0) ->
{ok, Fun};
- {lookup_fun, Fun} when is_function(Fun), is_function(Fun, 2) ->
+ {lookup_fun, Fun} when is_function(Fun, 2) ->
{ok, Fun};
{max_lookup, Max} when is_integer(Max), Max >= 0 ->
{ok, Max};
{max_lookup, infinity} ->
{ok, -1};
- {format_fun, Fun} when is_function(Fun), is_function(Fun, 1) ->
+ {format_fun, Fun} when is_function(Fun, 1) ->
{ok, Fun};
- {parent_fun, Fun} when is_function(Fun), is_function(Fun, 0) ->
+ {parent_fun, Fun} when is_function(Fun, 0) ->
{ok, Fun};
{key_equality, KE='=='} ->
{ok, KE};
@@ -885,7 +885,7 @@ options(Options0, [Key | Keys], L) when is_list(Options0) ->
{depth, Depth} when Depth =:= infinity;
is_integer(Depth), Depth >= 0 ->
{ok, Depth};
- {order, Order} when is_function(Order), is_function(Order, 2);
+ {order, Order} when is_function(Order, 2);
(Order =:= ascending);
(Order =:= descending) ->
{ok, Order};
diff --git a/lib/stdlib/src/qlc_pt.erl b/lib/stdlib/src/qlc_pt.erl
index 9577d17a85..9f69cd5003 100644
--- a/lib/stdlib/src/qlc_pt.erl
+++ b/lib/stdlib/src/qlc_pt.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2015. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -200,7 +200,7 @@ exclude_integers_from_unique_line_numbers(Forms, NodeInfo) ->
find_integers(Forms) ->
F = fun(A) ->
- Fs1 = erl_parse:map_anno(fun(_) -> A end, Forms),
+ Fs1 = map_anno(fun(_) -> A end, Forms),
ordsets:from_list(integers(Fs1, []))
end,
ordsets:to_list(ordsets:intersection(F(anno0()), F(anno1()))).
@@ -319,13 +319,13 @@ badarg(Forms, State) ->
E0.
lc_nodes(E, NodeInfo) ->
- erl_parse:map_anno(fun(Anno) ->
- N = erl_anno:line(Anno),
- [{N, Data}] = ets:lookup(NodeInfo, N),
- NData = Data#{inside_lc => true},
- true = ets:insert(NodeInfo, {N, NData}),
- Anno
- end, E).
+ map_anno(fun(Anno) ->
+ N = erl_anno:line(Anno),
+ [{N, Data}] = ets:lookup(NodeInfo, N),
+ NData = Data#{inside_lc => true},
+ true = ets:insert(NodeInfo, {N, NData}),
+ Anno
+ end, E).
used_genvar_messages(MsL, S) ->
[{File,[{Loc,?APIMOD,{used_generator_variable,V}}]}
@@ -416,7 +416,7 @@ intro_anno(LC, Where, QId, NodeInfo) ->
true = ets:insert(NodeInfo, {Location,Data}),
Anno
end,
- erl_parse:map_anno(Fun, save_anno(LC, NodeInfo)).
+ map_anno(Fun, save_anno(LC, NodeInfo)).
compile_errors(FormsNoShadows) ->
case compile_forms(FormsNoShadows, []) of
@@ -1650,7 +1650,7 @@ reset_anno(T) ->
set_anno(T, anno0()).
set_anno(T, A) ->
- erl_parse:map_anno(fun(_L) -> A end, T).
+ map_anno(fun(_L) -> A end, T).
-record(fstate, {state, bind_fun, imported}).
@@ -2609,7 +2609,7 @@ save_anno(Abstr, NodeInfo) ->
true = ets:insert(NodeInfo, Data),
erl_anno:new(N)
end,
- erl_parse:map_anno(F, Abstr).
+ map_anno(F, Abstr).
next_slot(T) ->
I = ets:update_counter(T, var_n, 1),
@@ -2633,7 +2633,7 @@ restore_anno(Abstr, NodeInfo) ->
Anno
end
end,
- erl_parse:map_anno(F, Abstr).
+ map_anno(F, Abstr).
restore_loc(Location, #state{node_info = NodeInfo}) ->
case ets:lookup(NodeInfo, Location) of
@@ -2872,6 +2872,14 @@ var_mapfold(F, A0, [E0 | Es0]) ->
var_mapfold(_F, A, E) ->
{E, A}.
+map_anno(F, AbstrList) when is_list(AbstrList) ->
+ [map_anno1(F, Abstr) || Abstr <- AbstrList];
+map_anno(F, Abstr) ->
+ map_anno1(F, Abstr).
+
+map_anno1(F, Abstr) ->
+ erl_parse:map_anno(F, Abstr).
+
family_list(L) ->
sofs:to_external(family(L)).
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index 7f9bbbf649..b8a7973cf2 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -105,7 +105,7 @@
dets]},
{applications, [kernel]},
{env, []},
- {runtime_dependencies, ["sasl-2.6","kernel-4.1","erts-7.0","crypto-3.3",
+ {runtime_dependencies, ["sasl-2.6","kernel-4.1","erts-7.3","crypto-3.3",
"compiler-5.0"]}
]}.