From e0845163a95c7d495f14f092f2251a67e3f85a58 Mon Sep 17 00:00:00 2001 From: Mateo Date: Mon, 12 Aug 2024 14:58:48 +0200 Subject: [PATCH 1/8] feat: support for textDocument/rename --- src/lsp/cobol_lsp/lsp_capabilities.ml | 4 +- src/lsp/cobol_lsp/lsp_imports.ml | 8 +- src/lsp/cobol_lsp/lsp_request.ml | 40 +++++- src/lsp/cobol_lsp/lsp_request.mli | 4 + src/lsp/cobol_lsp/lsp_server.ml | 3 + src/lsp/cobol_lsp/lsp_server.mli | 1 + test/lsp/lsp_rename.ml | 191 ++++++++++++++++++++++++++ 7 files changed, 245 insertions(+), 6 deletions(-) create mode 100644 test/lsp/lsp_rename.ml diff --git a/src/lsp/cobol_lsp/lsp_capabilities.ml b/src/lsp/cobol_lsp/lsp_capabilities.ml index 933d8ebf9..2e851f2ba 100644 --- a/src/lsp/cobol_lsp/lsp_capabilities.ml +++ b/src/lsp/cobol_lsp/lsp_capabilities.ml @@ -46,8 +46,7 @@ let reply (_: ClientCapabilities.t) = in ServerCapabilities.create_workspace () ~workspaceFolders - in - let codeLensProvider = CodeLensOptions.create () in + and codeLensProvider = CodeLensOptions.create () in ServerCapabilities.create () ~textDocumentSync:(`TextDocumentSyncOptions sync) ~definitionProvider:(`Bool true) @@ -61,3 +60,4 @@ let reply (_: ClientCapabilities.t) = ~workspace ~documentSymbolProvider:(`Bool true) ~codeLensProvider + ~renameProvider:(`Bool true) diff --git a/src/lsp/cobol_lsp/lsp_imports.ml b/src/lsp/cobol_lsp/lsp_imports.ml index 591b4fe27..1eea715c9 100644 --- a/src/lsp/cobol_lsp/lsp_imports.ml +++ b/src/lsp/cobol_lsp/lsp_imports.ml @@ -15,4 +15,10 @@ module CUs = Cobol_unit.Collections.SET module CUMap = Cobol_unit.Collections.MAP -module URIMap = Map.Make (Lsp.Uri) +module URIMap = struct + include Map.Make (Lsp.Uri) + + let add_to_list x data m = + let add = function None -> Some [data] | Some l -> Some (data :: l) in + update x add m +end diff --git a/src/lsp/cobol_lsp/lsp_request.ml b/src/lsp/cobol_lsp/lsp_request.ml index 8875feb81..5e2b8b268 100644 --- a/src/lsp/cobol_lsp/lsp_request.ml +++ b/src/lsp/cobol_lsp/lsp_request.ml @@ -605,7 +605,7 @@ let handle_folding_range registry (params: FoldingRangeParams.t) = let handle_document_symbol registry (params: DocumentSymbolParams.t) = try_with_main_document_data registry params.textDocument - ~f:begin fun ~doc { ptree; _ }-> + ~f:begin fun ~doc { ptree; _ } -> let uri = Lsp.Text_document.documentUri doc.textdoc in let symbols = Lsp_document_symbol.from_ptree_at ~uri ptree in Some (`DocumentSymbol symbols) @@ -702,6 +702,35 @@ let handle_codelens registry ({ textDocument; _ }: CodeLensParams.t) = end |> Option.value ~default:[] +(** { Rename } *) + +exception CopybookRenameError + +let handle_rename registry (params: RenameParams.t) = + let { textDocument; position; newName = newText; _ }: RenameParams.t = params in + let doc = Lsp_server.find_document params.textDocument registry in + let checked_doc = Lsp_document.checked doc in + let rootdir = Lsp_project.(string_of_rootdir @@ rootdir doc.project) in + let locations = Option.value ~default:[] @@ + let context = ReferenceContext.create ~includeDeclaration:true in + let params = ReferenceParams.create + ~context ~position ~textDocument () in + lookup_references_in_doc ~rootdir params checked_doc in + try + let changes = List.fold_left begin fun acc ({ range; uri }: Location.t) -> + if DocumentUri.compare uri params.textDocument.uri <> 0 + then raise CopybookRenameError + else + let textEdit = TextEdit.create ~newText ~range in + URIMap.add_to_list uri textEdit acc + end URIMap.empty locations + |> URIMap.to_seq + |> List.of_seq + in + Ok(WorkspaceEdit.create ~changes ()) + with CopybookRenameError -> + Error "Reference of variable found in copybook, aborting rename" + (** {3 Generic handling} *) let shutdown: state -> unit = function @@ -747,17 +776,21 @@ let on_request Ok (handle_folding_range registry params, state) | Shutdown -> Ok (handle_shutdown registry, ShuttingDown) - | DocumentSymbol (* DocumentSymbolParams.t.t *) params -> + | DocumentSymbol params -> Ok (handle_document_symbol registry params, state) | TextDocumentCodeLens (* CodeLensParams.t.t *) params -> Ok (handle_codelens registry params, state) + | TextDocumentRename params -> + begin match handle_rename registry params with + | Ok workspaceEdit -> Ok (workspaceEdit, state) + | Error _ -> Error (CopybookRenamingForbidden) + end | TextDocumentDeclaration (* TextDocumentPositionParams.t.t *) _ | TextDocumentTypeDefinition (* TypeDefinitionParams.t.t *) _ | TextDocumentImplementation (* ImplementationParams.t.t *) _ | TextDocumentCodeLensResolve (* CodeLens.t.t *) _ | TextDocumentPrepareCallHierarchy (* CallHierarchyPrepareParams.t.t *) _ | TextDocumentPrepareRename (* PrepareRenameParams.t.t *) _ - | TextDocumentRename (* RenameParams.t.t *) _ | TextDocumentLink (* DocumentLinkParams.t.t *) _ | TextDocumentLinkResolve (* DocumentLink.t.t *) _ | TextDocumentMoniker (* MonikerParams.t.t *) _ @@ -825,4 +858,5 @@ module INTERNAL = struct let codelens = handle_codelens let document_symbol = handle_document_symbol let formatting = handle_formatting + let rename = handle_rename end diff --git a/src/lsp/cobol_lsp/lsp_request.mli b/src/lsp/cobol_lsp/lsp_request.mli index 026acb858..665cb2104 100644 --- a/src/lsp/cobol_lsp/lsp_request.mli +++ b/src/lsp/cobol_lsp/lsp_request.mli @@ -45,4 +45,8 @@ module INTERNAL: sig : Lsp_server.t -> Lsp.Types.CodeLensParams.t -> Lsp.Types.CodeLens.t list + val rename + : Lsp_server.t + -> Lsp.Types.RenameParams.t + -> (Lsp.Types.WorkspaceEdit.t, string) result end diff --git a/src/lsp/cobol_lsp/lsp_server.ml b/src/lsp/cobol_lsp/lsp_server.ml index c502397e5..19bcc9afc 100644 --- a/src/lsp/cobol_lsp/lsp_server.ml +++ b/src/lsp/cobol_lsp/lsp_server.ml @@ -82,6 +82,7 @@ module TYPES = struct and exit_status = (unit, string) result type 'a error = + | CopybookRenamingForbidden | InvalidStatus of state | UnhandledRequest of 'a Lsp.Client_request.t | UnknownRequest of string @@ -735,5 +736,7 @@ let jsonrpc_of_error error method_ = RequestFailed, Fmt.str "Unhandled request: %s" method_ | UnknownRequest method_ -> MethodNotFound, Fmt.str "Unknown request method: %s" method_ + | CopybookRenamingForbidden -> + RequestFailed, Fmt.str "Cancelled rename of variable contained in a copybook" in Jsonrpc.Response.Error.make ~code ~message () diff --git a/src/lsp/cobol_lsp/lsp_server.mli b/src/lsp/cobol_lsp/lsp_server.mli index 2251c8c37..1a827817d 100644 --- a/src/lsp/cobol_lsp/lsp_server.mli +++ b/src/lsp/cobol_lsp/lsp_server.mli @@ -53,6 +53,7 @@ module TYPES: sig and exit_status = (unit, string) result type 'a error = + | CopybookRenamingForbidden | InvalidStatus of state | UnhandledRequest of 'a Lsp.Client_request.t | UnknownRequest of string diff --git a/test/lsp/lsp_rename.ml b/test/lsp/lsp_rename.ml new file mode 100644 index 000000000..1b0715cb9 --- /dev/null +++ b/test/lsp/lsp_rename.ml @@ -0,0 +1,191 @@ +(**************************************************************************) +(* *) +(* SuperBOL OSS Studio *) +(* *) +(* Copyright (c) 2022-2023 OCamlPro SAS *) +(* *) +(* All rights reserved. *) +(* This source code is licensed under the GNU Affero General Public *) +(* License version 3 found in the LICENSE.md file in the root directory *) +(* of this source tree. *) +(* *) +(**************************************************************************) + +open EzCompat (* StringMap *) +open Lsp.Types +open Lsp_testing + +let pp_assoc_elem ppf ((uri, edits): DocumentUri.t * TextEdit.t list) = + let pp_range ppf range = + let location_as_srcloc = new srcloc_resuscitator_cache in + location_as_srcloc#pp ppf @@ Location.create ~range ~uri + in + let pp_edit ppf (edit: TextEdit.t) = + Fmt.pf ppf "%s at " edit.newText; + pp_range ppf edit.range + in + Fmt.(list pp_edit) ppf edits + +let count l = + List.fold_left begin fun acc (_, t) -> acc + List.length t end 0 l + +let rename_positions ?(copybooks=[]) (doc, positions) : string -> unit = + let { end_with_postproc; projdir }, server = make_lsp_project () in + let server = List.fold_left begin fun server (name, document) -> + add_cobol_doc server ~projdir name document + |> fst + end server copybooks in + let server, prog = add_cobol_doc server ~projdir "prog.cob" doc in + let rename_at_position ?key (position: Position.t) = + let params = RenameParams.create ~newName:"aNewName" ~position ~textDocument:prog () in + Pretty.out "%a(line %d, character %d):\n" + Fmt.(option ~none:nop (string ++ sp)) key + position.line position.character; + begin + try + match LSP.Request.rename server params with + | Error e -> + Pretty.out "Renamed failed: %S@." e + | Ok { changes = None; _ } -> + Pretty.out "No renames@." + | Ok { changes = Some assoc; _ } -> + Pretty.out "@.@[%d rename entries:@;%a@]@\n" + (count assoc) + (Fmt.list ~sep:Fmt.sp pp_assoc_elem) assoc + with _ -> Pretty.out "Failed rename@." + end + in + StringMap.iter (fun n p -> rename_at_position ~key:n p) positions.pos_map; + List.iter (fun p -> rename_at_position p) positions.pos_anonymous; + end_with_postproc + +let%expect_test "rename" = + let end_with_postproc = rename_positions @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 o_|_ld-name PIC 9. + PROCEDURE DIVISION. + MOVE 1 TO old-na_|_me. + S_|_TOP RUN. + |cobol} + in + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + (line 5, character 12): + 2 rename entries: + aNewName at __rootdir__/prog.cob:8.20-8.28: + 5 WORKING-STORAGE SECTION. + 6 01 old-name PIC 9. + 7 PROCEDURE DIVISION. + 8 > MOVE 1 TO old-name. + ---- ^^^^^^^^ + 9 STOP RUN. + 10 + aNewName at __rootdir__/prog.cob:6.11-6.19: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 old-name PIC 9. + ---- ^^^^^^^^ + 7 PROCEDURE DIVISION. + 8 MOVE 1 TO old-name. + (line 7, character 26): + 2 rename entries: + aNewName at __rootdir__/prog.cob:8.20-8.28: + 5 WORKING-STORAGE SECTION. + 6 01 old-name PIC 9. + 7 PROCEDURE DIVISION. + 8 > MOVE 1 TO old-name. + ---- ^^^^^^^^ + 9 STOP RUN. + 10 + aNewName at __rootdir__/prog.cob:6.11-6.19: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 old-name PIC 9. + ---- ^^^^^^^^ + 7 PROCEDURE DIVISION. + 8 MOVE 1 TO old-name. + (line 8, character 11): + 0 rename entries: |}] + +let%expect_test "rename-copybook" = + let copybooks = [ + ("lib.cpy", {cobol| + 01 copied-var pic 9.|cobol}) + ] in + let end_with_postproc = rename_positions ~copybooks @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + COPY "lib.cpy". + PROCEDURE DIVISION. + MOVE 1 TO c_|_opied-var. + STOP RUN. + |cobol} + in + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/lib.cpy"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + (line 7, character 21): + Renamed failed: "Reference of variable found in copybook, aborting rename" |}] + +let%expect_test "rename-procedure" = + let end_with_postproc = rename_positions @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + PROCEDURE DIVISION. + s_|newSectionName|_ec SECTION. + PERFORM sec. + GO par_|_a. + para. + STOP RUN. + |cobol} + in + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + newSectionName + (line 4, character 11): + 2 rename entries: + aNewName at __rootdir__/prog.cob:6.18-6.21: + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 sec SECTION. + 6 > PERFORM sec. + ---- ^^^ + 7 GO para. + 8 para. + aNewName at __rootdir__/prog.cob:5.10-5.13: + 2 IDENTIFICATION DIVISION. + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 > sec SECTION. + ---- ^^^ + 6 PERFORM sec. + 7 GO para. + (line 6, character 16): + 2 rename entries: + aNewName at __rootdir__/prog.cob:7.13-7.17: + 4 PROCEDURE DIVISION. + 5 sec SECTION. + 6 PERFORM sec. + 7 > GO para. + ---- ^^^^ + 8 para. + 9 STOP RUN. + aNewName at __rootdir__/prog.cob:8.10-8.14: + 5 sec SECTION. + 6 PERFORM sec. + 7 GO para. + 8 > para. + ---- ^^^^ + 9 STOP RUN. + 10 |}] + From 9ed26f5d0e05c7582aa0e57c73da94c4e10c841f Mon Sep 17 00:00:00 2001 From: Mateo Date: Tue, 13 Aug 2024 12:39:47 +0200 Subject: [PATCH 2/8] refactor: used Lsp_io.notify_error to display error --- src/lsp/cobol_lsp/lsp_request.ml | 56 ++++++++++++++----------------- src/lsp/cobol_lsp/lsp_request.mli | 2 +- src/lsp/cobol_lsp/lsp_server.ml | 3 -- src/lsp/cobol_lsp/lsp_server.mli | 1 - test/lsp/lsp_rename.ml | 11 +++--- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/lsp/cobol_lsp/lsp_request.ml b/src/lsp/cobol_lsp/lsp_request.ml index 5e2b8b268..2ce1e733f 100644 --- a/src/lsp/cobol_lsp/lsp_request.ml +++ b/src/lsp/cobol_lsp/lsp_request.ml @@ -704,32 +704,31 @@ let handle_codelens registry ({ textDocument; _ }: CodeLensParams.t) = (** { Rename } *) -exception CopybookRenameError - -let handle_rename registry (params: RenameParams.t) = - let { textDocument; position; newName = newText; _ }: RenameParams.t = params in - let doc = Lsp_server.find_document params.textDocument registry in - let checked_doc = Lsp_document.checked doc in - let rootdir = Lsp_project.(string_of_rootdir @@ rootdir doc.project) in - let locations = Option.value ~default:[] @@ - let context = ReferenceContext.create ~includeDeclaration:true in - let params = ReferenceParams.create - ~context ~position ~textDocument () in - lookup_references_in_doc ~rootdir params checked_doc in - try - let changes = List.fold_left begin fun acc ({ range; uri }: Location.t) -> - if DocumentUri.compare uri params.textDocument.uri <> 0 - then raise CopybookRenameError - else - let textEdit = TextEdit.create ~newText ~range in - URIMap.add_to_list uri textEdit acc - end URIMap.empty locations - |> URIMap.to_seq - |> List.of_seq - in - Ok(WorkspaceEdit.create ~changes ()) - with CopybookRenameError -> - Error "Reference of variable found in copybook, aborting rename" +let handle_rename + registry + ({ textDocument; position; newName = newText; _ }: RenameParams.t) = + try_with_main_document_data registry textDocument + ~f:begin fun ~doc checked_doc -> + let rootdir = Lsp_project.(string_of_rootdir @@ rootdir doc.project) in + let locations = Option.value ~default:[] @@ + let context = ReferenceContext.create ~includeDeclaration:true in + let params = ReferenceParams.create + ~context ~position ~textDocument () in + lookup_references_in_doc ~rootdir params checked_doc in + try + let changes = List.fold_left begin fun acc ({ range; uri }: Location.t) -> + if DocumentUri.compare uri textDocument.uri <> 0 + then raise Exit; + URIMap.add_to_list uri (TextEdit.create ~newText ~range) acc + end URIMap.empty locations |> URIMap.to_seq |> List.of_seq + in + Some ( WorkspaceEdit.create ~changes () ) + with Exit -> + Lsp_io.notify_error "Ignored renaming of a reference that occurs in a copybook"; + Some ( WorkspaceEdit.create () ) + end + |> Option.get + (** {3 Generic handling} *) @@ -781,10 +780,7 @@ let on_request | TextDocumentCodeLens (* CodeLensParams.t.t *) params -> Ok (handle_codelens registry params, state) | TextDocumentRename params -> - begin match handle_rename registry params with - | Ok workspaceEdit -> Ok (workspaceEdit, state) - | Error _ -> Error (CopybookRenamingForbidden) - end + Ok (handle_rename registry params, state) | TextDocumentDeclaration (* TextDocumentPositionParams.t.t *) _ | TextDocumentTypeDefinition (* TypeDefinitionParams.t.t *) _ | TextDocumentImplementation (* ImplementationParams.t.t *) _ diff --git a/src/lsp/cobol_lsp/lsp_request.mli b/src/lsp/cobol_lsp/lsp_request.mli index 665cb2104..3731e6a6c 100644 --- a/src/lsp/cobol_lsp/lsp_request.mli +++ b/src/lsp/cobol_lsp/lsp_request.mli @@ -48,5 +48,5 @@ module INTERNAL: sig val rename : Lsp_server.t -> Lsp.Types.RenameParams.t - -> (Lsp.Types.WorkspaceEdit.t, string) result + -> Lsp.Types.WorkspaceEdit.t end diff --git a/src/lsp/cobol_lsp/lsp_server.ml b/src/lsp/cobol_lsp/lsp_server.ml index 19bcc9afc..c502397e5 100644 --- a/src/lsp/cobol_lsp/lsp_server.ml +++ b/src/lsp/cobol_lsp/lsp_server.ml @@ -82,7 +82,6 @@ module TYPES = struct and exit_status = (unit, string) result type 'a error = - | CopybookRenamingForbidden | InvalidStatus of state | UnhandledRequest of 'a Lsp.Client_request.t | UnknownRequest of string @@ -736,7 +735,5 @@ let jsonrpc_of_error error method_ = RequestFailed, Fmt.str "Unhandled request: %s" method_ | UnknownRequest method_ -> MethodNotFound, Fmt.str "Unknown request method: %s" method_ - | CopybookRenamingForbidden -> - RequestFailed, Fmt.str "Cancelled rename of variable contained in a copybook" in Jsonrpc.Response.Error.make ~code ~message () diff --git a/src/lsp/cobol_lsp/lsp_server.mli b/src/lsp/cobol_lsp/lsp_server.mli index 1a827817d..2251c8c37 100644 --- a/src/lsp/cobol_lsp/lsp_server.mli +++ b/src/lsp/cobol_lsp/lsp_server.mli @@ -53,7 +53,6 @@ module TYPES: sig and exit_status = (unit, string) result type 'a error = - | CopybookRenamingForbidden | InvalidStatus of state | UnhandledRequest of 'a Lsp.Client_request.t | UnknownRequest of string diff --git a/test/lsp/lsp_rename.ml b/test/lsp/lsp_rename.ml index 1b0715cb9..0927e998e 100644 --- a/test/lsp/lsp_rename.ml +++ b/test/lsp/lsp_rename.ml @@ -44,11 +44,9 @@ let rename_positions ?(copybooks=[]) (doc, positions) : string -> unit = begin try match LSP.Request.rename server params with - | Error e -> - Pretty.out "Renamed failed: %S@." e - | Ok { changes = None; _ } -> + | { changes = None; _ } -> Pretty.out "No renames@." - | Ok { changes = Some assoc; _ } -> + | { changes = Some assoc; _ } -> Pretty.out "@.@[%d rename entries:@;%a@]@\n" (count assoc) (Fmt.list ~sep:Fmt.sp pp_assoc_elem) assoc @@ -113,7 +111,7 @@ let%expect_test "rename" = (line 8, character 11): 0 rename entries: |}] -let%expect_test "rename-copybook" = +let%expect_test "rename-with-a-ref-in-a-copybook" = let copybooks = [ ("lib.cpy", {cobol| 01 copied-var pic 9.|cobol}) @@ -133,8 +131,9 @@ let%expect_test "rename-copybook" = [%expect {| {"params":{"diagnostics":[],"uri":"file://__rootdir__/lib.cpy"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + {"params":{"message":"Ignored renaming of a reference that occurs in a copybook","type":1},"method":"window/showMessage","jsonrpc":"2.0"} (line 7, character 21): - Renamed failed: "Reference of variable found in copybook, aborting rename" |}] + No renames |}] let%expect_test "rename-procedure" = let end_with_postproc = rename_positions @@ extract_position_markers {cobol| From f7248c7144cba5bcced36fedda950d2f97c4c7b3 Mon Sep 17 00:00:00 2001 From: Mateo Date: Tue, 13 Aug 2024 14:58:16 +0200 Subject: [PATCH 3/8] feat: allow rename in copybook with option to invert --- src/lsp/cobol_lsp/lsp_request.ml | 28 +++++++++++--------- src/lsp/cobol_lsp/lsp_request.mli | 3 ++- test/lsp/lsp_rename.ml | 43 ++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/lsp/cobol_lsp/lsp_request.ml b/src/lsp/cobol_lsp/lsp_request.ml index 2ce1e733f..05ff4c06b 100644 --- a/src/lsp/cobol_lsp/lsp_request.ml +++ b/src/lsp/cobol_lsp/lsp_request.ml @@ -704,7 +704,7 @@ let handle_codelens registry ({ textDocument; _ }: CodeLensParams.t) = (** { Rename } *) -let handle_rename +let handle_rename ?(ignore_when_copybook=false) registry ({ textDocument; position; newName = newText; _ }: RenameParams.t) = try_with_main_document_data registry textDocument @@ -715,17 +715,21 @@ let handle_rename let params = ReferenceParams.create ~context ~position ~textDocument () in lookup_references_in_doc ~rootdir params checked_doc in - try - let changes = List.fold_left begin fun acc ({ range; uri }: Location.t) -> - if DocumentUri.compare uri textDocument.uri <> 0 - then raise Exit; - URIMap.add_to_list uri (TextEdit.create ~newText ~range) acc - end URIMap.empty locations |> URIMap.to_seq |> List.of_seq - in - Some ( WorkspaceEdit.create ~changes () ) - with Exit -> - Lsp_io.notify_error "Ignored renaming of a reference that occurs in a copybook"; - Some ( WorkspaceEdit.create () ) + let changes, is_copybook = + List.fold_left begin fun (map, is_copybook) ({ range; uri }: Location.t) -> + URIMap.add_to_list uri (TextEdit.create ~newText ~range) map, + is_copybook || DocumentUri.compare uri textDocument.uri <> 0 + end (URIMap.empty, false) locations in + let changes = List.of_seq @@ URIMap.to_seq changes in + if is_copybook && ignore_when_copybook + then begin Lsp_io.notify_info + "Ignored renaming of a reference that occurs in a copybook"; + Some ( WorkspaceEdit.create () ) end + else + begin if is_copybook + then Lsp_io.notify_warn + "Proceeded to rename of a reference that occurs in a copybook"; + Some ( WorkspaceEdit.create ~changes () ) end end |> Option.get diff --git a/src/lsp/cobol_lsp/lsp_request.mli b/src/lsp/cobol_lsp/lsp_request.mli index 3731e6a6c..592cdef4a 100644 --- a/src/lsp/cobol_lsp/lsp_request.mli +++ b/src/lsp/cobol_lsp/lsp_request.mli @@ -46,7 +46,8 @@ module INTERNAL: sig -> Lsp.Types.CodeLensParams.t -> Lsp.Types.CodeLens.t list val rename - : Lsp_server.t + : ?ignore_when_copybook:bool + -> Lsp_server.t -> Lsp.Types.RenameParams.t -> Lsp.Types.WorkspaceEdit.t end diff --git a/test/lsp/lsp_rename.ml b/test/lsp/lsp_rename.ml index 0927e998e..cf5764f10 100644 --- a/test/lsp/lsp_rename.ml +++ b/test/lsp/lsp_rename.ml @@ -29,7 +29,7 @@ let pp_assoc_elem ppf ((uri, edits): DocumentUri.t * TextEdit.t list) = let count l = List.fold_left begin fun acc (_, t) -> acc + List.length t end 0 l -let rename_positions ?(copybooks=[]) (doc, positions) : string -> unit = +let rename_positions ?(ignore_when_copybook=false) ?(copybooks=[]) (doc, positions) : string -> unit = let { end_with_postproc; projdir }, server = make_lsp_project () in let server = List.fold_left begin fun server (name, document) -> add_cobol_doc server ~projdir name document @@ -43,7 +43,7 @@ let rename_positions ?(copybooks=[]) (doc, positions) : string -> unit = position.line position.character; begin try - match LSP.Request.rename server params with + match LSP.Request.rename ~ignore_when_copybook server params with | { changes = None; _ } -> Pretty.out "No renames@." | { changes = Some assoc; _ } -> @@ -131,7 +131,44 @@ let%expect_test "rename-with-a-ref-in-a-copybook" = [%expect {| {"params":{"diagnostics":[],"uri":"file://__rootdir__/lib.cpy"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} - {"params":{"message":"Ignored renaming of a reference that occurs in a copybook","type":1},"method":"window/showMessage","jsonrpc":"2.0"} + {"params":{"message":"Proceeded to rename of a reference that occurs in a copybook","type":2},"method":"window/showMessage","jsonrpc":"2.0"} + (line 7, character 21): + 2 rename entries: + aNewName at __rootdir__/lib.cpy:2.11-2.21: + 1 + 2 > 01 copied-var pic 9. + ---- ^^^^^^^^^^ + aNewName at __rootdir__/prog.cob:8.20-8.30: + 5 WORKING-STORAGE SECTION. + 6 COPY "lib.cpy". + 7 PROCEDURE DIVISION. + 8 > MOVE 1 TO copied-var. + ---- ^^^^^^^^^^ + 9 STOP RUN. + 10 |}] + +let%expect_test "rename-with-a-ignored-ref-in-a-copybook" = + let copybooks = [ + ("lib.cpy", {cobol| + 01 copied-var pic 9.|cobol}) + ] in + let end_with_postproc = rename_positions ~ignore_when_copybook:true ~copybooks + @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + COPY "lib.cpy". + PROCEDURE DIVISION. + MOVE 1 TO c_|_opied-var. + STOP RUN. + |cobol} + in + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/lib.cpy"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + {"params":{"message":"Ignored renaming of a reference that occurs in a copybook","type":3},"method":"window/showMessage","jsonrpc":"2.0"} (line 7, character 21): No renames |}] From 1d1d2559b755526249f2c3538043d7fb78ef46ac Mon Sep 17 00:00:00 2001 From: Mateo Date: Tue, 13 Aug 2024 16:47:51 +0200 Subject: [PATCH 4/8] feat: added qualificators to data and proc refs this fixes rename on parent field --- src/lsp/cobol_typeck/typeck_outputs.ml | 6 + src/lsp/cobol_typeck/typeck_procedure.ml | 25 ++- test/lsp/lsp_codelens.ml | 11 +- test/lsp/lsp_definition.ml | 4 +- test/lsp/lsp_references.ml | 170 +++++++++++++++++++ test/lsp/lsp_rename.ml | 207 ++++++++++++++++++----- 6 files changed, 367 insertions(+), 56 deletions(-) diff --git a/src/lsp/cobol_typeck/typeck_outputs.ml b/src/lsp/cobol_typeck/typeck_outputs.ml index ef55f7b85..c26adcf94 100644 --- a/src/lsp/cobol_typeck/typeck_outputs.ml +++ b/src/lsp/cobol_typeck/typeck_outputs.ml @@ -20,6 +20,12 @@ type references_in_unit = data_refs: qualrefmap; proc_refs: qualrefmap; (* TODO: const_refs, prog_refs?, others... *) + (* TODO atm data_refs and proc_refs contains BOTH direct references and indirect references + e.g.: DISPLAY B IN A result in + - a direct reference to B + - a indirect reference to A + In the future we may need/want to split those 2 kind of references + *) } type references_in_group = references_in_unit Cobol_unit.Collections.MAP.t diff --git a/src/lsp/cobol_typeck/typeck_procedure.ml b/src/lsp/cobol_typeck/typeck_procedure.ml index fac082df8..7aeaeb0b9 100644 --- a/src/lsp/cobol_typeck/typeck_procedure.ml +++ b/src/lsp/cobol_typeck/typeck_procedure.ml @@ -187,7 +187,7 @@ let references ~(data_definitions: Cobol_unit.Types.data_definitions) procedure method! fold_qualname qn acc = (* TODO: data_name' instead *) let loc = baseloc_of_qualname qn in - Visitor.skip_children @@ + Visitor.do_children @@ (* match Qualmap.find qn data_definitions.data_items.named with *) (* | Data_field { def; _ } -> *) (* { acc with *) @@ -226,18 +226,27 @@ let references ~(data_definitions: Cobol_unit.Types.data_definitions) procedure Cobol_ptree.Proc_division_visitor.fold_paragraph' v paragraph acc - method! fold_procedure_name' ({ loc; _ } as qn) + method! fold_procedure_name' qn ({ current_section = in_section; _ } as acc) = - Visitor.skip_children @@ - match Cobol_unit.Procedure.find ~&qn ?in_section procedure with - | block -> + let register ?in_section qn acc = + let loc = baseloc_of_qualname ~&qn in + match Cobol_unit.Procedure.find ~&qn ?in_section procedure with + | block -> { acc with refs = Typeck_outputs.register_procedure_ref ~loc block acc.refs } - | exception Not_found -> + | exception Not_found -> error acc @@ Unknown_proc_name qn - | exception Qualmap.Ambiguous (lazy matching_qualnames) -> + | exception Qualmap.Ambiguous (lazy matching_qualnames) -> error acc @@ Ambiguous_proc_name { given_qualname = qn; - matching_qualnames } + matching_qualnames } in + register ?in_section qn acc + |> begin match ~&qn with + | Name _ -> Fun.id + | Qual (_, section_qn) -> + let loc = baseloc_of_qualname section_qn in + register (section_qn &@ loc) + end + |> Visitor.skip_children end in diff --git a/test/lsp/lsp_codelens.ml b/test/lsp/lsp_codelens.ml index ebf6c8656..7385c66b5 100644 --- a/test/lsp/lsp_codelens.ml +++ b/test/lsp/lsp_codelens.ml @@ -47,6 +47,7 @@ let%expect_test "codelens" = 88 YYcond value "a". PROCEDURE DIVISION. MOVE aa TO aA. + DISPLAY BB IN AA. STOP RUN. |cobol} in end_with_postproc [%expect.output]; @@ -60,7 +61,7 @@ let%expect_test "codelens" = ---- ^ 7 02 BB PIC X. 8 02 BBprime REDEFINES BB PIC 9. - 3 references + 4 references __rootdir__/prog.cob:7.13: 4 DATA DIVISION. 5 WORKING-STORAGE SECTION. @@ -69,7 +70,7 @@ let%expect_test "codelens" = ---- ^ 8 02 BBprime REDEFINES BB PIC 9. 9 02 CC PIC X. 02 DD PIC X. - 3 references + 4 references __rootdir__/prog.cob:8.13: 5 WORKING-STORAGE SECTION. 6 01 AA. @@ -154,7 +155,7 @@ let%expect_test "codelens-procedure" = CC. DD SECTION. PERFORM AA. - PERFORM BB. + PERFORM BB IN AA. GO DD. STOP RUN. |cobol} in @@ -169,7 +170,7 @@ let%expect_test "codelens-procedure" = ---- ^ 6 BB. 7 PERFORM BB. - 2 references + 3 references __rootdir__/prog.cob:6.12: 3 PROGRAM-ID. prog. 4 PROCEDURE DIVISION. @@ -195,5 +196,5 @@ let%expect_test "codelens-procedure" = 9 > DD SECTION. ---- ^ 10 PERFORM AA. - 11 PERFORM BB. + 11 PERFORM BB IN AA. 2 references |}];; diff --git a/test/lsp/lsp_definition.ml b/test/lsp/lsp_definition.ml index 93fdb6163..23ebb7067 100644 --- a/test/lsp/lsp_definition.ml +++ b/test/lsp/lsp_definition.ml @@ -638,11 +638,11 @@ let%expect_test "definition-index" = SET _|3-i|_I IN V-TAB TO 0 SET _|4-j|_J IN w TO 0 SET _|5-k|_K IN W-TAB IN W TO 0 - SET _|6-missing|_L IN w-tab IN W TO 0 + SET _|6-missing|_L IN w-tab IN W TO 0. |cobol}; end_with_postproc [%expect.output]; [%expect {| - {"params":{"diagnostics":[{"message":"Missing .","range":{"end":{"character":35,"line":11},"start":{"character":35,"line":11}},"severity":4}],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} 1-j (line 4, character 41): __rootdir__/prog.cob:5.41-5.42: 2 PROGRAM-ID. prog. diff --git a/test/lsp/lsp_references.ml b/test/lsp/lsp_references.ml index e04c59a1f..0813ef5a8 100644 --- a/test/lsp/lsp_references.ml +++ b/test/lsp/lsp_references.ml @@ -302,3 +302,173 @@ let%expect_test "references-requests-filler" = ---- ^ 14 STOP RUN. 15 |}] + +let%expect_test "references-requests-group-var" = + let { end_with_postproc; projdir }, server = make_lsp_project () in + print_references ~projdir server @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 _|parent-in-def|_A. + 05 _|child-in-def|_B PIC 9. + PROCEDURE DIVISION. + DISPLAY _|parent-alone|_A. + DISPLAY _|child-alone|_B. + DISPLAY _|child-in-parent|_B IN _|parent-of-child|_A. + MOVE 1 TO X. + STOP RUN. + |cobol}; + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + child-alone (line 9, character 18): + __rootdir__/prog.cob:7.13-7.14: + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 01 A. + 7 > 05 B PIC 9. + ---- ^ + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + __rootdir__/prog.cob:10.18-10.19: + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 > DISPLAY B. + ---- ^ + 11 DISPLAY B IN A. + 12 MOVE 1 TO X. + __rootdir__/prog.cob:11.18-11.19: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. + child-in-def (line 6, character 13): + __rootdir__/prog.cob:7.13-7.14: + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 01 A. + 7 > 05 B PIC 9. + ---- ^ + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + __rootdir__/prog.cob:10.18-10.19: + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 > DISPLAY B. + ---- ^ + 11 DISPLAY B IN A. + 12 MOVE 1 TO X. + __rootdir__/prog.cob:11.18-11.19: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. + child-in-parent (line 10, character 18): + __rootdir__/prog.cob:7.13-7.14: + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 01 A. + 7 > 05 B PIC 9. + ---- ^ + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + __rootdir__/prog.cob:10.18-10.19: + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 > DISPLAY B. + ---- ^ + 11 DISPLAY B IN A. + 12 MOVE 1 TO X. + __rootdir__/prog.cob:11.18-11.19: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. + parent-alone (line 8, character 18): + __rootdir__/prog.cob:6.11-6.12: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 A. + ---- ^ + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + __rootdir__/prog.cob:9.18-9.19: + 6 01 A. + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 > DISPLAY A. + ---- ^ + 10 DISPLAY B. + 11 DISPLAY B IN A. + __rootdir__/prog.cob:11.23-11.24: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. + parent-in-def (line 5, character 11): + __rootdir__/prog.cob:6.11-6.12: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 A. + ---- ^ + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + __rootdir__/prog.cob:9.18-9.19: + 6 01 A. + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 > DISPLAY A. + ---- ^ + 10 DISPLAY B. + 11 DISPLAY B IN A. + __rootdir__/prog.cob:11.23-11.24: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. + parent-of-child (line 10, character 23): + __rootdir__/prog.cob:6.11-6.12: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 A. + ---- ^ + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + __rootdir__/prog.cob:9.18-9.19: + 6 01 A. + 7 05 B PIC 9. + 8 PROCEDURE DIVISION. + 9 > DISPLAY A. + ---- ^ + 10 DISPLAY B. + 11 DISPLAY B IN A. + __rootdir__/prog.cob:11.23-11.24: + 8 PROCEDURE DIVISION. + 9 DISPLAY A. + 10 DISPLAY B. + 11 > DISPLAY B IN A. + ---- ^ + 12 MOVE 1 TO X. + 13 STOP RUN. |}] diff --git a/test/lsp/lsp_rename.ml b/test/lsp/lsp_rename.ml index cf5764f10..568d80597 100644 --- a/test/lsp/lsp_rename.ml +++ b/test/lsp/lsp_rename.ml @@ -63,9 +63,9 @@ let%expect_test "rename" = PROGRAM-ID. prog. DATA DIVISION. WORKING-STORAGE SECTION. - 01 o_|_ld-name PIC 9. + 01 O_|_LD PIC 9. PROCEDURE DIVISION. - MOVE 1 TO old-na_|_me. + MOVE 1 TO old_|_. S_|_TOP RUN. |cobol} in @@ -74,43 +74,96 @@ let%expect_test "rename" = {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} (line 5, character 12): 2 rename entries: - aNewName at __rootdir__/prog.cob:8.20-8.28: + aNewName at __rootdir__/prog.cob:8.20-8.23: 5 WORKING-STORAGE SECTION. - 6 01 old-name PIC 9. + 6 01 OLD PIC 9. 7 PROCEDURE DIVISION. - 8 > MOVE 1 TO old-name. - ---- ^^^^^^^^ + 8 > MOVE 1 TO old. + ---- ^^^ 9 STOP RUN. 10 - aNewName at __rootdir__/prog.cob:6.11-6.19: + aNewName at __rootdir__/prog.cob:6.11-6.14: 3 PROGRAM-ID. prog. 4 DATA DIVISION. 5 WORKING-STORAGE SECTION. - 6 > 01 old-name PIC 9. - ---- ^^^^^^^^ + 6 > 01 OLD PIC 9. + ---- ^^^ 7 PROCEDURE DIVISION. - 8 MOVE 1 TO old-name. - (line 7, character 26): + 8 MOVE 1 TO old. + (line 7, character 23): 2 rename entries: - aNewName at __rootdir__/prog.cob:8.20-8.28: + aNewName at __rootdir__/prog.cob:8.20-8.23: 5 WORKING-STORAGE SECTION. - 6 01 old-name PIC 9. + 6 01 OLD PIC 9. 7 PROCEDURE DIVISION. - 8 > MOVE 1 TO old-name. - ---- ^^^^^^^^ + 8 > MOVE 1 TO old. + ---- ^^^ 9 STOP RUN. 10 - aNewName at __rootdir__/prog.cob:6.11-6.19: + aNewName at __rootdir__/prog.cob:6.11-6.14: 3 PROGRAM-ID. prog. 4 DATA DIVISION. 5 WORKING-STORAGE SECTION. - 6 > 01 old-name PIC 9. - ---- ^^^^^^^^ + 6 > 01 OLD PIC 9. + ---- ^^^ 7 PROCEDURE DIVISION. - 8 MOVE 1 TO old-name. + 8 MOVE 1 TO old. (line 8, character 11): 0 rename entries: |}] +let%expect_test "rename-group" = + let end_with_postproc = rename_positions @@ extract_position_markers {cobol| + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OLD. + 02 CHILD PIC 9. + PROCEDURE DIVISION. + DISPLAY _|_child in old_|_. + STOP RUN. + |cobol} + in + end_with_postproc [%expect.output]; + [%expect {| + {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} + (line 8, character 18): + 2 rename entries: + aNewName at __rootdir__/prog.cob:9.18-9.23: + 6 01 OLD. + 7 02 CHILD PIC 9. + 8 PROCEDURE DIVISION. + 9 > DISPLAY child in old. + ---- ^^^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:7.13-7.18: + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 01 OLD. + 7 > 02 CHILD PIC 9. + ---- ^^^^^ + 8 PROCEDURE DIVISION. + 9 DISPLAY child in old. + (line 8, character 30): + 2 rename entries: + aNewName at __rootdir__/prog.cob:9.27-9.30: + 6 01 OLD. + 7 02 CHILD PIC 9. + 8 PROCEDURE DIVISION. + 9 > DISPLAY child in old. + ---- ^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:6.11-6.14: + 3 PROGRAM-ID. prog. + 4 DATA DIVISION. + 5 WORKING-STORAGE SECTION. + 6 > 01 OLD. + ---- ^^^ + 7 02 CHILD PIC 9. + 8 PROCEDURE DIVISION. |}] + let%expect_test "rename-with-a-ref-in-a-copybook" = let copybooks = [ ("lib.cpy", {cobol| @@ -177,51 +230,123 @@ let%expect_test "rename-procedure" = IDENTIFICATION DIVISION. PROGRAM-ID. prog. PROCEDURE DIVISION. - s_|newSectionName|_ec SECTION. + s_|sec-simple|_ec SECTION. PERFORM sec. - GO par_|_a. + GO par_|para-simple|_a. para. + PERFORM _|para-in-sec|_PARA IN _|sec-of-para|_SEC STOP RUN. |cobol} in end_with_postproc [%expect.output]; [%expect {| {"params":{"diagnostics":[],"uri":"file://__rootdir__/prog.cob"},"method":"textDocument/publishDiagnostics","jsonrpc":"2.0"} - newSectionName - (line 4, character 11): - 2 rename entries: - aNewName at __rootdir__/prog.cob:6.18-6.21: - 3 PROGRAM-ID. prog. - 4 PROCEDURE DIVISION. - 5 sec SECTION. - 6 > PERFORM sec. - ---- ^^^ + para-in-sec + (line 8, character 18): + 3 rename entries: + aNewName at __rootdir__/prog.cob:9.18-9.22: + 6 PERFORM sec. 7 GO para. 8 para. - aNewName at __rootdir__/prog.cob:5.10-5.13: - 2 IDENTIFICATION DIVISION. - 3 PROGRAM-ID. prog. + 9 > PERFORM PARA IN SEC + ---- ^^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:7.13-7.17: 4 PROCEDURE DIVISION. - 5 > sec SECTION. - ---- ^^^ + 5 sec SECTION. + 6 PERFORM sec. + 7 > GO para. + ---- ^^^^ + 8 para. + 9 PERFORM PARA IN SEC + aNewName at __rootdir__/prog.cob:8.10-8.14: + 5 sec SECTION. 6 PERFORM sec. 7 GO para. + 8 > para. + ---- ^^^^ + 9 PERFORM PARA IN SEC + 10 STOP RUN. + para-simple (line 6, character 16): - 2 rename entries: - aNewName at __rootdir__/prog.cob:7.13-7.17: - 4 PROCEDURE DIVISION. + 3 rename entries: + aNewName at __rootdir__/prog.cob:9.18-9.22: + 6 PERFORM sec. + 7 GO para. + 8 para. + 9 > PERFORM PARA IN SEC + ---- ^^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:7.13-7.17: + 4 PROCEDURE DIVISION. 5 sec SECTION. 6 PERFORM sec. 7 > GO para. ---- ^^^^ 8 para. - 9 STOP RUN. + 9 PERFORM PARA IN SEC aNewName at __rootdir__/prog.cob:8.10-8.14: 5 sec SECTION. 6 PERFORM sec. 7 GO para. 8 > para. ---- ^^^^ - 9 STOP RUN. - 10 |}] + 9 PERFORM PARA IN SEC + 10 STOP RUN. + sec-of-para + (line 8, character 26): + 3 rename entries: + aNewName at __rootdir__/prog.cob:9.26-9.29: + 6 PERFORM sec. + 7 GO para. + 8 para. + 9 > PERFORM PARA IN SEC + ---- ^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:6.18-6.21: + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 sec SECTION. + 6 > PERFORM sec. + ---- ^^^ + 7 GO para. + 8 para. + aNewName at __rootdir__/prog.cob:5.10-5.13: + 2 IDENTIFICATION DIVISION. + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 > sec SECTION. + ---- ^^^ + 6 PERFORM sec. + 7 GO para. + sec-simple + (line 4, character 11): + 3 rename entries: + aNewName at __rootdir__/prog.cob:9.26-9.29: + 6 PERFORM sec. + 7 GO para. + 8 para. + 9 > PERFORM PARA IN SEC + ---- ^^^ + 10 STOP RUN. + 11 + aNewName at __rootdir__/prog.cob:6.18-6.21: + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 sec SECTION. + 6 > PERFORM sec. + ---- ^^^ + 7 GO para. + 8 para. + aNewName at __rootdir__/prog.cob:5.10-5.13: + 2 IDENTIFICATION DIVISION. + 3 PROGRAM-ID. prog. + 4 PROCEDURE DIVISION. + 5 > sec SECTION. + ---- ^^^ + 6 PERFORM sec. + 7 GO para. |}] From 981c29a8a96a30e99c5fc7fc24aa50e968791523 Mon Sep 17 00:00:00 2001 From: Mateo Date: Tue, 13 Aug 2024 16:52:22 +0200 Subject: [PATCH 5/8] chore: update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa551ea57..5badd77ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [0.1.4] Next release ### Added +- Support for LSP request `textDocument/rename` [#351](https://github.com/OCamlPro/superbol-studio-oss/pull/351) - Show documentation comments on hover information [#350](https://github.com/OCamlPro/superbol-studio-oss/pull/350) - Completion for more grammar constructs [#322](https://github.com/OCamlPro/superbol-studio-oss/pull/322) - Support for LSP request `textDocument/codeLens` [#349](https://github.com/OCamlPro/superbol-studio-oss/pull/349) From 59866da441e1cb44f9ef54162f16555b85eab71d Mon Sep 17 00:00:00 2001 From: Mateo Date: Wed, 14 Aug 2024 09:43:15 +0200 Subject: [PATCH 6/8] refactor: fix style --- src/lsp/cobol_typeck/typeck_procedure.ml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lsp/cobol_typeck/typeck_procedure.ml b/src/lsp/cobol_typeck/typeck_procedure.ml index 7aeaeb0b9..e201afc6d 100644 --- a/src/lsp/cobol_typeck/typeck_procedure.ml +++ b/src/lsp/cobol_typeck/typeck_procedure.ml @@ -238,15 +238,16 @@ let references ~(data_definitions: Cobol_unit.Types.data_definitions) procedure error acc @@ Unknown_proc_name qn | exception Qualmap.Ambiguous (lazy matching_qualnames) -> error acc @@ Ambiguous_proc_name { given_qualname = qn; - matching_qualnames } in - register ?in_section qn acc - |> begin match ~&qn with - | Name _ -> Fun.id + matching_qualnames } + in + let acc = register ?in_section qn acc in + let acc = match ~&qn with + | Name _ -> acc | Qual (_, section_qn) -> let loc = baseloc_of_qualname section_qn in - register (section_qn &@ loc) - end - |> Visitor.skip_children + register (section_qn &@ loc) acc + in + Visitor.skip_children acc end in From f7daa15d083d1703c3cfbe24890b6925de4d8482 Mon Sep 17 00:00:00 2001 From: Mateo Date: Wed, 14 Aug 2024 13:31:10 +0200 Subject: [PATCH 7/8] refactor: remove unnecessary try with --- test/lsp/lsp_rename.ml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/test/lsp/lsp_rename.ml b/test/lsp/lsp_rename.ml index 568d80597..c7c147c0b 100644 --- a/test/lsp/lsp_rename.ml +++ b/test/lsp/lsp_rename.ml @@ -41,17 +41,13 @@ let rename_positions ?(ignore_when_copybook=false) ?(copybooks=[]) (doc, positio Pretty.out "%a(line %d, character %d):\n" Fmt.(option ~none:nop (string ++ sp)) key position.line position.character; - begin - try - match LSP.Request.rename ~ignore_when_copybook server params with - | { changes = None; _ } -> - Pretty.out "No renames@." - | { changes = Some assoc; _ } -> - Pretty.out "@.@[%d rename entries:@;%a@]@\n" - (count assoc) - (Fmt.list ~sep:Fmt.sp pp_assoc_elem) assoc - with _ -> Pretty.out "Failed rename@." - end + match LSP.Request.rename ~ignore_when_copybook server params with + | { changes = None; _ } -> + Pretty.out "No renames@." + | { changes = Some assoc; _ } -> + Pretty.out "@.@[%d rename entries:@;%a@]@\n" + (count assoc) + (Fmt.list ~sep:Fmt.sp pp_assoc_elem) assoc in StringMap.iter (fun n p -> rename_at_position ~key:n p) positions.pos_map; List.iter (fun p -> rename_at_position p) positions.pos_anonymous; From 433c69427340f4c5a22d40f5147caedbaf7997bf Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 14 Aug 2024 14:02:54 +0200 Subject: [PATCH 8/8] Making `CHANGELOG.md` more user-oriented --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5badd77ed..fff26196b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,10 @@ ## [0.1.4] Next release ### Added -- Support for LSP request `textDocument/rename` [#351](https://github.com/OCamlPro/superbol-studio-oss/pull/351) +- Support for Symbol Renaming command [#351](https://github.com/OCamlPro/superbol-studio-oss/pull/351) - Show documentation comments on hover information [#350](https://github.com/OCamlPro/superbol-studio-oss/pull/350) - Completion for more grammar constructs [#322](https://github.com/OCamlPro/superbol-studio-oss/pull/322) -- Support for LSP request `textDocument/codeLens` [#349](https://github.com/OCamlPro/superbol-studio-oss/pull/349) +- Support for CodeLens [#349](https://github.com/OCamlPro/superbol-studio-oss/pull/349) - Show display example of `NUMERIC-EDITED` data on hover [#337](https://github.com/OCamlPro/superbol-studio-oss/pull/337) - Support for dump and listing files, along with a task attribute for outputting the latter [#347](https://github.com/OCamlPro/superbol-studio-oss/pull/347) - Improved information shown on completion [#336](https://github.com/OCamlPro/superbol-studio-oss/pull/336)