1%%% This file is part of PropEr.
2%%%
3%%% PropEr is free software: you can redistribute it and/or modify
4%%% it under the terms of the GNU General Public License as published by
5%%% the Free Software Foundation, either version 3 of the License, or
6%%% (at your option) any later version.
7%%%
8%%% PropEr is distributed in the hope that it will be useful,
9%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
10%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11%%% GNU General Public License for more details.
12%%%
13%%% You should have received a copy of the GNU General Public License
14%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>.
15%%%
16%%% Alternatively, you may use this file under the terms of the Apache
17%%% License, Version 2.0 (the "License"); you may not use this file
18%%% except in compliance with the License. You may obtain a copy of
19%%% the License at <http://www.apache.org/licenses/LICENSE-2.0>
20%%%
21%%% Unless required by applicable law or agreed to in writing, software
22%%% distributed under the License is distributed on an "AS IS" BASIS,
23%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24%%% See the License for the specific language governing permissions and
25%%% limitations under the License.
26%%%
27%%% If you wish to allow use of your version of this file only under
28%%% the terms of the Apache License, you should delete the provisions
29%%% above and replace them with the notice and other provisions
30%%% required by the Apache License; see
31%%% <http://www.apache.org/licenses/LICENSE-2.0>. If you do not delete
32%%% the provisions above, a recipient may use your version of this
33%%% file under the terms of either the GNU General Public License or
34%%% the Apache License.
35
36%%%
37%%% @doc PropEr generator of abstract code
38%%%
39%%% <p>This module is a PropEr generator for abstract code. It
40%%% generates guards, expressions, programs (modules), and terms. It
41%%% does not generate macros or other attributes than `function',
42%%% `record', `spec', and `type'. The generated programs (guards,
43%%% expressions) can be used for testing the Compiler or other modules
44%%% traversing programs as abstract forms. Typical examples of the
45%%% latter are <code>erl_eval</code>, <code>erl_pp</code>,
46%%% <code>erl_prettypr</code> (Syntax Tools), and parse transforms.
47%%% Created modules should compile without errors, but will most likely
48%%% crash immediately when invoked.</p>
49%%%
50%%% <p>This is an example how to test the Compiler:</p>
51%%%
52%%% ```
53%%% test() ->
54%%%     ?FORALL(Abstr, proper_erlang_abstract_code:module(),
55%%%             ?WHENFAIL(
56%%%                begin
57%%%                    io:format("~ts\n", [[erl_pp:form(F) || F <- Abstr]]),
58%%%                    compile(Abstr, [report_errors])
59%%%                end,
60%%%                case compile(Abstr, []) of
61%%%                    {error, _Es, _Ws} -> false;
62%%%                    _ -> true
63%%%                end)).
64%%%
65%%% compile(Abstr, Opts) ->
66%%%     compile:noenv_forms(Abstr, Opts).
67%%% '''
68-module(proper_erlang_abstract_code).
69
70-export([module/0, module/1, guard/0, guard/1, expr/0, expr/1]).
71
72-export([term/0, term/1]).
73
74%-compile(export_all). -compile(nowarn_export_all).
75
76%-define(debug, true).
77-ifdef(debug).
78-define(DEBUG(F, As), io:format(F, As)).
79-else.
80-define(DEBUG(F, AS), ok).
81-endif.
82
83-include("proper_internal.hrl").
84
85-type char_fun() :: fun(() -> proper_types:type()).
86%%% A function that generates characters. The default function
87%%% chooses from <code>$a..$z | $A..$Z</code>.
88
89-type atom_fun() :: fun(() -> proper_types:type()).
90%%% A function that generates atoms. The default function chooses
91%%% from 100 common English words.
92
93-type weight() :: non_neg_integer().
94-type limit() :: non_neg_integer().
95
96-type option() ::
97        {'variables', [atom()]} |
98        {'weight', {Key :: atom(), Weight :: weight()}} |
99        {'function', [{FunctionName :: atom(), Arity :: arity()}]} |
100        {'types', [{TypeName :: atom(), NumOfParms :: arity()}]} |
101        {'records', [{RecordName:: atom(), [FieldName :: atom()]}]} |
102        {'limit', [{Name :: atom(), Limit :: limit()}]} |
103        {'char', char_fun()} |
104        {'atom', atom_fun()} |
105        {'set_all_weights', weight()}.
106%%% See description below.
107
108-type fa() :: {atom(), arity()}.   % function+arity
109-type ta() :: {atom(), arity()}.   % type+arity
110-type rec() :: {RecordName :: atom(), [FieldName :: atom()]}.
111
112-record(gen_state,
113        {
114         size = 0 :: proper_gen:size(),
115         result_type = 'program' :: 'program' | 'guard' | 'expr' | 'term',
116         functions = [] :: [fa()],
117         functions_and_auto_imported = [] :: [{weight(), fa()}],
118         expr_bifs = [] :: [fa()],
119         guard_bifs = [] :: [fa()],
120         named_funs = [] :: [fa()],
121         records = [] :: [rec()],
122         guard_records = [] :: [rec()],
123         types = [] :: [ta()],
124         predef_types = [] :: [ta()],
125         module :: module(),
126         options = [] :: [option()],
127         weights = #{} :: #{Key :: atom() => Weight :: weight()},
128         limits = #{} :: #{Key :: atom() => Limit :: limit()},
129         variables = ordsets:new() :: ordsets:ordset(atom()),
130         simple_char = fun default_simple_char/0 :: char_fun(),
131         atom = fun default_atom/0 :: atom_fun(),
132         resize = 'false' :: boolean()
133        }).
134
135-record(post_state,
136        {
137         context = 'expr' :: 'expr' | 'type' | 'record' | 'pattern',
138         vars = ordsets:new() :: ordsets:ordset(atom()),
139         vindex = 0 :: non_neg_integer(),
140         forbidden = ordsets:new() :: ordsets:ordset(atom()),
141         known_functions = [] :: [fa()],
142         atom = fun default_atom/0 :: atom_fun()
143        }).
144
145-define(DEFAULT_SMALL_WEIGHT_PROGRAM, 50). % Needs to be quite high.
146-define(DEFAULT_SMALL_WEIGHT_TERM, 50).
147
148-define(MAX_CALL_ARGS, 2).
149-define(MAX_FUNCTION_CLAUSES, 2).
150
151-define(MAX_QUALIFIERS, 2).
152-define(MAX_IF_CLAUSES, 2).
153-define(MAX_CATCH_CLAUSES, 2).
154-define(MAX_CLAUSES, 2).
155-define(MAX_BODY, 2).
156-define(MAX_GUARD, 2).
157-define(MAX_GUARD_TESTS, 2).
158-define(MAX_MAP, 2).
159-define(MAX_TYPE_SPECIFIER, 2).
160-define(MAX_RECORD_FIELDS, 3).
161-define(MAX_TUPLE, 2).
162-define(MAX_BIN_ELEMENTS, 2).
163
164-define(MAX_FUNCTION_TYPES, 2).
165-define(MAX_FUNCTION_CONSTRAINTS, 2).
166-define(MAX_UNION_TYPES, 4).
167-define(MAX_TUPLE_TYPES, 2).
168
169-define(MAX_LIST, 4).
170-define(MAX_STRING, 4).
171
172%%% "div 2" is just a suggestion.
173-define(RESIZE(S), S#gen_state{size = S#gen_state.size div 2}).
174
175%%% @doc Returns abstract code of a term that can be handled by
176%%% <code>erl_parse:normalise/0</code>.
177
178%%% No pid() or port().
179
180-spec term() -> proper_types:type().
181
182term() ->
183    term([]).
184
185%%% @doc Same as {@link term/0}, but accepts a list of options.
186%%% === Options ===
187%%%
188%%% Many options are the same as the ones for {@link module/1}.
189%%% <ul>
190%%% <li><code>{atom, {@link atom_fun()}}</code> - A atom generating
191%%%    function to replace the default.</li>
192%%% <li><code>{char, {@link char_fun()}}</code> - A character generating
193%%%    function to replace the default. The function is used when
194%%%    generating strings and characters.</li>
195%%% <li><code>{limit, [{Name, Limit}]}</code> - Set the limit of
196%%%    <code>Name</code> to <code>Limit</code>. The limit names are:
197%%%   <ul>
198%%%     <li><code>bin_elements</code> - Number of segments of a bitstring.</li>
199%%%     <li><code>list</code> - Number of elements of a plain list.</li>
200%%%     <li><code>map</code> - Number of associations of a map.</li>
201%%%     <li><code>string</code> - Number of characters of a string.</li>
202%%%     <li><code>tuple</code> - Number of elements of a tuple.</li>
203%%%   </ul>
204%%% </li>
205%%% <li><code>{resize, boolean()}</code> - Use <code>?SIZED</code>
206%%%    to limit the size of the generated abstract code. With this
207%%%    option set to <code>false</code> (the default) big code
208%%%    may be generated among the first instances.</li>
209%%% <li><code>{set_all_weights, Weight}</code> - Set the weight of
210%%%    all keys to <code>Weight</code>.</li>
211%%% <li><code>{weight, {Key, Weight}}</code> - Set the weight of
212%%%    <code>Key</code> to weight <code>Weight</code>. A weight of zero
213%%%    means that a construct is not generated. Higher weights means that
214%%%    a construct i generated relatively often. Groups of weight keys
215%%%    follow. Notice that the weight of a key is relative to other
216%%%    keys of the same group. The weight of <code>small</code> needs
217%%%    to quite high to avoid generating too deeply nested abstract
218%%%    code.</li> <ul>
219%%%      <li>Atomic expressions (<code>small</code>): <code>atom, boolean,
220%%%        integer, string, char, float, nil</code></li>
221%%%      <li>Compound terms: <code>small, bitstring, list, tuple,
222%%%        map, 'fun'</code></li>
223%%%      <li>Map expressions (<code>map</code>): <code>build_map</code></li>
224%%%      <li>List expressions (<code>list</code>): <code>plain_list,
225%%%        cons</code></li>
226%%%      <li>Bitstrings (<code>bitstring</code>): <code>bits, bytes</code></li>
227%%%      <li>Function expressions (<code>'fun'</code>):
228%%%        <code>ext_mfa</code></li>
229%%%    </ul>
230%%% </ul>
231
232-spec term(Options :: [option()]) -> proper_types:type().
233
234term(Opts) ->
235    PreOpts = [{set_all_weights, 0}],
236    Tags = [compound, small, bitstring, list, tuple, map, 'fun',
237            atom, boolean, integer, string, char, float, nil,
238            bits, bytes,
239            plain_list, cons,
240            build_map,
241            ext_mfa],
242    WOpts = ([{weight, {small, ?DEFAULT_SMALL_WEIGHT_TERM}}]
243             ++ [{weight, {T, 1}} || T <- Tags]),
244    BadOpts = [Opt ||
245                  {weight, {T, _}} = Opt <- Opts,
246                  not lists:member(T, Tags)],
247    case BadOpts =:= [] andalso options(PreOpts ++ WOpts ++ Opts) of
248        false ->
249            erlang:error(badarg);
250        S0 ->
251            S1 = S0#gen_state{result_type = term},
252            S = eval_dependencies(S1),
253            ?LET(E,
254                 ?SIZED(Size, compound(S#gen_state{size = Size})),
255                 begin
256                     #gen_state{functions = Funs, atom = AtomGen} = S,
257                     [Term] = post_process([E], Funs, AtomGen, []),
258                     Term
259                 end)
260    end.
261
262%%% @doc Returns abstract code of a module.
263%%% The module has type declarations, functions, function specifications,
264%%% and record declarations.
265
266-spec module() -> proper_types:type().
267
268module() ->
269    module([]).
270
271%%% @doc Same as {@link module/0}, but accepts a list of options.
272%%% === Options ===
273%%%
274%%% <ul>
275%%% <li><code>{atom, {@link atom_fun()}}</code> - A atom generating
276%%%    function to replace the default.</li>
277%%% <li><code>{char, {@link char_fun()}}</code> - A character generating
278%%%    function to replace the default. The function is used when
279%%%    generating strings and characters.</li>
280%%% <li><code>{functions, [{Name, Arity}]}</code> - A list of FAs to
281%%%    be used as names of generated functions. The default is a small
282%%%    number of functions with a small number of arguments.</li>
283%%% <li><code>{limit, [{Name, Limit}]}</code> - Set the limit of
284%%%    <code>Name</code> to <code>Limit</code>. The limit names are:
285%%%   <ul>
286%%%     <li><code>bin_elements</code> - Number of segments of a bitstring.</li>
287%%%     <li><code>list</code> - Number of elements of a plain list.</li>
288%%%     <li><code>map</code> - Number of associations of a map.</li>
289%%%     <li><code>string</code> - Number of characters of a string.</li>
290%%%     <li><code>tuple</code> - Number of elements of a tuple.</li>
291%%%     <li><code>body</code> - Number of clauses of a body.</li>
292%%%     <li><code>call_args</code> - Number of arguments of function call.</li>
293%%%     <li><code>catch_clauses</code> - Number of clauses of the
294%%%       <code>catch</code> part of a <code>try/catch</code>.</li>
295%%%     <li><code>clauses</code> - Number of clauses of <code>case</code>,
296%%%       the <code>of</code> part of <code>try/catch</code>, and
297%%%       <code>receive</code>.</li>
298%%%     <li><code>function_clauses</code> - Number of clauses of
299%%%       a function.</li>
300%%%     <li><code>function_constraints</code> - Number of constraints of
301%%%       a function specification.</li>
302%%%     <li><code>function_constraints</code> - Number of constraints of
303%%%       a function specification.</li>
304%%%     <li><code>function_types</code> - Number of types of
305%%%       an overloaded function specification.</li>
306%%%     <li><code>guard</code> - Number of guards of a clause.</li>
307%%%     <li><code>guard_tests</code> - Number of guard tests of a guard.</li>
308%%%     <li><code>if_clauses</code> - Number of clauses of
309%%%       <code>if</code>.</li>
310%%%     <li><code>tuple_types</code> - Number of types (elements)
311%%%       of tuple types.</li>
312%%%     <li><code>qualifiers</code> - Number of qualifiers
313%%%       of comprehensions.</li>
314%%%     <li><code>record_fields</code> - Number of fields of record
315%%%       declarations.</li>
316%%%     <li><code>tsl</code> - Number of elements of
317%%%       type specifier lists (of segments of bit syntax expressions).</li>
318%%%     <li><code>union_types</code> - Number of types of type
319%%%       union.s</li>
320%%%   </ul>
321%%% </li>
322%%% <li><code>{records, [{Name, [Field]}]}</code> - A list
323%%%    of record names with field names  to be used as names of
324%%%    generated records. The default is a small number of records
325%%%    with a small number of fields.</li>
326%%% <li><code>{types, [{Name, NumOfParameters}]}</code> - A list
327%%%    of TAs to be used as names of generated types. The default
328%%%    is a small number of types.</li>
329%%% <li><code>{resize, boolean()}</code> - Use <code>?SIZED</code>
330%%%    to limit the size of the generated abstract code. With this
331%%%    option set to <code>false</code> (the default) big code
332%%%    may be generated among the first instances.</li>
333%%% <li><code>{set_all_weights, Weight}</code> - Set the weight of
334%%%    all keys to <code>Weight</code>.</li>
335%%% <li><code>{weight, {Key, Weight}}</code> - Set the weight of
336%%%    <code>Key</code> to weight <code>Weight</code>. A weight of zero
337%%%    means that a construct is not generated. Higher weights means that
338%%%    a construct i generated relatively often. Groups of weight keys
339%%%    follow. Notice that the weight of a key is relative to other
340%%%    keys of the same group. Also notice that some keys occur in
341%%%    more than one group, which makes it all more complicated. The
342%%%    weight of <code>small</code> needs to be quite high to avoid
343%%%    generating too deeply nested abstract code.</li>
344%%%    <ul>
345%%%      <li>Declarations: <code>record_decl, type_decl, function_decl,
346%%%        function_spec</code> (<code>type_decl</code> and
347%%%        <code>function_spec</code> are off by default)</li>
348%%%      <li>Atomic expressions (<code>small</code>): <code>atom, boolean,
349%%%        integer, string, char, float, nil, pat_var, var</code></li>
350%%%      <li>Compound expressions: <code>small, bitstring, list, tuple,
351%%%        map, match, binop, unop, record, 'case', block, 'if', 'fun',
352%%%        'receive', 'try', 'catch', try_of, termcall, varcall, localcall,
353%%%        extcall</code> (<code>termcall</code> is off by default)</li>
354%%%      <li>Map expressions (<code>map</code>): <code>build_map,
355%%%        update_map</code></li>
356%%%      <li>List expressions (<code>list</code>): <code>plain_list, cons,
357%%%        lc</code></li>
358%%%      <li>Qualifiers (of <code>lc</code>): <code>lc_gen, blc_gen,
359%%%        lc_any_filter, lc_guard_filter</code></li>
360%%%      <li>Bitstrings (<code>bitstring</code>): <code>bits, blc,
361%%%        literal_bits</code></li>
362%%%      <li>Try after (<code>'try', try_of</code>): <code>no_try_after,
363%%%        try_after</code></li>
364%%%      <li>Catch clause exception types (<code>'catch'</code>):
365%%%        <code>no_eclass, any_eclass, lit_eclass, var_eclass,
366%%%         bad_eclass</code></li>
367%%%      <li>Receive timouts (<code>'receive'</code>): <code>
368%%%         lit_timeout, inf_timeout, var_timeout</code></li>
369%%%      <li>Function expressions (<code>'fun'</code>): <code>
370%%%         lambda, rec_lambda, local_mfa, ext_mfa, any_mfa</code></li>
371%%%      <li>Guards: <code>no_guard, yes_guard</code></li>
372%%%      <li>Guard test: <code>small, tuple, map, cons, plain_list, bits,
373%%%         binop, unop, record, guard_call, remote_guard_call</code></li>
374%%%      <li>Pattern: <code>small, match, tuple, cons, plain_list, bits,
375%%%         unop, binop, record, map_pattern, string_prefix</code></li>
376%%%      <li>Pattern variables (<code>pat_var</code>):
377%%%         <code>fresh_var, bound_var</code></li>
378%%%      <li>Record field initialization (the <code>_ = V</code> syntax):
379%%%         <code>yes_multi_field_init, no_multi_field_init</code></li>
380%%%      <li>String prefix (<code>string_prefix</code>): <code>
381%%%         nil, string, string_prefix_list</code></li>
382%%%      <li>Types: <code>annotated_type, atom, bitstring, 'fun',
383%%%         integer_range_type, nil, map, predefined_type, record,
384%%%         remote_type, singleton_integer_type, tuple, type_union,
385%%%         type_variable, user_defined_type</code></li>
386%%%      <li>Function specifications: <code>yes_constrained_function_type,
387%%%         no_constrained_function_type</code></li>
388%%%      <li>Overloaded function specifications: <code>
389%%%         no_overloaded, yes_overloaded</code></li>
390%%%      <li>Singleton integer type (<code>singleton_integer_type</code>):
391%%%         <code>integer, char, unop, binop</code></li>
392%%%    </ul>
393%%% </ul>
394
395-spec module(Options :: [option()]) -> proper_types:type().
396
397module(Opts)  when is_list(Opts) ->
398    case options(Opts) of
399        false ->
400            erlang:error(badarg);
401        State0 ->
402            TopTags = [record_decl, type_decl, function_decl, function_spec],
403            TagWeights = get_weights(TopTags, State0),
404            ?DEBUG(" TagWeights ~p\n", [TagWeights]),
405            State = set_up(State0),
406            FormsL = [form(TW, TagWeights, State) || TW <- TagWeights],
407            Fs = ([{attribute, anno(), module, State#gen_state.module}]
408                  ++ lists:append(FormsL)),
409            #gen_state{functions = Funs, atom = AtomGen} = State,
410            true = length(Funs) > 0,
411            ?SUCHTHAT(T,
412                      ?LET(P,
413                           Fs,
414                           post_process(P, Funs, AtomGen, [])),
415                      ok_by_the_linter(forms, T))
416    end.
417
418%%% @doc Returns abstract code of a guard. A guard is a sequence
419%%% of guard tests.
420
421-spec guard() -> proper_types:type().
422
423guard() ->
424    guard([]).
425
426%%% @doc Same as {@link guard/0}, but accepts a list of options. See
427%%% {@link module/1} for a description of the options.
428
429-spec guard(Options :: [option()]) -> proper_types:type().
430
431guard(Opts)  when is_list(Opts) ->
432    case options(Opts) of
433        false ->
434            erlang:error(badarg);
435        State0 ->
436            State1 = State0#gen_state{result_type = guard},
437            State = set_up(State1),
438            ?LET(G,
439                 ?SIZED(Size, a_guard(State#gen_state{size = Size})),
440                 begin
441                     #gen_state{functions = Funs,
442                                atom = AtomGen,
443                                variables = Vars} = State,
444                     [Guard] = post_process([G], Funs, AtomGen, Vars),
445                     Guard
446                 end)
447    end.
448
449%%% @doc Returns abstract code of an expression.
450
451-spec expr() -> proper_types:type().
452
453expr() ->
454    expr([]).
455
456%%% @doc Same as {@link expr/0}, but accepts a list of options. See
457%%% {@link module/1} for a description of the options.
458
459-spec expr(Options :: list()) -> proper_types:type().
460
461expr(Opts)  when is_list(Opts) ->
462    case options(Opts) of
463        false ->
464            erlang:error(badarg);
465        State0 ->
466            State1 = State0#gen_state{result_type = expr,
467                                      functions = []},
468            State2 = set_up(State1),
469            ?SUCHTHAT(Expr,
470                      ?LET(E1,
471                           ?SIZED(Size,
472                                  begin
473                                      State = State2#gen_state{size = Size},
474                                      abstract_expr(State)
475                                  end),
476                           begin
477                               #gen_state{functions = Funs,
478                                          atom = AtomGen,
479                                          variables = Vars} = State2,
480                               [E2] = post_process([E1], Funs, AtomGen, Vars),
481                               E2
482                           end),
483                      ok_by_the_linter(expr, Expr))
484    end.
485
486set_up(S0) ->
487    #gen_state{functions = Fs, records = Rs, types = Ts} = S0,
488    GRs = guard_records(Rs),
489    case {Fs, Rs, Ts} of
490        {[], [], []} ->
491            erlang:error(nothing_to_work_with);
492        _ ->
493            %% Give local functions higher weight.
494            AutoImported = auto_imported(),
495            FW = case length(Fs) of
496                     0 ->
497                         0; % not used
498                     NumFs ->
499                         max(1, round(length(AutoImported) / NumFs))
500                 end,
501            FAWs = ([{FW, FA} || FA <- Fs]
502                    ++ [{1, FA} || FA <- AutoImported]),
503            S1 = S0#gen_state{functions_and_auto_imported = FAWs,
504                              expr_bifs = guard_bifs() ++ expr_ops(),
505                              guard_bifs = guard_bifs() ++ guard_ops(),
506                              guard_records = GRs},
507            State = eval_dependencies(S1),
508            ?DEBUG(" records: ~p\n", [State#gen_state.records]),
509            ?DEBUG(" types: ~p\n", [State#gen_state.types]),
510            ?DEBUG(" functions: ~p\n", [State#gen_state.functions]),
511            ?DEBUG(" weights: ~p\n", [State#gen_state.weights]),
512            ?DEBUG(" limits: ~p\n", [State#gen_state.limits]),
513            ?DEBUG(" resize: ~p\n", [State#gen_state.resize]),
514            State
515    end.
516
517%%% The fields of the chosen record are initiated with guard
518%%% expressions, which means that the record can occur in a guard
519%%% expression.
520guard_records([]) ->
521    [];
522guard_records([R | _]) ->
523    [R].
524
525form({_Tag, 0}, _, _State) ->
526    [];
527form({type_decl, _}, _, State) ->
528    TypeNames = State#gen_state.types,
529    Exports = [{attribute, anno(), export_type, TypeNames}],
530    Decls = [type_decl(State, TN) || TN <- TypeNames],
531    Exports ++ Decls;
532form({record_decl, _}, _, State) ->
533    RecordNames = State#gen_state.records,
534    State = State#gen_state{records = RecordNames},
535    State1 = exclude_tags([fresh_var], State),
536    State2 = State1#gen_state{records = []},
537    declare_recs(RecordNames, State2);
538form({function_decl, _}, TagWeights, State) ->
539    FunctionNames = State#gen_state.functions,
540    Exports = [{attribute, anno(), export, FunctionNames}],
541    State = State#gen_state{functions = FunctionNames},
542    {function_spec, SpecW} = lists:keyfind(function_spec, 1, TagWeights),
543    Decls = [begin
544                 FD = function_decl(State, FN),
545                 case SpecW of
546                     0 ->
547                         [FD];
548                     _ ->
549                         [function_spec(State, FN), FD]
550                 end
551             end ||
552                FN <- FunctionNames],
553    Exports ++ lists:append(Decls);
554form({function_spec, _}, _, _State) ->
555    [].
556
557declare_recs([], _) ->
558    [];
559declare_recs([Rec|Recs], S0) ->
560    S0_1 = exclude_tags([record], S0),
561    R = record_decl(S0_1, Rec),
562    S = S0#gen_state{records = [Rec|S0#gen_state.records]},
563    [R | declare_recs1(Recs, S)].
564
565declare_recs1([], _S) ->
566    [];
567declare_recs1([Rec|Recs], S0) ->
568    R = record_decl(S0, Rec),
569    S = S0#gen_state{records = [Rec|S0#gen_state.records]},
570    [R | declare_recs1(Recs, S)].
571
572record_decl(S0, {RecName, Fs}=R) ->
573    ?SIZED(Size,
574           begin
575               S = S0#gen_state{size = Size},
576               {'attribute', anno(), 'record',
577                {RecName, field_decls(S, R, Fs)}}
578           end).
579
580field_decls(S, R, Fs) ->
581    [field_decl(S, R, F) || F <- Fs].
582
583field_decl(S0, R, F) ->
584    S = case rec_init_guard_expr(S0, R) of
585            true ->
586                exclude_tags([complex_field_init], S0);
587            false ->
588                S0
589        end,
590    ?LET(Field,
591         wunion([field_no_type, field_yes_type], S, ?FUNCTION_NAME),
592         set_field_name(Field, F)).
593
594rec_init_guard_expr(S, R) ->
595    lists:member(R, S#gen_state.guard_records).
596
597set_field_name({'typed_record_field', Field, AbstractType}, F) ->
598    {'typed_record_field', set_field_name(Field, F), AbstractType};
599set_field_name({'record_field', A, field_name}, F) ->
600    {'record_field', A, lit_atom(F)};
601set_field_name({'record_field', A, field_name, AbstractExpr}, F) ->
602    {'record_field', A, lit_atom(F), AbstractExpr}.
603
604field_yes_type(S) ->
605    {'typed_record_field', field_no_type(S), abstract_type(S)}.
606
607field_no_type(S) ->
608    wunion([field_no_init, field_yes_init], S, ?FUNCTION_NAME).
609
610field_no_init(_S) ->
611    {'record_field', anno(), field_name()}.
612
613field_yes_init(S) ->
614    {'record_field',
615     anno(),
616     field_name(),
617     case get_weight(complex_field_init, S) of
618         0 ->
619             guard_test(S);
620         1 ->
621             abstract_expr(S)
622     end}.
623
624field_name() ->
625    field_name.
626
627type_decl(S0, {TypeName, N}) ->
628    ?SIZED(Size,
629           begin
630               S = S0#gen_state{size = Size},
631               Parms = list_of_gen2(N, type_parameter()),
632               {'attribute', anno(), type_attr(),
633                %% Not affected by weight of 'variable'.
634                {TypeName, abstract_type(S), Parms}}
635           end).
636
637type_parameter() ->
638    a_variable(type_parameter).
639
640type_attr() ->
641    proper_types:oneof(['type', 'opaque']).
642
643function_spec(S0, {F, N}) ->
644    ?SIZED(Size,
645           begin
646               S = S0#gen_state{size = Size},
647               {'attribute', anno(), spec_attr(),
648                {{F, N}, function_type_list(S, N)}}
649           end).
650
651spec_attr() ->
652    'spec'.
653    %%    oneof(['callback', 'spec']).
654
655function_decl(S0, {F, N}) ->
656    ?SIZED(Size,
657           begin
658               S = S0#gen_state{size = Size},
659               {'function', anno(), F, N, function_clause_seq(S, N)}
660           end).
661
662abstract_expr(S) ->
663    compound(S).
664
665compound(#gen_state{size = 0}=S) ->
666    wunion([small], S, ?FUNCTION_NAME); % assume weight(small) > 0
667compound(S) ->
668    Tags = [small, bitstring, list, tuple, map, match, binop, unop,
669            record, 'case', block, 'if', 'fun', 'receive', 'try',
670            'catch', try_of, termcall, varcall, localcall, extcall],
671    wunion(Tags, resize(S), ?FUNCTION_NAME).
672
673a_map(S, abstract_type) ->
674    map_type(S);
675a_map(S, Where) ->
676    wunion([build_map, update_map], S, Where).
677
678a_list(S, Where) ->
679    wunion([plain_list, cons, lc], S, Where).
680
681%%% Assume 'plain' means 'proper' (see eqc:eqc_erlang_program).
682plain_list(S, T) ->
683    ?LET(L,
684         list_of_gen(T, get_limit(list, S)),
685         lists:foldr(fun(E, A) ->
686                             {'cons', anno(), E, A}
687                     end, nil(), L)).
688
689cons(_S, T) ->
690    {'cons', anno(), T, T}.
691
692nil(_S, abstract_type) ->
693    empty_list_type();
694nil(_S, _Where) ->
695    nil().
696
697nil() ->
698    {'nil', anno()}.
699
700update_record(S, T) ->
701    ?LET({RecName, Fields},
702         known_record(S),
703         {'record',
704          anno(),
705          abstract_expr(S),
706          RecName,
707          record_field_seq(S, T, Fields, update)}).
708
709'catch'(S) ->
710    {'catch', anno(), abstract_expr(S)}.
711
712termcall(_S, T) ->
713    {'tuple', anno(), [T, T]}.
714
715varcall(S, T) ->
716    {'call', anno(), T, args(S)}.
717
718localcall(S) ->
719    ?LET({F, N},
720         local_function_or_auto_imported(S),
721         {'call', anno(), F, n_args(S, N)}).
722
723extcall(S) ->
724    proper_types:weighted_union(
725      [{1, ?LAZY(any_extcall(S))},
726       {1, ?LAZY(known_extcall(S))}]).
727
728any_extcall(S) ->
729    N = random_n_args(S),
730    {'call', anno(), remote_function(S), n_args(S, N)}.
731
732known_extcall(S) ->
733    ?LET({F, N},
734         expr_bif(S),
735         {'call', anno(),
736          {'remote', anno(), lit_atom('erlang'), lit_atom(F)},
737          n_args(S, N)}).
738
739expr_bif(S) ->
740    proper_types:oneof(S#gen_state.expr_bifs).
741
742n_args(S, N) ->
743    list_of_gen2(N, abstract_expr(S)).
744
745args(S) ->
746    N = random_n_args(S),
747    list_of_gen2(N, abstract_expr(S)).
748
749local_function_or_auto_imported(S) ->
750    ?LET({F, N},
751         proper_types:weighted_union(S#gen_state.functions_and_auto_imported),
752         case lists:member({F, N}, S#gen_state.named_funs) of
753             true ->
754                 {a_variable(F), N};
755             false ->
756                 {lit_atom(F), N}
757         end).
758
759remote_function(S) ->
760    {'remote', anno(), abstract_expr(S), abstract_expr(S)}.
761
762lc(S) ->
763    {'lc', anno(), template(S), qualifier_seq(S)}.
764
765blc(S) ->
766    LiteralW = get_weight(literal_bits, S),
767    wunion1(
768      [{1, ?LAZY({'bc', anno(), template(S), qualifier_seq(S)})},
769       {LiteralW, ?LAZY(literal_bc(S))}
770      ]).
771
772literal_bc(S) ->
773    %% The weight of `literal_bits' is not zero.
774    SBC = set_tag_weights([{in_literal_bc, 1}], S),
775    {'bc', anno(), bits(SBC, compound), qualifier_seq(SBC)}.
776
777template(S) ->
778    abstract_expr(S).
779
780qualifier_seq(S) ->
781    non_empty_list_of_gen(qualifier(S), get_limit(qualifiers, S)).
782
783qualifier(S) ->
784    Tags = [lc_gen, blc_gen, lc_any_filter, lc_guard_filter],
785    wunion(Tags, S, ?FUNCTION_NAME).
786
787lc_gen(S) ->
788    {'generate', anno(), pattern(S), abstract_expr(S)}.
789
790blc_gen(S) ->
791    LiteralW = get_weight(literal_bits, S),
792    WildBitsW = wild_bits_weight(S),
793    ?LET({Pattern, Expr},
794         {bits(S, pattern),
795          wunion1(
796            [{WildBitsW, ?LAZY(abstract_expr(S))},
797             {LiteralW, ?LAZY(bits(S, compound))}
798            ])},
799         {'b_generate', anno(), Pattern, Expr}).
800
801lc_any_filter(S) ->
802    abstract_expr(S).
803
804lc_guard_filter(S) ->
805    guard_test(S).
806
807block(S) ->
808    {'block', anno(), body(S)}.
809
810'if'(S) ->
811    {'if', anno(), if_clause_seq(S)}.
812
813if_clause_seq(S) ->
814    non_empty_list_of_gen(if_clause(S), get_limit(if_clauses, S)).
815
816if_clause(S) ->
817    {'clause', anno(), [], if_guard_seq(S), body(S)}.
818
819if_guard_seq(S) ->
820    list_of_gen(a_guard(S), get_limit(guard, S)).
821
822'case'(S) ->
823    {'case', anno(), abstract_expr(S), clause_seq(S)}.
824
825'try'(S) ->
826    NESeq = non_empty_catch_clause_seq(S),
827    Seq = catch_clause_seq(S),
828    ?LET(After,
829         wunion([no_try_after, try_after], S, ?FUNCTION_NAME),
830         case After of
831             [] ->
832                 {'try', anno(), body(S), [], NESeq, After};
833             _ ->
834                 {'try', anno(), body(S), [], Seq, After}
835         end).
836
837try_of(S) ->
838    NESeq = non_empty_catch_clause_seq(S),
839    Seq = catch_clause_seq(S),
840    ?LET(After,
841         wunion([no_try_after, try_after], S, ?FUNCTION_NAME),
842         case After of
843             [] ->
844                 {'try', anno(), body(S), clause_seq(S), NESeq, After};
845             _ ->
846                 {'try', anno(), body(S), clause_seq(S), Seq, After}
847         end).
848
849no_try_after(_S) ->
850    [].
851
852try_after(S) ->
853    body(S).
854
855catch_clause_seq(S) ->
856    list_of_gen(catch_clause(S), get_limit(catch_clauses, S)).
857
858non_empty_catch_clause_seq(S) ->
859    non_empty_list_of_gen(catch_clause(S), get_limit(catch_clauses, S)).
860
861catch_clause(S) ->
862    Tags = [no_eclass, any_eclass, lit_eclass, var_eclass, bad_eclass],
863    ?LET({EClass, St},
864         {wunion(Tags, S, ?FUNCTION_NAME), stacktrace_variable(S)},
865         {'clause', anno(),
866          [{'tuple', anno(), [EClass, pattern(S), St]}],
867          clause_guard_seq(S),
868          body(S)}).
869
870no_eclass(_S) ->
871    a_variable('_').
872
873any_eclass(_S) ->
874    a_variable('_').
875
876lit_eclass(_S) ->
877    proper_types:oneof([lit_atom('exit'),
878                        lit_atom('error'),
879                        lit_atom('throw')]).
880
881var_eclass(S) ->
882    var(S). % atom is fallback
883
884bad_eclass(_S) ->
885    lit_atom(bad_eclass).
886
887stacktrace_variable(S) ->
888    %% weight(fresh_var) = 0 results in an anonymous variable.
889    fresh_var(S).
890
891'receive'(S) ->
892    Ws = sum_weights([lit_timeout, inf_timeout, var_timeout], S),
893    AfterW = min(Ws, 1),
894    proper_types:weighted_union(
895      [{1, ?LAZY(receive_no_after(S))},
896       {AfterW, ?LAZY(receive_yes_after(S))}
897      ]).
898
899receive_no_after(S) ->
900    {'receive', anno(), clause_seq(S)}.
901
902receive_yes_after(S) ->
903    ?LET(Timeout,
904         wunion([lit_timeout, inf_timeout, var_timeout], S, ?FUNCTION_NAME),
905         {'receive', anno(), receive_after_clause_seq(S), Timeout, body(S)}).
906
907receive_after_clause_seq(S) ->
908    list_of_gen(clause(S), get_limit(clauses, S)).
909
910clause_seq(S) ->
911    non_empty_list_of_gen(clause(S), get_limit(clauses, S)).
912
913lit_timeout(S) ->
914    an_integer(S).
915
916inf_timeout(_S) ->
917    lit_atom('infinity').
918
919var_timeout(S) ->
920    abstract_expr(S).
921
922'fun'(S, abstract_type) ->
923    fun_type(S);
924'fun'(S, Where) ->
925    Tags = [lambda, rec_lambda, local_mfa, ext_mfa, any_mfa],
926    wunion(Tags, S, Where).
927
928lambda(S) ->
929    ?LET({_F, N},
930         proper_types:oneof(S#gen_state.named_funs),
931         {'fun', anno(), {'clauses', function_clause_seq(S, N)}}).
932
933rec_lambda(S) ->
934    ?LET({F, N},
935         proper_types:oneof(S#gen_state.named_funs),
936         begin
937             FNW = {1, {F, N}}, % too low?
938             Functions = [FNW | S#gen_state.functions_and_auto_imported],
939             S1 = S#gen_state{functions_and_auto_imported = Functions},
940             {'named_fun', anno(), F, function_clause_seq(S1, N)}
941         end).
942
943function_clause_seq(S, N) ->
944    NCl = random_n_clauses(S),
945    list_of_gen2(NCl, function_clause(S, N)).
946
947random_n_clauses(S) ->
948    uniform(get_limit(function_clauses, S)).
949
950function_clause(S, N) ->
951    {'clause', anno(), pattern_seq(S, N), clause_guard_seq(S), body(S)}.
952
953local_mfa(S) ->
954    ?LET({F, N},
955         local_function(S),
956         {'fun', anno(), {'function', F, N}}).
957
958ext_mfa(S) ->
959    LW =
960        case
961            (S#gen_state.result_type =:= term orelse
962             get_weight(function_decl, S) > 0)
963        of
964            true ->
965                1;
966            false ->
967                0
968         end,
969    wunion1(
970      [{LW, ?LAZY(?LET({F, N},
971                       local_function(S),
972                       {'fun', anno(),
973                        {'function', lit_atom(S#gen_state.module),
974                         lit_atom(F),
975                         lit_integer(N)}}))},
976       {1, ?LAZY({'fun', anno(),
977                  {'function', any_module(S),
978                   any_function(),
979                   lit_integer(proper_types:arity())}})}
980      ]).
981
982any_mfa(S) ->
983    ?SUCHTHAT(Fun_MFA,
984              ?LET({M, F, A},
985                   {var_or_atom(S), var_or_atom(S), var_or_arity(S)},
986                   {'fun', anno(), {'function', M, F, A}}),
987              begin
988                  {'fun', _, {'function', M, F, A}} = Fun_MFA,
989                  is_var(M) orelse is_var(F) orelse is_var(A)
990              end).
991
992var_or_atom(S) ->
993    var(S). % atom is fallback
994
995var_or_arity(_S) ->
996    proper_types:oneof([a_variable(bound_var_or_an_arity),
997                        lit_integer(proper_types:arity())]).
998
999is_var({'var', _, _}) -> true;
1000is_var(_) -> false.
1001
1002local_function(S) ->
1003    one_of(S#gen_state.functions, no_functions).
1004
1005clause(S) ->
1006    {'clause', anno(), [pattern(S)], clause_guard_seq(S), body(S)}.
1007
1008pattern_seq(S, N) ->
1009    list_of_gen2(N, pattern(S)).
1010
1011body(S) ->
1012    non_empty_list_of_gen(abstract_expr(S), get_limit(body, S)).
1013
1014clause_guard_seq(S) ->
1015    wunion([no_guard, yes_guard], S, ?FUNCTION_NAME).
1016
1017no_guard(_S) ->
1018    [].
1019
1020yes_guard(S) ->
1021    non_empty_list_of_gen(a_guard(S), get_limit(guard, S)).
1022
1023a_guard(S) ->
1024    non_empty_list_of_gen(guard_test(S), get_limit(guard_tests, S)).
1025
1026guard_test(#gen_state{size = 0}=S) ->
1027    wunion([small], S, ?FUNCTION_NAME); % assume weight(small) > 0
1028guard_test(S) ->
1029    Tags = [small, tuple, map, cons, plain_list, bits, binop,
1030            unop, record, guard_call, remote_guard_call],
1031    wunion(Tags, resize(S), ?FUNCTION_NAME).
1032
1033build_map(S, T) ->
1034    {'map', anno(), assoc_seq(S, 0, T)}.
1035
1036update_map(S, T) ->
1037    {'map', anno(), T, assoc_seq(S, 1, T)}.
1038
1039assoc_seq(S, ExactWeight, T) ->
1040    list_of_gen(assoc(ExactWeight, T), get_limit(map, S)).
1041
1042assoc(ExactWeight, T) ->
1043    wunion1(
1044      [{1, ?LAZY({'map_field_assoc', anno(), T, T})},
1045       {ExactWeight, ?LAZY(assoc_exact(T))}]).
1046
1047assoc_exact(T) ->
1048    {'map_field_exact', anno(), T, T}.
1049
1050%%% The type test is_record() is not handled well.
1051guard_call(S) ->
1052    case has_fields(S) of
1053        false ->
1054            guard_call_1(S);
1055        true ->
1056            proper_types:weighted_union([{10, ?LAZY(guard_call_1(S))},
1057                                         {1, ?LAZY(guard_call_2(S))},
1058                                         {1, ?LAZY(guard_call_3(S))}])
1059    end.
1060
1061guard_call_1(S) ->
1062    ?LET({F, N},
1063         guard_bif(S),
1064         {'call', anno(), lit_atom(F), guard_call_args(N, S)}).
1065
1066guard_call_2(S) ->
1067    ?LET({RecName, _Fields},
1068         known_record_with_fields(S),
1069         {'call', anno(), lit_atom('is_record'),
1070          guard_call_args(1, S) ++ [lit_atom(RecName)]}).
1071
1072guard_call_3(S) ->
1073    ?LET({RecName, Fields},
1074         known_record_with_fields(S),
1075         {'call', anno(),
1076          {'remote', anno(), lit_atom('erlang'), lit_atom('is_record')},
1077          (guard_call_args(1, S) ++
1078           [lit_atom(RecName), lit_integer(length(Fields))])}).
1079
1080remote_guard_call(S) ->
1081    ?LET({F, N},
1082         guard_bif(S),
1083         {'call', anno(),
1084          {'remote', anno(), lit_atom('erlang'), lit_atom(F)},
1085          guard_call_args(N, S)}).
1086
1087guard_bif(S) ->
1088    proper_types:oneof(S#gen_state.guard_bifs).
1089
1090%%% Guard BIFs with arity greater than than the limit of call_args are
1091%%% not excluded.
1092guard_call_args(N, S) ->
1093    list_of_gen2(N, guard_test(S)).
1094
1095pattern(#gen_state{size = 0}=S) ->
1096    wunion([small], S, ?FUNCTION_NAME); % assume weight(small) > 0
1097pattern(S) ->
1098    Tags = [small, match, tuple, cons, plain_list, bits, unop, binop,
1099            record, map_pattern, string_prefix],
1100    wunion(Tags, resize(S), ?FUNCTION_NAME).
1101
1102a_record(S, abstract_type) ->
1103    record_type(S);
1104a_record(S, compound=Where) ->
1105    a_record2([build_record, record_field_access, record_index,
1106               update_record], S, Where);
1107a_record(S, guard_test=Where) ->
1108    a_record2([build_record, record_field_access, record_index], S, Where);
1109a_record(S, pattern=Where) ->
1110    a_record2([record_pattern, record_index], S, Where).
1111
1112a_record2(Tags, S0, Where) ->
1113    S = maybe_exclude_field_access(S0),
1114    wunion(Tags, S, Where).
1115
1116maybe_exclude_field_access(S) ->
1117    %% Maybe the user should fix this kind of issues.
1118    case has_fields(S) of
1119        false ->
1120            exclude_tags([record_field_access, record_index], S);
1121        true ->
1122            S
1123    end.
1124
1125has_fields(S) ->
1126    lists:any(fun({_, Fields}) -> Fields =/= [] end, S#gen_state.records).
1127
1128record_field_access(S, T) ->
1129    ?LET({RecName, Fields},
1130         known_record_with_fields(S),
1131         begin
1132             Field = lit_atom(proper_types:oneof(Fields)),
1133             {'record_field', anno(), T, RecName, Field}
1134         end).
1135
1136record_index(S) ->
1137    ?LET({RecName, Fields},
1138         known_record_with_fields(S),
1139         begin
1140             Field = lit_atom(proper_types:oneof(Fields)),
1141             {'record_index', anno(), RecName, Field}
1142         end).
1143
1144record_pattern(S) ->
1145    ?LET({RecName, Fields},
1146         known_guard_record(S),
1147         {'record',
1148          anno(),
1149          RecName,
1150          record_field_seq(S, pattern(S), Fields, build)}).
1151
1152build_record(S, guard_test) ->
1153    ?LET({RecName, Fields},
1154         known_guard_record(S),
1155         {'record',
1156          anno(),
1157          RecName,
1158          record_field_seq(S, guard_test(S), Fields, build)});
1159build_record(S, compound) ->
1160    ?LET({RecName, Fields},
1161         known_record(S),
1162         {'record',
1163          anno(),
1164          RecName,
1165          record_field_seq(S, abstract_expr(S), Fields, build)}).
1166
1167record_field_seq(_S, _T, [], _Context) ->
1168    [];
1169record_field_seq(S, T, Fs0, build) ->
1170    ?LET(IF,
1171         wunion([yes_multi_field_init, no_multi_field_init], S, anywhere),
1172         begin
1173             Fs = IF ++ Fs0,
1174             record_field_seq2(S, T, Fs)
1175         end);
1176record_field_seq(S, T, Fs, update) ->
1177    record_field_seq2(S, T, Fs).
1178
1179record_field_seq2(S, T, Fs) ->
1180    N = uniform(min(length(Fs), get_limit(record_fields, S))),
1181    record_field(N, T, Fs).
1182
1183yes_multi_field_init(_S) ->
1184    ['_'].
1185
1186no_multi_field_init(_S) ->
1187    [].
1188
1189record_field(0, _T, _Fs) ->
1190    [];
1191record_field(N, T, Fs0) ->
1192    ?LET(F,
1193         proper_types:oneof(Fs0),
1194         begin
1195             Name = case F of
1196                        '_' -> a_variable(F);
1197                        _ -> lit_atom(F)
1198                    end,
1199             Field = {'record_field', anno(), Name, T},
1200             Fs = lists:delete(F, Fs0),
1201             [Field | record_field(N - 1, T, Fs)]
1202         end).
1203
1204map_pattern(S0) ->
1205    S = exclude_tags([record_index, string_prefix, pat_var], S0),
1206    {'map', anno(), assoc_pattern_seq(S)}.
1207
1208assoc_pattern_seq(S) ->
1209    KeyW = get_weight(map_pattern_assoc, S),
1210    ValueW = get_weight(map_pattern_exact, S),
1211    %% Note that when excluding tags, more zero_weights errors are
1212    %% possible.
1213    InKey = [{fresh_var, 0},
1214             {map_pattern_assoc, 1},
1215             {map_pattern_exact, 0},
1216             {match, 0}],
1217    SKey = set_tag_weights(InKey, S), % only => in key; no =/2 in key
1218    G = proper_types:weighted_union(
1219          [{KeyW,
1220            %% EEP 52.
1221            ?LAZY({'map_field_assoc', anno(), guard_test(SKey), pattern(S)})},
1222           {ValueW,
1223            ?LAZY({'map_field_exact', anno(), pattern(SKey), pattern(S)})}]),
1224    non_empty_list_of_gen(G, ?MAX_MAP).
1225
1226string_prefix(S) ->
1227    StringPrefix = wunion([nil, string, string_prefix_list], S, pattern),
1228    S1 = exclude_tags([record_index, string_prefix], S),
1229    {'op', anno(), '++', StringPrefix, pattern(S1)}.
1230
1231string_prefix_list(S) ->
1232    plain_list(S, proper_types:union([a_char(S), an_integer(S)])).
1233
1234%%% Maybe something like 'small'. Should obey S.size.
1235abstract_type(S) ->
1236    Tags = [annotated_type, atom, bitstring, 'fun',
1237            integer_range_type, nil, map, predefined_type, record,
1238            remote_type, singleton_integer_type, tuple, type_union,
1239            type_variable, user_defined_type],
1240    wunion(Tags, S, ?FUNCTION_NAME).
1241
1242annotated_type(S) ->
1243    ?LET({Var, Type},
1244         {annotation(S), abstract_type(S)},
1245         {'ann_type', anno(), [Var, Type]}).
1246
1247annotation(S) ->
1248    proper_types:weighted_union(
1249      [{20, ?LAZY(type_variable(S))},
1250       {1, ?LAZY(anonymous_var(S))}]).
1251
1252empty_list_type() ->
1253    {'type', anno(), 'nil', []}.
1254
1255fun_type(S) ->
1256    proper_types:weighted_union(
1257      [{1, ?LAZY({'type', anno(), 'fun', []})},
1258       {1, ?LAZY({'type', anno(), 'fun', [{'type', anno(), 'any'},
1259                                          abstract_type(S)]})},
1260       {2, ?LAZY(fun_type_n(S))}]).
1261
1262fun_type_n(S) ->
1263    N = random_n_args(S),
1264    function_type(S, N).
1265
1266random_n_args(S) ->
1267    uniform(get_limit(call_args, S) + 1) - 1.
1268
1269integer_range_type(S) ->
1270    ?LET({T1, T2},
1271         {singleton_integer_type(S), singleton_integer_type(S)},
1272         {'type', anno(), 'range', [T1, T2]}).
1273
1274map_type(S) ->
1275    proper_types:weighted_union(
1276      [{1, ?LAZY({'type', anno(), 'map', 'any'})},
1277       {1, ?LAZY({'type', anno(), 'map', assoc_type_seq(S)})}]).
1278
1279assoc_type_seq(S) ->
1280    list_of_gen(assoc_type(S), ?MAX_MAP).
1281
1282assoc_type(S) ->
1283    proper_types:weighted_union(
1284      [{1, ?LAZY({'type', anno(), 'map_field_assoc',
1285                  [abstract_type(S), abstract_type(S)]})},
1286       {1, ?LAZY({'type', anno(), 'map_field_exact',
1287                  [abstract_type(S), abstract_type(S)]})}]).
1288
1289predefined_type(S) ->
1290    ?LET({TypeName, N},
1291         proper_types:oneof(S#gen_state.predef_types),
1292         {'type',
1293          anno(),
1294          TypeName,
1295          list_of_gen2(N, abstract_type(S))}).
1296
1297record_type(S) ->
1298    ?LET({RecName, Fields},
1299         known_record(S),
1300         {'type',
1301          anno(),
1302          'record',
1303          [lit_atom(RecName) | record_field_types(S, Fields)]}).
1304
1305record_field_types(_S, []) ->
1306    [];
1307record_field_types(S, Fs) ->
1308    N = uniform(min(length(Fs), get_limit(record_fields, S))),
1309    Type = abstract_type(S),
1310    record_field_type(N, Type, Fs).
1311
1312record_field_type(0, _T, _Fs) ->
1313    [];
1314record_field_type(N, T, Fs0) ->
1315    ?LET(FieldName,
1316         proper_types:oneof(Fs0),
1317         begin
1318             Name = lit_atom(FieldName),
1319             Field = {'type', anno(), 'field_type', [Name, T]},
1320             Fs = lists:delete(FieldName, Fs0),
1321             [Field | record_field_type(N - 1, T, Fs)]
1322         end).
1323
1324remote_type(S) ->
1325    ?LET({Module, Name, T},
1326         {an_atom(S), an_atom(S), abstract_type(S)},
1327         {'remote_type', anno(), [Module, Name, [T]]}).
1328
1329tuple_type(S) ->
1330    proper_types:weighted_union(
1331      [{1, ?LAZY({'type', anno(), 'tuple', abstract_type_seq(S)})},
1332       {1, ?LAZY({'type', anno(), 'tuple', 'any'})}]).
1333
1334abstract_type_seq(S) ->
1335    list_of_gen(abstract_type(S), get_limit(tuple_types, S)).
1336
1337type_union(S) ->
1338    N = uniform(get_limit(union_types, S) - 2) + 2,
1339    {'type',
1340     anno(),
1341     'union',
1342     list_of_gen2(N, abstract_type(S))}.
1343
1344user_defined_type(S) ->
1345    ?LET({TypeName, N},
1346         local_type(S),
1347         {'user_type', anno(), TypeName, list_of_gen2(N, abstract_type(S))}).
1348
1349function_type_list(S, N) ->
1350    ?LET({Ft, {MinTypes, MaxTypes}},
1351         {function_type(S, N), n_function_types(S)},
1352         begin
1353             Tags = [yes_constrained_function_type,
1354                     no_constrained_function_type],
1355             G = wunion(Tags, S, ?FUNCTION_NAME),
1356             NTypes = MinTypes + uniform(MaxTypes - MinTypes + 1) - 1,
1357             ?LET(Ts,
1358                  list_of_gen2(NTypes, G),
1359                  [case T of
1360                       no_function_constraint ->
1361                           Ft;
1362                       Fc ->
1363                           {'type', anno(), 'bounded_fun', [Ft, Fc]}
1364                   end || T <- Ts])
1365         end).
1366
1367function_type(S, N) ->
1368    {'type', anno(), 'fun',
1369     [{'type', anno(),
1370       'product',
1371       list_of_gen2(N, abstract_type(S))},
1372      abstract_type(S)]}.
1373
1374no_constrained_function_type(_S) ->
1375    no_function_constraint.
1376
1377yes_constrained_function_type(S) ->
1378    function_constraint(S).
1379
1380function_constraint(S) ->
1381    non_empty_list_of_gen(constraint(S), get_limit(function_constraints, S)).
1382
1383constraint(S) ->
1384    ?LET({IsSubtype, V, T},
1385         {lit_atom('is_subtype'), type_variable(S), abstract_type(S)},
1386         {'type', anno(), 'constraint', [IsSubtype, [V, T]]}).
1387
1388n_function_types(S) ->
1389    wunion([no_overloaded, yes_overloaded], S, ?FUNCTION_NAME).
1390
1391%%% Maybe function_types-limit is enough?
1392no_overloaded(_S) ->
1393    {1, 1}.
1394
1395yes_overloaded(S) ->
1396    {2, max(get_limit(function_types, S), 2)}.
1397
1398type_variable(_S) ->
1399    a_variable(type_variable).
1400
1401singleton_integer_type(S) ->
1402    wunion([integer, char, unop, binop], S, abstract_type).
1403
1404small(S, pattern) ->
1405    Tags = [atom, boolean, integer, string, char, float, nil, pat_var],
1406    wunion(Tags, S, ?FUNCTION_NAME);
1407small(S, _Where) ->
1408    Tags = [atom, boolean, integer, string, char, float, nil, var],
1409    wunion(Tags, S, ?FUNCTION_NAME).
1410
1411a_boolean(_S) ->
1412    proper_types:union([lit_atom('true'), lit_atom('false')]).
1413
1414an_integer(_S) ->
1415    lit_integer(proper_types:non_neg_integer()).
1416
1417a_string(S) ->
1418    {'string', anno(), simple_string(S)}.
1419
1420simple_string(S) ->
1421    N = uniform(get_limit(string, S) + 1) - 1,
1422    simple_string1(S, N).
1423
1424simple_string1(_S, 0) ->
1425    [];
1426simple_string1(S, N) ->
1427    [simple_char(S) | simple_string1(S, N - 1)].
1428
1429a_char(S) ->
1430    {'char', anno(), simple_char(S)}.
1431
1432simple_char(S) ->
1433    (S#gen_state.simple_char)().
1434
1435default_simple_char() ->
1436    proper_types:union([proper_types:integer($a, $z),
1437                        proper_types:integer($A, $Z)]).
1438
1439default_atom() ->
1440    any_of(some_atoms()).
1441
1442a_float(_S) ->
1443    ?LET(Float,
1444         proper_types:float(),
1445         {'float', anno(), abs(Float)}).
1446
1447var(_S) ->
1448    a_variable(bound_var_or_an_atom).
1449
1450pat_var(S) ->
1451    wunion([fresh_var, bound_var], S, ?FUNCTION_NAME).
1452
1453fresh_var(S) ->
1454    case get_weight(fresh_var, S) of
1455        0 ->
1456            anonymous_var(S);
1457        _ ->
1458            proper_types:weighted_union(
1459              [{20, ?LAZY(a_variable(fresh_var))},
1460               {1, ?LAZY(anonymous_var(S))}])
1461    end.
1462
1463bound_var(_S) ->
1464    a_variable(bound_var_or_an_integer).
1465
1466anonymous_var(_S) ->
1467    a_variable('_').
1468
1469a_variable(Name) ->
1470    {'var', anno(), Name}.
1471
1472match(S, pattern) ->
1473    {'match', anno(), pattern(S), pattern(S)};
1474match(S, compound) ->
1475    {'match', anno(), pattern(S), abstract_expr(S)}.
1476
1477tuple(S, abstract_type) ->
1478    tuple_type(S);
1479tuple(S, Where) ->
1480    T = where(S, Where),
1481    {'tuple', anno(), list_of_gen(T, get_limit(tuple, S))}.
1482
1483non_empty_list_of_gen(G, Max) ->
1484    N = uniform(Max),
1485    list_of_gen2(N, G).
1486
1487list_of_gen(G, Max) ->
1488    N = uniform(Max + 1) - 1,
1489    list_of_gen2(N, G).
1490
1491list_of_gen2(0, _G) ->
1492    [];
1493list_of_gen2(N, G) ->
1494    [G | list_of_gen2(N - 1, G)].
1495
1496bitstring(S, abstract_type) ->
1497    {'type', anno(), 'binary', [singleton_integer_type(S),
1498                                singleton_integer_type(S)]};
1499bitstring(S, Where) ->
1500    case S#gen_state.result_type of
1501        term ->
1502            wunion([bits, bytes], S, Where);
1503        ResType when ResType =:= program;
1504                     ResType =:= guard;
1505                     ResType =:= expr  ->
1506            wunion([bits, blc], S, Where)
1507    end.
1508
1509bytes(S) ->
1510    {'bin', anno(), binelement_seq_term(S, bytes)}.
1511
1512bits(#gen_state{result_type = term} = S, compound) ->
1513    {'bin', anno(), binelement_seq_term(S, bits)};
1514bits(S, compound=Where) ->
1515    LiteralW = get_weight(literal_bits, S),
1516    WildBitsW = wild_bits_weight(S),
1517    proper_types:weighted_union(
1518      [{WildBitsW,
1519        ?LAZY({'bin', anno(), binelement_seq(S, abstract_expr(S), Where)})},
1520       {LiteralW, ?LAZY(literal_bits(S, Where))}
1521      ]);
1522bits(S, guard_test=Where) ->
1523    {'bin', anno(), binelement_seq(S, guard_test(S), Where)};
1524bits(S, pattern=Where) ->
1525    LiteralW = get_weight(literal_bits, S),
1526    WildBitsW = wild_bits_weight(S),
1527    proper_types:weighted_union(
1528      [{WildBitsW,
1529        ?LAZY({'bin', anno(), binelement_seq(S, bin_pattern(S), Where)})},
1530       {LiteralW, ?LAZY(literal_bits(S, Where))}
1531      ]).
1532
1533wild_bits_weight(S) ->
1534    case get_weight(in_literal_bc, S) of
1535        1 -> 0;
1536        _ -> 1
1537    end.
1538
1539binelement_seq_term(S, B) ->
1540    N = uniform(get_limit(bin_elements, S)),
1541    binelements_term(N, B).
1542
1543binelements_term(0, _) ->
1544    [];
1545binelements_term(N, B) ->
1546    Expr = lit_integer(uniform(1 bsl 32) - 1),
1547    Size = case B of
1548               bits ->
1549                   lit_integer(8 * uniform(4) - uniform(7));
1550               bytes ->
1551                   lit_integer(8 * uniform(4))
1552           end,
1553    TSL = default,
1554    [{'bin_element', anno(), Expr, Size, TSL} | binelements_term(N - 1, B)].
1555
1556bin_pattern(S) ->
1557    Tags = [pat_var, string, integer, char, float, atom, unop, binop],
1558    wunion(Tags, S, pattern).
1559
1560binelement_seq(S, T, Where) ->
1561    N = uniform(get_limit(bin_elements, S)),
1562    binelements(N, S, T, Where).
1563
1564binelements(0, _S, _T, _W) ->
1565    [];
1566binelements(N, S, T, Where) ->
1567    [binelement(S, T, Where, N =:= 1) | binelements(N - 1, S, T, Where)].
1568
1569binelement(S, T, Where, IsLast) ->
1570    ?LET(Expr,
1571         T,
1572         case {Where, Expr} of
1573             {pattern, {string, _, _}} ->
1574                 {'bin_element',
1575                  anno(),
1576                  Expr,
1577                  'default',
1578                  proper_types:union(['default',
1579                                      [proper_types:union(['utf8',
1580                                                           'utf16',
1581                                                           'utf32'])]])};
1582             _ ->
1583                 %% If HasUnit then Size =/= default.
1584                 %% If HasUtf then Size =:= default and not HasUnit
1585                 ?LET(TSL0,
1586                      type_specifier_list(S, IsLast),
1587                      begin
1588                          HasUtf = TSL0 =/= 'default'
1589                              andalso TSL0 -- [utf8, utf16, utf32] =/= TSL0,
1590                          {TSL, Size} =
1591                              case HasUtf of
1592                                  true ->
1593                                      {[TS || TS <- TSL0,
1594                                              (not is_tuple(TS) orelse
1595                                               element(1, TS) =/= 'unit')],
1596                                       'default'};
1597                                  false ->
1598                                      HasUnit =
1599                                          TSL0 =/= 'default'
1600                                          andalso
1601                                          lists:keymember('unit', 1, TSL0),
1602                                      case HasUnit of
1603                                          true when Where =:= pattern ->
1604                                              {TSL0,
1605                                               %% not 'default':
1606                                               binelement_size_pattern(S)};
1607                                          true ->
1608                                              {TSL0,
1609                                               T}; % not 'default'
1610                                          false when Where =:= pattern ->
1611                                              {TSL0,
1612                                               binelement_size
1613                                                 (binelement_size_pattern(S))};
1614                                          false ->
1615                                              {TSL0,
1616                                               binelement_size(T)} % any size
1617                                      end
1618                              end,
1619                          {'bin_element', anno(), Expr, Size, TSL}
1620                      end)
1621         end).
1622
1623binelement_size_pattern(S0) ->
1624    S = exclude_tags([fresh_var], S0),
1625    guard_test(S). %% EEP 52
1626
1627binelement_size(T) ->
1628    proper_types:weighted_union(
1629      [{1, ?LAZY('default')},
1630       {2, ?LAZY(T)}]).
1631
1632%%% Generate simple and--most of the time--correct binary and
1633%%% bitstring expressions. The purpose is to cover more of the
1634%%% Compiler as the random code seldom passes the many tests of binary
1635%%% lists comprehensions.
1636literal_bits(S, Where) ->
1637    N = uniform(get_limit(bin_elements, S)),
1638    {'bin', anno(), literal_binelements(N, S, Where)}.
1639
1640literal_binelements(0, _S, _Where) ->
1641    [];
1642literal_binelements(N, S, Where) ->
1643    [literal_binelement(S, N =:= 1, Where) |
1644     literal_binelements(N - 1, S, Where)].
1645
1646literal_binelement(S, IsLast, Where) ->
1647    ?LET(Type,
1648         a_type(IsLast andalso Where =/= pattern),
1649         if
1650             Type =:= integer ->
1651                 %% Strings?
1652                 ?LET({Size, Unit},
1653                      {proper_types:integer(0, 8),
1654                       proper_types:integer(1, 32)}, % not too big...
1655                      {'bin_element',
1656                       anno(),
1657                       case Where of
1658                           compound ->
1659                               singleton_integer_type(S); % A bit sloppy.
1660                           pattern ->
1661                               singleton_integer_type(S) % More?
1662                       end,
1663                       lit_integer(Size),
1664                       [Type, {'unit', Unit}, signedness(), endianness()]});
1665             Type =:= utf8; Type =:= utf16; Type =:= utf32 ->
1666                 ?LET(CharOrString,
1667                      literal_unicode(S),
1668                      {'bin_element',
1669                       anno(),
1670                       CharOrString,
1671                       default,
1672                       [Type, signedness(), endianness()]});
1673             Type =:= float ->
1674                 ?LET({Size, Unit},
1675                      proper_types:oneof([{16, 1}, {32, 1}, {64, 1}]),
1676                      {'bin_element',
1677                       anno(),
1678                       a_float(S),
1679                       lit_integer(Size),
1680                       [Type, {'unit', Unit}, signedness(), endianness()]});
1681             true ->
1682                 ?LET({Bin, Unit0},
1683                      {literal_bits(S, Where), unit()},
1684                      begin
1685                          BitSize =
1686                              %% This could be slow if deeply nested.
1687                              try
1688                                  {value, B, _} = erl_eval:expr(Bin, []),
1689                                  bit_size(B)
1690                              catch
1691                                  _:_ ->
1692                                      1000
1693                              end,
1694                          {Unit, MaxSize} =
1695                              if
1696                                  Type =:= bytes ->
1697                                      {8, BitSize div 8};
1698                                  Type =:= binary ->
1699                                      Unit1 = max(min(Unit0, BitSize), 1),
1700                                      {Unit1, BitSize div Unit1};
1701                                  Type =:= bitstring; Type =:= bits ->
1702                                      {1, BitSize}
1703                              end,
1704                          Size = proper_types:integer(0, MaxSize),
1705                          {'bin_element',
1706                           anno(),
1707                           Bin,
1708                           lit_integer(Size),
1709                           [Type, {'unit', Unit}, signedness(), endianness()]}
1710                      end)
1711         end).
1712
1713%%% Does not use #gen_state.simple_char. Perhaps it should.
1714literal_unicode(S) ->
1715    StringW = get_weight(string, S),
1716    S1 = S#gen_state{simple_char = fun unicode/0},
1717    wunion1([{3, ?LAZY(lit_integer(unicode()))},
1718             {StringW, ?LAZY(a_string(S1))}]).
1719
1720unicode() ->
1721    proper_types:oneof([proper_types:integer(0, 16#D7FF),
1722                        proper_types:integer(16#E000, 16#10FFFF)]).
1723
1724binop(S, abstract_type) ->
1725    T = singleton_integer_type(S),
1726    {'op', anno(), type_binop(), T, T};
1727binop(S, compound=Where) ->
1728    wunion([any_op, guard_op], S, Where);
1729binop(S, guard_test) ->
1730    guard_binop(S, guard_test(S));
1731binop(S, pattern) ->
1732    pattern_binop(pattern_expr_operand(S)).
1733
1734any_binop(_S, T) ->
1735    {'op', anno(), any_binop(), T, T}.
1736
1737guard_binop(_S, T) ->
1738    {'op', anno(), guard_binop(), T, T}.
1739
1740pattern_binop(T) ->
1741    {'op', anno(), pattern_binop(), T, T}.
1742
1743%%% The operators according to erl_internal. orelse/andalso added.
1744any_binop() ->
1745    proper_types:oneof(
1746      ['+', '-', '*', '/', 'div', 'rem', 'band', 'bor', 'bxor', 'bsl', 'bsr',
1747       'and', 'or', 'xor',
1748       '=:=', '=/=', '==', '/=', '=<', '<', '>=', '>',
1749       'orelse', 'andalso', % not proper operators, but handled as such
1750       '++', '--', '!']). % not in guards
1751
1752guard_binop() ->
1753    proper_types:oneof(
1754      ['+', '-', '*', '/', 'div', 'rem', 'band', 'bor', 'bxor', 'bsl', 'bsr',
1755       'and', 'or', 'xor',
1756       '=:=', '=/=', '==', '/=', '=<', '<', '>=', '>',
1757       'orelse', 'andalso']). % not proper operators, but handled as such
1758
1759pattern_binop() ->
1760    proper_types:oneof(
1761      ['+', '-', '*', '/', 'div', 'rem', 'band', 'bor', 'bxor', 'bsl',
1762       'bsr']).
1763
1764type_binop() ->
1765    proper_types:oneof(
1766      ['+', '-', '*', 'div', 'rem', 'band', 'bor', 'bxor', 'bsl', 'bsr']).
1767
1768unop(S, abstract_type) ->
1769    {'op', anno(), type_unop(), singleton_integer_type(S)};
1770unop(S, compound) ->
1771    %% any_op and guard_op: they are the same for unary operators
1772    {'op', anno(), any_unop(), abstract_expr(S)};
1773unop(S, guard_test) ->
1774    {'op', anno(), any_unop(), guard_test(S)};
1775unop(S, pattern) ->
1776    {'op', anno(), pattern_unop(), pattern_expr_operand(S)}.
1777
1778pattern_expr_operand(S0) ->
1779    S = exclude_tags([record_index, string_prefix], S0),
1780    %% Simplified. Evaluates to an integer.
1781    wunion([char, float, integer, unop, binop], S, pattern).
1782
1783any_unop() ->
1784    proper_types:oneof(['+', '-', 'bnot', 'not']).
1785
1786pattern_unop() ->
1787    proper_types:oneof(['+', '-']).
1788
1789type_unop() ->
1790    proper_types:oneof(['+', '-', 'bnot']).
1791
1792type_specifier_list(S, IsLast) ->
1793    proper_types:weighted_union(
1794      [{1, 'default'},
1795       {1, ?LAZY(type_specifiers(S, IsLast))}]).
1796
1797type_specifiers(S, IsLast) ->
1798   N = uniform(get_limit(tsl, S)),
1799   type_specifier(N, IsLast, []).
1800
1801type_specifier(0, _IsLast, _L) ->
1802    [];
1803type_specifier(N, IsLast, L) ->
1804    ?LET({Tag, TS},
1805         ?SUCHTHAT({Tag, _},
1806                   a_type_specifier(IsLast, L),
1807                   not is_chosen(Tag, L)),
1808         [TS | type_specifier(N - 1, IsLast, [Tag, TS | L])]).
1809
1810a_type_specifier(IsLast0, L) ->
1811    %% A bit sloppy. Cannot generate [{unit, 8}, binary], for example.
1812    %% Maybe do nothing here and everyting in post_process()?
1813    IsLast = IsLast0 andalso not is_chosen(unit, L),
1814    UnitWeight = case is_member([bitstring, bits, bytes, binary], L) of
1815                     true -> 0;
1816                     false -> 1
1817                 end,
1818    wunion1(
1819      [{1, ?LAZY({'type', a_type(IsLast)})},
1820       {1, ?LAZY({'signedness', signedness()})},
1821       {1, ?LAZY({'endianness', endianness()})},
1822       {UnitWeight, ?LAZY({unit, {'unit', unit()}})}]).
1823
1824is_member([], _) ->
1825    false;
1826is_member([E|Es], L) ->
1827    lists:member(E, L) orelse is_member(Es, L).
1828
1829is_chosen(Tag, L) ->
1830    lists:member(Tag, L).
1831
1832a_type(IsLast) ->
1833    wunion1(bit_segment_types(IsLast)).
1834
1835bit_segment_types(false) ->
1836    [{3, 'integer'},
1837     {2, 'float'},
1838     {1, 'utf8'},
1839     {1, 'utf16'},
1840     {1, 'utf32'}];
1841bit_segment_types(true) ->
1842    [{3, 'integer'},
1843     {2, 'float'},
1844     {3, 'binary'},
1845     {3, 'bytes'},
1846     {3, 'bitstring'},
1847     {3, 'bits'},
1848     {1, 'utf8'},
1849     {1, 'utf16'},
1850     {1, 'utf32'}].
1851
1852signedness() ->
1853    proper_types:oneof(['signed', 'unsigned']).
1854
1855endianness() ->
1856    proper_types:oneof(['big', 'little', 'native']).
1857
1858unit() ->
1859    wunion1(
1860      [{10, ?LAZY(proper_types:oneof([1, 8, 16, 32]))},
1861       {1, proper_types:integer(1, 256)}]).
1862
1863known_record_with_fields(S) ->
1864    ?SUCHTHAT(R, known_record(S), element(2, R) =/= []).
1865
1866known_record(S) ->
1867    one_of(S#gen_state.records, no_records).
1868
1869known_guard_record(S) ->
1870    [R|_] = S#gen_state.guard_records,
1871    R.
1872
1873local_type(S) ->
1874    one_of(S#gen_state.types, no_types).
1875
1876one_of([], Err) ->
1877    erlang:error(Err);
1878one_of(L, _Err) ->
1879    proper_types:oneof(L).
1880
1881an_atom(_S) ->
1882    lit_atom(any_atom()).
1883
1884any_atom() ->
1885    any_atom.
1886
1887any_module(_S) ->
1888    lit_atom(any_module).
1889
1890any_function() ->
1891    lit_atom(any_function).
1892
1893lit_atom(A) ->
1894    {'atom', anno(), A}.
1895
1896lit_integer(I) ->
1897    {'integer', anno(), I}.
1898
1899anno() ->
1900    erl_anno:new(0).
1901
1902resize(#gen_state{resize = false} = S) ->
1903    S;
1904resize(#gen_state{resize = true} = S) ->
1905    ?RESIZE(S).
1906
1907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1908
1909eval_dependencies(State0) ->
1910    State = case State0#gen_state.functions of
1911                [] ->
1912                    exclude_tags([function_decl], State0);
1913                _ ->
1914                    State0
1915            end,
1916    Deps = deps(State#gen_state.result_type),
1917    Fun = fun(Dep, S) ->
1918                  {Tags, AffectedTags} = Dep,
1919                  eval_dep(S, Tags, AffectedTags)
1920          end,
1921    lists:foldl(Fun, State, Deps).
1922
1923%%% The list is not exhaustive. Maybe the user should fix this kind of
1924%%% issues.
1925deps(term) ->
1926    [{[nil, string, char, integer], [string_prefix]},
1927     {[bits, bytes], [bitstring]},
1928     {[bitstring], [bits, bytes]},
1929     {[build_map], [map]},
1930     {[plain_list, cons], [list]}];
1931deps(ResType) when ResType =:= program; ResType =:= guard; ResType =:= expr ->
1932    [{[type_decl], [user_defined_type]},
1933     {[record_decl], [record]},
1934     {[nil, string, char, integer], [string_prefix]},
1935     {[bits, blc], [bitstring]},
1936     {[function_decl], [local_mfa]},
1937     {[bitstring], [bits, blc]},
1938     {[build_map, update_map], [map]},
1939     {[fresh_var, bound_var], [pat_var]},
1940     {[plain_list, cons, lc], [list]}].
1941
1942eval_dep(S, Tags, AffectedTags) ->
1943    case sum_weights(Tags, S) of
1944        0 ->
1945            exclude_tags(AffectedTags, S);
1946        _ ->
1947            S
1948    end.
1949
1950sum_weights(Tags, State) ->
1951    Ws = get_weights(Tags, State),
1952    lists:sum([W || {_, W} <- Ws]).
1953
1954get_weights(Tags, State) ->
1955    [{Tag, get_weight(Tag, State)} || Tag <- Tags].
1956
1957get_weight(Tag, State) ->
1958    maps:get(Tag, State#gen_state.weights).
1959
1960exclude_tags(Tags, State) ->
1961    TagWeights = [{Tag, 0} || Tag <- Tags],
1962    set_tag_weights(TagWeights, State).
1963
1964set_tag_weights(TagWeights, State) ->
1965    Weights = State#gen_state.weights,
1966    Fun = fun({Tag, Weight}, Ws) ->
1967                  maps:put(Tag, Weight, Ws)
1968          end,
1969    NewWeights = lists:foldl(Fun, Weights, TagWeights),
1970    State#gen_state{weights = NewWeights}.
1971
1972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973
1974wunion(Tags, State, Where) ->
1975    FreqTypes = weights(Tags, State, Where),
1976    wunion2(FreqTypes, Tags).
1977
1978wunion1(FreqTypes) ->
1979    wunion2(FreqTypes, []).
1980
1981wunion2(FreqTypes0, Tags) ->
1982    FreqTypes = non_zero(FreqTypes0),
1983    case FreqTypes of
1984        [] ->
1985            erlang:error({zero_weights, Tags});
1986        _ ->
1987            ok
1988    end,
1989    proper_types:weighted_union(FreqTypes).
1990
1991non_zero(FreqTypes) ->
1992    [FT || {F, _} = FT <- FreqTypes, F =/= 0].
1993
1994weights(Tags, State, Where) ->
1995    Weights = State#gen_state.weights,
1996    [{maps:get(Tag, Weights),
1997      ?LAZY((pfun(Tag, Where))(State))}
1998      || Tag <- Tags].
1999
2000pfun(annotated_type, _) -> fun annotated_type/1;
2001pfun(atom, _) -> fun an_atom/1;
2002pfun(integer_range_type, _) -> fun integer_range_type/1;
2003pfun(no_constrained_function_type, _) -> fun no_constrained_function_type/1;
2004pfun(no_overloaded, _) -> fun no_overloaded/1;
2005pfun(predefined_type, _) -> fun predefined_type/1;
2006pfun(remote_type, _) -> fun remote_type/1;
2007pfun(singleton_integer_type, _) -> fun singleton_integer_type/1;
2008pfun(type_union, _) -> fun type_union/1;
2009pfun(type_variable, _) -> fun type_variable/1;
2010pfun(user_defined_type, _) -> fun user_defined_type/1;
2011pfun(yes_constrained_function_type, _) -> fun yes_constrained_function_type/1;
2012pfun(yes_overloaded, _) -> fun yes_overloaded/1;
2013%%pfun(anonymous_var, _) -> fun anonymous_var/1;
2014pfun(any_eclass, _) -> fun any_eclass/1;
2015pfun(any_mfa, _) -> fun any_mfa/1;
2016pfun(any_op, Where) -> pfun1(fun any_binop/2, Where);
2017pfun(boolean, _) -> fun a_boolean/1;
2018pfun(bad_eclass, _) -> fun bad_eclass/1;
2019pfun(bitstring, Where) -> fun(S) -> bitstring(S, Where) end;
2020pfun(bits, Where) -> fun(S) -> bits(S, Where) end;
2021pfun(blc, _) -> fun blc/1;
2022pfun(blc_gen, _) -> fun blc_gen/1;
2023pfun(binop, Where) -> fun(S) -> binop(S, Where) end;
2024pfun(block, _) -> fun block/1;
2025pfun(bound_var, _) -> fun bound_var/1;
2026pfun(bytes, _) -> fun bytes/1;
2027pfun('case', _) -> fun 'case'/1;
2028pfun('catch', _) -> fun 'catch'/1;
2029pfun(char, _) -> fun a_char/1;
2030pfun(cons, Where) -> pfun1(fun cons/2, Where);
2031pfun(ext_mfa, _) -> fun ext_mfa/1;
2032pfun(field_no_init, _) -> fun field_no_init/1;
2033pfun(field_no_type, _) -> fun field_no_type/1;
2034pfun(field_yes_init, _) -> fun field_yes_init/1;
2035pfun(field_yes_type, _) -> fun field_yes_type/1;
2036pfun(float, _) -> fun a_float/1;
2037pfun(fresh_var, _) -> fun fresh_var/1;
2038pfun('fun', Where) -> fun(S) -> 'fun'(S, Where) end;
2039pfun(guard_call, _) -> fun guard_call/1;
2040pfun(guard_op, Where) -> pfun1(fun guard_binop/2, Where);
2041pfun('if', _) -> fun 'if'/1;
2042pfun(inf_timeout, _) -> fun inf_timeout/1;
2043pfun(integer, _) -> fun an_integer/1;
2044pfun(lambda, _) -> fun lambda/1;
2045pfun(lc, _) -> fun lc/1;
2046pfun(lc_any_filter, _) -> fun lc_any_filter/1;
2047pfun(lc_guard_filter, _) -> fun lc_guard_filter/1;
2048pfun(lc_gen, _) -> fun lc_gen/1;
2049pfun(list, Where) -> fun(S) -> a_list(S, Where) end;
2050pfun(lit_eclass, _) -> fun lit_eclass/1;
2051pfun(lit_timeout, _) -> fun lit_timeout/1;
2052pfun(localcall, _) -> fun localcall/1;
2053pfun(local_mfa, _) -> fun local_mfa/1;
2054pfun(map, Where) -> fun(S) -> a_map(S, Where) end;
2055pfun(build_map, Where) -> pfun1(fun build_map/2, Where);
2056pfun(map_pattern, _) -> fun map_pattern/1;
2057pfun(string_prefix, _) -> fun string_prefix/1;
2058pfun(string_prefix_list, _) -> fun string_prefix_list/1; % internal
2059pfun(match, Where) -> fun(S) -> match(S, Where) end;
2060pfun(nil, Where) -> fun(S) -> nil(S, Where) end;
2061pfun(no_eclass, _) -> fun no_eclass/1;
2062pfun(no_guard, _) -> fun no_guard/1;
2063pfun(no_multi_field_init,_) -> fun no_multi_field_init/1;
2064pfun(no_try_after, _) -> fun no_try_after/1;
2065pfun(pat_var, _) -> fun pat_var/1;
2066pfun(plain_list, Where) -> pfun1(fun plain_list/2, Where);
2067pfun('receive', _) -> fun 'receive'/1;
2068pfun(rec_lambda, _) -> fun rec_lambda/1;
2069pfun(record, Where) -> fun(S) -> a_record(S, Where) end;
2070pfun(build_record, Where) -> fun(S) -> build_record(S, Where) end;
2071pfun(record_pattern, _) -> fun record_pattern/1;
2072pfun(update_record, Where) -> pfun1(fun update_record/2, Where);
2073pfun(record_index, _) -> fun(S) -> record_index(S) end;
2074pfun(record_field_access, Where) -> pfun1(fun record_field_access/2, Where);
2075pfun(extcall, _) -> fun extcall/1;
2076pfun(remote_guard_call, _) -> fun remote_guard_call/1;
2077pfun(small, Where) -> fun(S) -> small(S, Where) end;
2078pfun(string, _) -> fun a_string/1;
2079pfun(termcall, Where) -> pfun1(fun termcall/2, Where);
2080pfun(tuple, Where) -> fun(S) -> tuple(S, Where) end;
2081pfun('try', _) -> fun 'try'/1;
2082pfun(try_of, _) -> fun try_of/1;
2083pfun(try_after, _) -> fun try_after/1;
2084pfun(unop, Where) -> fun(S) -> unop(S, Where) end;
2085pfun(update_map, Where) -> pfun1(fun update_map/2, Where);
2086pfun(var, _) -> fun var/1;
2087pfun(varcall, Where) -> pfun1(fun varcall/2, Where);
2088pfun(var_eclass, _) -> fun var_eclass/1;
2089pfun(var_timeout, _) -> fun var_timeout/1;
2090pfun(yes_guard, _) -> fun yes_guard/1;
2091pfun(yes_multi_field_init, _) -> fun yes_multi_field_init/1.
2092
2093pfun1(F, Where) -> fun(S) -> F(S, where(S, Where)) end.
2094
2095where(S, compound) -> abstract_expr(S);
2096where(S, guard_test) -> guard_test(S);
2097where(S, pattern) -> pattern(S).
2098
2099%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2100
2101options(Options) ->
2102    State = create_template(),
2103    #gen_state{weights = Weights, limits = Limits} = State,
2104    (check_options(Weights, Limits, Options)
2105     andalso eval_options(Options, State)).
2106
2107check_options(Weights, Limits, Options) ->
2108    lists:all(fun ({K, {V1, V2}}) -> check_option2(Weights, Limits, K, V1, V2)
2109                ; ({K, V}) -> check_option(K, V)
2110              end, Options).
2111
2112check_option(set_all_weights, Value) ->
2113    is_integer(Value) andalso Value >= 0;
2114check_option(variables, Term) ->
2115    try
2116        %% true = length(Term) > 0,
2117        lists:all(fun(V) -> is_variable(V) end, Term)
2118    catch
2119        _:_ ->
2120            false
2121    end;
2122check_option(functions, Term) ->
2123    try
2124        lists:all(fun(F) -> is_fa(F) end, Term)
2125    catch
2126        _:_ ->
2127            false
2128    end;
2129check_option(types, Term) ->
2130    try
2131        lists:all(fun(T) -> is_fa(T) end, Term)
2132    catch
2133        _:_ ->
2134            false
2135    end;
2136check_option(records, Term) ->
2137    try
2138        lists:all(fun(R) -> is_record(R) end, Term)
2139    catch
2140        _:_ ->
2141            false
2142    end;
2143check_option(char, Term) when is_function(Term, 0) ->
2144    true;
2145check_option(atom, Term) when is_function(Term, 0) ->
2146    true;
2147check_option(resize, Term) when is_boolean(Term) ->
2148    true;
2149check_option(_, _) ->
2150    false.
2151
2152check_option2(Weights, _Limits, weight, Term1, W) ->
2153    is_integer(W) andalso W >= 0 andalso
2154    is_map(Weights) andalso maps:is_key(Term1, Weights);
2155check_option2(_Weights, Limits, limit, Term1, L) ->
2156    %% A limit equal to zero would mean the same as setting the weight
2157    %% to zero.
2158    is_integer(L) andalso L > 0 andalso
2159    is_map(Limits) andalso maps:is_key(Term1, Limits) andalso
2160    (Term1 =/= tsl orelse L =< 3);
2161check_option2(_, _, _, _, _) ->
2162    false.
2163
2164is_variable(T) ->
2165    case atom_to_list(T) of
2166        [C|_Cs] when C >= $A, C =< $Z ->
2167            true;
2168        [C|_Cs] when C =:= $_ ->
2169            true
2170    end.
2171
2172is_fa({F, A}) when is_atom(F), is_integer(A), A >= 0, A < 256 -> true.
2173
2174is_record({R, Fs}) when is_atom(R) ->
2175    true = lists:all(fun erlang:is_atom/1, Fs).
2176
2177eval_options([], State) ->
2178    State;
2179eval_options([{weight, {K, V}}|Options], State0) ->
2180    State = set_weight(State0, K, V),
2181    eval_options(Options, State);
2182eval_options([{set_all_weights, V}|Options], State0) ->
2183    Weights = maps:map(fun (termcall, V0) -> V0
2184                         ; (map_pattern_assoc, V0) -> V0
2185                         ; (map_pattern_exact, V0) -> V0
2186                         ; (complex_field_init, V0) -> V0
2187                         ; (string_prefix_list, V0) -> V0
2188                         ; (in_literal_bc, V0) -> V0
2189                         ; (_, _) -> V
2190                       end, State0#gen_state.weights),
2191    State = State0#gen_state{weights = Weights},
2192    eval_options(Options, State);
2193eval_options([{limit, {K, W}}|Options], State0) ->
2194    State = set_limit(State0, K, W),
2195    eval_options(Options, State);
2196eval_options([{variables, Vars}|Options], State0) ->
2197    State = State0#gen_state{variables = ordsets:from_list(Vars)},
2198    eval_options(Options, State);
2199eval_options([{functions, Funcs}|Options], State) ->
2200    State1 = State#gen_state{functions = Funcs},
2201    eval_options(Options, State1);
2202eval_options([{types, Types}|Options], State) ->
2203    State1 = State#gen_state{types = Types},
2204    eval_options(Options, State1);
2205eval_options([{records, Records}|Options], State) ->
2206    State1 = State#gen_state{records = Records},
2207    eval_options(Options, State1);
2208eval_options([{char, CharGen}|Options], State) ->
2209    State1 = State#gen_state{simple_char = CharGen},
2210    eval_options(Options, State1);
2211eval_options([{atom, AtomGen}|Options], State) ->
2212    State1 = State#gen_state{atom = AtomGen},
2213    eval_options(Options, State1);
2214eval_options([{resize, Boolean}|Options], State) ->
2215    State1 = State#gen_state{resize = Boolean},
2216    eval_options(Options, State1).
2217
2218set_weight(State, K, V) ->
2219    Weights = State#gen_state.weights,
2220    State#gen_state{weights = maps:update(K, V, Weights)}.
2221
2222set_limit(State, Name, Value) ->
2223    Limits = State#gen_state.limits,
2224    State#gen_state{limits = maps:update(Name, Value, Limits)}.
2225
2226get_limit(Tag, State) ->
2227    maps:get(Tag, State#gen_state.limits).
2228
2229create_template() ->
2230    NamedFunctions = some_named_functions(),
2231    PredefTypes = predef_types(),
2232    #gen_state{module = module_name,
2233               functions = some_functions(),
2234               records = some_records(),
2235               types = some_types(),
2236               named_funs = NamedFunctions,
2237               predef_types = PredefTypes,
2238               weights = default_weights(),
2239               limits = default_limits()}.
2240
2241default_weights() ->
2242    #{
2243     'case' => 1,
2244     'catch' => 1,
2245     'fun' => 1,
2246     'if' => 1,
2247     'receive' => 1,
2248     'try' => 1,
2249     annotated_type => 1,
2250     %% anonymous_var => 1,
2251     any_eclass => 1,
2252     any_mfa => 1,
2253     any_op => 1,
2254     atom => 1,
2255     bad_eclass => 1,
2256     bitstring => 1,
2257     bits => 1,
2258     bytes => 1, % term only
2259     blc => 1,
2260     blc_gen => 1,
2261     binop => 1,
2262     block => 1,
2263     boolean => 1,
2264     bound_var => 1,
2265     char => 1,
2266     compound => 1,
2267     cons => 1,
2268     default => 1,
2269     ext_mfa => 1,
2270     field => 1,
2271     field_no_init => 1,
2272     field_no_type => 1,
2273     field_yes_init => 1,
2274     field_yes_type => 1,
2275     file => 1,
2276     float => 1,
2277     fresh_var => 1,
2278     function_decl => 1,
2279     function_spec => 0,
2280     generate => 1,
2281     guard_op => 1,
2282     guard_call => 1,
2283     inf_timeout => 1,
2284     integer => 3,
2285     integer_range_type => 1,
2286     lambda => 1,
2287     lc => 1,
2288     lc_any_filter => 10,
2289     lc_guard_filter => 5,
2290     lc_gen => 5,
2291     list => 1,
2292     lit_eclass => 1,
2293     lit_timeout => 1,
2294     localcall => 1,
2295     local_mfa => 1,
2296     map => 1,
2297     build_map => 1,
2298     map_pattern => 1,
2299     string_prefix => 1,
2300     match => 1,
2301     nil => 1,
2302     no_constrained_function_type => 1,
2303     no_eclass => 1,
2304     no_guard => 1,
2305     no_multi_field_init => 1,
2306     no_overloaded => 1,
2307     no_try_after => 1,
2308     pat_var => 1,
2309     plain_list => 1,
2310     predefined_type => 1,
2311     rec_lambda => 1,
2312     record => 1,
2313     build_record => 1,
2314     record_pattern => 1,
2315     record_decl => 1,
2316     record_field_access => 1,
2317     record_index => 1,
2318     update_record => 1,
2319     extcall => 1,
2320     remote_guard_call => 1,
2321     remote_type => 1,
2322     signedness => 1,
2323     singleton_integer_type => 1,
2324     size => 1,
2325     small => ?DEFAULT_SMALL_WEIGHT_PROGRAM,
2326     string => 1,
2327     termcall => 0,
2328     try_of => 1,
2329     try_after => 1,
2330     tuple => 1,
2331     type => 1,
2332     type_decl => 0,
2333     type_union => 1,
2334     type_variable => 1,
2335     unop => 1,
2336     update_map => 1,
2337     user_defined_type => 1,
2338     varcall => 1,
2339     var_eclass => 1,
2340     var_timeout => 1,
2341     var => 1,
2342     yes_constrained_function_type => 1,
2343     yes_guard => 1,
2344     yes_multi_field_init => 1,
2345     yes_overloaded => 1,
2346
2347     literal_bits => 1,
2348     %% See also eval_options().
2349     %% Used internally, see literal_bc().
2350     in_literal_bc => 0,
2351
2352     %% Used internally, see assoc_pattern_seq().
2353     map_pattern_exact => 1,
2354     map_pattern_assoc => 0,
2355
2356     %% Also used internally:
2357     complex_field_init => 1,
2358     string_prefix_list => 1
2359    }.
2360
2361default_limits() ->
2362    #{
2363      %% term and program
2364      bin_elements => ?MAX_BIN_ELEMENTS,
2365      list => ?MAX_LIST,
2366      map => ?MAX_MAP,
2367      string => ?MAX_STRING,
2368      tuple => ?MAX_TUPLE,
2369      %% program
2370      body => ?MAX_BODY,
2371      call_args => ?MAX_CALL_ARGS,
2372      catch_clauses => ?MAX_CATCH_CLAUSES,
2373      clauses  => ?MAX_CLAUSES,
2374      function_clauses => ?MAX_FUNCTION_CLAUSES,
2375      function_constraints => ?MAX_FUNCTION_CONSTRAINTS,
2376      function_types => ?MAX_FUNCTION_TYPES,
2377      guard => ?MAX_GUARD,
2378      guard_tests => ?MAX_GUARD_TESTS,
2379      if_clauses => ?MAX_IF_CLAUSES,
2380      tuple_types => ?MAX_TUPLE_TYPES,
2381      qualifiers => ?MAX_QUALIFIERS,
2382      record_fields => ?MAX_RECORD_FIELDS,
2383      tsl => ?MAX_TYPE_SPECIFIER,
2384      union_types => ?MAX_UNION_TYPES
2385     }.
2386
2387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2388
2389%%% Postprocess generated abstract format.
2390
2391post_process(Abstracts, Functions, AtomGen, Variables) ->
2392    Known = (Functions ++ auto_imported() ++
2393             guard_bifs() ++ other_bifs()),
2394    State = #post_state{known_functions = Known,
2395                        atom = AtomGen,
2396                        vars = Variables},
2397    ?DEBUG("\n\n<original>\n~p\n</original>\n", [Abstracts]),
2398    [post1(Abstr, State) || Abstr <- Abstracts].
2399
2400post1(AbstrL, State) when is_list(AbstrL) ->
2401    {AbstrL1, _} = post_list(AbstrL, State),
2402    AbstrL1;
2403post1(Abstr, State) ->
2404    {Abstr1, _} = post(Abstr, State),
2405    Abstr1.
2406
2407%%% - unbound/unsafe linter errors are avoided, but the code is
2408%%%   probably a bit too complex...
2409
2410post({var, A, fresh_var}, S) ->
2411    new_var(A, S);
2412post({var, A, bound_var_or_an_atom}, S) ->
2413    any_var(A, S, atom);
2414post({var, A, bound_var_or_an_integer}, S) ->
2415    any_var(A, S, integer);
2416post({var, A, bound_var_or_an_arity}, S) ->
2417    any_var(A, S, arity);
2418post({var, A, type_variable}, S) ->
2419    any_var(A, S, fresh_var);
2420post({var, A, type_parameter}, S) ->
2421    new_var(A, S);
2422post({atom, A, any_function}, S) ->
2423    {{atom, A, create_atom(S)}, S};
2424post({atom, A, any_module}, S) ->
2425    {{atom, A, create_atom(S)}, S};
2426post({atom, A, create_atom}, S) ->
2427    {{atom, A, create_atom(S)}, S};
2428post({atom, A, bad_eclass}, S) ->
2429    {{atom, A, create_atom(S)}, S};
2430post({cons, A, H, T}, S) ->
2431    {[H1,T1], S1} = post_expr_list([H, T], S),
2432    {{cons, A, H1, T1}, S1};
2433post({call, A1, {remote, A2, M, F}, As}, S) ->
2434    {[M1, F1|As1], S1} = post_expr_list([M, F|As], S),
2435    {{call, A1, {remote, A2, M1, F1}, As1}, S1};
2436post({call, A, F, As}, S) ->
2437    {[F1|As1], S1} = post_expr_list([F|As], S),
2438    case F1 of
2439        {atom, _, Name} = Atom ->
2440            KnownFunctions = S#post_state.known_functions,
2441            case lists:member({Name, length(As)}, KnownFunctions) of
2442                true ->
2443                    {{call, A, F1, As1}, S1};
2444                false ->
2445                    {Atom, S}
2446                end;
2447        _ -> % named fun or other
2448            {{call, A, F1, As1}, S1}
2449    end;
2450post({match, A, P, E}, S) ->
2451    {[P2, E2], S3} =
2452        case S#post_state.context of
2453            pattern -> % alias
2454                post_expr_list([P, E], S);
2455            _ ->
2456                {E1, S1} = post(E, S),
2457                {[P1], S2} = post_patterns([P], S1),
2458                {[P1, E1], S2}
2459        end,
2460    {{match, A, P2, E2}, S3};
2461post({lc, A, E, Qs}, S) ->
2462    {Qs1, S1} = post_qualifiers(Qs, S),
2463    {E1, _} = post(E, S1),
2464    {{lc, A, E1, Qs1}, S};
2465post({bc, A, E, Qs}, S) ->
2466    {Qs1, S1} = post_qualifiers(Qs, S),
2467    {E1, _} = post(E, S1),
2468    {{bc, A, E1, Qs1}, S};
2469post({op, A, Op, E}, S) ->
2470    {E1, S1} = post(E, S),
2471    E3 = case S#post_state.context of
2472             pattern ->
2473                 {E2, _} = post_round(E1, A),
2474                 E2;
2475             _ ->
2476                 E1
2477         end,
2478    {{op, A, Op, E3}, S1};
2479post({op, A, Op, L, R}, S) when Op =:= 'bsl'; Op =:= 'bsr' ->
2480    %% bsl and bsr can create huge integers, which is not what we want
2481    %% to test here.
2482    {[L1, R1], S1} = post_expr_list([L, R], S),
2483    {L3, R3} =
2484        case S1#post_state.context of
2485            expr ->
2486                {L1, R1};
2487            pattern ->
2488                {L2, _} = post_round(L1, A),
2489                {R2, V} = post_round(R1, A),
2490                case V of % can be slow...
2491                    {integer, _, I} when I > 30 ->
2492                        {L2, {integer, A, 30}};
2493                    {integer, _, I} when I < -30 ->
2494                        {L2, {integer, A, -30}};
2495                    _ ->
2496                        {L2, R2}
2497                end;
2498            type ->
2499                case erl_eval:partial_eval(R1) of % can be slow...
2500                    {integer, _, I} when I > 30 ->
2501                        {L1, {integer, A, 30}};
2502                    {integer, _, I} when I < -30 ->
2503                        {L1, {integer, A, -30}};
2504                    _ ->
2505                        {L1, R1}
2506                end
2507        end,
2508    {{op, A, Op, L3, R3}, S1};
2509post({op, A, Op, L, R}, S) when Op =:= 'rem'; Op =:= 'div'; % type and pattern
2510                                Op =:= '/' -> % pattern
2511    {[L1, R1], S1} = post_expr_list([L, R], S),
2512    {L3, R3} =
2513        case S1#post_state.context of
2514            expr ->
2515                {L1, R1};
2516            pattern ->
2517                {L2, _} = post_round(L1, A),
2518                {R2, V} = post_round(R1, A),
2519                case V of % can be slow...
2520                    {integer, _, 0} -> % division by zero
2521                        {L2, {op, A, '+', R2, {integer, A, 1}}};
2522                    _ ->
2523                        {L2, R2}
2524                end;
2525            type ->
2526                case erl_eval:partial_eval(R1) of % can be slow...
2527                    {integer, _, 0} -> % division by zero
2528                        {L1, {op, A, '+', R1, {integer, A, 1}}};
2529                    _ ->
2530                        {L1, R1}
2531                end
2532        end,
2533    {{op, A, Op, L3, R3}, S1};
2534post({op, A, Op, L, R}, S) when Op =:= 'orelse'; Op =:= 'andalso' ->
2535    {L1, S1} = post(L, S),
2536    {R1, S2} = post(R, S1),
2537    IntroducedVariables = introduced_variables(S1, S2),
2538    S3 = forbidden_variables(S2, IntroducedVariables),
2539    {{op, A, Op, L1, R1}, S3};
2540post({op, A, Op, L, R}, S) ->
2541    {[L1, R1], S1} = post_expr_list([L, R], S),
2542    {L3, R3} =
2543        case S1#post_state.context of
2544            pattern ->
2545                {L2, _} = post_round(L1, A),
2546                {R2, _} = post_round(R1, A),
2547                {L2, R2};
2548            _ ->
2549                {L1, R1}
2550        end,
2551    {{op, A, Op, L3, R3}, S1};
2552post({map, A, Es}, S) ->
2553    {Es1, S1} = post_expr_list(Es, S),
2554    {{map, A, Es1}, S1};
2555post({map, A, B, Es}, S) ->
2556    {[B1|Es1], S1} = post_expr_list([B|Es], S),
2557    {{map, A, B1, Es1}, S1};
2558post({map_field_assoc, A, K, V}, S) ->
2559    {[K2, V2], S1} =
2560        case S#post_state.context of
2561            pattern ->
2562                %% K is any guard expression, which the linter accepts.
2563                L = [post_expr(K, S), post(V, S)],
2564                expr_list2(L, S);
2565            _ ->
2566                post_expr_list([K, V], S)
2567        end,
2568    {{map_field_assoc, A, K2, V2}, S1};
2569post({map_field_exact, A, K, V}, S) ->
2570    {[K1, V1], S1} = post_expr_list([K, V], S),
2571    {{map_field_exact, A, K1, V1}, S1};
2572post({'if', A, Clauses}, S) ->
2573    {Clauses1, S1} = clauses(Clauses, S),
2574    {{'if', A, Clauses1}, S1};
2575post({'case', A, E, Clauses}, S) ->
2576    {E1, S1} = post(E, S),
2577    {Clauses1, S2} = clauses(Clauses, S1),
2578    {{'case', A, E1, Clauses1}, S2};
2579post({'try', A, B, Cls, TCls, After}, S) ->
2580    {B1, S1} = post_list(B, S),
2581    IntroVars = introduced_variables(S, S1),
2582    {Cls1, S2} = clauses_in_try(Cls, S1, clause),
2583    %% New variables in B are unsafe in TCls and After.
2584    S3 = forbidden_variables(S2, IntroVars),
2585    {TCls1, S4} = clauses_in_try(TCls, S3, catch_clause),
2586    {After1, S5} = post_list(After, S4),
2587    AllIntroVars = introduced_variables(S, S5),
2588    ForbiddenVars = ordsets:union(AllIntroVars, S#post_state.forbidden),
2589    S6 = forbidden_variables(S5, ForbiddenVars),
2590    {{'try', A, B1, Cls1, TCls1, After1}, S6};
2591post({'receive', A, Clauses}, S) ->
2592    {Clauses1, S1} = clauses(Clauses, S),
2593    {{'receive', A, Clauses1}, S1};
2594post({'receive', A, Clauses, E, B}, S) ->
2595    {Clauses1, S1} = clauses(Clauses, S),
2596    {E1, S2} = post(E, S),
2597    %% New variables in E are not visible in B:
2598    IntroVars0 = introduced_variables(S, S2),
2599    S3 = forbidden_variables(S2, IntroVars0),
2600    {B1, S4} = post_list(B, S3),
2601    %% New variables in receive are unsafe.
2602    IntroVars1 = introduced_variables(S, S1),
2603    IntroVars3 = introduced_variables(S, S4),
2604    IntroVars = ordsets:union(IntroVars1, IntroVars3),
2605    ForbiddenVars = ordsets:union(IntroVars, S4#post_state.forbidden),
2606    S5 = forbidden_variables(S1, ForbiddenVars),
2607    {{'receive', A, Clauses1, E1, B1}, S5};
2608post({tuple, A, Es}, S) ->
2609    {Es1, S1} = post_expr_list(Es, S),
2610    {{tuple, A, Es1}, S1};
2611post({'catch', A, E}, S) ->
2612    {E1, S1} = post(E, S),
2613    IntroducedVariables = introduced_variables(S, S1),
2614    S2 = forbidden_variables(S1, IntroducedVariables),
2615    {{'catch', A, E1}, S2};
2616post({'fun', A, {clauses, Clauses}}, S) ->
2617    {Clauses1, _} = clauses(Clauses, S),
2618    {{'fun', A, {clauses, Clauses1}}, S};
2619post({named_fun, A, F, Clauses}, S) ->
2620    {Clauses1, _} = clauses(Clauses, S),
2621    {{named_fun, A, F, Clauses1}, S};
2622post({bin, A, Es}, S) ->
2623    {Es1, S1} = post_expr_list(Es, S),
2624    {{bin, A, Es1}, S1};
2625post({bin_element, A, Expr, default, TSL}, S) ->
2626    {[Expr1], S1} = post_expr_list([Expr], S),
2627    {{bin_element, A, Expr1, default, TSL}, S1};
2628post({bin_element, A, Expr, Size, TSL}, S) ->
2629    {[Expr2, Size2], S1} =
2630        case S#post_state.context of
2631            pattern ->
2632                %% Size is any guard expression, which the linter accepts.
2633                L = [post(Expr, S), post_expr(Size, S)],
2634                expr_list2(L, S);
2635            _ ->
2636                post_expr_list([Expr, Size], S)
2637        end,
2638    {{bin_element, A, Expr2, Size2, TSL}, S1};
2639post({record, A, E, RecName, Fields}, S) ->
2640    {[E1|Fields1], S1} = post_expr_list([E|Fields], S),
2641    {{record, A, E1, RecName, Fields1}, S1};
2642post({record, A, RecName, Fields}, S) ->
2643    {Fields1, S1} = post_expr_list(Fields, S),
2644    {{record, A, RecName, Fields1}, S1};
2645post({type, A, binary, [_B, _U]=BU}, S) ->
2646    {[B1, U1], S1} = post_expr_list(BU, S),
2647    Check = fun(E) ->
2648                    case erl_eval:partial_eval(E) of
2649                        {integer, _, V} when V >= 0 ->
2650                            E;
2651                        {integer, _, V} when V < 0 ->
2652                            {op, A, '-', E};
2653                        (_) -> % cannot happen
2654                            E
2655                    end
2656            end,
2657    {{type, A, binary, [Check(B1), Check(U1)]}, S1};
2658post({type, A, range, [_L, _H]=LH}, S) ->
2659    {[L1, H1] = LH1, S1} = post_expr_list(LH, S),
2660    Low = erl_eval:partial_eval(L1),
2661    High = erl_eval:partial_eval(H1),
2662    case {Low, High} of
2663        {{integer, _, V}, {integer, _, V}} ->
2664            {{type, A, range, [L1, {op, A, '+', H1, {integer, A, 1}}]}, S1};
2665        {{integer, _, V1}, {integer, _, V2}} when V1 >= V2 ->
2666            {{type, A, range, [H1, L1]}, S1};
2667        {{integer, _, V1}, {integer, _, V2}} when V1 < V2 ->
2668            {{type, A, range, LH1}, S1};
2669        _ -> % cannot happen
2670            {{type, A, range, LH1}, S1}
2671    end;
2672post({attribute, A, Type, {TypeName, AbstrType, Parms}}, S)
2673                  when Type =:= 'opaque'; Type =:= 'type' ->
2674    in_context
2675      (type, S,
2676       fun(State) ->
2677               {Parms1, S1} = post_list(Parms, State),
2678               {AbstrType1, S2} = post(AbstrType, S1),
2679               {{attribute, A, Type, {TypeName, AbstrType1, Parms1}}, S2}
2680       end);
2681post({function, A, F, N, ClauseSeq}, S) ->
2682    in_context
2683      (expr, S,
2684       fun(State) ->
2685               {ClauseSeq1, State1} = function_clauses(ClauseSeq, State),
2686               {{function, A, F, N, ClauseSeq1}, State1}
2687       end);
2688post({attribute, A, Spec, {{_F, _N}=FN, FuncTypeList}}, S) ->
2689    in_context
2690      (type, S,
2691       fun(State) ->
2692               {FuncTypeList1, State1} = post_list(FuncTypeList, State),
2693               {{attribute, A, Spec, {FN, FuncTypeList1}}, State1}
2694       end);
2695post({attribute, A, record, {Name, Fields}}, S) ->
2696    in_context
2697      (record, S,
2698       fun(State) ->
2699               {Fields1, State1} = post_list(Fields, State),
2700               {{attribute, A, record, {Name, Fields1}}, State1}
2701       end);
2702post({record_field, A, Name, Expr}, #post_state{context = record} = S) ->
2703    in_context
2704      (expr, S,
2705       fun(State) ->
2706               {Expr1, State1} = post(Expr, State),
2707               {{record_field, A, Name, Expr1}, State1}
2708       end);
2709post({typed_record_field, Field, Type}, S) ->
2710    in_context
2711      (type, S,
2712       fun(State) ->
2713               {Field1, State1} = post(Field, State),
2714               {Type1, State2} = post(Type, State1),
2715               {{typed_record_field, Field1, Type1}, State2}
2716       end);
2717%%% No special handling of the following cases:
2718post({ann_type, A, T}, S) ->
2719    {T1, S1} = post_list(T, S),
2720    {{ann_type, A, T1}, S1};
2721post({atom, _, _}=A, S) ->
2722    {A, S};
2723post({attribute, _, _, _}=A, S) ->
2724    {A, S};
2725post({block, A, Body}, S) ->
2726    {Body1, S1} = post_list(Body, S),
2727    {{block, A, Body1}, S1};
2728post({char, _, _}=C, S) ->
2729    {C, S};
2730post({float, _, _}=F, S) ->
2731    {F, S};
2732post({'fun', _A, {function, M, N, Arity}}=F, S) when is_atom(M),
2733                                                     is_atom(N),
2734                                                     is_integer(Arity) ->
2735    %% cannot happen
2736    {F, S};
2737post({'fun', A, {function, M, N, Arity}}, S) ->
2738    {[M1, N1, Arity1], S1} = post_list([M, N, Arity], S),
2739    {{'fun', A, {function, M1, N1, Arity1}}, S1};
2740post({'fun', _A, {function, N, Arity}}=F, S) when is_atom(N),
2741                                                  is_integer(Arity) ->
2742    {F, S};
2743post({integer, _, _}=I, S) ->
2744    {I, S};
2745post({nil, _}=N, S) ->
2746    {N, S};
2747post({record_field, A, N}, S) ->
2748    {N1, S1} = post(N, S),
2749    {{record_field, A, N1}, S1};
2750post({record_field, A, F, E}, S) ->
2751    {[F1, E1], S1} = post_list([F, E], S),
2752    {{record_field, A, F1, E1}, S1};
2753post({record_field, A, E0, N, F}, S) ->
2754    {[E1, F1], S1} = post_list([E0, F], S),
2755    {{record_field, A, E1, N, F1}, S1};
2756post({record_index, A, N, F}, S) ->
2757    {F1, S1} = post(F, S),
2758    {{record_index, A, N, F1}, S1};
2759post({remote_type, A, [M, N, Ts]}, S) ->
2760    {[M1, N1], S1} = post_list([M, N], S),
2761    {Ts1, S2} = post_list(Ts, S1),
2762    {{remote_type, A, [M1, N1, Ts1]}, S2};
2763post({string, _, _}=Str, S) ->
2764    {Str, S};
2765post({type, _A, any}=Any, S) ->
2766    {Any, S};
2767post({type, _A, _N, any}=Any, S) ->
2768    {Any, S};
2769post({type, A, 'fun', Ts}, S) ->
2770    {Ts1, S1} = post_list(Ts, S),
2771    {{type, A, 'fun', Ts1}, S1};
2772post({type, A, constraint, [C, [V, T]]}, S) ->
2773    {[C1, V1, T1], S1} = post_list([C, V, T], S),
2774    {{type, A, constraint, [C1, [V1, T1]]}, S1};
2775post({type, A, bounded_fun, [Ft, Fcs]}, S) ->
2776    {Ft1, S1} = post(Ft, S),
2777    {Fcs1, S2} = post_list(Fcs, S1),
2778    {{type, A, bounded_fun, [Ft1, Fcs1]}, S2};
2779post({type, A, N, Ts}, S) ->
2780    {Ts1, S1} = post_list(Ts, S),
2781    {{type, A, N, Ts1}, S1};
2782post({user_type, A, N, Ts}, S) ->
2783    {Ts1, S1} = post_list(Ts, S),
2784    {{user_type, A, N, Ts1}, S1};
2785post({var, _A, '_'}=VarU, S) ->
2786    {VarU, S};
2787post({var, _A, _NamedFun}=VarNF, S) ->
2788    {VarNF, S}.
2789
2790in_context(Context, S, Fun) ->
2791    S1 = S#post_state{context = Context,
2792                      vars = [],
2793                      vindex = 0,
2794                      forbidden = []},
2795    {T, _} = Fun(S1),
2796    {T, S}.
2797
2798post_round(E, A) ->
2799    case erl_eval:partial_eval(E) of % can be slow if E is deep
2800        {float, _, F} ->
2801            %% Very crude. A pity guard BIFs cannot be evaluated by
2802            %% erl_eval:partial_eval/1 (for example erlang:guard/1).
2803            I = {integer, A, round(F)},
2804            {I, I};
2805        V ->
2806            {E, V}
2807    end.
2808
2809post_qualifiers([], S) ->
2810    {[], S};
2811post_qualifiers([{Gen, A, P, E}|Qs], S) when Gen =:= generate;
2812                                             Gen =:= b_generate ->
2813    %% Variables introduced in E can only be used in E, and can be
2814    %% introduced in subsequent generators.
2815    {E1, _} = post(E, S),
2816    {[P1], S1} = post_patterns([P], S),
2817    {Qs1, S2} = post_qualifiers(Qs, S1),
2818    {[{Gen, A, P1, E1}|Qs1], S2};
2819post_qualifiers([F|Qs], S) ->
2820    {F1, S1} = post(F, S),
2821    {Qs1, S2} = post_qualifiers(Qs, S1),
2822    {[F1|Qs1], S2}.
2823
2824function_clauses(Clauses, S) ->
2825    L = [post_clause(Cl, S) || Cl <- Clauses],
2826    {Clauses1, _} = lists:unzip(L),
2827    {Clauses1, S}.
2828
2829clauses([], S) ->
2830    {[], S}; % receive after T -> E end
2831clauses(Clauses, S) ->
2832    L = [post_clause(Cl, S) || Cl <- Clauses],
2833    {Clauses1, Ss} = lists:unzip(L),
2834    VarsInCls = [introduced_variables(S, S1) || S1 <- Ss],
2835    NewVars = ordsets:union(VarsInCls),
2836    ExportedVars = ordsets:intersection(VarsInCls),
2837    ForbiddenVars = ordsets:subtract(NewVars, ExportedVars),
2838    ForbiddenVarsInCls = [S1#post_state.forbidden || S1 <- Ss],
2839    AllForbiddenVars = ordsets:union([ForbiddenVars|ForbiddenVarsInCls]),
2840    S1 = forbidden_variables(S, AllForbiddenVars),
2841    S2 = S1#post_state{vars = ordsets:union(ExportedVars, S#post_state.vars)},
2842    {Clauses1, S2}.
2843
2844clauses_in_try([], S, _Kind) ->
2845    {[], S};
2846clauses_in_try(Clauses, S, Kind) ->
2847    L = [post_try_clause(Cl, S, Kind) || Cl <- Clauses],
2848    {Clauses1, Ss} = lists:unzip(L),
2849    VarsInCls = [introduced_variables(S, S1) || S1 <- Ss],
2850    ForbiddenVars = ordsets:union(VarsInCls),
2851    ForbiddenVarsInCls = [S1#post_state.forbidden || S1 <- Ss],
2852    AllForbiddenVars = ordsets:union([ForbiddenVars|ForbiddenVarsInCls]),
2853    S1 = forbidden_variables(S, AllForbiddenVars),
2854    {Clauses1, S1}.
2855
2856post_try_clause(Clause, S, clause) ->
2857    post_clause(Clause, S);
2858post_try_clause(Clause, S, catch_clause) ->
2859    {clause, A1, [{'tuple', A2, [EClass, P, St]}], GuardSeq, Body} = Clause,
2860    {EClass1, S1} = post(EClass, S),
2861    {[P1], S2} = post_patterns([P], S1),
2862    %% Stacktrace variable must not be bound:
2863    SSt = forbidden_variables(S2, S2#post_state.vars),
2864    {St1, S3} = post(St, SSt),
2865    StackVars = introduced_variables(SSt, S3),
2866    %% The stacktrace variable cannot be used in the catch clause guard:
2867    S4 = forbidden_variables(S3, StackVars),
2868    {GuardSeq1, S5} = post_guard_seq(GuardSeq, S4),
2869    %% Should simplify this...
2870    S6 = allowed_variables(S5, StackVars),
2871    {Body1, S7} = post_list(Body, S6),
2872    S8 = forbidden_variables(S7, StackVars),
2873    {{clause, A1, [{'tuple', A2, [EClass1, P1, St1]}], GuardSeq1, Body1},
2874     S8}.
2875
2876post_clause({clause, A, Patterns, GuardSeq, Body}, S0) ->
2877    {Patterns1, S1} = post_patterns(Patterns, S0),
2878    {GuardSeq1, S2} = post_guard_seq(GuardSeq, S1),
2879    {Body1, S3} = post_list(Body, S2),
2880    {{clause, A, Patterns1, GuardSeq1, Body1}, S3}.
2881
2882post_patterns(Patterns, S0) ->
2883    Ctxt = S0#post_state.context,
2884    S1 = S0#post_state{context = pattern},
2885    {Patterns1, S2} = post_expr_list(Patterns, S1),
2886    {Patterns1, S2#post_state{context = Ctxt}}.
2887
2888post_guard_seq(GuardSeq, S)  ->
2889    GuardSeq1 = [post_list(G, S) || G <- GuardSeq],
2890    expr_list2(GuardSeq1, S).
2891
2892post_list([], S) ->
2893    {[], S};
2894post_list([E|Es], S) ->
2895    {E1, S1} = post(E, S),
2896    {Es1, S2} = post_list(Es, S1),
2897    {[E1|Es1], S2}.
2898
2899post_expr_list(Es, S) ->
2900    L = [post(E, S) || E <- Es],
2901    expr_list2(L, S).
2902
2903expr_list2(L, S) ->
2904    {Es1, Ss} = lists:unzip(L),
2905    VsInEs = [S1#post_state.vars || S1 <- Ss],
2906    Vs = ordsets:union([S#post_state.vars|VsInEs]),
2907    Forbidden = ordsets:union([S1#post_state.forbidden || S1 <- Ss]),
2908    S1 = S#post_state{vars = Vs},
2909    S2 = forbidden_variables(S1, Forbidden),
2910    {Es1, S2}.
2911
2912post_expr(Expr, S0) ->
2913    Ctxt = S0#post_state.context,
2914    S1 = S0#post_state{context = expr},
2915    {Expr1, S2} = post(Expr, S1),
2916    {Expr1, S2#post_state{context = Ctxt}}.
2917
2918introduced_variables(S0, S1) ->
2919    ordsets:from_list(S1#post_state.vars -- S0#post_state.vars).
2920
2921forbidden_variables(S, Vs) ->
2922    S#post_state{forbidden = ordsets:union(S#post_state.forbidden, Vs)}.
2923
2924allowed_variables(S, Vs) ->
2925    S#post_state{forbidden = ordsets:subtract(S#post_state.forbidden, Vs)}.
2926
2927any_var(Anno, State, Fallback) ->
2928    #post_state{vars = Vs, forbidden = NoNo} = State,
2929    case find_var(Vs, NoNo, length(Vs)) of
2930        no ->
2931            case Fallback of
2932                arity ->
2933                    {{integer, Anno, uniform(256) - 1}, State};
2934                atom ->
2935                    {{atom, Anno, create_atom(State)}, State};
2936                fresh_var ->
2937                    new_var(Anno, State);
2938                integer ->
2939                    {{integer, Anno, uniform(1024) - 1}, State} % smallish
2940            end;
2941        {yes, Var} ->
2942            {{var, Anno, Var}, State}
2943    end.
2944
2945find_var([], _NoNo, 0) ->
2946    no;
2947find_var(Vs, NoNo, N) ->
2948    V = lists:nth(uniform(N), Vs),
2949    case ordsets:is_element(V, NoNo) of
2950        true ->
2951            find_var(Vs -- [V], NoNo, N - 1);
2952        false ->
2953            {yes, V}
2954    end.
2955
2956create_atom(S) ->
2957    (S#post_state.atom)().
2958
2959any_of(L) ->
2960    lists:nth(uniform(length(L)), L).
2961
2962new_var(Anno, S) ->
2963    #post_state{vars = Vs, forbidden = NoNo, vindex = I} = S,
2964    Seed = case S#post_state.context of
2965               type ->
2966                   '_V'; % avoid singleton_typevar error..
2967               expr ->
2968                   'V';
2969               pattern ->
2970                   'V'
2971           end,
2972    NewVar = list_to_atom(lists:concat([Seed, I])),
2973    S1 = S#post_state{vindex = I + 1},
2974    case ordsets:is_element(NewVar, NoNo) of
2975        true ->
2976            new_var(Anno, S1);
2977        false ->
2978            NewVars = ordsets:add_element(NewVar, Vs),
2979            S2 = S#post_state{vars = NewVars},
2980            {{var, Anno, NewVar}, S2}
2981    end.
2982
2983%%% Some errors detected by the linter are not compensated for in this
2984%%% module. However, such errors should not occur very often, which
2985%%% means that bad instances can be discarded without (almost) any
2986%%% slow-down. But check that the errors returned are expected as
2987%%% unexpected errors can slow down the generator.
2988ok_by_the_linter(What, T) ->
2989    case call_linter(What, T) of
2990        {ok, _Ws} ->
2991            true;
2992        {error, [{_File,Errors}], _Ws} ->
2993            ?DEBUG("LINT ~p\n", [Errors]),
2994            ?DEBUG("HARD? ~p\n", [all_hard_to_fix_errors(Errors)]),
2995            case all_hard_to_fix_errors(Errors) of
2996                true ->
2997                    ?DEBUG("DISCARD!\n", []),
2998                    false % discard; try again
2999              %% ; false ->
3000              %%       io:format("The linter found an error that should not "
3001              %%                 "have occurred:\n ~p\n ~p\n", [Errors, T]),
3002              %%       exit({bug, Errors, T})
3003            end
3004    end.
3005
3006call_linter(expr, Expr) ->
3007    erl_lint:exprs([Expr], []);
3008call_linter(forms, Forms) ->
3009    erl_lint:module(Forms).
3010
3011all_hard_to_fix_errors(Errors) ->
3012    lists:all(fun hard_error/1, Errors).
3013
3014%%% After some testing it seems harmless to treat all linter errors
3015%%% as "hard". The "leakage" is negligible.
3016
3017%%% hard_error({_, erl_lint, illegal_bin_pattern}) -> true;
3018%%% hard_error({_, erl_lint, {error, bittype_unit}}) -> true;
3019%%% hard_error({_, erl_lint, illegal_map_key}) -> true;
3020%%% hard_error({_, erl_lint, unsized_binary_in_bin_gen_pattern}) -> true;
3021%%% Not yet seen:
3022%%% illegal_guard_expr
3023%%% utf_bittype_size_or_unit
3024%%% {undefined_bittype, _}
3025%%% unsized_binary_in_bin_gen_pattern
3026%%% illegal_pattern_end
3027%%% and probably more...
3028%%% Not so hard errors, should have been taken care of:
3029%%% ({_, erl_lint, {bittype_mismatch, _, _, _}})
3030%%% ({_, erl_lint, unsized_binary_not_at_end})
3031%%% hard_error({_, erl_lint, unsized_binary_in_bin_gen_pattern}) -> true;
3032hard_error({_, erl_lint, _}) -> true.
3033
3034some_atoms() ->
3035    ['', air, area, art, back, body, book, business, car, change,
3036     child, city, community, company, country, day, door, education,
3037     eye, face, fact, family, father, force, friend, game, girl,
3038     government, group, guy, hand, head, health, history, home, hour,
3039     house, idea, information, issue, job, kid, kind, law, level,
3040     life, line, lot, man, member, minute, moment, money, month,
3041     morning, mother, name, night, number, office, others, parent,
3042     part, party, people, person, place, point, power, president,
3043     problem, program, question, reason, research, result, right,
3044     room, school, service, side, state, story, student, study,
3045     system, teacher, team, thing, time, war, water, way, week, woman,
3046     word, work, world, year].
3047
3048some_named_functions() ->
3049    %% Do not include {'_', ...} since "fun _() -> _() end"
3050    %% results in unbound variable.
3051    [{'F1',1}, {'F2',0}, {'F3',2}, {'F3',3}].
3052
3053some_functions() ->
3054    [{f1,1}, {f1,2}, {f2,0}].
3055
3056some_records() ->
3057    %% The first one is chosen as "guard record", which means that
3058    %% all field initializations are guard expressions.
3059    [{r1,[f1,f2]}, {r2,[]}, {r3,[f1]}].
3060
3061%%% An arbitrary, small, collection of BIFs.
3062auto_imported() ->
3063    [{abs,1}, {atom_to_list,1}, {ceil,1}, {erase,1},
3064     {exit,1}, {group_leader,2}, {is_function,2},
3065     %% Old BIFs:
3066     {check_process_code,2}, {get,0}, {is_atom,1}].
3067
3068some_types() ->
3069    [{t1,0}, {t2,1}].
3070
3071predef_types() ->
3072    [{any,0}, {arity,0}, {atom,0}, {binary,0}, {bitstring,0},
3073     {boolean,0}, {byte,0}, {char,0}, {float,0}, {function,0},
3074     {identifier,0}, {integer,0}, {iodata,0}, {iolist,0}, {list,0},
3075     {list,1}, {map,0}, {maybe_improper_list,0},
3076     {maybe_improper_list,2}, {mfa,0}, {module,0}, {neg_integer,0},
3077     {nil,0}, {no_return,0}, {node,0}, {non_neg_integer,0}, {none,0},
3078     {nonempty_binary, 0}, {nonempty_bitstring, 0},
3079     {nonempty_improper_list,2}, {nonempty_list,0}, {nonempty_list,1},
3080     {nonempty_maybe_improper_list,0},
3081     {nonempty_maybe_improper_list,2}, {nonempty_string,0},
3082     {number,0}, {pid,0}, {port,0}, {pos_integer,0}, {reference,0},
3083     {string,0}, {term,0}, {timeout,0}, {tuple,0}].
3084
3085guard_bifs() ->
3086    [{abs,1}, {binary_part,2}, {binary_part,3}, {bit_size,1},
3087     {byte_size,1}, {ceil,1}, {element,2}, {float,1}, {floor,1},
3088     {hd,1}, {is_map_key,2}, {length,1}, {map_size,1}, {map_get,2},
3089     {node,0}, {node,1}, {round,1}, {self,0}, {size,1}, {tl,1},
3090     {trunc,1}, {tuple_size,1}, {is_atom,1}, {is_binary,1},
3091     {is_bitstring,1}, {is_boolean,1}, {is_float,1}, {is_function,1},
3092     {is_function,2}, {is_integer,1}, {is_list,1}, {is_map,1},
3093     {is_number,1}, {is_pid,1}, {is_port,1}, {is_reference,1},
3094     {is_tuple,1}].
3095
3096other_bifs() ->
3097    [{is_record,2}, {is_record,3}].
3098
3099expr_ops() ->
3100    %% Can be used in expressions with the "erlang:"-prefix.
3101    [{'++',2}, {'--',2}, {'!',2}] ++ guard_ops().
3102
3103guard_ops() ->
3104    %% Like guard_binop() and any_unop(), but excluding
3105    %% andalso, orelse, ++, --, and !.
3106    %% Can be used in guards with the "erlang:"-prefix.
3107    [{'+',2}, {'+',1}, {'-',2}, {'-',1}, {'*',2}, {'/',2},
3108     {'div',2}, {'rem',2}, {'band',2}, {'bnot',1}, {'bor',2}, {'bxor',2},
3109     {'bsl',2}, {'bsr',2},
3110     {'and',2}, {'or',2}, {'not',1}, {'xor',2},
3111     {'=:=',2}, {'=/=',2}, {'==',2}, {'/=',2},
3112     {'=<',2}, {'<',2}, {'>=',2}, {'>',2}].
3113
3114uniform(N) ->
3115    rand:uniform(N).
3116