From 3fb557d04e91391856db67de3f56a11a8c55076a Mon Sep 17 00:00:00 2001 From: Philippe Gil Date: Thu, 16 May 2024 17:40:18 +0200 Subject: [PATCH] Display GPR variables/types comment in tooltip LSP.GPR_Documentation.Get_Tooltip_Text: add variable/types declaration comment on variable references - Add Type_Id to LSP.GPR_Files API - Add Referenced_Type getter. - Let type definition be a type reference. - Add type reference to GPR2.Project.Typ.Object converter - Add type reference tooltip handling - Return structured tooltip declaration/location/documentation Closes eng/ide/ada_language_server#1352 --- source/gpr/lsp-gpr_documentation.adb | 194 ++++++++++++- source/gpr/lsp-gpr_documentation.ads | 15 +- source/gpr/lsp-gpr_documents.adb | 69 +++++ source/gpr/lsp-gpr_documents.ads | 9 + source/gpr/lsp-gpr_files-references.adb | 34 +-- source/gpr/lsp-gpr_files-references.ads | 11 + source/gpr/lsp-gpr_files.ads | 14 +- source/gpr/lsp-gpr_handlers.adb | 70 ++++- source/gpr/lsp-gpr_handlers.ads | 8 + testsuite/gpr_lsp/hover/test.json | 103 +++++-- testsuite/gpr_lsp/hover_type_comment/prj.gpr | 11 + .../gpr_lsp/hover_type_comment/test.json | 256 ++++++++++++++++++ .../gpr_lsp/hover_type_comment/test.yaml | 3 + .../gpr_lsp/hover_variable_comment/prj.gpr | 11 + .../gpr_lsp/hover_variable_comment/test.json | 256 ++++++++++++++++++ .../gpr_lsp/hover_variable_comment/test.yaml | 3 + 16 files changed, 988 insertions(+), 79 deletions(-) create mode 100644 testsuite/gpr_lsp/hover_type_comment/prj.gpr create mode 100644 testsuite/gpr_lsp/hover_type_comment/test.json create mode 100644 testsuite/gpr_lsp/hover_type_comment/test.yaml create mode 100644 testsuite/gpr_lsp/hover_variable_comment/prj.gpr create mode 100644 testsuite/gpr_lsp/hover_variable_comment/test.json create mode 100644 testsuite/gpr_lsp/hover_variable_comment/test.yaml diff --git a/source/gpr/lsp-gpr_documentation.adb b/source/gpr/lsp-gpr_documentation.adb index a91529dc0..b9b5b5812 100644 --- a/source/gpr/lsp-gpr_documentation.adb +++ b/source/gpr/lsp-gpr_documentation.adb @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- Language Server Protocol -- -- -- --- Copyright (C) 2023-2024, AdaCore -- +-- Copyright (C) 2023-2024, AdaCore -- -- -- -- This 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- -- @@ -17,10 +17,15 @@ with Ada.Characters.Conversions; with Ada.Characters.Latin_1; +with Ada.Characters.Wide_Wide_Latin_1; + with GPR2.Project.Attribute; +with GPR2.Project.Typ; with GPR2.Project.Variable; +with GPR2.Source_Reference; with Gpr_Parser.Common; +with Gpr_Parser_Support.Slocs; with GPR2.Project.Registry.Attribute.Description; with GPR2.Project.Registry.Pack.Description; @@ -32,12 +37,119 @@ with VSS.Strings.Conversions; package body LSP.GPR_Documentation is + function Get_Documentation + (Ref : Gpr_Parser.Common.Token_Reference; + Style : GNATdoc.Comments.Options.Documentation_Style) + return VSS.Strings.Virtual_String; + -- Get variable/type declaration comment. + + ----------------------- + -- Get_Documentation -- + ----------------------- + + function Get_Documentation + (Ref : Gpr_Parser.Common.Token_Reference; + Style : GNATdoc.Comments.Options.Documentation_Style) + return VSS.Strings.Virtual_String + is + Documentation : VSS.Strings.Virtual_String; + Add_LF : Boolean := False; + package Slocs renames Gpr_Parser_Support.Slocs; + use type Slocs.Line_Number; + + Line : Slocs.Line_Number := Ref.Data.Sloc_Range.Start_Line; + Token : Gpr_Parser.Common.Token_Reference := Ref; + + use type GNATdoc.Comments.Options.Documentation_Style; + + function Next return Gpr_Parser.Common.Token_Reference is + (if Style = GNATdoc.Comments.Options.GNAT + then Token.Next + else Token.Previous); + -- Go to next or previous token depending on 'Style' value + + function Valid_Comment return Boolean; + -- Return True if comment token is still part of 'Ref' comment. + + ------------------- + -- Valid_Comment -- + ------------------- + + function Valid_Comment return Boolean is + Current_Line : constant Slocs.Line_Number := + Token.Data.Sloc_Range.Start_Line; + Valid : Boolean := False; + begin + case Style is + when GNATdoc.Comments.Options.GNAT => + if Current_Line <= Line + 1 then + Valid := True; + end if; + when GNATdoc.Comments.Options.Leading => + if Current_Line >= Line - 1 then + Valid := True; + end if; + end case; + if Valid then + -- update Line to allow next/previous comment to still be valid + Line := Current_Line; + end if; + return Valid; + end Valid_Comment; + + use type Gpr_Parser.Common.Token_Reference; + use type Gpr_Parser.Common.Token_Kind; + begin + Token := Next; + while Token /= Gpr_Parser.Common.No_Token loop + if Token.Data.Kind = Gpr_Parser.Common.Gpr_Comment + then + if Valid_Comment then + case Style is + when GNATdoc.Comments.Options.GNAT => + if Add_LF then + Documentation.Append + (VSS.Strings.To_Virtual_String + (Ada.Characters.Wide_Wide_Latin_1.LF & Token.Text)); + else + Documentation.Append + (VSS.Strings.To_Virtual_String + (Token.Text)); + end if; + when GNATdoc.Comments.Options.Leading => + if Add_LF then + Documentation.Prepend + (VSS.Strings.To_Virtual_String + (Token.Text & Ada.Characters.Wide_Wide_Latin_1.LF)); + else + Documentation.Prepend + (VSS.Strings.To_Virtual_String + (Token.Text)); + end if; + end case; + Add_LF := True; + else + exit; + end if; + end if; + Token := Next; + end loop; + return Documentation; + end Get_Documentation; + + ---------------------- + -- Get_Tooltip_Text -- + ---------------------- + procedure Get_Tooltip_Text - (Self : LSP.GPR_Files.File_Access; - URI : LSP.Structures.DocumentUri; - Document_Provider : LSP.GPR_Documents.Document_Provider_Access; - Position : LSP.Structures.Position; - Tooltip_Text : out VSS.Strings.Virtual_String) is + (Self : LSP.GPR_Files.File_Access; + URI : LSP.Structures.DocumentUri; + Document_Provider : LSP.GPR_Documents.Document_Provider_Access; + Position : LSP.Structures.Position; + Style : GNATdoc.Comments.Options.Documentation_Style; + Declaration_Text : out VSS.Strings.Virtual_String; + Documentation_Text : out VSS.Strings.Virtual_String; + Location_Text : out VSS.Strings.Virtual_String) is use Gpr_Parser.Common; package LKD renames LSP.Text_Documents.Langkit_Documents; @@ -69,6 +181,7 @@ package body LSP.GPR_Documentation is begin if Reference.Is_Variable_Reference or else Reference.Is_Attribute_Reference + or else Reference.Is_Type_Reference then declare Document : constant LSP.GPR_Documents.Document_Access := @@ -85,9 +198,27 @@ package body LSP.GPR_Documentation is Reference => Reference); begin if Variable.Is_Defined then - Tooltip_Text.Append + Declaration_Text.Append (VSS.Strings.Conversions.To_Virtual_String (GPR2.Project.Variable.Image (Variable))); + Location_Text.Append + (VSS.Strings.Conversions.To_Virtual_String + (GPR2.Source_Reference.Format + (GPR2.Source_Reference.Object + (Variable)))); + if Variable.Has_Type then + declare + Typ : constant GPR2.Project.Typ.Object := + Variable.Typ; + begin + if Typ.Is_Defined then + Declaration_Text.Prepend + (VSS.Strings.Conversions.To_Virtual_String + (GPR2.Project.Typ.Image (Typ) + & Ada.Characters.Latin_1.CR)); + end if; + end; + end if; end if; end; elsif Reference.Is_Attribute_Reference then @@ -98,12 +229,39 @@ package body LSP.GPR_Documentation is Reference => Reference); begin if Attribute.Is_Defined then - Tooltip_Text.Append + Declaration_Text.Append (VSS.Strings.Conversions.To_Virtual_String (GPR2.Project.Attribute.Image (Attribute) & Ada.Characters.Latin_1.CR)); + Location_Text.Append + (VSS.Strings.Conversions.To_Virtual_String + (GPR2.Source_Reference.Format + (GPR2.Source_Reference.Object + (Attribute)))); + end if; + + end; + elsif Reference.Is_Type_Reference then + declare + Typ : constant GPR2.Project.Typ.Object := + Document.Get_Type + + (Root_File => Self, + Reference => Reference); + begin + if Typ.Is_Defined then + Declaration_Text.Append + (VSS.Strings.Conversions.To_Virtual_String + (GPR2.Project.Typ.Image (Typ) + & Ada.Characters.Latin_1.CR)); + Location_Text.Append + (VSS.Strings.Conversions.To_Virtual_String + (GPR2.Source_Reference.Format + (GPR2.Source_Reference.Object + (Typ)))); end if; end; + end if; end if; end; @@ -112,8 +270,6 @@ package body LSP.GPR_Documentation is begin - Tooltip_Text.Clear; - if Token /= No_Token and then Token.Data.Kind = Gpr_Identifier then declare Reference : constant FR.Reference := @@ -127,14 +283,14 @@ package body LSP.GPR_Documentation is if Previous /= No_Token then case Previous.Data.Kind is when Gpr_Package | Gpr_End => - Tooltip_Text.Append + Documentation_Text.Append (VSS.Strings.Conversions.To_Virtual_String (Get_Package_Description (Self.Get_Package (Position)))); when Gpr_For => Append_Value (Reference); - Tooltip_Text.Append + Documentation_Text.Append (VSS.Strings.Conversions.To_Virtual_String (Get_Attribute_Description (( Self.Get_Package (Position), @@ -143,11 +299,11 @@ package body LSP.GPR_Documentation is when others => Append_Value (Reference); if Reference.Is_Package_Reference then - Tooltip_Text.Append + Documentation_Text.Append (VSS.Strings.Conversions.To_Virtual_String (Get_Package_Description (Reference.Referenced_Package))); - else + elsif Reference.Is_Attribute_Reference then declare Attribute : constant FR.Attribute_Definition := Reference.Referenced_Attribute; @@ -155,12 +311,20 @@ package body LSP.GPR_Documentation is use type FR.Attribute_Definition; begin if Attribute /= FR.No_Attribute_Definition then - Tooltip_Text.Append + Documentation_Text.Append (VSS.Strings.Conversions.To_Virtual_String (Get_Attribute_Description (Attribute.Name))); end if; end; + elsif Reference.Is_Variable_Reference + or else Reference.Is_Type_Reference + then + Documentation_Text.Append + (Get_Documentation + (LSP.GPR_Files.References.Token_Reference + (Self, Position), + Style)); end if; end case; end if; diff --git a/source/gpr/lsp-gpr_documentation.ads b/source/gpr/lsp-gpr_documentation.ads index d2bef4188..cc2756f49 100644 --- a/source/gpr/lsp-gpr_documentation.ads +++ b/source/gpr/lsp-gpr_documentation.ads @@ -17,6 +17,8 @@ -- Subprogram to obtain documentation for packages & attributes. +with GNATdoc.Comments.Options; + with LSP.GPR_Documents; with LSP.GPR_Files; with LSP.Structures; @@ -26,11 +28,14 @@ with VSS.Strings; package LSP.GPR_Documentation is procedure Get_Tooltip_Text - (Self : LSP.GPR_Files.File_Access; - URI : LSP.Structures.DocumentUri; - Document_Provider : LSP.GPR_Documents.Document_Provider_Access; - Position : LSP.Structures.Position; - Tooltip_Text : out VSS.Strings.Virtual_String); + (Self : LSP.GPR_Files.File_Access; + URI : LSP.Structures.DocumentUri; + Document_Provider : LSP.GPR_Documents.Document_Provider_Access; + Position : LSP.Structures.Position; + Style : GNATdoc.Comments.Options.Documentation_Style; + Declaration_Text : out VSS.Strings.Virtual_String; + Documentation_Text : out VSS.Strings.Virtual_String; + Location_Text : out VSS.Strings.Virtual_String); -- Get all the information needed to produce tooltips (hover and completion -- requests) diff --git a/source/gpr/lsp-gpr_documents.adb b/source/gpr/lsp-gpr_documents.adb index d1c6b6871..2288eadc2 100644 --- a/source/gpr/lsp-gpr_documents.adb +++ b/source/gpr/lsp-gpr_documents.adb @@ -368,4 +368,73 @@ package body LSP.GPR_Documents is return GPR2.Project.Attribute.Undefined; end Get_Attribute; + -------------- + -- Get_Type -- + -------------- + + function Get_Type + (Self : Document'Class; + Root_File : LSP.GPR_Files.File_Access; + Reference : LSP.GPR_Files.References.Reference) + return GPR2.Project.Typ.Object is + + function Typ + (View : GPR2.Project.View.Object) return GPR2.Project.Typ.Object; + + --------- + -- Typ -- + --------- + + function Typ + (View : GPR2.Project.View.Object) return GPR2.Project.Typ.Object + is + Name : constant GPR2.Optional_Name_Type := + GPR2.Optional_Name_Type + (VSS.Strings.Conversions.To_UTF_8_String + (LSP.GPR_Files.Image (Reference.Referenced_Type))); + + begin + if View.Has_Types (Name) then + return View.Typ (Name); + else + return GPR2.Project.Typ.Undefined; + end if; + end Typ; + + begin + if LSP.GPR_Files.References.Is_Type_Reference (Reference) + and then not Self.Tree.Log_Messages.Has_Error + then + declare + File : constant LSP.GPR_Files.File_Access := + LSP.GPR_Files.References.Referenced_File + (File => Root_File, + Reference => Reference); + Path : constant GPR2.Path_Name.Object := + LSP.GPR_Files.Path (File.all); + Root : constant GPR2.Project.View.Object := Self.Tree.Root_Project; + begin + if Root.Path_Name = Path then + return Typ (Root); + end if; + if Root.Is_Extended then + declare + Extending : constant GPR2.Project.View.Object := + Root.Extending; + begin + if Extending.Path_Name = Path then + return Typ (Extending); + end if; + end; + end if; + for Import of Root.Imports loop + if Import.Path_Name = Path then + return Typ (Import); + end if; + end loop; + end; + end if; + return GPR2.Project.Typ.Undefined; + end Get_Type; + end LSP.GPR_Documents; diff --git a/source/gpr/lsp-gpr_documents.ads b/source/gpr/lsp-gpr_documents.ads index 11d13da91..d02bc4584 100644 --- a/source/gpr/lsp-gpr_documents.ads +++ b/source/gpr/lsp-gpr_documents.ads @@ -31,6 +31,7 @@ with GPR2.Log; with GPR2.Path_Name; with GPR2.Path_Name.Set; with GPR2.Project.Tree; +with GPR2.Project.Typ; with GPR2.Project.Attribute; with GPR2.Project.Variable; @@ -149,6 +150,14 @@ package LSP.GPR_Documents is -- if Document contains a valid Tree & Reference is an attribute reference -- returns corresponding value otherwise returns 'Undefined' + function Get_Type + (Self : Document'Class; + Root_File : LSP.GPR_Files.File_Access; + Reference : LSP.GPR_Files.References.Reference) + return GPR2.Project.Typ.Object; + -- if Document contains a valid Tree & Reference is a type reference + -- returns corresponding value otherwise returns 'Undefined' + private type Name_Information is record diff --git a/source/gpr/lsp-gpr_files-references.adb b/source/gpr/lsp-gpr_files-references.adb index f345458f4..8cc4fe5a6 100644 --- a/source/gpr/lsp-gpr_files-references.adb +++ b/source/gpr/lsp-gpr_files-references.adb @@ -180,7 +180,9 @@ package body LSP.GPR_Files.References is Identifiers.Clear; return; - elsif Token.Data.Kind = GPC.Gpr_Colon then + elsif Token.Data.Kind = GPC.Gpr_Colon + or else Token.Data.Kind = GPC.Gpr_Type + then -- Let 'Initialize' return a type reference In_Type_Reference := True; @@ -425,22 +427,20 @@ package body LSP.GPR_Files.References is +To_String (Identifiers.First_Element); begin if Referenced_Project.Types.Contains (Typ) then - if Previous_Token_Kind /= GPC.Gpr_Type then - declare - C : constant LSP.GPR_Files.Type_Maps.Cursor := - Referenced_Project.Types.Find (Typ); - begin - if LSP.GPR_Files.Type_Maps.Has_Element (C) then - return (Kind => Type_Ref, - Token => - LSP.GPR_Files.Type_Maps.Element (C).Token, - Project => - Referenced_Project.Name, - In_Type_Reference => In_Type_Reference, - Typ => Typ); - end if; - end; - end if; + declare + C : constant LSP.GPR_Files.Type_Maps.Cursor := + Referenced_Project.Types.Find (Typ); + begin + if LSP.GPR_Files.Type_Maps.Has_Element (C) then + return (Kind => Type_Ref, + Token => + LSP.GPR_Files.Type_Maps.Element (C).Token, + Project => + Referenced_Project.Name, + In_Type_Reference => In_Type_Reference, + Typ => Typ); + end if; + end; elsif Next_Token_Kind not in GPC.Gpr_Assign | GPC.Gpr_Colon then if not Project_Provided and then not Package_Provided then if Current_Package /= GPR2.Project_Level_Scope then diff --git a/source/gpr/lsp-gpr_files-references.ads b/source/gpr/lsp-gpr_files-references.ads index b5de058ed..acc376a6d 100644 --- a/source/gpr/lsp-gpr_files-references.ads +++ b/source/gpr/lsp-gpr_files-references.ads @@ -56,6 +56,10 @@ package LSP.GPR_Files.References is (Reference : LSP.GPR_Files.References.Reference) return LSP.GPR_Files.Variable_Id; + function Referenced_Type + (Reference : LSP.GPR_Files.References.Reference) + return LSP.GPR_Files.Type_Id; + function Has_Project (Reference : LSP.GPR_Files.References.Reference) return Boolean; @@ -184,4 +188,11 @@ private then Reference.Variable else No_Variable); + function Referenced_Type + (Reference : LSP.GPR_Files.References.Reference) + return LSP.GPR_Files.Type_Id is + (if Reference.Kind = Type_Ref + then Reference.Typ + else No_Type); + end LSP.GPR_Files.References; diff --git a/source/gpr/lsp-gpr_files.ads b/source/gpr/lsp-gpr_files.ads index 735e96d0d..29a049aa4 100644 --- a/source/gpr/lsp-gpr_files.ads +++ b/source/gpr/lsp-gpr_files.ads @@ -261,6 +261,16 @@ package LSP.GPR_Files is function Image (Id : Variable_Id) return VSS.Strings.Virtual_String; -- Variable_Id/String conversions + type Type_Id is private; + -- Used to describe variable's type's names + + No_Type : constant Type_Id; + -- Used by untyped variable + + function "+" (Name : String) return Type_Id; + function Image (Id : Type_Id) return VSS.Strings.Virtual_String; + -- Type_Id/String conversions + private type Source_Position is record @@ -351,10 +361,6 @@ private No_Type : constant Type_Id := 0; -- Used by untyped variable - function "+" (Name : String) return Type_Id; - function Image (Id : Type_Id) return VSS.Strings.Virtual_String; - -- Type_Id/String conversions - type Variable_Id is new Natural with Default_Value => 0; -- Used to describe variable's names diff --git a/source/gpr/lsp-gpr_handlers.adb b/source/gpr/lsp-gpr_handlers.adb index 1976e18ad..ec16db028 100644 --- a/source/gpr/lsp-gpr_handlers.adb +++ b/source/gpr/lsp-gpr_handlers.adb @@ -291,30 +291,59 @@ package body LSP.GPR_Handlers is (File_Provider => Self'Unchecked_Access, Path => Self.To_File (Value.textDocument.uri)); - Tooltip_Text : VSS.Strings.Virtual_String; + Declaration_Text : VSS.Strings.Virtual_String; + Documentation_Text : VSS.Strings.Virtual_String; + Location_Text : VSS.Strings.Virtual_String; begin LSP.GPR_Documentation.Get_Tooltip_Text - (Self => File, - URI => Value.textDocument.uri, - Document_Provider => Self'Unchecked_Access, - Position => Value.position, - Tooltip_Text => Tooltip_Text); - - if Tooltip_Text.Is_Empty then + (Self => File, + URI => Value.textDocument.uri, + Document_Provider => Self'Unchecked_Access, + Position => Value.position, + Style => Self.Configuration.Documentation_Style, + Declaration_Text => Declaration_Text, + Documentation_Text => Documentation_Text, + Location_Text => Location_Text); + + if Declaration_Text.Is_Empty + and then Documentation_Text.Is_Empty + and then Location_Text.Is_Empty + then return; end if; Response := (Is_Null => False, others => <>); Response.Value.contents := (Is_MarkupContent => False, others => <>); - -- Append the package/attribute description + -- Append the whole declaration text to the response + + if not Declaration_Text.Is_Empty then + Response.Value.contents.MarkedString_Vector.Append + (LSP.Structures.MarkedString' + (Is_Virtual_String => False, + value => Declaration_Text, + language => "gpr")); + end if; + + -- Append the location text to the response + + if not Location_Text.Is_Empty then + Response.Value.contents.MarkedString_Vector.Append + (LSP.Structures.MarkedString' + (Is_Virtual_String => True, + Virtual_String => Location_Text)); + end if; + + -- Append the comments associated with the basic declaration if any. - Response.Value.contents.MarkedString_Vector.Append - (LSP.Structures.MarkedString' - (Is_Virtual_String => False, - language => "plaintext", - value => Tooltip_Text)); + if not Documentation_Text.Is_Empty then + Response.Value.contents.MarkedString_Vector.Append + (LSP.Structures.MarkedString' + (Is_Virtual_String => False, + language => "plaintext", + value => Documentation_Text)); + end if; end Compute_Response; @@ -612,6 +641,19 @@ package body LSP.GPR_Handlers is Self.Sender.On_Shutdown_Response (Id, Response); end On_Shutdown_Request; + -------------------------------------------- + -- On_DidChangeConfiguration_Notification -- + -------------------------------------------- + + overriding procedure On_DidChangeConfiguration_Notification + (Self : in out Message_Handler; + Value : LSP.Structures.DidChangeConfigurationParams) is + Reload : Boolean; + pragma Warnings (Off, Reload); + begin + Self.Configuration.Read_JSON (Value.settings, Reload); + end On_DidChangeConfiguration_Notification; + ------------------------- -- Publish_Diagnostics -- ------------------------- diff --git a/source/gpr/lsp-gpr_handlers.ads b/source/gpr/lsp-gpr_handlers.ads index 92d7842b2..5a7e0e9c9 100644 --- a/source/gpr/lsp-gpr_handlers.ads +++ b/source/gpr/lsp-gpr_handlers.ads @@ -25,6 +25,7 @@ private with GNATCOLL.VFS; private with GPR2.File_Readers; private with GPR2.Path_Name; +with LSP.Ada_Configurations; with LSP.Client_Message_Receivers; with LSP.GPR_Client_Capabilities; with LSP.GPR_Documents; @@ -116,6 +117,9 @@ private Is_Canceled : Has_Been_Canceled_Function; -- Is request has been canceled + + Configuration : LSP.Ada_Configurations.Configuration; + -- Ada/GPR configuration settings end record; overriding procedure On_Server_Notification @@ -173,6 +177,10 @@ private Id : LSP.Structures.Integer_Or_Virtual_String; Value : LSP.Structures.DeclarationParams); + overriding procedure On_DidChangeConfiguration_Notification + (Self : in out Message_Handler; + Value : LSP.Structures.DidChangeConfigurationParams); + ----------------------------------------- -- LSP.GPR_Documents.Document_Provider -- ----------------------------------------- diff --git a/testsuite/gpr_lsp/hover/test.json b/testsuite/gpr_lsp/hover/test.json index 7e2195bab..b06a47005 100644 --- a/testsuite/gpr_lsp/hover/test.json +++ b/testsuite/gpr_lsp/hover/test.json @@ -223,9 +223,14 @@ "id": 4, "result": { "contents": [ + { + "language": "gpr", + "value": "for Source_Dirs use (\"src\");\r" + }, + "prj1.gpr:2:05", { "language": "plaintext", - "value": "for Source_Dirs use (\"src\");\rThe list of source directories of the project." + "value": "The list of source directories of the project." } ] } @@ -254,9 +259,14 @@ "id": 5, "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (\"Ada\") use ();\r" + }, + "prj1.gpr:4:05", { "language": "plaintext", - "value": "for Switches (\"Ada\") use ();\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } @@ -316,9 +326,14 @@ "id": 8, "result": { "contents": [ + { + "language": "gpr", + "value": "for Artifacts_Dir use \"\";\r" + }, + "prj1.gpr:7:05", { "language": "plaintext", - "value": "for Artifacts_Dir use \"\";\rThe directory in which the files generated by 'gnatstudio' for this project (cross-references database, locations etc.) are stored by default. Defaults to Object_Dir if not specified." + "value": "The directory in which the files generated by 'gnatstudio' for this project (cross-references database, locations etc.) are stored by default. Defaults to Object_Dir if not specified." } ] } @@ -337,7 +352,7 @@ "languageId": "Gpr", "version": 1, "text": "project Prj3 is\n type T is (\"project.Var value \");\n Var : T := \"project.Var value \";\n package Builder is\n Var := \"project.Builder.Var value \";\n for Global_Configuration_Pragmas use \"project.Builder'Global_Configuration_Pragmas value \";\n end Builder;\n Var1 := Var & project.Var & project.Builder.Var & project'Name & Prj3'Name & Prj3.Builder'Global_Configuration_Pragmas;\n package Compiler is\n for Switches (\"main.adb\") use (\"value1\");\n for Switches (\"main.adb\" at 1) use (\"value2\");\n for Switches (others) use (\"value3\");\n Var := Compiler'Switches (\"main.adb\") & Compiler'Switches (others);\n end Compiler;\nend Prj3;\n" - } + } } }, "wait": [] @@ -365,9 +380,10 @@ "result": { "contents": [ { - "language": "plaintext", - "value": "Var : T := \"project.Var value \";" - } + "language": "gpr", + "value": "type T is (\"project.Var value \");\rVar : T := \"project.Var value \";" + }, + "prj3.gpr:3:03" ] } } @@ -396,9 +412,10 @@ "result": { "contents": [ { - "language": "plaintext", + "language": "gpr", "value": "Var := \"project.Builder.Var value \";" - } + }, + "prj3.gpr:5:05" ] } } @@ -427,9 +444,10 @@ "result": { "contents": [ { - "language": "plaintext", - "value": "Var : T := \"project.Var value \";" - } + "language": "gpr", + "value": "type T is (\"project.Var value \");\rVar : T := \"project.Var value \";" + }, + "prj3.gpr:3:03" ] } } @@ -482,9 +500,10 @@ "result": { "contents": [ { - "language": "plaintext", - "value": "Var : T := \"project.Var value \";" - } + "language": "gpr", + "value": "type T is (\"project.Var value \");\rVar : T := \"project.Var value \";" + }, + "prj3.gpr:3:03" ] } } @@ -544,9 +563,10 @@ "result": { "contents": [ { - "language": "plaintext", + "language": "gpr", "value": "Var := \"project.Builder.Var value \";" - } + }, + "prj3.gpr:5:05" ] } } @@ -574,9 +594,14 @@ "id": "7,63", "result": { "contents": [ + { + "language": "gpr", + "value": "for Name use \"prj3\";\r" + }, + "prj3.gpr", { "language": "plaintext", - "value": "for Name use \"prj3\";\rThe name of the project." + "value": "The name of the project." } ] } @@ -605,9 +630,14 @@ "id": "7,74", "result": { "contents": [ + { + "language": "gpr", + "value": "for Name use \"prj3\";\r" + }, + "prj3.gpr", { "language": "plaintext", - "value": "for Name use \"prj3\";\rThe name of the project." + "value": "The name of the project." } ] } @@ -667,9 +697,14 @@ "id": "9,13", "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (\"main.adb\") use (\"value1\");\r" + }, + "prj3.gpr:10:09", { "language": "plaintext", - "value": "for Switches (\"main.adb\") use (\"value1\");\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } @@ -698,9 +733,14 @@ "id": "10,13", "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (\"main.adb\") use (\"value2\");\r" + }, + "prj3.gpr:11:09", { "language": "plaintext", - "value": "for Switches (\"main.adb\") use (\"value2\");\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } @@ -729,9 +769,14 @@ "id": "11,11", "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (others) use (\"value3\");\r" + }, + "prj3.gpr:12:09", { "language": "plaintext", - "value": "for Switches (others) use (\"value3\");\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } @@ -791,9 +836,14 @@ "id": "12,24", "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (\"main.adb\") use (\"value1\");\r" + }, + "prj3.gpr:10:09", { "language": "plaintext", - "value": "for Switches (\"main.adb\") use (\"value1\");\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } @@ -822,9 +872,14 @@ "id": "12,58", "result": { "contents": [ + { + "language": "gpr", + "value": "for Switches (others) use (\"value3\");\r" + }, + "prj3.gpr:12:09", { "language": "plaintext", - "value": "for Switches (others) use (\"value3\");\rIndex is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." + "value": "Index is a source file name or a language name. Value is the list of switches to be used when invoking the compiler for the source or for its language." } ] } diff --git a/testsuite/gpr_lsp/hover_type_comment/prj.gpr b/testsuite/gpr_lsp/hover_type_comment/prj.gpr new file mode 100644 index 000000000..c9ab27996 --- /dev/null +++ b/testsuite/gpr_lsp/hover_type_comment/prj.gpr @@ -0,0 +1,11 @@ +project Prj is + -- Not part of My_Type comment + + -- Leading style comment start + -- Leading style comment end + type My_Type is ("a", "b"); -- GNAT style comment start + -- GNAT style comment end + + -- Not part of My_Type comment + Var : My_Type := "a"; +end Prj; \ No newline at end of file diff --git a/testsuite/gpr_lsp/hover_type_comment/test.json b/testsuite/gpr_lsp/hover_type_comment/test.json new file mode 100644 index 000000000..8bfd0b901 --- /dev/null +++ b/testsuite/gpr_lsp/hover_type_comment/test.json @@ -0,0 +1,256 @@ +[ + { + "comment": [ + "test textDocument/hover request works on variable reference" + ] + }, + { + "start": { + "cmd": [ + "${ALS}", + "--language-gpr" + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "id": "init", + "method": "initialize", + "params": { + "processId": 441587, + "rootUri": "$URI{.}", + "capabilities": { + "workspace": { + "applyEdit": true, + "workspaceEdit": {}, + "didChangeConfiguration": {}, + "didChangeWatchedFiles": {}, + "executeCommand": {} + }, + "textDocument": { + "synchronization": {}, + "completion": { + "dynamicRegistration": true, + "completionItem": { + "snippetSupport": true, + "documentationFormat": [ + "plaintext", + "markdown" + ] + } + }, + "hover": {}, + "signatureHelp": {}, + "declaration": {}, + "definition": {}, + "typeDefinition": {}, + "implementation": {}, + "references": {}, + "documentHighlight": {}, + "documentSymbol": { + "hierarchicalDocumentSymbolSupport": true + }, + "codeLens": {}, + "colorProvider": {}, + "formatting": { + "dynamicRegistration": false + }, + "rangeFormatting": { + "dynamicRegistration": false + }, + "onTypeFormatting": { + "dynamicRegistration": false + }, + "foldingRange": { + "lineFoldingOnly": true + }, + "selectionRange": {}, + "linkedEditingRange": {}, + "callHierarchy": {}, + "moniker": {} + } + } + } + }, + "wait": [ + { + "jsonrpc": "2.0", + "id": "init", + "result": { + "capabilities": { + "textDocumentSync": { + "openClose": true, + "change": 1 + } + } + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "initialized" + }, + "wait": [] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "textDocument/didOpen", + "params": { + "textDocument": { + "uri": "$URI{prj.gpr}", + "languageId": "Gpr", + "version": 1, + "text": "project Prj is\n -- Not part of My_Type comment\n\n -- Leading style comment start\n -- Leading style comment end\n type My_Type is (\"a\", \"b\"); -- GNAT style comment start\n -- GNAT style comment end\n\n -- Not part of My_Type comment\n Var : My_Type := \"a\";\nend Prj;" + } + } + }, + "wait": [] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 5, + "character": 11 + }, + "textDocument": { + "uri": "$URI{prj.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1, + "method": "textDocument/hover" + }, + "wait": [ + { + "id": 1, + "result": { + "contents": [ + { + "language": "gpr", + "value": "type My_Type is (\"a\", \"b\");\r" + }, + "prj.gpr:6:09", + { + "language": "plaintext", + "value": "-- GNAT style comment start\n-- GNAT style comment end" + } + ] + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "workspace/didChangeConfiguration", + "params": { + "settings": { + "ada": { + "projectFile": "", + "scenarioVariables": {}, + "defaultCharset": "iso-8859-1", + "relocateBuildTree": "", + "rootDir": "", + "onTypeFormatting": { + "indentOnly": true + }, + "documentationStyle": "leading", + "displayMethodAncestryOnNavigation": "usage_and_abstract_only", + "enableDiagnostics": true, + "foldComments": true, + "namedNotationThreshold": 3, + "useCompletionSnippets": false, + "renameInComments": false, + "enableIndexing": true, + "followSymlinks": true, + "trace": { + "server": "off" + } + } + } + } + }, + "wait": [] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 9, + "character": 12 + }, + "textDocument": { + "uri": "$URI{prj.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 2, + "method": "textDocument/hover" + }, + "wait": [ + { + "id": 2, + "result": { + "contents": [ + { + "language": "gpr", + "value": "type My_Type is (\"a\", \"b\");\r" + }, + "prj.gpr:6:09", + { + "language": "plaintext", + "value": "-- Leading style comment start\n-- Leading style comment end" + } + ] + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "id": "shutdown", + "method": "shutdown", + "params": null + }, + "wait": [ + { + "id": "shutdown", + "result": null + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "exit" + }, + "wait": [] + } + }, + { + "stop": { + "exit_code": 0 + } + } +] \ No newline at end of file diff --git a/testsuite/gpr_lsp/hover_type_comment/test.yaml b/testsuite/gpr_lsp/hover_type_comment/test.yaml new file mode 100644 index 000000000..bd215f7a0 --- /dev/null +++ b/testsuite/gpr_lsp/hover_type_comment/test.yaml @@ -0,0 +1,3 @@ +title: 'textDocument/hover request, test type comment gnat/leading style' +skip: + - ['SKIP', 'env.build.os.name not in ("linux","windows")'] diff --git a/testsuite/gpr_lsp/hover_variable_comment/prj.gpr b/testsuite/gpr_lsp/hover_variable_comment/prj.gpr new file mode 100644 index 000000000..b3f71bcae --- /dev/null +++ b/testsuite/gpr_lsp/hover_variable_comment/prj.gpr @@ -0,0 +1,11 @@ +project Prj is + -- Not part of Var comment + + -- Var Leading style comment start + -- Var Leading style comment end + Var := ""; -- Var GNAT style comment start + -- Var GNAT style comment end + + -- Not part of Var comment + V := Var; +end Prj; \ No newline at end of file diff --git a/testsuite/gpr_lsp/hover_variable_comment/test.json b/testsuite/gpr_lsp/hover_variable_comment/test.json new file mode 100644 index 000000000..4adb5d6ed --- /dev/null +++ b/testsuite/gpr_lsp/hover_variable_comment/test.json @@ -0,0 +1,256 @@ +[ + { + "comment": [ + "test textDocument/hover request works on variable reference" + ] + }, + { + "start": { + "cmd": [ + "${ALS}", + "--language-gpr" + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "id": "init", + "method": "initialize", + "params": { + "processId": 441587, + "rootUri": "$URI{.}", + "capabilities": { + "workspace": { + "applyEdit": true, + "workspaceEdit": {}, + "didChangeConfiguration": {}, + "didChangeWatchedFiles": {}, + "executeCommand": {} + }, + "textDocument": { + "synchronization": {}, + "completion": { + "dynamicRegistration": true, + "completionItem": { + "snippetSupport": true, + "documentationFormat": [ + "plaintext", + "markdown" + ] + } + }, + "hover": {}, + "signatureHelp": {}, + "declaration": {}, + "definition": {}, + "typeDefinition": {}, + "implementation": {}, + "references": {}, + "documentHighlight": {}, + "documentSymbol": { + "hierarchicalDocumentSymbolSupport": true + }, + "codeLens": {}, + "colorProvider": {}, + "formatting": { + "dynamicRegistration": false + }, + "rangeFormatting": { + "dynamicRegistration": false + }, + "onTypeFormatting": { + "dynamicRegistration": false + }, + "foldingRange": { + "lineFoldingOnly": true + }, + "selectionRange": {}, + "linkedEditingRange": {}, + "callHierarchy": {}, + "moniker": {} + } + } + } + }, + "wait": [ + { + "jsonrpc": "2.0", + "id": "init", + "result": { + "capabilities": { + "textDocumentSync": { + "openClose": true, + "change": 1 + } + } + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "initialized" + }, + "wait": [] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "textDocument/didOpen", + "params": { + "textDocument": { + "uri": "$URI{prj.gpr}", + "languageId": "Gpr", + "version": 1, + "text": "project Prj is\n -- Not part of Var comment\n\n -- Var Leading style comment start\n -- Var Leading style comment end\n Var := \"\"; -- Var GNAT style comment start\n -- Var GNAT style comment end\n\n -- Not part of Var comment\n V := Var;\nend Prj;" + } + } + }, + "wait": [] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 5, + "character": 5 + }, + "textDocument": { + "uri": "$URI{prj.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1, + "method": "textDocument/hover" + }, + "wait": [ + { + "id": 1, + "result": { + "contents": [ + { + "language": "gpr", + "value": "Var := \"\";" + }, + "prj.gpr:6:04", + { + "language": "plaintext", + "value": "-- Var GNAT style comment start\n-- Var GNAT style comment end" + } + ] + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "workspace/didChangeConfiguration", + "params": { + "settings": { + "ada": { + "projectFile": "", + "scenarioVariables": {}, + "defaultCharset": "iso-8859-1", + "relocateBuildTree": "", + "rootDir": "", + "onTypeFormatting": { + "indentOnly": true + }, + "documentationStyle": "leading", + "displayMethodAncestryOnNavigation": "usage_and_abstract_only", + "enableDiagnostics": true, + "foldComments": true, + "namedNotationThreshold": 3, + "useCompletionSnippets": false, + "renameInComments": false, + "enableIndexing": true, + "followSymlinks": true, + "trace": { + "server": "off" + } + } + } + } + }, + "wait": [] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 9, + "character": 10 + }, + "textDocument": { + "uri": "$URI{prj.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 2, + "method": "textDocument/hover" + }, + "wait": [ + { + "id": 2, + "result": { + "contents": [ + { + "language": "gpr", + "value": "Var := \"\";" + }, + "prj.gpr:6:04", + { + "language": "plaintext", + "value": "-- Var Leading style comment start\n-- Var Leading style comment end" + } + ] + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "id": "shutdown", + "method": "shutdown", + "params": null + }, + "wait": [ + { + "id": "shutdown", + "result": null + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "exit" + }, + "wait": [] + } + }, + { + "stop": { + "exit_code": 0 + } + } +] \ No newline at end of file diff --git a/testsuite/gpr_lsp/hover_variable_comment/test.yaml b/testsuite/gpr_lsp/hover_variable_comment/test.yaml new file mode 100644 index 000000000..be598ae30 --- /dev/null +++ b/testsuite/gpr_lsp/hover_variable_comment/test.yaml @@ -0,0 +1,3 @@ +title: 'textDocument/hover request, test variable comment gnat/leading style' +skip: + - ['SKIP', 'env.build.os.name not in ("linux","windows")']