From 76e3c054e1cf218dbf32a94c2f82af75fc4562d3 Mon Sep 17 00:00:00 2001 From: Philippe Gil Date: Fri, 5 Apr 2024 14:52:15 +0200 Subject: [PATCH] testDocument/declaration support - implements On_Declaration_Request - add test See ada_language_server#1225 --- source/gpr/lsp-gpr_handlers.adb | 50 + source/gpr/lsp-gpr_handlers.ads | 5 + testsuite/gpr_lsp/declaration/aggregating.gpr | 7 + testsuite/gpr_lsp/declaration/imported.gpr | 13 + testsuite/gpr_lsp/declaration/navigation.gpr | 23 + testsuite/gpr_lsp/declaration/prj.gpr | 7 + testsuite/gpr_lsp/declaration/test.json | 887 ++++++++++++++++++ testsuite/gpr_lsp/declaration/test.yaml | 3 + 8 files changed, 995 insertions(+) create mode 100644 testsuite/gpr_lsp/declaration/aggregating.gpr create mode 100644 testsuite/gpr_lsp/declaration/imported.gpr create mode 100644 testsuite/gpr_lsp/declaration/navigation.gpr create mode 100644 testsuite/gpr_lsp/declaration/prj.gpr create mode 100644 testsuite/gpr_lsp/declaration/test.json create mode 100644 testsuite/gpr_lsp/declaration/test.yaml diff --git a/source/gpr/lsp-gpr_handlers.adb b/source/gpr/lsp-gpr_handlers.adb index 7aa53e488..92e1dbcd8 100644 --- a/source/gpr/lsp-gpr_handlers.adb +++ b/source/gpr/lsp-gpr_handlers.adb @@ -341,6 +341,7 @@ package body LSP.GPR_Handlers is Capabilities.hoverProvider := LSP.Constants.True; Capabilities.definitionProvider := LSP.Constants.True; + Capabilities.declarationProvider := LSP.Constants.True; Capabilities.completionProvider := (Is_Set => True, Value => (triggerCharacters => [" "], @@ -431,6 +432,55 @@ package body LSP.GPR_Handlers is Self.Sender.On_Completion_Resolve_Response (Id, Response); end On_Completion_Resolve_Request; + ---------------------------- + -- On_Declaration_Request -- + ---------------------------- + + overriding procedure On_Declaration_Request + (Self : in out Message_Handler; + Id : LSP.Structures.Integer_Or_Virtual_String; + Value : LSP.Structures.DeclarationParams) + is + procedure Fill_Declaration; + -- Utility function, appends to Vector the definition if any. + + Response : LSP.Structures.Declaration_Result (LSP.Structures.Variant_1); + + ---------------------- + -- Fill_Declaration -- + ---------------------- + + procedure Fill_Declaration is + File : constant LSP.GPR_Files.File_Access := + LSP.GPR_Files.Parse + (File_Provider => Self'Unchecked_Access, + Path => Self.To_File + (Value.textDocument.uri)); + + Reference : constant Gpr_Parser.Common.Token_Reference := + LSP.GPR_Files.References.Token_Reference + (File, Value.position); + + Location : LSP.Structures.Location; + + use type Gpr_Parser.Common.Token_Reference; + + begin + if Reference /= Gpr_Parser.Common.No_Token then + Location.uri := + LSP.GPR_File_Readers.To_URI (Reference.Origin_Filename); + Location.a_range := To_Range (Self'Unchecked_Access, Reference); + Response.Variant_1.Append (Location); + end if; + + end Fill_Declaration; + + begin + Fill_Declaration; + + Self.Sender.On_Declaration_Response (Id, Response); + end On_Declaration_Request; + --------------------------- -- On_Definition_Request -- --------------------------- diff --git a/source/gpr/lsp-gpr_handlers.ads b/source/gpr/lsp-gpr_handlers.ads index bcdd6477d..461a5db23 100644 --- a/source/gpr/lsp-gpr_handlers.ads +++ b/source/gpr/lsp-gpr_handlers.ads @@ -167,6 +167,11 @@ private Id : LSP.Structures.Integer_Or_Virtual_String; Value : LSP.Structures.DefinitionParams); + overriding procedure On_Declaration_Request + (Self : in out Message_Handler; + Id : LSP.Structures.Integer_Or_Virtual_String; + Value : LSP.Structures.DeclarationParams); + ----------------------------------------- -- LSP.GPR_Documents.Document_Provider -- ----------------------------------------- diff --git a/testsuite/gpr_lsp/declaration/aggregating.gpr b/testsuite/gpr_lsp/declaration/aggregating.gpr new file mode 100644 index 000000000..819eda365 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/aggregating.gpr @@ -0,0 +1,7 @@ +aggregate project GPS_Aggregated is + + for Project_Files use + ("ignored.gpr", "navigation.gpr"); + for Object_Dir use "obj"; + +end GPS_Aggregated; \ No newline at end of file diff --git a/testsuite/gpr_lsp/declaration/imported.gpr b/testsuite/gpr_lsp/declaration/imported.gpr new file mode 100644 index 000000000..38fc15b13 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/imported.gpr @@ -0,0 +1,13 @@ +abstract project Imported is + type T is ("0", "1"); + V := "0"; + for Exec_Dir use "exe"; + package Compiler is + V := "0"; + for Switches ("Ada") use (); + end Compiler; + package Builder is + end Builder; + package Binder is + end Binder; +end Imported; \ No newline at end of file diff --git a/testsuite/gpr_lsp/declaration/navigation.gpr b/testsuite/gpr_lsp/declaration/navigation.gpr new file mode 100644 index 000000000..2ec10ff30 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/navigation.gpr @@ -0,0 +1,23 @@ +with "ignored", "imported"; +project Navigation is + + type T is ("0", "1"); + V : T := "0"; + for Source_Dirs use ("src"); + package Compiler is + V := (); + for Switches ("Ada") use V; + V1 := Navigation.Compiler'Switches ("Ada"); + V2 := Compiler'Switches ("Ada"); + V3 := Compiler.V; + V4 : Imported.T := Imported.V; + V5 := Imported'Exec_Dir; + V6 := Imported.Compiler'Switches ("Ada"); + V7 := Imported.Compiler.V; + end Compiler; + package Builder renames Imported.Builder; + package Binder extends Imported.Binder is + end Binder; + V8 := V; + +end Navigation; diff --git a/testsuite/gpr_lsp/declaration/prj.gpr b/testsuite/gpr_lsp/declaration/prj.gpr new file mode 100644 index 000000000..819eda365 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/prj.gpr @@ -0,0 +1,7 @@ +aggregate project GPS_Aggregated is + + for Project_Files use + ("ignored.gpr", "navigation.gpr"); + for Object_Dir use "obj"; + +end GPS_Aggregated; \ No newline at end of file diff --git a/testsuite/gpr_lsp/declaration/test.json b/testsuite/gpr_lsp/declaration/test.json new file mode 100644 index 000000000..c21b92a29 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/test.json @@ -0,0 +1,887 @@ +[ + { + "comment": [ + "test textDocument/declaration request works" + ] + }, + { + "start": { + "cmd": [ + "${ALS}", + "--language-gpr" + ] + } + }, + { + "send": { + "request": { + "params": { + "processId": 30612, + "capabilities": { + "workspace": { + "applyEdit": false + } + }, + "rootUri": "$URI{.}" + }, + "jsonrpc": "2.0", + "id": 1, + "method": "initialize" + }, + "wait": [ + { + "jsonrpc": "2.0", + "id": 1, + "result": { + "capabilities": { + "textDocumentSync": { + "openClose": true, + "change": 1 + }, + "completionProvider": { + "triggerCharacters": [ + " " + ], + "resolveProvider": true + }, + "hoverProvider": true, + "declarationProvider": true, + "documentSymbolProvider": {} + } + } + } + ] + } + }, + { + "send": { + "request": { + "jsonrpc": "2.0", + "method": "initialized" + }, + "wait": [] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 3, + "character": 29 + }, + "textDocument": { + "uri": "$URI{aggregating.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 329, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 329, + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 18 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 0, + "character": 25 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 25, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 25, + "result": { + "range": { + "start": { + "line": 0, + "character": 17 + }, + "end": { + "line": 0, + "character": 25 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 4, + "character": 7 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 47, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 47, + "result": { + "range": { + "start": { + "line": 3, + "character": 8 + }, + "end": { + "line": 3, + "character": 9 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 8, + "character": 31 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 831, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 831, + "result": { + "range": { + "start": { + "line": 7, + "character": 6 + }, + "end": { + "line": 7, + "character": 7 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 9, + "character": 16 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 916, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 916, + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 18 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 9, + "character": 26 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 926, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 926, + "result": { + "range": { + "start": { + "line": 6, + "character": 11 + }, + "end": { + "line": 6, + "character": 19 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 9, + "character": 34 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 934, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 934, + "result": { + "range": { + "start": { + "line": 8, + "character": 10 + }, + "end": { + "line": 8, + "character": 18 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 10, + "character": 16 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1016, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1016, + "result": { + "range": { + "start": { + "line": 6, + "character": 11 + }, + "end": { + "line": 6, + "character": 19 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 10, + "character": 22 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1022, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1022, + "result": { + "range": { + "start": { + "line": 8, + "character": 10 + }, + "end": { + "line": 8, + "character": 18 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 11, + "character": 21 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1121, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1121, + "result": { + "range": { + "start": { + "line": 7, + "character": 6 + }, + "end": { + "line": 7, + "character": 7 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 12, + "character": 20 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1220, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1220, + "result": { + "range": { + "start": { + "line": 1, + "character": 8 + }, + "end": { + "line": 1, + "character": 9 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 12, + "character": 34 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1234, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1234, + "result": { + "range": { + "start": { + "line": 2, + "character": 3 + }, + "end": { + "line": 2, + "character": 4 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 12, + "character": 13 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1213, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1213, + "result": { + "range": { + "start": { + "line": 0, + "character": 17 + }, + "end": { + "line": 0, + "character": 25 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 13, + "character": 14 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1314, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1314, + "result": { + "range": { + "start": { + "line": 0, + "character": 17 + }, + "end": { + "line": 0, + "character": 25 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 13, + "character": 21 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1321, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1321, + "result": { + "range": { + "start": { + "line": 3, + "character": 7 + }, + "end": { + "line": 3, + "character": 15 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 14, + "character": 22 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1422, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1422, + "result": { + "range": { + "start": { + "line": 4, + "character": 11 + }, + "end": { + "line": 4, + "character": 19 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 14, + "character": 34 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1434, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1434, + "result": { + "range": { + "start": { + "line": 6, + "character": 10 + }, + "end": { + "line": 6, + "character": 18 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 15, + "character": 27 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1527, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1527, + "result": { + "range": { + "start": { + "line": 4, + "character": 11 + }, + "end": { + "line": 4, + "character": 19 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 15, + "character": 30 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1530, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1530, + "result": { + "range": { + "start": { + "line": 5, + "character": 6 + }, + "end": { + "line": 5, + "character": 7 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 17, + "character": 38 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1738, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1738, + "result": { + "range": { + "start": { + "line": 8, + "character": 11 + }, + "end": { + "line": 8, + "character": 18 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 18, + "character": 38 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 1838, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 1838, + "result": { + "range": { + "start": { + "line": 10, + "character": 11 + }, + "end": { + "line": 10, + "character": 17 + } + }, + "uri": "$URI{imported.gpr}" + } + } + ] + } + }, + { + "send": { + "request": { + "params": { + "position": { + "line": 20, + "character": 9 + }, + "textDocument": { + "uri": "$URI{navigation.gpr}" + } + }, + "jsonrpc": "2.0", + "id": 209, + "method": "textDocument/declaration" + }, + "wait": [ + { + "id": 209, + "result": { + "range": { + "start": { + "line": 4, + "character": 3 + }, + "end": { + "line": 4, + "character": 4 + } + }, + "uri": "$URI{navigation.gpr}" + } + } + ] + } + }, + { + "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/declaration/test.yaml b/testsuite/gpr_lsp/declaration/test.yaml new file mode 100644 index 000000000..6a34525c2 --- /dev/null +++ b/testsuite/gpr_lsp/declaration/test.yaml @@ -0,0 +1,3 @@ +title: 'textDocument/declaration request' +skip: + - ['SKIP', 'env.build.os.name not in ("linux","windows")']