1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 | ------------------------------------------------------------------------------
-- --
-- TGen --
-- --
-- Copyright (C) 2023, AdaCore --
-- --
-- TGen is free software; you can redistribute it and/or modify it under --
-- under terms of the GNU General Public License as published by the --
-- Free Software Foundation; either version 3, or (at your option) any --
-- later version. This software is distributed in the hope that it will be --
-- useful but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are --
-- granted additional permissions described in the GCC Runtime Library --
-- Exception, version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and a --
-- copy of the GCC Runtime Library Exception along with this program; see --
-- the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
------------------------------------------------------------------------------
with Ada.Containers.Hashed_Maps;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Hash_Case_Insensitive;
with Ada.Strings.Unbounded.Equal_Case_Insensitive;
with Libadalang.Analysis; use Libadalang.Analysis;
with TGen.Types.Record_Types; use TGen.Types.Record_Types;
-- This is a proof of concept for specification of strategies and by no
-- means should be considered a full-fledged implementation. It supports
-- only custom strategies for scalar types for now. The way to specify a
-- strategy right now is best shown on an example:
--
-- function My_Random return Integer;
-- procedure Foo (I : Integer)
-- with Generation => (Strategies => (I => My_Random));
--
-- In the example above, we specify a custom strategy for I configuring the
-- tool to use the My_Random function to generate values for I.
--
-- This strategy specification scheme should be extended to all of the
-- supported types, and should also support built-in tgen strategies that are
-- not the default.
package TGen.Parse_Strategy is
-- A strategy can be specified as an aspect at different spots.
--
-- * As an aspect for a type declaration in which case it will apply
-- to all of the type's references.
--
-- * As an aspect for a function declaration, for a subset of the
-- parameters type. This overrides the previous setting.
--
-- * As a parameter of the Test_Case aspect. This overrides the
-- previous settings.
--
-- A strategy can be of different kinds:
--
-- * Random kind: an arbitrary number of values can be generated from
-- the strategy.
--
-- * Enumerative kind: a specific number of values can be generated
-- from the strategy. This includes pairwise-testing strategies which
-- enumerate in a way that does not come with a combinartorial
-- explosion.
type Strategy_Kind is (Custom, Predefined);
type Parsed_Strategy (Kind : Strategy_Kind := Predefined) is record
case Kind is
when Custom =>
-- When this is a custom strategy, we are specifying a function
-- name. A TGen strategy will be generated from this function
-- name.
Generate_Name : Unbounded_String;
when Predefined =>
Predefined_Str : Unbounded_String;
end case;
end record;
Strategy_Parsing_Error : exception;
-- Exception raised when a strategy expression is malformed
package FQN_To_Parsed_Strat_Maps is new Ada.Containers.Hashed_Maps
(Key_Type => Unbounded_String,
Element_Type => Parsed_Strategy,
Hash => Ada.Strings.Unbounded.Hash_Case_Insensitive,
Equivalent_Keys => Ada.Strings.Unbounded.Equal_Case_Insensitive);
subtype FQN_To_Parsed_Strat_Map is FQN_To_Parsed_Strat_Maps.Map;
procedure Parse_Strategy
(Fct_Typ : in out Function_Typ'Class;
Aspect : Libadalang.Analysis.Aspect_Assoc;
Strategies : out FQN_To_Parsed_Strat_Maps.Map);
-- Parse a strategy aspect. For each strategy that is specified for a
-- parameter / parameter component, put an entry in the Strategies map.
--
-- Also returns a function type where every parameter / parameter component
-- type to which a specified strategies applies to has been replaced by
-- an Instance_Typ, to identify it by its fully qualified name in the
-- specific function context.
end TGen.Parse_Strategy;
|