File: gnatcoll-projects-normalize.ads

package info (click to toggle)
libgnatcoll 18-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 5,068 kB
  • sloc: ada: 40,393; python: 354; ansic: 310; makefile: 245; sh: 31
file content (326 lines) | stat: -rw-r--r-- 14,520 bytes parent folder | download
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
------------------------------------------------------------------------------
--                             G N A T C O L L                              --
--                                                                          --
--                     Copyright (C) 2002-2017, AdaCore                     --
--                                                                          --
-- This library is free software;  you can redistribute it and/or modify it --
-- 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 library is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY;  without even the implied warranty of MERCHAN- --
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE.                            --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
--                                                                          --
-- 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/>.                                          --
--                                                                          --
------------------------------------------------------------------------------

--  This internal unit provides support for editing projects.

--  Project files can be written freely by the user (through any standard
--  editor). However, although we are able to import them whatever form they
--  have, these can'be easily manipulated, and a different form needs to be
--  used, called normalized project files.
--
--  Projects are normalized only the first time they are actually modified (ie
--  if they are open in the project browser but never modified, then we don't
--  need to modify what the user did, since GPR.Proc.Process can of course work
--  with any form of projects).
--
--  However, the normalized projects are needed, so that we know exactly where
--  to add new statements depending on the current scenario.
--
--  Normalized projects have the following invariant:
--      There is only one case statement per project or package.
--  This is in fact a nested case statement, where each environment variable is
--  referenced.
--
--  They also have the following invariant:
--      A project has exactly the same behavior in its normalized form as in
--      its original form.
--  Of course, this is only true until the next modification to any of the two
--  forms.
--
--  Thus, the projects have the following format:
--
--      Project_Header
--      [Variable_Declarations]
--      [Common_Section]
--      [Nested_Case]
--      [Package_Declaration
--         [Common_Section]
--         [Nested_Case]
--      ]*
--
--  Where:
--     Project_Header is the standard header, including importing other
--     projects, declaring the name of the current project, ...
--
--     Variable_Declarations is the list of scenario variables, including their
--     types. There can be no variable declaration outside of this section,
--     including in packages.
--     ??? Not two variables can reference the same external variables.
--
--     Common_Section is the list of statements that need to be executed in all
--     scenarios (like common source directories, common switches when inside a
--     package, ...). This section can not include any case statement.
--
--     Nested_Case is one big case statement, including other nested cases. Its
--     format is similar to:
--
--           case Var1 is
--              when Value1 =>
--                 case Var2 is
--                    when Value1_1 => stmt1;
--                    when Value1_2 => stmt2;
--                 end case;
--              when Value2 =>
--                 case Var2 is
--                    when Value2_1 => stmt3;
--                    when Value2_2 => stmt4;
--                 end case;
--           end case;
--
--     The "when others" section is not allowed in the nested cases, and are
--     replaced by the appropriate list of "when" statements.

private package GNATCOLL.Projects.Normalize is

   Normalize_Error : exception;
   --  Raised when a project could not be normalized (necessary step before any
   --  modification). The project cannot be edited by GPS.
   --  Any subprogram in this package might raise this exception. In that case,
   --  the exception message is set to the text of the error.

   procedure Normalize
     (Tree    : Project_Tree_Data_Access;
      Project : Project_Type);
   --  Normalize Project.
   --  The exception Normalize_Error is raised if Project uses some features
   --  that cannot currently be normalized.
   --  If Recurse is true, then imported projects area also normalized.

   function Get_String (Id  : GPR.Name_Id) return String;
   function Get_String (Str : String)      return GPR.Name_Id;

   function Clone_Node
     (Tree       : GPR.Tree.Project_Node_Tree_Ref;
      Node       : GPR.Project_Node_Id;
      Deep_Clone : Boolean := False)
      return GPR.Project_Node_Id;
   --  Return a copy of Node. If Deep_Clone is true, then all the children of
   --  node are also copied.
   --  If Deep_Clone is false, then the two nodes will share part of their
   --  structure.
   --
   --  Note: nodes like variable or type declarations, packages,... are not
   --  chained up when they are cloned, you need to recreate the proper lists
   --  afterwards. See Post_Process_After_Clone below
   --
   --  A special case also occurs for a N_Typed_Variable_Declaration, since the
   --  type that is referenced is a pointer to the same node as the type for
   --  Node. No deep copy is done for this type. This needs to be fixed in a
   --  post-processing phase, as above.
   --
   --  The same limitation exists for N_Variable_Reference and
   --  N_Attribute_Reference and the package they are referencing

   function Is_Virtual_Extending
     (Tree : GPR.Tree.Project_Node_Tree_Ref;
      Node : GPR.Project_Node_Id) return Boolean;
   --  Return True if Node is a virtual extending project created
   --  automatically by GNAT's project manager

   function Find_Type_Declaration
     (Tree    : GPR.Tree.Project_Node_Tree_Ref;
      Project : GPR.Project_Node_Id;
      Name    : GPR.Name_Id) return GPR.Project_Node_Id;
   --  Return the declaration of the type whose name is Name

   function Create_Typed_Variable
     (Tree                         : GPR.Tree.Project_Node_Tree_Ref;
      Prj_Or_Pkg                   : GPR.Project_Node_Id;
      Name                         : String;
      Typ                          : GPR.Project_Node_Id;
      Add_Before_First_Case_Or_Pkg : Boolean := False)
      return GPR.Project_Node_Id;
   --  Create a new variable of a specific type Typ.
   --  The declaration is appended at the end of the declarative items list in
   --  the project or the package, unless Add_Before_First_Case is True. In
   --  this case, it is put just before the first N_Case_Construction node is
   --  encountered (i.e the last position in the common section of a normalized
   --  project).

   procedure Add_In_Front
     (Tree   : GPR.Tree.Project_Node_Tree_Ref;
      Parent : GPR.Project_Node_Id;
      Node   : GPR.Project_Node_Id);
   --  Add Node at the begining of the list for Parent.
   --  Node can also be a N_Declarative_Item (or a list of them).

   procedure Normalize_Cases
     (Tree    : GPR.Tree.Project_Node_Tree_Ref;
      Project : Project_Type);
   --  Make sure that all possible values of a variable appear in a case
   --  statement, to avoid warnings from the project manager.
   --  This subprogram doesn't apply recursively to imported projects

   function Add_Imported_Project
     (Tree                      : Project_Tree_Data_Access;
      Project                   : Project_Type'Class;
      Imported_Project          : Project_Type'Class;
      Errors                    : Error_Report := null;
      Use_Relative_Path         : Boolean;
      Use_Base_Name             : Boolean;
      Limited_With              : Boolean := False)
      return Import_Project_Error;
   --  Internal version of Add_Imported_Project.
   --  You must have computed the list of importing projects for Project.

   ---------------
   -- Variables --
   ---------------

   function Is_External_Variable
     (Var  : GPR.Project_Node_Id;
      Tree : GPR.Tree.Project_Node_Tree_Ref) return Boolean;
   --  Return True if Var is a reference to an external variable

   function External_Reference_Of
     (Var  : GPR.Project_Node_Id;
      Tree : GPR.Tree.Project_Node_Tree_Ref) return GPR.Name_Id;
   --  Return the name of the external reference used in the declaration of
   --  Var (Var := external ("REF")).

   procedure Set_Value_As_External
     (Tree          : GPR.Tree.Project_Node_Tree_Ref;
      Var           : GPR.Project_Node_Id;
      External_Name : String;
      Default       : String := "");
   --  Set the value of the variable as a reference to the environment variable
   --  External_Name. Var must be a single value, not a string.
   --  If Var is a typed variable, the default value is checked against the
   --  list of possible values (Invalid_Value raised if not).

   function Create_Variable_Reference
     (Tree : GPR.Tree.Project_Node_Tree_Ref;
      Var  : GPR.Project_Node_Id)
      return GPR.Project_Node_Id;
   --  Create and return a reference to the variable Var.
   --  Var must be a variable declaration

   procedure Delete_Scenario_Variable
     (Tree                     : Project_Tree_Data_Access;
      Root_Project             : Project_Type;
      External_Name            : String;
      Keep_Choice              : String;
      Delete_Direct_References : Boolean := True);
   --  Internal version of Delete_External_Variable

   function Create_Type
     (Tree       : GPR.Tree.Project_Node_Tree_Ref;
      Prj_Or_Pkg : GPR.Project_Node_Id;
      Name       : String) return GPR.Project_Node_Id;
   --  Create a new type. By default, there is no possible value, you
   --  must add some with Add_Possible_Value.
   --  The new declaration is added at the end of the declarative item list for
   --  Prj_Or_Pkg (but before any package declaration).

   procedure Add_Possible_Value
     (Tree   : GPR.Tree.Project_Node_Tree_Ref;
      Typ    : GPR.Project_Node_Id;
      Choice : String);
   --  Add a new choice in the list of possible values for the type Typ.
   --  If Choice is already available in Typ, then it is not added again.

   function Expression_As_String
     (Tree       : GPR.Tree.Project_Node_Tree_Ref;
      Expression : GPR.Project_Node_Id) return GPR.Name_Id;
   --  Return the string contained in an expression. If the expression contains
   --  more than a string literal, No_Name is returned.
   --  This also accepts cases when Expression itself is a string_literal

   function Find_Scenario_Variable
     (Tree          : GPR.Tree.Project_Node_Tree_Ref;
      Project       : Project_Type;
      External_Name : String) return GPR.Project_Node_Id;
   --  Return the declaration of the scenario variable associated with
   --  the external variable External_Name.
   --  In normalized projects, there should be only such variable.

   type Environment_Variable_Callback is access procedure
     (Project, Parent, Node, Choice : GPR.Project_Node_Id);
   --  Callback for For_Each_Environment_Variable.
   --  The various possible combinations are:
   --    Node                    Parent                 Choice
   --  N_Variable_Reference      N_Term in expression   Empty_Node
   --  N_External_Value          N_Term in expression   Empty_Node
   --  N_Case_Item               N_Declarative_Item of  matching choice
   --                            case construction      N_Literal_String
   --  N_String_Type_Declaration Empty_Node             Empty_Node
   --  N_Typed_Variable_Declaration N_Declarative_Item  Empty_Node

   procedure For_Each_Environment_Variable
     (Tree              : GPR.Tree.Project_Node_Tree_Ref;
      Root_Project      : Project_Type;
      Ext_Variable_Name : GPR.Name_Id;
      Specific_Choice   : GPR.Name_Id;
      Action            : Environment_Variable_Callback);
   --  Iterate over all possible references to an external variable. This
   --  returns N_External_Value, N_Variable_Reference,
   --  N_Typed_Variable_Declaration and N_String_Type_Declaration (the last
   --  three are indirect references through a named variable.

   -------------
   -- Editing --
   -------------

   procedure Set_Attribute
     (Tree      : Project_Tree_Data_Access;
      Project   : Project_Type;
      Attribute : Attribute_Pkg_String;
      Value     : String;
      Scenario  : Scenario_Variable_Array := All_Scenarios;
      Index     : String := "";
      At_Index  : Natural := 0);
   procedure Set_Attribute
     (Tree      : Project_Tree_Data_Access;
      Project   : Project_Type;
      Attribute : Attribute_Pkg_List;
      Values    : GNAT.Strings.String_List;
      Scenario  : Scenario_Variable_Array := All_Scenarios;
      Index     : String := "";
      Prepend   : Boolean := False);
   --  Edit the value of an attribute

   procedure Delete_Attribute
     (Tree      : Project_Tree_Data_Access;
      Project   : Project_Type;
      Attribute : String;
      Scenario  : Scenario_Variable_Array := All_Scenarios;
      Index     : String := "");
   --  Delete an attribute from the project

   procedure Rename_And_Move
     (Tree          : Project_Tree_Data_Access;
      Project       : Project_Type;
      New_Name      : String;
      New_Path      : GNATCOLL.VFS.Virtual_File;
      Errors        : Error_Report := null);
   --  Internal version of Rename_And_Move

   function Rename_Path
     (Tree               : Project_Tree_Data_Access;
      Project            : Project_Type;
      Old_Path           : GNATCOLL.VFS.Virtual_File;
      New_Path           : GNATCOLL.VFS.Virtual_File;
      Use_Relative_Paths : Boolean) return Boolean;
   --  Internal version of Rename_Path

end GNATCOLL.Projects.Normalize;