Skip to content

Commit

Permalink
Merge pull request #377 from nberth/more-documentation
Browse files Browse the repository at this point in the history
Document latest features
  • Loading branch information
nberth authored Oct 25, 2024
2 parents 3139eb4 + 2d0ad6a commit f6d4830
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 51 deletions.
101 changes: 87 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ selected suggestion.
> (Temporary limitation)
>
> Suggestions of user-defined words may not comprise symbols that are
> defined in some sections of the data division.
> defined in the communication, report, or screen section of the data
> division. Although user-defined words that occur in [configured
> copybooks](#editing-an-existing-project) are also suggested,
> preprocessor-related variables or phrases are not.
## Navigation features

Expand Down Expand Up @@ -146,6 +149,13 @@ select  `Go to Definition` (or press <kbd>F12</kbd>).

![Go to Definition](./assets/superbol-goto-definition.gif)

> [!NOTE]
> (Temporary limitation)
>
> At the moment, definitions that belong to communication, report, or
> screen sections of the data division are ignored by the extension.
> They will be covered by the first stable release.
### Peek Definition

To only have a peek at where such a data item defined, you can
Expand All @@ -169,9 +179,25 @@ every reference to this item.
> [!NOTE]
> (Temporary limitation)
>
> At the moment, definitions that belong to *some* sections of the
> data division, and some references to data items, are ignored by the
> extension. They will be covered by the first stable release.
> In addition to limitations mentioned in [Go to
> Definition](#go-to-definition), references that occur in
> `EXEC`/`END-EXEC` blocks are also not taken into account yet.
### Reference Information

The extension shows inline reference information above definitons of
data items and elements of the procedure division.
The same limitations as for [Go to Definition](#go-to-definition)
apply.

![Reference Information](./assets/superbol-reference-information.png)

> [!TIP]
>
> This feature can be turned on or off by tuning the
> `"editor.codeLens"` configuration setting (you can type
> <kbd>Ctrl</kbd>+<kbd>,</kbd> and then `codelens` to change this
> setting).
### Hover to Show Copybooks

Expand All @@ -191,6 +217,50 @@ replacement by a `REPLACE` directive in the same way.

![Hover over replacement](./assets/superbol-hover-replacement.gif)

## Editing

### Rename Data Items, Sections, and Paragraphs

You can rename any data item by pressing <kbd>F2</kbd> while your
cursor is positioned on one of its references. The extension will
warn you if a reference to the renamed item appears in a copybook (in
which case the renaming of every reference is not performed).

![Rename Symbol](./assets/superbol-rename-symbol.gif)

![Rename Symbol in Copybook](./assets/superbol-rename-symbol-in-copybook.gif)

Sections and paragraphs of the procedure division can also be renamed
in the same way.
The same limitations as for [Go to References](#go-to-references)
apply to this feature.

## Exploring the Control-flow

Navigating a graphical representation of a COBOL program's
control-flow proves invaluable when it comes to decipher its overall
logic. To do this, open the command palette (or type
<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>), and select `SuperBOL:
Show Control-flow` (you can also right click and select `Show
Control-flow` in the menu). You are then presented with a list of
portions of program to consider (either the entire program, or
individiual sections): select one element to see the corresponding
CFG.

![CFG Explorer](./assets/superbol-cfg-explorer.gif)

Various settings are provided to tune the rendering of CFGs.

![CFG Explorer Collapse Fallthrough](./assets/superbol-cfg-explorer-collapse-fallthrough.gif)

### CFG as an arc diagram

A rendering of CFGs as arc diagrams is also available. In this
representation, named sections and paragraphs are laid out vertically,
and arcs show the direction of control-flow between them.

![CFG Explorer as Arc Diagram](./assets/superbol-cfg-explorer-arc.gif)

## Debugging

In order to debug a COBOL program, you first need to run a *build
Expand Down Expand Up @@ -248,9 +318,9 @@ whenever you start a debugging session, *e.g* with <kbd>F5</kbd>).

Save the `tasks.json` as shown. Definitions for this task notably
include a `for-debug` flag, that instructs the compiler to insert
debug annotations into generated executable files, as well as
`extra-args`, that can be edited to pass additional arguments to the
`cobc` compiler.
debug annotations into generated executable files (this effectively
passes flags `-ftraceall` and `-g` to `cobc`). The `extra-args`
setting can be edited to pass additional arguments to `cobc`.

![`tasks.json` for debug](./assets/superbol-tasks.json.png)

Expand All @@ -259,8 +329,9 @@ debug annotations into generated executable files, as well as
GnuCOBOL can instrument your programs so they can generate coverage
information at runtime. To enable this feature, you can set the
`for-coverage` setting to `true` in the `Superbol: build (debug)` task
in your `tasks.json` file (see [Section Customizing Build
Tasks](#customizing-build-tasks)).
in your `tasks.json` file (see [Customizing Build
Tasks](#customizing-build-tasks)). This flag instructs the extension
to pass the `--coverage` flag to the `cobc` compiler.

### Coverage Information

Expand All @@ -275,11 +346,13 @@ Coverage data can be shown after the execution of a program that was
compiled to generate this information terminates. SuperBOL will
display coverage on a line-by-line basis, by highlighting the lines of
your source code using colors that represent their coverage status.
To enable coverage highlighting, you can open the command palette
(or type <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>), and select
`SuperBOL: Show Coverage`.
You can also hide the highlighting with the command `SuperBOL: Hide Coverage`,
and update it after re-executing your program with `SuperBOL: Update Coverage`.
To enable coverage highlighting, you can open the command palette (or
type <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>), and select
`SuperBOL: Show Coverage`. You can also hide the highlighting with
the command `SuperBOL: Hide Coverage`, and update it after
re-executing your program with `SuperBOL: Update Coverage`.

![Show Coverage](./assets/superbol-show-coverage.png)

<!-- ## Formatting the source code -->

Expand Down
Binary file added assets/superbol-cfg-explorer-arc.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/superbol-cfg-explorer.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/superbol-reference-information.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/superbol-rename-symbol-in-copybook.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/superbol-rename-symbol.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/superbol-show-coverage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 24 additions & 20 deletions src/lsp/cobol_lsp/lsp_request.ml
Original file line number Diff line number Diff line change
Expand Up @@ -753,34 +753,38 @@ let handle_codelens registry ({ textDocument; _ }: CodeLensParams.t) =

(** { Rename } *)

let handle_rename ?(ignore_when_copybook=false)
let handle_rename
?(abort_when_in_copybook = true)
registry
({ textDocument; position; newName = newText; _ }: RenameParams.t) =
Option.value ~default:(WorkspaceEdit.create ()) @@
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 locations =
let context = ReferenceContext.create ~includeDeclaration:true in
let params = ReferenceParams.create
~context ~position ~textDocument () in
lookup_references_in_doc ~rootdir params checked_doc in
let changes, is_copybook =
List.fold_left begin fun (map, is_copybook) ({ range; uri }: Location.t) ->
Option.value ~default:[] @@
lookup_references_in_doc ~rootdir
(ReferenceParams.create () ~context ~position ~textDocument )
checked_doc
in
let changes, in_copybook =
List.fold_left begin fun (map, in_copybook) Location.{ range; uri } ->
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
in_copybook || DocumentUri.compare uri textDocument.uri <> 0
end (URIMap.empty, false) locations
in
if in_copybook && abort_when_in_copybook
then begin
Lsp_io.notify_error "Reference occurs in a copybook: not renaming";
None
end else begin
if in_copybook then
Lsp_io.notify_warn "Renamed reference that occurs in a copybook";
let changes = List.of_seq @@ URIMap.to_seq changes in
Some (WorkspaceEdit.create ~changes ())
end
end
|> Option.get


(** {3 Generic handling} *)
Expand Down
2 changes: 1 addition & 1 deletion src/lsp/cobol_lsp/lsp_request.mli
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module INTERNAL: sig
-> Lsp.Types.CodeLensParams.t
-> Lsp.Types.CodeLens.t list
val rename
: ?ignore_when_copybook:bool
: ?abort_when_in_copybook:bool
-> Lsp_server.t
-> Lsp.Types.RenameParams.t
-> Lsp.Types.WorkspaceEdit.t
Expand Down
4 changes: 2 additions & 2 deletions src/lsp/superbol_free_lib/vscode_extension.ml
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,11 @@ let contributes =
~category:"SuperBOL";
Manifest.command ()
~command:"superbol.cfg.open"
~title:"Show control-flow"
~title:"Show Control-flow"
~category:"SuperBOL";
Manifest.command ()
~command:"superbol.cfg.open.arc"
~title:"Show control-flow as an arc-diagram"
~title:"Show Control-flow as an Arc-diagram"
~category:"SuperBOL";
]
~tomlValidation: [
Expand Down
2 changes: 1 addition & 1 deletion src/vscode/superbol-vscode-platform/superbol_tasks.ml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ let cobc_execution ?config attributes =
config_string "cobol.source-format" ~config
~append:(fun f -> List.cons ("-fformat=" ^ f)) |>
attr_bool_flag "for-debug" ~attributes
~ok:(List.append ["-fsource-location"; "-ftraceall"; "-g"]) |>
~ok:(List.append ["-ftraceall"; "-g"]) |>
attr_bool_flag "for-coverage" ~attributes
~ok:(List.cons "--coverage") |>
attr_bool_flag "executable" ~attributes
Expand Down
25 changes: 14 additions & 11 deletions test/lsp/lsp_rename.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,23 @@ 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 ?(ignore_when_copybook=false) ?(copybooks=[]) (doc, positions) : string -> unit =
let rename_positions ?(abort_when_in_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
|> fst
end server copybooks in
let server =
List.fold_left begin fun server (name, document) ->
fst @@ add_cobol_doc server ~projdir name document
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
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;
match LSP.Request.rename ~ignore_when_copybook server params with
match LSP.Request.rename ~abort_when_in_copybook server params with
| { changes = None; _ } ->
Pretty.out "No renames@."
| { changes = Some assoc; _ } ->
Expand Down Expand Up @@ -181,7 +185,7 @@ let%expect_test "rename-with-a-ref-in-a-copybook" =
{"params":{"message":"file://__rootdir__/lib.cpy appears to be a copybook","type":4},"method":"window/logMessage","jsonrpc":"2.0"}
{"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":"Proceeded to rename of a reference that occurs in a copybook","type":2},"method":"window/showMessage","jsonrpc":"2.0"}
{"params":{"message":"Renamed 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:
Expand All @@ -202,7 +206,7 @@ let%expect_test "rename-with-a-ignored-ref-in-a-copybook" =
("lib.cpy", {cobol|
01 copied-var pic 9.|cobol})
] in
let end_with_postproc = rename_positions ~ignore_when_copybook:true ~copybooks
let end_with_postproc = rename_positions ~abort_when_in_copybook:true ~copybooks
@@ extract_position_markers {cobol|
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
Expand All @@ -219,7 +223,7 @@ let%expect_test "rename-with-a-ignored-ref-in-a-copybook" =
{"params":{"message":"file://__rootdir__/lib.cpy appears to be a copybook","type":4},"method":"window/logMessage","jsonrpc":"2.0"}
{"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"}
{"params":{"message":"Reference occurs in a copybook: not renaming","type":1},"method":"window/showMessage","jsonrpc":"2.0"}
(line 7, character 21):
No renames |}]

Expand Down Expand Up @@ -347,4 +351,3 @@ let%expect_test "rename-procedure" =
---- ^^^
6 PERFORM sec.
7 GO para. |}]

0 comments on commit f6d4830

Please sign in to comment.