-
Notifications
You must be signed in to change notification settings - Fork 59
Fix references to file modules #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6ddf611
a328945
f15a838
13a09b3
f8802ba
96ef240
e31cf55
53344ce
db7f838
c025498
b1dc77d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,6 +176,78 @@ let documentSymbol ~path = | |
in | ||
print_endline ("[\n" ^ (allSymbols |> String.concat ",\n") ^ "\n]") | ||
|
||
let rename ~path ~line ~col ~newName = | ||
let uri = Uri2.fromPath path in | ||
let result = | ||
match ProcessCmt.getFullFromCmt ~uri with | ||
| None -> Protocol.null | ||
| Some full -> ( | ||
let pos = Utils.protocolLineColToCmtLoc ~line ~col in | ||
match References.locItemForPos ~full pos with | ||
| None -> Protocol.null | ||
| Some locItem -> | ||
let allReferences = References.allReferencesForLocItem ~full locItem in | ||
let referencesToToplevelModules, referencesToItems = | ||
allReferences | ||
|> List.fold_left | ||
(fun acc (uri2, references) -> | ||
(references |> List.map (fun loc -> (uri2, loc))) @ acc) | ||
[] | ||
|> List.partition (fun (_, loc) -> Utils.isTopLoc loc) | ||
in | ||
let fileRenames = | ||
referencesToToplevelModules | ||
|> List.map (fun (uri, _) -> | ||
let path = Uri2.toPath uri in | ||
let dir = Filename.dirname path in | ||
let ext = Filename.extension path in | ||
let sep = Filename.dir_sep in | ||
let newPath = dir ^ sep ^ newName ^ ext in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better use |
||
let newUri = Uri2.fromPath newPath in | ||
Protocol. | ||
{ | ||
kind = `rename; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I think it's easier to expose a constructor function in the protocol that only takes 2 parameters: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I would just remove |
||
oldUri = uri |> Uri2.toString; | ||
newUri = newUri |> Uri2.toString; | ||
}) | ||
in | ||
let textDocumentEdits = | ||
let module StringMap = Misc.StringMap in | ||
let textEditsByUri = | ||
referencesToItems | ||
|> List.map (fun (uri, loc) -> (Uri2.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 | ||
|
||
let test ~path = | ||
Uri2.stripPath := true; | ||
match Files.readFile path with | ||
|
@@ -211,6 +283,15 @@ let test ~path = | |
| "doc" -> | ||
print_endline ("DocumentSymbol " ^ path); | ||
documentSymbol ~path | ||
| "ren" -> | ||
let newName = String.sub rest 4 (len - mlen - 4) in | ||
let () = | ||
print_endline | ||
("Rename " ^ path ^ " " ^ string_of_int line ^ ":" | ||
^ string_of_int col ^ " " ^ newName) | ||
in | ||
|
||
rename ~path ~line ~col ~newName | ||
| "com" -> | ||
print_endline | ||
("Complete " ^ path ^ " " ^ string_of_int line ^ ":" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,20 @@ type location = {uri : string; range : range} | |
|
||
type documentSymbolItem = {name : string; kind : int; location : location} | ||
|
||
type renameFile = {kind : [`rename]; oldUri : string; newUri : string} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: remove |
||
|
||
type textEdit = {range : range; newText : string} | ||
|
||
type optionalVersionedTextDocumentIdentifier = { | ||
version : int option; | ||
uri : string; | ||
} | ||
|
||
type textDocumentEdit = { | ||
textDocument : optionalVersionedTextDocumentIdentifier; | ||
edits : textEdit list; | ||
} | ||
|
||
let null = "null" | ||
|
||
let array l = "[" ^ String.concat ", " l ^ "]" | ||
|
@@ -52,7 +66,7 @@ let stringifyCompletionItem c = | |
let stringifyHover h = | ||
Printf.sprintf {|{"contents": "%s"}|} (Json.escape h.contents) | ||
|
||
let stringifyLocation h = | ||
let stringifyLocation (h : location) = | ||
Printf.sprintf {|{"uri": "%s", "range": %s}|} (Json.escape h.uri) | ||
(stringifyRange h.range) | ||
|
||
|
@@ -65,3 +79,35 @@ let stringifyDocumentSymbolItem i = | |
}|} | ||
(Json.escape i.name) i.kind | ||
(stringifyLocation i.location) | ||
|
||
let stringifyRenameFile rf = | ||
Printf.sprintf {|{ | ||
"kind": "%s", | ||
"oldUri": "%s", | ||
"newUri": "%s" | ||
}|} | ||
(match rf.kind with `rename -> "rename") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can go once field |
||
(Json.escape rf.oldUri) (Json.escape rf.newUri) | ||
|
||
let stringifyTextEdit te = | ||
Printf.sprintf {|{ | ||
"range": %s, | ||
"newText": "%s" | ||
}|} | ||
(stringifyRange te.range) (Json.escape te.newText) | ||
|
||
let stringifyoptionalVersionedTextDocumentIdentifier td = | ||
Printf.sprintf {|{ | ||
"version": %s, | ||
"uri": "%s" | ||
}|} | ||
(match td.version with None -> null | Some v -> string_of_int v) | ||
(Json.escape td.uri) | ||
|
||
let stringifyTextDocumentEdit tde = | ||
Printf.sprintf {|{ | ||
"textDocument": %s, | ||
"edits": %s | ||
}|} | ||
(stringifyoptionalVersionedTextDocumentIdentifier tde.textDocument) | ||
(tde.edits |> List.map stringifyTextEdit |> array) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,12 @@ let topLoc fname = | |
loc_ghost = false; | ||
} | ||
|
||
let isTopLoc (loc : Warnings.loc) = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be possible to clean this up further, but looks OK for now. |
||
let isTopPos (pos : Lexing.position) = | ||
pos.pos_lnum = 1 && pos.pos_bol = 0 && pos.pos_cnum = 0 | ||
in | ||
isTopPos loc.loc_start && isTopPos loc.loc_end && loc.loc_ghost = false | ||
|
||
(** | ||
* `startsWith(string, prefix)` | ||
* true if the string starts with the prefix | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
let x = 2 | ||
// ^ref |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
let x: int | ||
// ^ref |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
let x = 12 | ||
// ^ren y | ||
|
||
let a = x | ||
|
||
let b = a | ||
|
||
let c = x | ||
|
||
let foo = (~xx) => xx + 1 | ||
// ^ren yy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
let x = 2 | ||
// ^ren y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
let x: int | ||
// ^ren y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list I think can be non-deterministic.
Some fixed order should be chosen (e.g. by sorting the results on Uri then loc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be enough to make
fileReferences
insideextra
inSharedTypes.ml
store a set of locations instead of a list.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will check what's going wrong on a windows setup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there was an issue checking for interface file on windows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thanks. I've also looked at removing some nondeterminism:
#263
Which I might add later on. To make debugging across platforms easier.