1515-- of the license. --
1616-- ----------------------------------------------------------------------------
1717
18+ with GPR2 ; use GPR2;
19+ with GPR2.Build.Source ;
1820with GPR2.Build.Unit_Info ;
1921with GPR2.Project.View ;
2022with VSS.JSON.Streams ;
2123
22- with GNATCOLL.VFS ; use GNATCOLL.VFS;
24+ with GNATCOLL.VFS ; use GNATCOLL.VFS;
2325
2426with GPR2.Build.Compilation_Unit ;
2527with GPR2.Path_Name ;
2628
2729with LSP.Constants ;
30+ with LSP.Enumerations ;
2831with LSP.Servers ;
2932
3033package body LSP.Ada_Handlers.Other_File_Commands is
@@ -85,13 +88,23 @@ package body LSP.Ada_Handlers.Other_File_Commands is
8588 File : constant GNATCOLL.VFS.Virtual_File :=
8689 Handler.To_File (Self.URI);
8790
88- function Other_File return GNATCOLL.VFS.Virtual_File;
91+ function Get_Other_File
92+ (Success : out Boolean;
93+ Error_Msg : out VSS.Strings.Virtual_String)
94+ return GNATCOLL.VFS.Virtual_File;
95+ -- Return File's other file. If it does not exist,
96+ -- Success is set to False and it will return No_File,
97+ -- with an Error_Msg explaining why the other file could not be found.
8998
90- -- --------------
91- -- Other_File --
92- -- --------------
99+ -- ------------------
100+ -- Get_Other_File --
101+ -- ------------------
93102
94- function Other_File return GNATCOLL.VFS.Virtual_File is
103+ function Get_Other_File
104+ (Success : out Boolean;
105+ Error_Msg : out VSS.Strings.Virtual_String)
106+ return GNATCOLL.VFS.Virtual_File
107+ is
95108
96109 F : constant GPR2.Path_Name.Object := GPR2.Path_Name.Create (File);
97110
@@ -100,9 +113,12 @@ package body LSP.Ada_Handlers.Other_File_Commands is
100113 return GNATCOLL.VFS.Virtual_File;
101114 -- Return the other file, knowing that the original file was
102115 -- related to Unit.
116+ -- Return No_File if no other file has been found
117+ -- (e.g: when querying the other file of a package that has only a
118+ -- a specification file).
103119
104120 function Unit_For_File return GPR2.Build.Compilation_Unit.Object;
105- -- File the Unit object corresponding to File.
121+ -- Return the Unit object corresponding to File
106122
107123 -- ------------------------
108124 -- Other_File_From_Unit --
@@ -115,8 +131,11 @@ package body LSP.Ada_Handlers.Other_File_Commands is
115131 Spec_File : Virtual_File;
116132 Body_File : Virtual_File;
117133 begin
118- Spec_File := Unit.Spec.Source.Virtual_File;
119- Body_File := Unit.Main_Body.Source.Virtual_File;
134+ Spec_File := (if Unit.Has_Part (S_Spec) then
135+ Unit.Spec.Source.Virtual_File else No_File);
136+ Body_File := (if Unit.Has_Part (S_Body) then
137+ Unit.Main_Body.Source.Virtual_File else No_File);
138+
120139 if File = Spec_File then
121140 return Body_File;
122141 else
@@ -128,48 +147,102 @@ package body LSP.Ada_Handlers.Other_File_Commands is
128147 -- Unit_For_File --
129148 -- -----------------
130149
131- function Unit_For_File return GPR2.Build.Compilation_Unit.Object is
150+ function Unit_For_File
151+ return GPR2.Build.Compilation_Unit.Object is
132152 begin
133153 -- Check in the root project's closure for a visible source
134154 -- corresponding to this file.
135155 -- Not that the root's project closure includes the runtime.
136156 if Handler.Project_Tree.Is_Defined then
137157 declare
138- View : constant GPR2.Project.View.Object :=
158+ View : constant GPR2.Project.View.Object :=
139159 Handler.Project_Tree.Root_Project;
140- Unit_Info : constant GPR2.Build.Unit_Info .Object :=
141- View.Visible_Source (F.Simple_Name).Unit ;
142- Unit : GPR2.Build.Compilation_Unit.Object :=
160+ Visible_Source : constant GPR2.Build.Source .Object :=
161+ View.Visible_Source (F.Simple_Name);
162+ Unit : GPR2.Build.Compilation_Unit.Object :=
143163 GPR2.Build.Compilation_Unit.Undefined;
144164 begin
145- if Unit_Info.Is_Defined then
146- Unit := View.Namespace_Roots.First_Element.Unit
147- (Unit_Info.Name);
165+ -- The source is not visible from the root project (e.g:
166+ -- when querying the other file of an Ada file that
167+ -- does not belong to the loaded project).
168+ if not Visible_Source.Is_Defined then
169+ return GPR2.Build.Compilation_Unit.Undefined;
148170 end if ;
149171
150- return Unit;
172+ declare
173+ Unit_Info : constant GPR2.Build.Unit_Info.Object :=
174+ Visible_Source.Unit;
175+ begin
176+ if Unit_Info.Is_Defined then
177+ Unit :=
178+ View.Namespace_Roots.First_Element.Unit
179+ (Unit_Info.Name);
180+ end if ;
181+
182+ return Unit;
183+ end ;
151184 end ;
152185 else
153186 return GPR2.Build.Compilation_Unit.Undefined;
154187 end if ;
155188 end Unit_For_File ;
156189
190+ Unit : constant GPR2.Build.Compilation_Unit.Object := Unit_For_File;
191+ Other_File : Virtual_File;
157192 begin
158- return Other_File_From_Unit (Unit_For_File);
159- end Other_File ;
160-
161- URI : constant LSP.Structures.DocumentUri :=
162- Handler.To_URI (Other_File.Display_Full_Name);
193+ if not Unit.Is_Defined then
194+ Success := False;
195+ Error_Msg :=
196+ VSS.Strings.Conversions.To_Virtual_String
197+ (" Could not find other file for '"
198+ & File.Display_Base_Name
199+ & " ': this file is not visible from the current project." );
200+
201+ return No_File;
202+ else
203+ Other_File := Other_File_From_Unit (Unit => Unit);
204+
205+ if Other_File = No_File then
206+ Success := False;
207+ Error_Msg :=
208+ VSS.Strings.Conversions.To_Virtual_String
209+ (" Could not find other file for '"
210+ & File.Display_Base_Name
211+ & " ': the unit has no other part." );
212+ else
213+ Success := True;
214+ end if ;
163215
164- Message : constant LSP.Structures.ShowDocumentParams :=
165- (uri => (VSS.Strings.Virtual_String (URI) with null record ),
166- takeFocus => LSP.Constants.True,
167- others => <>);
216+ return Other_File;
217+ end if ;
218+ end Get_Other_File ;
168219
169- New_Id : constant LSP.Structures.Integer_Or_Virtual_String :=
170- Handler.Server.Allocate_Request_Id;
220+ Success : Boolean;
221+ Error_Msg : VSS.Strings.Virtual_String;
222+ Other_File : constant Virtual_File := Get_Other_File (Success, Error_Msg);
171223 begin
172- Handler.Sender.On_ShowDocument_Request (New_Id, Message);
224+ if not Success then
225+ Error :=
226+ (Is_Set => True,
227+ Value =>
228+ (code => LSP.Enumerations.InternalError, message => Error_Msg));
229+ return ;
230+ end if ;
231+
232+ declare
233+ URI : constant LSP.Structures.DocumentUri :=
234+ Handler.To_URI (Other_File.Display_Full_Name);
235+
236+ Message : constant LSP.Structures.ShowDocumentParams :=
237+ (uri => (VSS.Strings.Virtual_String (URI) with null record ),
238+ takeFocus => LSP.Constants.True,
239+ others => <>);
240+
241+ New_Id : constant LSP.Structures.Integer_Or_Virtual_String :=
242+ Handler.Server.Allocate_Request_Id;
243+ begin
244+ Handler.Sender.On_ShowDocument_Request (New_Id, Message);
245+ end ;
173246 end Execute ;
174247
175248 -- --------------
0 commit comments