Commit 1a5d715a by Vincent Celier Committed by Arnaud Charlet

prj-dect.adb (Parse_Package_Declaration): When a package name is not known...

2008-03-26  Vincent Celier  <celier@adacore.com>

	* prj-dect.adb (Parse_Package_Declaration): When a package name is not
	known, check if it may be a missspelling of a known package name. In
	not verbose, not mode, issue warnings only if the package name is a
	possible misspelling.
	In verbose mode, always issue a warning for a not known package name,
	plus a warning if the name is a misspelling of a known package name.

	* prj-part.adb (Post_Parse_Context_Clause): Modify so that only non
	limited withs or limited withs are parse during one call.
	(Parse_Single_Project): Post parse context clause in two passes: non
	limited withs before current project and limited withs after current
	project.

	* prj-proc.adb (Imported_Or_Extended_Project_From): Returns an extended
	project with the name With_Name, even if it is only extended indirectly.
	(Recursive_Process): Process projects in order: first single withs, then
	current project, then limited withs.

	* prj-tree.adb (Imported_Or_Extended_Project_Of): Returns an extended
	project with the name With_Name, even if it is only extended indirectly.

From-SVN: r133573
parent 2b2b6798
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
with Err_Vars; use Err_Vars; with Err_Vars; use Err_Vars;
with GNAT.Case_Util; use GNAT.Case_Util; with GNAT.Case_Util; use GNAT.Case_Util;
with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
with Opt; use Opt; with Opt; use Opt;
with Prj.Attr; use Prj.Attr; with Prj.Attr; use Prj.Attr;
...@@ -36,8 +37,12 @@ with Prj.Tree; use Prj.Tree; ...@@ -36,8 +37,12 @@ with Prj.Tree; use Prj.Tree;
with Snames; with Snames;
with Uintp; use Uintp; with Uintp; use Uintp;
with System.Strings;
package body Prj.Dect is package body Prj.Dect is
use System;
type Zone is (In_Project, In_Package, In_Case_Construction); type Zone is (In_Project, In_Package, In_Case_Construction);
-- Used to indicate if we are parsing a package (In_Package), -- Used to indicate if we are parsing a package (In_Package),
-- a case construction (In_Case_Construction) or none of those two -- a case construction (In_Case_Construction) or none of those two
...@@ -983,11 +988,44 @@ package body Prj.Dect is ...@@ -983,11 +988,44 @@ package body Prj.Dect is
if Current_Package = Empty_Package then if Current_Package = Empty_Package then
if not Quiet_Output then if not Quiet_Output then
Error_Msg ("?""" & declare
Get_Name_String List : constant Strings.String_List := Package_Name_List;
(Name_Of (Package_Declaration, In_Tree)) & Index : Natural;
""" is not a known package name", Name : constant String := Get_Name_String (Token_Name);
Token_Ptr);
begin
-- Check for possible misspelling of a known package name
Index := 0;
loop
if Index >= List'Last then
Index := 0;
exit;
end if;
Index := Index + 1;
exit when
GNAT.Spelling_Checker.Is_Bad_Spelling_Of
(Name, List (Index).all);
end loop;
-- Issue warning(s) in verbose mode or when a possible
-- misspelling has been found.
if Verbose_Mode or else Index /= 0 then
Error_Msg ("?""" &
Get_Name_String
(Name_Of (Package_Declaration, In_Tree)) &
""" is not a known package name",
Token_Ptr);
end if;
if Index /= 0 then
Error_Msg ("\?possible misspelling of """ &
List (Index).all & """",
Token_Ptr);
end if;
end;
end if; end if;
-- Set the package declaration to "ignored" so that it is not -- Set the package declaration to "ignored" so that it is not
......
...@@ -72,13 +72,16 @@ package body Prj.Part is ...@@ -72,13 +72,16 @@ package body Prj.Part is
Table_Increment => 100, Table_Increment => 100,
Table_Name => "Prj.Part.Withs"); Table_Name => "Prj.Part.Withs");
-- Table used to store temporarily paths and locations of imported -- Table used to store temporarily paths and locations of imported
-- projects. These imported projects will be effectively parsed after the -- projects. These imported projects will be effectively parsed later: just
-- name of the current project has been extablished. -- before parsing the current project for the non limited withed projects,
-- after getting its name; after complete parsing of the current project
-- for the limited withed projects.
type Names_And_Id is record type Names_And_Id is record
Path_Name : Path_Name_Type; Path_Name : Path_Name_Type;
Canonical_Path_Name : Path_Name_Type; Canonical_Path_Name : Path_Name_Type;
Id : Project_Node_Id; Id : Project_Node_Id;
Limited_With : Boolean;
end record; end record;
package Project_Stack is new Table.Table package Project_Stack is new Table.Table
...@@ -147,25 +150,28 @@ package body Prj.Part is ...@@ -147,25 +150,28 @@ package body Prj.Part is
procedure Pre_Parse_Context_Clause procedure Pre_Parse_Context_Clause
(In_Tree : Project_Node_Tree_Ref; (In_Tree : Project_Node_Tree_Ref;
Context_Clause : out With_Id); Context_Clause : out With_Id);
-- Parse the context clause of a project. -- Parse the context clause of a project. Store the paths and locations of
-- Store the paths and locations of the imported projects in table Withs. -- the imported projects in table Withs. Does nothing if there is no
-- Does nothing if there is no context clause (if the current -- context clause (if the current token is not "with" or "limited" followed
-- token is not "with" or "limited" followed by "with"). -- by "with").
procedure Post_Parse_Context_Clause procedure Post_Parse_Context_Clause
(Context_Clause : With_Id; (Context_Clause : With_Id;
In_Tree : Project_Node_Tree_Ref; In_Tree : Project_Node_Tree_Ref;
Imported_Projects : out Project_Node_Id; Limited_Withs : Boolean;
Imported_Projects : in out Project_Node_Id;
Project_Directory : Path_Name_Type; Project_Directory : Path_Name_Type;
From_Extended : Extension_Origin; From_Extended : Extension_Origin;
In_Limited : Boolean; In_Limited : Boolean;
Packages_To_Check : String_List_Access; Packages_To_Check : String_List_Access;
Depth : Natural; Depth : Natural;
Current_Dir : String); Current_Dir : String);
-- Parse the imported projects that have been stored in table Withs, -- Parse the imported projects that have been stored in table Withs, if
-- if any. From_Extended is used for the call to Parse_Single_Project -- any. From_Extended is used for the call to Parse_Single_Project below.
-- below. When In_Limited is True, the importing path includes at least -- When In_Limited is True, the importing path includes at least one
-- one "limited with". -- "limited with". When Limited_Withs is False, only non limited withed
-- projects are parsed. When Limited_Withs is True, only limited withed
-- projects are parsed.
function Project_Path_Name_Of function Project_Path_Name_Of
(Project_File_Name : String; (Project_File_Name : String;
...@@ -645,7 +651,7 @@ package body Prj.Part is ...@@ -645,7 +651,7 @@ package body Prj.Part is
Comma_Loop : Comma_Loop :
loop loop
Scan (In_Tree); -- scan past WITH or "," Scan (In_Tree); -- past WITH or ","
Expect (Tok_String_Literal, "literal string"); Expect (Tok_String_Literal, "literal string");
...@@ -682,7 +688,7 @@ package body Prj.Part is ...@@ -682,7 +688,7 @@ package body Prj.Part is
-- End of (possibly multiple) with clause; -- End of (possibly multiple) with clause;
Scan (In_Tree); -- scan past the semicolon. Scan (In_Tree); -- past the semicolon
exit Comma_Loop; exit Comma_Loop;
elsif Token = Tok_Comma then elsif Token = Tok_Comma then
...@@ -707,7 +713,8 @@ package body Prj.Part is ...@@ -707,7 +713,8 @@ package body Prj.Part is
procedure Post_Parse_Context_Clause procedure Post_Parse_Context_Clause
(Context_Clause : With_Id; (Context_Clause : With_Id;
In_Tree : Project_Node_Tree_Ref; In_Tree : Project_Node_Tree_Ref;
Imported_Projects : out Project_Node_Id; Limited_Withs : Boolean;
Imported_Projects : in out Project_Node_Id;
Project_Directory : Path_Name_Type; Project_Directory : Path_Name_Type;
From_Extended : Extension_Origin; From_Extended : Extension_Origin;
In_Limited : Boolean; In_Limited : Boolean;
...@@ -717,7 +724,7 @@ package body Prj.Part is ...@@ -717,7 +724,7 @@ package body Prj.Part is
is is
Current_With_Clause : With_Id := Context_Clause; Current_With_Clause : With_Id := Context_Clause;
Current_Project : Project_Node_Id := Empty_Node; Current_Project : Project_Node_Id := Imported_Projects;
Previous_Project : Project_Node_Id := Empty_Node; Previous_Project : Project_Node_Id := Empty_Node;
Next_Project : Project_Node_Id := Empty_Node; Next_Project : Project_Node_Id := Empty_Node;
...@@ -725,163 +732,177 @@ package body Prj.Part is ...@@ -725,163 +732,177 @@ package body Prj.Part is
Get_Name_String (Project_Directory); Get_Name_String (Project_Directory);
Current_With : With_Record; Current_With : With_Record;
Limited_With : Boolean := False;
Extends_All : Boolean := False; Extends_All : Boolean := False;
begin begin
Imported_Projects := Empty_Node; -- Set Current_Project to the last project in the current list, if the
-- list is not empty.
if Current_Project /= Empty_Node then
while
Next_With_Clause_Of (Current_Project, In_Tree) /= Empty_Node
loop
Current_Project := Next_With_Clause_Of (Current_Project, In_Tree);
end loop;
end if;
while Current_With_Clause /= No_With loop while Current_With_Clause /= No_With loop
Current_With := Withs.Table (Current_With_Clause); Current_With := Withs.Table (Current_With_Clause);
Current_With_Clause := Current_With.Next; Current_With_Clause := Current_With.Next;
Limited_With := In_Limited or Current_With.Limited_With; if Limited_Withs = Current_With.Limited_With then
declare
declare Original_Path : constant String :=
Original_Path : constant String := Get_Name_String (Current_With.Path);
Get_Name_String (Current_With.Path);
Imported_Path_Name : constant String :=
Project_Path_Name_Of
(Original_Path, Project_Directory_Path);
Resolved_Path : constant String :=
Normalize_Pathname
(Imported_Path_Name,
Directory => Current_Dir,
Resolve_Links => Opt.Follow_Links_For_Files,
Case_Sensitive => True);
Withed_Project : Project_Node_Id := Empty_Node;
begin Imported_Path_Name : constant String :=
if Imported_Path_Name = "" then Project_Path_Name_Of
(Original_Path,
Project_Directory_Path);
-- The project file cannot be found Resolved_Path : constant String :=
Normalize_Pathname
(Imported_Path_Name,
Directory => Current_Dir,
Resolve_Links =>
Opt.Follow_Links_For_Files,
Case_Sensitive => True);
Error_Msg_File_1 := File_Name_Type (Current_With.Path); Withed_Project : Project_Node_Id := Empty_Node;
Error_Msg ("unknown project file: {", Current_With.Location); begin
if Imported_Path_Name = "" then
-- If this is not imported by the main project file, -- The project file cannot be found
-- display the import path.
if Project_Stack.Last > 1 then Error_Msg_File_1 := File_Name_Type (Current_With.Path);
for Index in reverse 1 .. Project_Stack.Last loop Error_Msg
Error_Msg_File_1 := ("unknown project file: {", Current_With.Location);
File_Name_Type (Project_Stack.Table (Index).Path_Name);
Error_Msg ("\imported by {", Current_With.Location);
end loop;
end if;
else -- If this is not imported by the main project file, display
-- New with clause -- the import path.
Previous_Project := Current_Project; if Project_Stack.Last > 1 then
for Index in reverse 1 .. Project_Stack.Last loop
Error_Msg_File_1 :=
File_Name_Type
(Project_Stack.Table (Index).Path_Name);
Error_Msg
("\imported by {", Current_With.Location);
end loop;
end if;
if Current_Project = Empty_Node then else
-- New with clause
-- First with clause of the context clause Previous_Project := Current_Project;
Current_Project := Current_With.Node; if Current_Project = Empty_Node then
Imported_Projects := Current_Project;
else -- First with clause of the context clause
Next_Project := Current_With.Node;
Set_Next_With_Clause_Of
(Current_Project, In_Tree, Next_Project);
Current_Project := Next_Project;
end if;
Set_String_Value_Of Current_Project := Current_With.Node;
(Current_Project, In_Tree, Name_Id (Current_With.Path)); Imported_Projects := Current_Project;
Set_Location_Of
(Current_Project, In_Tree, Current_With.Location);
-- If this is a "limited with", check if we have a circularity. else
-- If we have one, get the project id of the limited imported Next_Project := Current_With.Node;
-- project file, and do not parse it. Set_Next_With_Clause_Of
(Current_Project, In_Tree, Next_Project);
Current_Project := Next_Project;
end if;
if Limited_With and then Project_Stack.Last > 1 then Set_String_Value_Of
declare (Current_Project,
Canonical_Path_Name : Path_Name_Type; In_Tree,
Name_Id (Current_With.Path));
Set_Location_Of
(Current_Project, In_Tree, Current_With.Location);
-- If it is a limited with, check if we have a circularity.
-- If we have one, get the project id of the limited
-- imported project file, and do not parse it.
if Limited_Withs and then Project_Stack.Last > 1 then
declare
Canonical_Path_Name : Path_Name_Type;
begin
Name_Len := Resolved_Path'Length;
Name_Buffer (1 .. Name_Len) := Resolved_Path;
Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
Canonical_Path_Name := Name_Find;
for Index in 1 .. Project_Stack.Last loop
if Project_Stack.Table (Index).Canonical_Path_Name =
Canonical_Path_Name
then
-- We have found the limited imported project,
-- get its project id, and do not parse it.
begin Withed_Project := Project_Stack.Table (Index).Id;
Name_Len := Resolved_Path'Length; exit;
Name_Buffer (1 .. Name_Len) := Resolved_Path; end if;
Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); end loop;
Canonical_Path_Name := Name_Find; end;
end if;
for Index in 1 .. Project_Stack.Last loop -- Parse the imported project, if its project id is unknown
if Project_Stack.Table (Index).Canonical_Path_Name =
Canonical_Path_Name
then
-- We have found the limited imported project,
-- get its project id, and do not parse it.
Withed_Project := Project_Stack.Table (Index).Id; if Withed_Project = Empty_Node then
exit; Parse_Single_Project
end if; (In_Tree => In_Tree,
end loop; Project => Withed_Project,
end; Extends_All => Extends_All,
end if; Path_Name => Imported_Path_Name,
Extended => False,
From_Extended => From_Extended,
In_Limited => Limited_Withs,
Packages_To_Check => Packages_To_Check,
Depth => Depth,
Current_Dir => Current_Dir);
-- Parse the imported project, if its project id is unknown else
Extends_All := Is_Extending_All (Withed_Project, In_Tree);
if Withed_Project = Empty_Node then end if;
Parse_Single_Project
(In_Tree => In_Tree,
Project => Withed_Project,
Extends_All => Extends_All,
Path_Name => Imported_Path_Name,
Extended => False,
From_Extended => From_Extended,
In_Limited => Limited_With,
Packages_To_Check => Packages_To_Check,
Depth => Depth,
Current_Dir => Current_Dir);
else if Withed_Project = Empty_Node then
Extends_All := Is_Extending_All (Withed_Project, In_Tree);
end if;
if Withed_Project = Empty_Node then -- If parsing unsuccessful, remove the context clause
-- If parsing was not successful, remove the
-- context clause.
Current_Project := Previous_Project; Current_Project := Previous_Project;
if Current_Project = Empty_Node then if Current_Project = Empty_Node then
Imported_Projects := Empty_Node; Imported_Projects := Empty_Node;
else
Set_Next_With_Clause_Of
(Current_Project, In_Tree, Empty_Node);
end if;
else else
Set_Next_With_Clause_Of -- If parsing was successful, record project name and
(Current_Project, In_Tree, Empty_Node); -- path name in with clause
end if;
else Set_Project_Node_Of
-- If parsing was successful, record project name (Node => Current_Project,
-- and path name in with clause In_Tree => In_Tree,
To => Withed_Project,
Set_Project_Node_Of Limited_With => Current_With.Limited_With);
(Node => Current_Project, Set_Name_Of
In_Tree => In_Tree, (Current_Project,
To => Withed_Project, In_Tree,
Limited_With => Current_With.Limited_With); Name_Of (Withed_Project, In_Tree));
Set_Name_Of
(Current_Project,
In_Tree,
Name_Of (Withed_Project, In_Tree));
Name_Len := Resolved_Path'Length; Name_Len := Resolved_Path'Length;
Name_Buffer (1 .. Name_Len) := Resolved_Path; Name_Buffer (1 .. Name_Len) := Resolved_Path;
Set_Path_Name_Of (Current_Project, In_Tree, Name_Find); Set_Path_Name_Of (Current_Project, In_Tree, Name_Find);
if Extends_All then if Extends_All then
Set_Is_Extending_All (Current_Project, In_Tree); Set_Is_Extending_All (Current_Project, In_Tree);
end if;
end if; end if;
end if; end if;
end if; end;
end; end if;
end loop; end loop;
end Post_Parse_Context_Clause; end Post_Parse_Context_Clause;
...@@ -909,17 +930,16 @@ package body Prj.Part is ...@@ -909,17 +930,16 @@ package body Prj.Part is
Extending : Boolean := False; Extending : Boolean := False;
Extended_Project : Project_Node_Id := Empty_Node; Extended_Project : Project_Node_Id := Empty_Node;
A_Project_Name_And_Node : Tree_Private_Part.Project_Name_And_Node := A_Project_Name_And_Node : Tree_Private_Part.Project_Name_And_Node :=
Tree_Private_Part.Projects_Htable.Get_First Tree_Private_Part.Projects_Htable.Get_First
(In_Tree.Projects_HT); (In_Tree.Projects_HT);
Name_From_Path : constant Name_Id := Project_Name_From (Path_Name); Name_From_Path : constant Name_Id := Project_Name_From (Path_Name);
Name_Of_Project : Name_Id := No_Name;
Name_Of_Project : Name_Id := No_Name; First_With : With_Id;
Imported_Projects : Project_Node_Id := Empty_Node;
First_With : With_Id;
use Tree_Private_Part; use Tree_Private_Part;
...@@ -939,7 +959,6 @@ package body Prj.Part is ...@@ -939,7 +959,6 @@ package body Prj.Part is
Directory => Current_Dir, Directory => Current_Dir,
Resolve_Links => Opt.Follow_Links_For_Files, Resolve_Links => Opt.Follow_Links_For_Files,
Case_Sensitive => False); Case_Sensitive => False);
begin begin
Name_Len := Normed_Path'Length; Name_Len := Normed_Path'Length;
Name_Buffer (1 .. Name_Len) := Normed_Path; Name_Buffer (1 .. Name_Len) := Normed_Path;
...@@ -951,7 +970,9 @@ package body Prj.Part is ...@@ -951,7 +970,9 @@ package body Prj.Part is
-- Check for a circular dependency -- Check for a circular dependency
for Index in 1 .. Project_Stack.Last loop for Index in reverse 1 .. Project_Stack.Last loop
exit when Project_Stack.Table (Index).Limited_With;
if Canonical_Path_Name = if Canonical_Path_Name =
Project_Stack.Table (Index).Canonical_Path_Name Project_Stack.Table (Index).Canonical_Path_Name
then then
...@@ -982,10 +1003,11 @@ package body Prj.Part is ...@@ -982,10 +1003,11 @@ package body Prj.Part is
-- Put the new path name on the stack -- Put the new path name on the stack
Project_Stack.Increment_Last; Project_Stack.Append
Project_Stack.Table (Project_Stack.Last).Path_Name := Normed_Path_Name; ((Path_Name => Normed_Path_Name,
Project_Stack.Table (Project_Stack.Last).Canonical_Path_Name := Canonical_Path_Name => Canonical_Path_Name,
Canonical_Path_Name; Id => Empty_Node,
Limited_With => In_Limited));
-- Check if the project file has already been parsed -- Check if the project file has already been parsed
...@@ -1009,9 +1031,9 @@ package body Prj.Part is ...@@ -1009,9 +1031,9 @@ package body Prj.Part is
Extends_All := Extends_All :=
Is_Extending_All (A_Project_Name_And_Node.Node, In_Tree); Is_Extending_All (A_Project_Name_And_Node.Node, In_Tree);
-- If the imported project is an extended project A, -- If the imported project is an extended project A, and we are
-- and we are in an extended project, replace A with the -- in an extended project, replace A with the ultimate project
-- ultimate project extending A. -- extending A.
if From_Extended /= None then if From_Extended /= None then
declare declare
...@@ -1048,8 +1070,8 @@ package body Prj.Part is ...@@ -1048,8 +1070,8 @@ package body Prj.Part is
Tree_Private_Part.Projects_Htable.Get_Next (In_Tree.Projects_HT); Tree_Private_Part.Projects_Htable.Get_Next (In_Tree.Projects_HT);
end loop; end loop;
-- We never encountered this project file -- We never encountered this project file. Save the scan state, load the
-- Save the scan state, load the project file and start to scan it. -- project file and start to scan it.
Save_Project_Scan_State (Project_Scan_State); Save_Project_Scan_State (Project_Scan_State);
Source_Index := Load_Project_File (Path_Name); Source_Index := Load_Project_File (Path_Name);
...@@ -1069,8 +1091,8 @@ package body Prj.Part is ...@@ -1069,8 +1091,8 @@ package body Prj.Part is
if (not In_Configuration) and then (Name_From_Path = No_Name) then if (not In_Configuration) and then (Name_From_Path = No_Name) then
-- The project file name is not correct (no or bad extension, -- The project file name is not correct (no or bad extension, or not
-- or not following Ada identifier's syntax). -- following Ada identifier's syntax).
Error_Msg_File_1 := File_Name_Type (Canonical_Path_Name); Error_Msg_File_1 := File_Name_Type (Canonical_Path_Name);
Error_Msg ("?{ is not a valid path name for a project file", Error_Msg ("?{ is not a valid path name for a project file",
...@@ -1084,24 +1106,27 @@ package body Prj.Part is ...@@ -1084,24 +1106,27 @@ package body Prj.Part is
Write_Eol; Write_Eol;
end if; end if;
Project_Directory := Immediate_Directory_Of (Normed_Path_Name);
-- Is there any imported project? -- Is there any imported project?
Pre_Parse_Context_Clause (In_Tree, First_With); Pre_Parse_Context_Clause
(In_Tree => In_Tree,
Context_Clause => First_With);
Project_Directory := Immediate_Directory_Of (Normed_Path_Name);
Project := Default_Project_Node Project := Default_Project_Node
(Of_Kind => N_Project, In_Tree => In_Tree); (Of_Kind => N_Project, In_Tree => In_Tree);
Project_Stack.Table (Project_Stack.Last).Id := Project; Project_Stack.Table (Project_Stack.Last).Id := Project;
Set_Directory_Of (Project, In_Tree, Project_Directory); Set_Directory_Of (Project, In_Tree, Project_Directory);
Set_Path_Name_Of (Project, In_Tree, Normed_Path_Name); Set_Path_Name_Of (Project, In_Tree, Normed_Path_Name);
Set_Location_Of (Project, In_Tree, Token_Ptr); Set_Location_Of (Project, In_Tree, Token_Ptr);
Set_First_With_Clause_Of (Project, In_Tree, Imported_Projects);
Expect (Tok_Project, "PROJECT"); Expect (Tok_Project, "PROJECT");
-- Mark location of PROJECT token if present -- Mark location of PROJECT token if present
if Token = Tok_Project then if Token = Tok_Project then
Scan (In_Tree); -- scan past PROJECT Scan (In_Tree); -- past PROJECT
Set_Location_Of (Project, In_Tree, Token_Ptr); Set_Location_Of (Project, In_Tree, Token_Ptr);
end if; end if;
...@@ -1156,7 +1181,7 @@ package body Prj.Part is ...@@ -1156,7 +1181,7 @@ package body Prj.Part is
Extending := True; Extending := True;
Scan (In_Tree); -- scan past EXTENDS Scan (In_Tree); -- past EXTENDS
if Token = Tok_All then if Token = Tok_All then
Extends_All := True; Extends_All := True;
...@@ -1216,7 +1241,6 @@ package body Prj.Part is ...@@ -1216,7 +1241,6 @@ package body Prj.Part is
end; end;
declare declare
Imported_Projects : Project_Node_Id := Empty_Node;
From_Ext : Extension_Origin := None; From_Ext : Extension_Origin := None;
begin begin
...@@ -1235,6 +1259,7 @@ package body Prj.Part is ...@@ -1235,6 +1259,7 @@ package body Prj.Part is
Post_Parse_Context_Clause Post_Parse_Context_Clause
(In_Tree => In_Tree, (In_Tree => In_Tree,
Context_Clause => First_With, Context_Clause => First_With,
Limited_Withs => False,
Imported_Projects => Imported_Projects, Imported_Projects => Imported_Projects,
Project_Directory => Project_Directory, Project_Directory => Project_Directory,
From_Extended => From_Ext, From_Extended => From_Ext,
...@@ -1372,7 +1397,7 @@ package body Prj.Part is ...@@ -1372,7 +1397,7 @@ package body Prj.Part is
end if; end if;
end; end;
Scan (In_Tree); -- scan past the extended project path Scan (In_Tree); -- past the extended project path
end if; end if;
end if; end if;
...@@ -1553,6 +1578,36 @@ package body Prj.Part is ...@@ -1553,6 +1578,36 @@ package body Prj.Part is
end if; end if;
end if; end if;
declare
From_Ext : Extension_Origin := None;
begin
-- Extending_All is always propagated
if From_Extended = Extending_All or else Extends_All then
From_Ext := Extending_All;
-- Otherwise, From_Extended is set to Extending_Single if the
-- current project is an extending project.
elsif Extended then
From_Ext := Extending_Simple;
end if;
Post_Parse_Context_Clause
(In_Tree => In_Tree,
Context_Clause => First_With,
Limited_Withs => True,
Imported_Projects => Imported_Projects,
Project_Directory => Project_Directory,
From_Extended => From_Ext,
In_Limited => In_Limited,
Packages_To_Check => Packages_To_Check,
Depth => Depth + 1,
Current_Dir => Current_Dir);
Set_First_With_Clause_Of (Project, In_Tree, Imported_Projects);
end;
-- Restore the scan state, in case we are not the main project -- Restore the scan state, in case we are not the main project
Restore_Project_Scan_State (Project_Scan_State); Restore_Project_Scan_State (Project_Scan_State);
......
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- -- -- --
-- GNAT COMPILER COMPONENTS -- -- GNAT COMPILER COMPONENTS --
-- -- -- --
...@@ -7,7 +6,7 @@ ...@@ -7,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2001-2007, Free Software Foundation, Inc. -- -- Copyright (C) 2001-2008, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -1104,64 +1103,59 @@ package body Prj.Proc is ...@@ -1104,64 +1103,59 @@ package body Prj.Proc is
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
With_Name : Name_Id) return Project_Id With_Name : Name_Id) return Project_Id
is is
Data : constant Project_Data := Data : constant Project_Data := In_Tree.Projects.Table (Project);
In_Tree.Projects.Table (Project); List : Project_List;
List : Project_List := Data.Imported_Projects; Result : Project_Id;
Result : Project_Id := No_Project; Temp_Result : Project_Id;
Temp_Result : Project_Id := No_Project;
begin begin
-- First check if it is the name of an extended project -- First check if it is the name of an extended project
if Data.Extends /= No_Project Result := Data.Extends;
and then In_Tree.Projects.Table (Data.Extends).Name = while Result /= No_Project loop
With_Name if In_Tree.Projects.Table (Result).Name = With_Name then
then return Result;
return Data.Extends; else
Result := In_Tree.Projects.Table (Result).Extends;
end if;
end loop;
else -- Then check the name of each imported project
-- Then check the name of each imported project
while List /= Empty_Project_List loop Temp_Result := No_Project;
Result := In_Tree.Project_Lists.Table (List).Project; List := Data.Imported_Projects;
while List /= Empty_Project_List loop
Result := In_Tree.Project_Lists.Table (List).Project;
-- If the project is directly imported, then returns its ID -- If the project is directly imported, then returns its ID
if if In_Tree.Projects.Table (Result).Name = With_Name then
In_Tree.Projects.Table (Result).Name = With_Name return Result;
then end if;
return Result;
end if;
-- If a project extending the project is imported, then keep -- If a project extending the project is imported, then keep this
-- this extending project as a possibility. It will be the -- extending project as a possibility. It will be the returned ID
-- returned ID if the project is not imported directly. -- if the project is not imported directly.
declare declare
Proj : Project_Id := Proj : Project_Id := In_Tree.Projects.Table (Result).Extends;
In_Tree.Projects.Table (Result).Extends;
begin
while Proj /= No_Project loop
if In_Tree.Projects.Table (Proj).Name =
With_Name
then
Temp_Result := Result;
exit;
end if;
Proj := In_Tree.Projects.Table (Proj).Extends; begin
end loop; while Proj /= No_Project loop
end; if In_Tree.Projects.Table (Proj).Name = With_Name then
Temp_Result := Result;
exit;
end if;
List := In_Tree.Project_Lists.Table (List).Next; Proj := In_Tree.Projects.Table (Proj).Extends;
end loop; end loop;
end;
pragma Assert List := In_Tree.Project_Lists.Table (List).Next;
(Temp_Result /= No_Project, end loop;
"project not found");
return Temp_Result; pragma Assert (Temp_Result /= No_Project, "project not found");
end if; return Temp_Result;
end Imported_Or_Extended_Project_From; end Imported_Or_Extended_Project_From;
------------------ ------------------
...@@ -2530,6 +2524,7 @@ package body Prj.Proc is ...@@ -2530,6 +2524,7 @@ package body Prj.Proc is
Processed_Projects.Set (Name, Project); Processed_Projects.Set (Name, Project);
Processed_Data.Name := Name; Processed_Data.Name := Name;
In_Tree.Projects.Table (Project).Name := Name;
Get_Name_String (Name); Get_Name_String (Name);
...@@ -2588,61 +2583,74 @@ package body Prj.Proc is ...@@ -2588,61 +2583,74 @@ package body Prj.Proc is
Prj.Attr.Attribute_First, Prj.Attr.Attribute_First,
Project_Level => True); Project_Level => True);
-- Process non limited withed projects
With_Clause := With_Clause :=
First_With_Clause_Of (From_Project_Node, From_Project_Node_Tree); First_With_Clause_Of (From_Project_Node, From_Project_Node_Tree);
while With_Clause /= Empty_Node loop while With_Clause /= Empty_Node loop
declare declare
New_Project : Project_Id; New_Project : Project_Id;
New_Data : Project_Data; New_Data : Project_Data;
Proj_Node : Project_Node_Id;
begin begin
Recursive_Process Proj_Node :=
(In_Tree => In_Tree, Non_Limited_Project_Node_Of
Project => New_Project, (With_Clause, From_Project_Node_Tree);
From_Project_Node =>
Project_Node_Of (With_Clause, From_Project_Node_Tree), if Proj_Node /= Empty_Node then
From_Project_Node_Tree => From_Project_Node_Tree, Recursive_Process
Extended_By => No_Project); (In_Tree => In_Tree,
New_Data := Project => New_Project,
In_Tree.Projects.Table (New_Project); From_Project_Node =>
Project_Node_Of
-- If we were the first project to import it, (With_Clause, From_Project_Node_Tree),
-- set First_Referred_By to us. From_Project_Node_Tree => From_Project_Node_Tree,
Extended_By => No_Project);
if New_Data.First_Referred_By = No_Project then
New_Data.First_Referred_By := Project;
In_Tree.Projects.Table (New_Project) :=
New_Data;
end if;
-- Add this project to our list of imported projects New_Data :=
In_Tree.Projects.Table (New_Project);
Project_List_Table.Increment_Last -- If we were the first project to import it,
(In_Tree.Project_Lists); -- set First_Referred_By to us.
In_Tree.Project_Lists.Table
(Project_List_Table.Last
(In_Tree.Project_Lists)) :=
(Project => New_Project, Next => Empty_Project_List);
-- Imported is the id of the last imported project. if New_Data.First_Referred_By = No_Project then
-- If it is nil, then this imported project is our first. New_Data.First_Referred_By := Project;
In_Tree.Projects.Table (New_Project) :=
New_Data;
end if;
if Imported = Empty_Project_List then -- Add this project to our list of imported projects
Processed_Data.Imported_Projects :=
Project_List_Table.Last Project_List_Table.Increment_Last
(In_Tree.Project_Lists); (In_Tree.Project_Lists);
else
In_Tree.Project_Lists.Table In_Tree.Project_Lists.Table
(Imported).Next := Project_List_Table.Last (Project_List_Table.Last
(In_Tree.Project_Lists)) :=
(Project => New_Project, Next => Empty_Project_List);
-- Imported is the id of the last imported project. If it
-- is nil, then this imported project is our first.
if Imported = Empty_Project_List then
Processed_Data.Imported_Projects :=
Project_List_Table.Last
(In_Tree.Project_Lists);
else
In_Tree.Project_Lists.Table
(Imported).Next := Project_List_Table.Last
(In_Tree.Project_Lists); (In_Tree.Project_Lists);
end if; end if;
Imported := Project_List_Table.Last Imported := Project_List_Table.Last
(In_Tree.Project_Lists); (In_Tree.Project_Lists);
end if;
With_Clause := With_Clause :=
Next_With_Clause_Of (With_Clause, From_Project_Node_Tree); Next_With_Clause_Of
(With_Clause, From_Project_Node_Tree);
end; end;
end loop; end loop;
...@@ -2676,9 +2684,9 @@ package body Prj.Proc is ...@@ -2676,9 +2684,9 @@ package body Prj.Proc is
-- or renamed. Also inherit the languages, if attribute Languages -- or renamed. Also inherit the languages, if attribute Languages
-- is not explicitely defined. -- is not explicitely defined.
if Processed_Data.Extends /= No_Project then Processed_Data := In_Tree.Projects.Table (Project);
Processed_Data := In_Tree.Projects.Table (Project);
if Processed_Data.Extends /= No_Project then
declare declare
Extended_Pkg : Package_Id; Extended_Pkg : Package_Id;
Current_Pkg : Package_Id; Current_Pkg : Package_Id;
...@@ -2778,9 +2786,78 @@ package body Prj.Proc is ...@@ -2778,9 +2786,78 @@ package body Prj.Proc is
end if; end if;
end if; end if;
end; end;
In_Tree.Projects.Table (Project) := Processed_Data;
end if; end if;
-- Process limited withed projects
With_Clause :=
First_With_Clause_Of
(From_Project_Node, From_Project_Node_Tree);
while With_Clause /= Empty_Node loop
declare
New_Project : Project_Id;
New_Data : Project_Data;
Proj_Node : Project_Node_Id;
begin
Proj_Node :=
Non_Limited_Project_Node_Of
(With_Clause, From_Project_Node_Tree);
if Proj_Node = Empty_Node then
Recursive_Process
(In_Tree => In_Tree,
Project => New_Project,
From_Project_Node =>
Project_Node_Of
(With_Clause, From_Project_Node_Tree),
From_Project_Node_Tree => From_Project_Node_Tree,
Extended_By => No_Project);
New_Data :=
In_Tree.Projects.Table (New_Project);
-- If we were the first project to import it, set
-- First_Referred_By to us.
if New_Data.First_Referred_By = No_Project then
New_Data.First_Referred_By := Project;
In_Tree.Projects.Table (New_Project) :=
New_Data;
end if;
-- Add this project to our list of imported projects
Project_List_Table.Increment_Last
(In_Tree.Project_Lists);
In_Tree.Project_Lists.Table
(Project_List_Table.Last
(In_Tree.Project_Lists)) :=
(Project => New_Project, Next => Empty_Project_List);
-- Imported is the id of the last imported project. If
-- it is nil, then this imported project is our first.
if Imported = Empty_Project_List then
In_Tree.Projects.Table (Project).Imported_Projects :=
Project_List_Table.Last
(In_Tree.Project_Lists);
else
In_Tree.Project_Lists.Table
(Imported).Next := Project_List_Table.Last
(In_Tree.Project_Lists);
end if;
Imported := Project_List_Table.Last
(In_Tree.Project_Lists);
end if;
With_Clause :=
Next_With_Clause_Of
(With_Clause, From_Project_Node_Tree);
end;
end loop;
end; end;
end if; end if;
end Recursive_Process; end Recursive_Process;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2001-2007, Free Software Foundation, Inc. -- -- Copyright (C) 2001-2008, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -1047,18 +1047,18 @@ package body Prj.Tree is ...@@ -1047,18 +1047,18 @@ package body Prj.Tree is
With_Clause := Next_With_Clause_Of (With_Clause, In_Tree); With_Clause := Next_With_Clause_Of (With_Clause, In_Tree);
end loop; end loop;
-- If it is not an imported project, it might be the imported project -- If it is not an imported project, it might be an extended project
if With_Clause = Empty_Node then if With_Clause = Empty_Node then
Result := Result := Project;
Extended_Project_Of loop
(Project_Declaration_Of (Project, In_Tree), In_Tree); Result :=
Extended_Project_Of
if Result /= Empty_Node (Project_Declaration_Of (Result, In_Tree), In_Tree);
and then Name_Of (Result, In_Tree) /= With_Name
then exit when Result = Empty_Node
Result := Empty_Node; or else Name_Of (Result, In_Tree) = With_Name;
end if; end loop;
end if; end if;
return Result; return Result;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment