File 0964-Add-missing-specs-for-et.patch of Package erlang

From 8a16f3b50fd39d36e5e59214e0a399b983ad0a63 Mon Sep 17 00:00:00 2001
From: Dan Gudmundsson <dgud@erlang.org>
Date: Fri, 5 Jan 2024 15:30:52 +0100
Subject: [PATCH 4/4] Add missing specs for et

---
 lib/et/src/et.erl           |  37 ++++++++++
 lib/et/src/et_collector.erl | 136 +++++++++++++++++++++++++++++++-----
 lib/et/src/et_selector.erl  |  26 ++++++-
 lib/et/src/et_viewer.erl    |  39 +++++++++--
 4 files changed, 214 insertions(+), 24 deletions(-)

diff --git a/lib/et/src/et.erl b/lib/et/src/et.erl
index b951439ef3..220a2c884b 100644
--- a/lib/et/src/et.erl
+++ b/lib/et/src/et.erl
@@ -89,6 +89,10 @@
 	 trace_me/5, phone_home/5, report_event/5
         ]).
 
+
+-type actor() :: term().
+-type level() :: 0..100.
+
 %%----------------------------------------------------------------------
 %% Reports an event, such as a message
 %%
@@ -126,26 +130,59 @@
 %% Other events (termed actions) may be undirected and only have one actor.
 %%----------------------------------------------------------------------
 
+-spec trace_me(DetailLevel, FromTo, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      FromTo :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 trace_me(DetailLevel, FromTo, Label, Contents)
   when is_integer(DetailLevel) ->
     ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
 
+-spec trace_me(DetailLevel, From, To, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      From :: actor(),
+      To :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 trace_me(DetailLevel, _From, _To, _Label, _Contents)
   when is_integer(DetailLevel) ->
     hopefully_traced.
 
+-spec phone_home(DetailLevel, FromTo, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      FromTo :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 phone_home(DetailLevel, FromTo, Label, Contents) ->
     %% N.B External call
     ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
 
+-spec phone_home(DetailLevel, From, To, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      From :: actor(),
+      To :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 phone_home(DetailLevel, From, To, Label, Contents) ->
     %% N.B External call
     ?MODULE:trace_me(DetailLevel, From, To, Label, Contents).
 
+-spec report_event(DetailLevel, FromTo, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      FromTo :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 report_event(DetailLevel, FromTo, Label, Contents) ->
     %% N.B External call
     ?MODULE:trace_me(DetailLevel, FromTo, FromTo, Label, Contents).
 
+-spec report_event(DetailLevel, From, To, Label, Contents) -> hopefully_traced when
+      DetailLevel :: level(),
+      From :: actor(),
+      To :: actor(),
+      Label :: atom() | string() | term(),
+      Contents :: [{Key::term(), Value::term()}] | term().
 report_event(DetailLevel, From, To, Label, Contents)
   when is_integer(DetailLevel) ->
     %% N.B External call
diff --git a/lib/et/src/et_collector.erl b/lib/et/src/et_collector.erl
index 835bb380b8..058e7f473f 100644
--- a/lib/et/src/et_collector.erl
+++ b/lib/et/src/et_collector.erl
@@ -87,6 +87,44 @@
 -record(trace_ts, {trace_ts, event_ts}).
 -record(event_ts, {event_ts, trace_ts}).
 
+-type event() :: #event{}.
+-type table_handle() :: #table_handle{}.
+-type event_ts() :: #event_ts{}.
+-type trace_ts() :: #trace_ts{}.
+
+-type collector_fun() :: trace_filter_fun() | event_filter_fun().
+
+-type trace_filter_fun() :: fun((TraceData::tuple()) -> boolean() | {true, event()}).
+-type event_filter_fun() :: fun((Event::event()) -> boolean() | {true, event()}).
+
+-type dbg_match_spec() :: [tuple()].  %% See dbg match specs
+-type dbg_trace_type() :: ip | file | follow_file.   %% See dbg:trace_client
+-type dbg_trace_parameters() :: file:filename() | integer() | {string(), integer()}. %% See dbg:trace_client
+
+-type ets_match_object_pattern() :: term(). %% See ets:match_object()
+
+-type level() :: 0..100.
+
+-type option()::
+        {parent_pid, pid() | undefined} |
+        {event_order, trace_ts | event_ts} |
+        {dict_insert, {filter, all}, collector_fun()} |
+        {dict_insert, {filter, EventFilterName::atom()}, event_filter_fun()} |
+        {dict_insert, {subscriber, pid()}, Val::term()} |
+        {dict_insert, Key::term(), Val::term()} |
+        {dict_delete, Key::term()} |
+        {trace_client, {event_file, file:filename()} |
+         {dbg_trace_type(), dbg_trace_parameters()}} |
+        {trace_global, boolean()} |
+        {trace_pattern, {module() | undefined, Level::level() | dbg_match_spec()} |
+         undefined} |
+        {trace_port, integer()} |
+        {trace_max_queue, integer()}.
+
+-type actor() :: term().
+
+-export_type([option/0]).
+
 %%%----------------------------------------------------------------------
 %%% Client side
 %%%----------------------------------------------------------------------
@@ -163,7 +201,8 @@
 %% CollectorPid = pid()
 %% Reason = term()
 %%----------------------------------------------------------------------
-
+-spec start_link(Options) -> {ok, Pid::pid()} | {error, term()} when
+      Options :: [option()].
 start_link(Options) ->
     case parse_opt(Options, default_state(), [], []) of
 	{ok, S, Dict2, Clients} ->
@@ -266,7 +305,7 @@ start_clients(CollectorPid, []) ->
 %%
 %% CollectorPid = pid()
 %%----------------------------------------------------------------------
-
+-spec stop(CollectorPid::pid()) -> ok.
 stop(CollectorPid) ->
     call(CollectorPid, stop).
 
@@ -295,7 +334,10 @@ stop(CollectorPid) ->
 %% 
 %% The options defaults to existing, write and keep.
 %%----------------------------------------------------------------------
-
+-spec save_event_file(CollectorPid, FileName, [Option]) -> ok | {error, term()} when
+      CollectorPid :: pid(),
+      FileName :: file:filename(),
+      Option :: existing | write | append | keep | clear.
 save_event_file(CollectorPid, FileName, Options) ->
     call(CollectorPid, {save_event_file, FileName, Options}).
 
@@ -309,7 +351,10 @@ save_event_file(CollectorPid, FileName, Options) ->
 %% BadBytes = integer(X) where X >= 0
 %% Reason = term()
 %%----------------------------------------------------------------------
-
+-spec load_event_file(CollectorPid, FileName) ->{ok, BadBytes} when
+      CollectorPid :: pid(),
+      FileName :: file:filename(),
+      BadBytes :: pos_integer().
 load_event_file(CollectorPid, FileName) ->
     Fd = make_ref(),
     Args = [{file, FileName}, {name, Fd}, {repair, true}, {mode, read_only}],
@@ -359,6 +404,11 @@ do_load_event_file(Fun, Fd, Cont, Acc, FileName, BadBytes) ->
 %% Returns: {ok, Continuation} | exit(Reason)
 %%----------------------------------------------------------------------
 
+-spec report(Handle, TraceOrEvent) -> {ok, Continuation} when
+      Handle :: table_handle() | CollectorPid::pid(),
+      TraceOrEvent :: event() | TraceData | end_of_trace,
+      TraceData :: tuple(),
+      Continuation :: table_handle().
 report(CollectorPid, TraceOrEvent) when is_pid(CollectorPid) ->
     case get_table_handle(CollectorPid) of
         {ok, TH} when is_record(TH, table_handle) ->
@@ -411,9 +461,24 @@ report(TH, TraceOrEvent) when is_record(TH, table_handle) ->
 report(_, Bad) ->
     exit({bad_event, Bad}).
 
+-spec report_event(CollectorPid, DetailLevel, FromTo, Label, Contents) -> {ok, Continuation} when
+      CollectorPid :: pid(),
+      DetailLevel :: level(),
+      FromTo :: actor(),
+      Label  :: term(),
+      Contents :: [{Key::term(), Value::term()}] | term(),
+      Continuation :: table_handle().
 report_event(CollectorPid, DetailLevel, FromTo, Label, Contents) ->
     report_event(CollectorPid, DetailLevel, FromTo, FromTo, Label, Contents).
 
+-spec report_event(CollectorPid, DetailLevel, From, To, Label, Contents) -> {ok, Continuation} when
+      CollectorPid :: pid(),
+      DetailLevel :: level(),
+      From :: actor(),
+      To :: actor(),
+      Label  :: term(),
+      Contents :: [{Key::term(), Value::term()}] | term(),
+      Continuation :: table_handle().
 report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
   when is_integer(DetailLevel), 
        DetailLevel >= ?detail_level_min,
@@ -438,6 +503,10 @@ report_event(CollectorPid, DetailLevel, From, To, Label, Contents)
 %% Key = record(event_ts) | record(trace_ts)
 %%----------------------------------------------------------------------
 
+-spec make_key(Handle, Stuff) -> Key when
+      Handle :: table_handle() | trace_ts | event_ts,
+      Stuff :: event() | Key,
+      Key :: event_ts() | trace_ts().
 make_key(TH, Stuff) when is_record(TH, table_handle) ->
     make_key(TH#table_handle.event_order, Stuff);
 make_key(trace_ts, Stuff) ->
@@ -490,7 +559,7 @@ get_table_handle(CollectorPid) when is_pid(CollectorPid) ->
 %% CollectorPid = pid()
 %% Reason = term()
 %%----------------------------------------------------------------------
-
+-spec get_global_pid() -> CollectorPid :: pid().
 get_global_pid() ->
     case global:whereis_name(?MODULE) of
         CollectorPid when is_pid(CollectorPid) ->
@@ -512,7 +581,10 @@ get_global_pid() ->
 %% detail_level() = min | max | integer(X) when X =< 0, X >= 100
 %% TracePattern = {report_module(), dbg_match_spec_match_spec()}
 %%----------------------------------------------------------------------
-
+-spec change_pattern(CollectorPid, RawPattern) -> {old_pattern, TracePattern} when
+      CollectorPid :: pid(),
+      RawPattern :: {module(), min | max | level()},
+      TracePattern :: [{[term()] | '_' | atom(), [term()], [term()]}].
 change_pattern(CollectorPid, RawPattern) ->
     Pattern = et_selector:make_pattern(RawPattern),
     call(CollectorPid, {change_pattern, Pattern}).
@@ -542,7 +614,11 @@ change_pattern(CollectorPid, RawPattern) ->
 %% Key = term()
 %% Val = term()
 %%----------------------------------------------------------------------
-
+-spec dict_insert(CollectorPid, What, Value) -> ok when
+      CollectorPid :: pid(),
+      What :: {filter, atom()} | {subscriber, pid()} | Key,
+      Key  :: term(),
+      Value :: collector_fun() | term().
 dict_insert(CollectorPid, Key = {filter, Name}, Fun) ->
     if
 	is_atom(Name), is_function(Fun) ->
@@ -569,14 +645,14 @@ dict_insert(CollectorPid, Key, Val) ->
 %% Key = term()
 %% Val = term()
 %%----------------------------------------------------------------------
-
+-spec dict_lookup(CollectorPid::pid(), Key::term()) -> [Val::term()].
 dict_lookup(CollectorPid, Key) ->
     call(CollectorPid, {dict_lookup, Key}).
 
 %%----------------------------------------------------------------------
-%% Ddict_delete(CollectorPid, Key) -> ok
+%% dict_delete(CollectorPid, Key) -> ok
 %%
-%% elete a dictionary entry
+%% Delete a dictionary entry
 %% and send a {et, {dict_delete, Key}} tuple
 %% to all registered subscribers.
 %%
@@ -591,7 +667,7 @@ dict_lookup(CollectorPid, Key) ->
 %% SubscriberPid = pid()
 %% Key = term()
 %%----------------------------------------------------------------------
-
+-spec dict_delete(CollectorPid::pid(), Key::term()) -> ok.
 dict_delete(CollectorPid, Key) ->
     call(CollectorPid, {dict_delete, Key}).
 
@@ -608,7 +684,10 @@ dict_delete(CollectorPid, Key) ->
 %% key() = term()
 %% val() = term()
 %%----------------------------------------------------------------------
-
+-spec dict_match(CollectorPid::pid(), {KeyPattern, ValPattern}) -> [Match] when
+      KeyPattern :: ets_match_object_pattern(),
+      ValPattern :: ets_match_object_pattern(),
+      Match :: {Key::term(), Val::term()}.
 dict_match(CollectorPid, Pattern)  ->
     call(CollectorPid, {dict_match, Pattern}).
 
@@ -620,7 +699,7 @@ dict_match(CollectorPid, Pattern)  ->
 %% CollectorPid = pid()
 %% Msg = term()
 %%----------------------------------------------------------------------
-
+-spec multicast(CollectorPid :: pid(), Msg::term()) -> ok.
 multicast(_CollectorPid, Msg = {dict_insert, _Key, _Val}) ->
     exit({badarg, Msg});
 multicast(_CollectorPid, Msg = {dict_delete, _Key}) ->
@@ -638,7 +717,10 @@ multicast(CollectorPid, Msg) ->
 %% Parameters = dbg_trace_client_parameters()
 %% Pid        = dbg_trace_client_pid()
 %%----------------------------------------------------------------------
-
+-spec start_trace_client(CollectorPid, Type, Parameter) -> file_loaded | {trace_client_pid, pid()} when
+      CollectorPid :: pid(),
+      Type :: event_file | dbg_trace_type(),
+      Parameter :: dbg_trace_parameters().
 start_trace_client(CollectorPid, Type, FileName) when Type =:= event_file ->
     load_event_file(CollectorPid, FileName);
 start_trace_client(CollectorPid, Type, FileName) when Type =:= file -> 
@@ -697,7 +779,15 @@ monitor_trace_port(CollectorPid, Parameters) ->
 %% 
 %% Short for iterate/5.
 %%----------------------------------------------------------------------
-
+-spec iterate(Handle, Prev, Limit) -> NewAcc when
+      Handle :: CollectorPid | table_handle(),
+      CollectorPid :: pid(),
+      Prev :: first | last | term(),
+      Limit :: Done | Forward | Backward,
+      Done :: 0,
+      Forward :: pos_integer(),
+      Backward :: neg_integer(),
+      NewAcc :: term().
 iterate(Handle, Prev, Limit) ->
     iterate(Handle, Prev, Limit, undefined, Prev).
 
@@ -720,7 +810,17 @@ iterate(Handle, Prev, Limit) ->
 %% Fun = fun(Event, Acc) -> NewAcc
 %% Acc = NewAcc = term()
 %%----------------------------------------------------------------------
-
+-spec iterate(Handle, Prev, Limit, Fun, Acc) -> NewAcc when
+      Handle :: CollectorPid | table_handle(),
+      CollectorPid :: pid(),
+      Prev :: first | last | term(),
+      Limit :: Done | Forward | Backward,
+      Done :: 0,
+      Forward :: pos_integer() | 'infinity',
+      Backward :: neg_integer() | '-infinity',
+      Fun :: fun((event(), Acc) -> NewAcc) | undefined,
+      Acc :: term(),
+      NewAcc :: term().
 iterate(_, _, Limit, _, Acc) when Limit =:= 0 ->
     Acc;
 iterate(CollectorPid, Prev, Limit, Fun, Acc) when is_pid(CollectorPid) ->
@@ -858,7 +958,9 @@ incr(Val, Incr) ->
 %% collector_pid() = pid()
 %% table_handle() = record(table_handle)
 %%----------------------------------------------------------------------
-
+-spec clear_table(Handle) -> ok when
+      Handle :: CollectorPid | table_handle(),
+      CollectorPid :: pid().
 clear_table(CollectorPid) when is_pid(CollectorPid) ->
     call(CollectorPid, clear_table);
 clear_table(TH) when is_record(TH, table_handle) ->
diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl
index 18a7e66b1d..e83088d823 100644
--- a/lib/et/src/et_selector.erl
+++ b/lib/et/src/et_selector.erl
@@ -31,6 +31,10 @@
 
 -include("../include/et.hrl").
 
+-type event() :: #event{}.
+
+-type level() :: 0..100.
+
 %%----------------------------------------------------------------------
 %% make_pattern(RawPattern) -> TracePattern
 %%
@@ -46,7 +50,9 @@
 %%   max       - maximum level of tracing  (all calls to trace_me/4,5)
 %%   integer() - explicit detail level of tracing
 %%----------------------------------------------------------------------
-
+-spec make_pattern({Mod::module(), RawPattern}) -> {Mod::module(), TracePattern} when
+      RawPattern :: level(),
+      TracePattern :: [{[term()] | '_' | atom(), [term()], [term()]}].
 make_pattern(undefined) ->
     {undefined, undefined};
 make_pattern({Mod, Pattern}) when is_atom(Mod) ->
@@ -93,7 +99,11 @@ make_pattern({Mod, Pattern}) when is_atom(Mod) ->
 %% Other match specs activates tracing of calls to trace_me/4,5
 %% accordingly with erlang:trace_pattern/2.
 %%----------------------------------------------------------------------
-
+-spec change_pattern({Mod::module(), Pattern}) -> ok when
+      Pattern :: DetailLevel | TracePattern | EmptyTracePattern,
+      DetailLevel :: level(),
+      TracePattern :: [{[term()] | '_' | atom(), [term()], [term()]}],
+      EmptyTracePattern :: [].
 change_pattern({Mod, Pattern}) when is_atom(Mod) ->
     MFA = {Mod, trace_me, 5},
     case Pattern of
@@ -176,7 +186,17 @@ error_to_exit({ok, _Res}) ->
 %%   false         - means that the trace data is uninteresting and
 %%                   should be dropped
 %%----------------------------------------------------------------------
-
+-spec parse_event(Mod, ValidTraceData) -> boolean | {true, event()} when
+      Mod :: module(),
+      ValidTraceData :: ErlangTraceData | event(),
+      ErlangTraceData ::
+        {trace, pid(), atom(), term()} |
+        {trace, pid(), atom(), term(), term()} |
+        {trace_ts, pid(), atom(), term(), TS::{integer(), integer(), integer()}} |
+        {trace_ts, pid(), atom(), term(), term(), TS::{integer(), integer(), integer()}} |
+        {seq_trace, atom(), term()} |
+        {seq_trace, atom(), term(), TS::{integer(), integer(), integer()}} |
+        {drop, integer()}.
 parse_event(_Mod, E) when is_record(E, event) ->
     true;
 parse_event(Mod, Trace) ->
diff --git a/lib/et/src/et_viewer.erl b/lib/et/src/et_viewer.erl
index 3928764c7f..d3e2c2f409 100644
--- a/lib/et/src/et_viewer.erl
+++ b/lib/et/src/et_viewer.erl
@@ -40,6 +40,24 @@
 
 -define(unknown, "UNKNOWN").
 
+-type actors() :: [term()].
+-type first_key() :: term().
+-type option() ::
+        {title, string()} |
+        {detail_level, 0..100} |
+        {is_suspended, boolean()} |
+        {scale, integer()} |
+        {width, integer()} |
+        {height, integer()}|
+        {collector_pid, pid() | undefined} |
+        {active_filter, atom()} |
+        {max_events, integer() | undefined} |
+        {max_actors, integer() | undefined} |
+        {actors, actors()} |
+        {first_event, first_key()} |
+        {hide_unknown, boolean()} |
+        {hide_actions, boolean()} |
+        {display_mode, all | {search_actors, forward | reverse, first_key(), actors()}}.
 
 %%%----------------------------------------------------------------------
 %%% Client side
@@ -55,7 +73,7 @@
 %% ViewerPid = pid()
 %% Reason = term()
 %%----------------------------------------------------------------------
-
+-spec file(FileName::file:filename()) -> {ok, pid()} | {error, term()}.
 file(FileName) ->
     start_link([{trace_client, {file, FileName}}], default).
 
@@ -70,18 +88,25 @@ file(FileName) ->
 %% processes are unlinked from the calling process.
 %%----------------------------------------------------------------------
 
+-spec start() -> {ok, pid()} | {error, term()}.
 start() ->
     start([{trace_global, true}], default).
 
 %%----------------------------------------------------------------------
 %% start(Options) -> {ok, ViewerPid} | {error, Reason}
 %%----------------------------------------------------------------------
-
+-spec start(GUIorOptions) -> {ok, Viewer::pid()} | {error, term()} when
+      GUIorOptions :: wx | default | Options,
+      Options :: [option() | et_collector:option()].
 start(GUI) when GUI =:= wx; GUI =:= default ->
     start_link([{trace_global, true}], GUI);
 start(Options) ->
     start_link([{parent_pid, undefined} | Options], default).
 
+-spec start(Options, GUI) -> {ok, Viewer::pid()} | {error, term()} when
+      GUI :: wx | default,
+      Options :: [option() | et_collector:option()].
+
 start(Options, GUI) ->
     start_link([{parent_pid, undefined} | Options], GUI).
 
@@ -139,12 +164,17 @@ start(Options, GUI) ->
 %% A filter_fun() takes an event record as sole argument
 %% and returns false | true | {true, NewEvent}.
 %%----------------------------------------------------------------------
-
+-spec start_link(GUIorOptions) -> {ok, Viewer::pid()} | {error, term()} when
+      GUIorOptions :: wx | default | Options,
+      Options :: [option() | et_collector:option()].
 start_link(GUI) when GUI =:= wx; GUI =:= default ->
     start_link([{trace_global, true}], GUI);
 start_link(Options) ->
     start_link(Options, default).
 
+-spec start_link(Options, GUI) -> {ok, Viewer::pid()} | {error, term()} when
+      GUI :: wx | default,
+      Options :: [option() | et_collector:option()].
 start_link(Options, GUI) -> 
     case GUI of
 	wx ->
@@ -155,6 +185,7 @@ start_link(Options, GUI) ->
 
 which_gui() -> wx.
 
+-spec get_collector_pid(ViewerPid::pid()) -> pid().
 get_collector_pid(ViewerPid) ->
     call(ViewerPid, get_collector_pid).
 
@@ -165,7 +196,7 @@ get_collector_pid(ViewerPid) ->
 %% 
 %% ViewerPid = pid()
 %%----------------------------------------------------------------------
-
+-spec stop(ViewerPid::pid()) -> ok.
 stop(ViewerPid) ->
     call(ViewerPid, stop).
 
-- 
2.35.3

openSUSE Build Service is sponsored by