Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Code Lenses for functions (experimetal). `rescript.settings.codeLens: true`. Turned off by default. https://github.com/rescript-lang/rescript-vscode/pull/513
- Markdown code blocks tagged as `rescript` now get basic syntax highlighting. https://github.com/rescript-lang/rescript-vscode/pull/97
- Hover support for doc comments on v10 compiler `/** this is a doc comment */`
- Code action to convert type to module.

#### :bug: Bug Fix

Expand Down
11 changes: 1 addition & 10 deletions analysis/src/CodeActions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,4 @@ let stringifyCodeActions codeActions =
Printf.sprintf {|%s|}
(codeActions |> List.map Protocol.stringifyCodeAction |> Protocol.array)

let make ~title ~kind ~uri ~newText ~range =
{
Protocol.title;
codeActionKind = kind;
edit =
{
documentChanges =
[{textDocument = {version = None; uri}; edits = [{newText; range}]}];
};
}
let make ~title ~kind ~edit = {Protocol.title; codeActionKind = kind; edit}
91 changes: 16 additions & 75 deletions analysis/src/Commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,73 +175,9 @@ let references ~path ~pos ~debug =

let rename ~path ~pos ~newName ~debug =
let result =
match Cmt.fullFromPath ~path with
match Rename.command ~path ~pos ~newName ~debug with
| Some workspaceEdit -> workspaceEdit |> Protocol.stringifyWorkspaceEdit
| None -> Protocol.null
| Some full -> (
match References.getLocItem ~full ~pos ~debug with
| None -> Protocol.null
| Some locItem ->
let allReferences = References.allReferencesForLocItem ~full locItem in
let referencesToToplevelModules =
allReferences
|> Utils.filterMap (fun {References.uri = uri2; locOpt} ->
if locOpt = None then Some uri2 else None)
in
let referencesToItems =
allReferences
|> Utils.filterMap (function
| {References.uri = uri2; locOpt = Some loc} -> Some (uri2, loc)
| {locOpt = None} -> None)
in
let fileRenames =
referencesToToplevelModules
|> List.map (fun uri ->
let path = Uri.toPath uri in
let dir = Filename.dirname path in
let newPath =
Filename.concat dir (newName ^ Filename.extension path)
in
let newUri = Uri.fromPath newPath in
Protocol.
{
oldUri = uri |> Uri.toString;
newUri = newUri |> Uri.toString;
})
in
let textDocumentEdits =
let module StringMap = Misc.StringMap in
let textEditsByUri =
referencesToItems
|> List.map (fun (uri, loc) -> (Uri.toString uri, loc))
|> List.fold_left
(fun acc (uri, loc) ->
let textEdit =
Protocol.
{range = Utils.cmtLocToRange loc; newText = newName}
in
match StringMap.find_opt uri acc with
| None -> StringMap.add uri [textEdit] acc
| Some prevEdits ->
StringMap.add uri (textEdit :: prevEdits) acc)
StringMap.empty
in
StringMap.fold
(fun uri edits acc ->
let textDocumentEdit =
Protocol.{textDocument = {uri; version = None}; edits}
in
textDocumentEdit :: acc)
textEditsByUri []
in
let fileRenamesString =
fileRenames |> List.map Protocol.stringifyRenameFile
in
let textDocumentEditsString =
textDocumentEdits |> List.map Protocol.stringifyTextDocumentEdit
in
"[\n"
^ (fileRenamesString @ textDocumentEditsString |> String.concat ",\n")
^ "\n]")
in
print_endline result

Expand Down Expand Up @@ -383,15 +319,20 @@ let test ~path =
|> List.iter (fun {Protocol.title; edit = {documentChanges}} ->
Printf.printf "Hit: %s\n" title;
documentChanges
|> List.iter (fun {Protocol.edits} ->
edits
|> List.iter (fun {Protocol.range; newText} ->
let indent =
String.make range.start.character ' '
in
Printf.printf "%s\nnewText:\n%s<--here\n%s%s\n"
(Protocol.stringifyRange range)
indent indent newText)))
|> List.iter
(fun (documentChange : Protocol.documentChange) ->
match documentChange with
| TextDocumentEdit {edits} ->
edits
|> List.iter (fun {Protocol.range; newText} ->
let indent =
String.make range.start.character ' '
in
Printf.printf
"%s\nnewText:\n%s<--here\n%s%s\n"
(Protocol.stringifyRange range)
indent indent newText)
| _ -> ()))
| "dia" -> diagnosticSyntax ~path
| "hin" ->
let line_start = 0 in
Expand Down
19 changes: 14 additions & 5 deletions analysis/src/Protocol.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ type textDocumentEdit = {
edits: textEdit list;
}

type codeActionEdit = {documentChanges: textDocumentEdit list}
type documentChange =
| TextDocumentEdit of textDocumentEdit
| RenameFile of renameFile

type workspaceEdit = {documentChanges: documentChange list}
type codeActionKind = RefactorRewrite

type codeAction = {
title: string;
codeActionKind: codeActionKind;
edit: codeActionEdit;
edit: workspaceEdit;
}

let null = "null"
Expand Down Expand Up @@ -133,14 +137,19 @@ let codeActionKindToString kind =
match kind with
| RefactorRewrite -> "refactor.rewrite"

let stringifyCodeActionEdit cae =
let stringifyWorkspaceEdit we =
Printf.sprintf {|{"documentChanges": %s}|}
(cae.documentChanges |> List.map stringifyTextDocumentEdit |> array)
(we.documentChanges
|> List.map (fun documentChange ->
match documentChange with
| TextDocumentEdit textEdit -> textEdit |> stringifyTextDocumentEdit
| RenameFile renameFile -> renameFile |> stringifyRenameFile)
|> array)

let stringifyCodeAction ca =
Printf.sprintf {|{"title": "%s", "kind": "%s", "edit": %s}|} ca.title
(codeActionKindToString ca.codeActionKind)
(ca.edit |> stringifyCodeActionEdit)
(ca.edit |> stringifyWorkspaceEdit)

let stringifyHint hint =
Printf.sprintf
Expand Down
58 changes: 58 additions & 0 deletions analysis/src/Rename.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
let command ~path ~pos ~newName ~debug =
match Cmt.fullFromPath ~path with
| None -> None
| Some full -> (
match References.getLocItem ~full ~pos ~debug with
| None -> None
| Some locItem ->
let allReferences = References.allReferencesForLocItem ~full locItem in
let referencesToToplevelModules =
allReferences
|> Utils.filterMap (fun {References.uri = uri2; locOpt} ->
if locOpt = None then Some uri2 else None)
in
let referencesToItems =
allReferences
|> Utils.filterMap (function
| {References.uri = uri2; locOpt = Some loc} -> Some (uri2, loc)
| {locOpt = None} -> None)
in
let fileRenames =
referencesToToplevelModules
|> List.map (fun uri ->
let path = Uri.toPath uri in
let dir = Filename.dirname path in
let newPath =
Filename.concat dir (newName ^ Filename.extension path)
in
let newUri = Uri.fromPath newPath in
Protocol.RenameFile
{oldUri = uri |> Uri.toString; newUri = newUri |> Uri.toString})
in
let textDocumentEdits =
let module StringMap = Misc.StringMap in
let textEditsByUri =
referencesToItems
|> List.map (fun (uri, loc) -> (Uri.toString uri, loc))
|> List.fold_left
(fun acc (uri, loc) ->
let textEdit =
Protocol.{range = Utils.cmtLocToRange loc; newText = newName}
in
match StringMap.find_opt uri acc with
| None -> StringMap.add uri [textEdit] acc
| Some prevEdits ->
StringMap.add uri (textEdit :: prevEdits) acc)
StringMap.empty
in
StringMap.fold
(fun uri edits acc ->
let textDocumentEdit =
Protocol.TextDocumentEdit
{textDocument = {uri; version = None}; edits}
in
textDocumentEdit :: acc)
textEditsByUri []
in
let documentChanges = fileRenames @ textDocumentEdits in
Some Protocol.{documentChanges})
Loading