Skip to content

Add type definition #271

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

Merged
merged 2 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
125 changes: 96 additions & 29 deletions analysis/.depend
Original file line number Diff line number Diff line change
@@ -1,39 +1,106 @@
src/BuildSystem.cmx : src/ModuleResolution.cmx src/Log.cmx src/Files.cmx
src/Cli.cmx : src/Commands.cmx
src/Cmt.cmx : src/Utils.cmx src/Uri2.cmx src/SharedTypes.cmx \
src/ProcessCmt.cmx src/Packages.cmx src/FindFiles.cmx src/BuildSystem.cmx
src/Commands.cmx : src/Utils.cmx src/Uri2.cmx src/SharedTypes.cmx \
src/Shared.cmx src/References.cmx src/Protocol.cmx src/NewCompletions.cmx \
src/Hover.cmx src/Files.cmx src/Cmt.cmx
src/BuildSystem.cmx : \
src/ModuleResolution.cmx \
src/Log.cmx \
src/Files.cmx
src/Cli.cmx : \
src/Commands.cmx
src/Cmt.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/ProcessCmt.cmx \
src/Packages.cmx \
src/FindFiles.cmx \
src/BuildSystem.cmx
src/Commands.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/Shared.cmx \
src/References.cmx \
src/Protocol.cmx \
src/NewCompletions.cmx \
src/Hover.cmx \
src/Files.cmx \
src/Cmt.cmx
src/Files.cmx :
src/FindFiles.cmx : src/Utils.cmx src/SharedTypes.cmx \
src/ModuleResolution.cmx src/Log.cmx src/vendor/Json.cmx src/Infix.cmx \
src/Files.cmx src/BuildSystem.cmx
src/Hover.cmx : src/Utils.cmx src/SharedTypes.cmx src/Shared.cmx \
src/References.cmx src/ProcessCmt.cmx
src/FindFiles.cmx : \
src/Utils.cmx \
src/SharedTypes.cmx \
src/ModuleResolution.cmx \
src/Log.cmx \
src/vendor/Json.cmx \
src/Infix.cmx \
src/Files.cmx \
src/BuildSystem.cmx
src/Hover.cmx : \
src/Utils.cmx \
src/SharedTypes.cmx \
src/Shared.cmx \
src/References.cmx \
src/ProcessCmt.cmx
src/Infix.cmx :
src/Log.cmx :
src/ModuleResolution.cmx : src/Files.cmx
src/NewCompletions.cmx : src/Utils.cmx src/Uri2.cmx src/SharedTypes.cmx \
src/Shared.cmx src/Protocol.cmx src/ProcessCmt.cmx src/PartialParser.cmx \
src/Log.cmx src/Hover.cmx
src/Packages.cmx : src/Uri2.cmx src/SharedTypes.cmx src/Log.cmx \
src/vendor/Json.cmx src/Infix.cmx src/FindFiles.cmx src/Files.cmx \
src/ModuleResolution.cmx : \
src/Files.cmx
src/NewCompletions.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/Shared.cmx \
src/Protocol.cmx \
src/ProcessCmt.cmx \
src/PartialParser.cmx \
src/Log.cmx \
src/Hover.cmx
src/Packages.cmx : \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/Log.cmx \
src/vendor/Json.cmx \
src/Infix.cmx \
src/FindFiles.cmx \
src/Files.cmx \
src/BuildSystem.cmx
src/PartialParser.cmx : src/SharedTypes.cmx
src/PartialParser.cmx : \
src/SharedTypes.cmx
src/PrepareUtils.cmx :
src/PrintType.cmx : src/vendor/res_outcome_printer/res_outcome_printer.cmx \
src/PrintType.cmx : \
src/vendor/res_outcome_printer/res_outcome_printer.cmx \
src/vendor/res_outcome_printer/res_doc.cmx
src/ProcessAttributes.cmx : src/SharedTypes.cmx src/PrepareUtils.cmx
src/ProcessCmt.cmx : src/Utils.cmx src/Uri2.cmx src/SharedTypes.cmx \
src/Shared.cmx src/ProcessAttributes.cmx src/Log.cmx src/Files.cmx
src/Protocol.cmx : src/vendor/Json.cmx
src/References.cmx : src/Utils.cmx src/Uri2.cmx src/SharedTypes.cmx \
src/ProcessCmt.cmx src/Log.cmx src/Infix.cmx src/Cmt.cmx
src/Shared.cmx : src/PrintType.cmx src/Log.cmx src/Files.cmx
src/SharedTypes.cmx : src/Utils.cmx src/Uri2.cmx src/Shared.cmx
src/ProcessAttributes.cmx : \
src/SharedTypes.cmx \
src/PrepareUtils.cmx
src/ProcessCmt.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/Shared.cmx \
src/ProcessAttributes.cmx \
src/Log.cmx \
src/Files.cmx
src/Protocol.cmx : \
src/vendor/Json.cmx
src/References.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/SharedTypes.cmx \
src/Shared.cmx \
src/ProcessCmt.cmx \
src/Log.cmx \
src/Infix.cmx \
src/Cmt.cmx
src/Shared.cmx : \
src/PrintType.cmx \
src/Log.cmx \
src/Files.cmx
src/SharedTypes.cmx : \
src/Utils.cmx \
src/Uri2.cmx \
src/Shared.cmx
src/Uri2.cmx :
src/Utils.cmx : src/Protocol.cmx
src/Utils.cmx : \
src/Protocol.cmx
src/vendor/Json.cmx :
src/vendor/res_outcome_printer/res_comment.cmx : \
src/vendor/res_outcome_printer/res_comment.cmi
Expand Down
8 changes: 8 additions & 0 deletions analysis/src/Cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ let help =
API examples:
./rescript-editor-analysis.exe completion src/MyFile.res 0 4 currentContent.res
./rescript-editor-analysis.exe definition src/MyFile.res 9 3
./rescript-editor-analysis.exe typeDefinition src/MyFile.res 9 3
./rescript-editor-analysis.exe documentSymbol src/Foo.res
./rescript-editor-analysis.exe hover src/MyFile.res 10 2
./rescript-editor-analysis.exe references src/MyFile.res 10 2
Expand All @@ -27,6 +28,10 @@ Options:

./rescript-editor-analysis.exe definition src/MyFile.res 10 2

typeDefinition: get type definition for item in MyFile.res at line 10 column 2:

./rescript-editor-analysis.exe typeDefinition src/MyFile.res 10 2

documentSymbol: get all symbols declared in MyFile.res

./rescript-editor-analysis.exe documentSymbol src/MyFile.res
Expand Down Expand Up @@ -60,6 +65,9 @@ let main () =
| [_; "definition"; path; line; col] ->
Commands.definition ~path ~line:(int_of_string line)
~col:(int_of_string col)
| [_; "typeDefinition"; path; line; col] ->
Commands.typeDefinition ~path ~line:(int_of_string line)
~col:(int_of_string col)
| _ :: "dump" :: files -> Commands.dump files
| [_; "documentSymbol"; path] -> Commands.documentSymbol ~path
| [_; "hover"; path; line; col] ->
Expand Down
25 changes: 25 additions & 0 deletions analysis/src/Commands.ml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,26 @@ let definition ~path ~line ~col =
| None -> Protocol.null
| Some location -> location |> Protocol.stringifyLocation)

let typeDefinition ~path ~line ~col =
let maybeLocation =
match Cmt.fromPath ~path with
| None -> None
| Some full -> (
match References.getLocItem ~full ~line ~col with
| None -> None
| Some locItem -> (
match References.typeDefinitionForLocItem ~full locItem with
| None -> None
| Some (uri, loc) ->
Some
{Protocol.uri = Uri2.toString uri; range = Utils.cmtLocToRange loc})
)
in
print_endline
(match maybeLocation with
| None -> Protocol.null
| Some location -> location |> Protocol.stringifyLocation)

let references ~path ~line ~col =
let allLocs =
match Cmt.fromPath ~path with
Expand Down Expand Up @@ -281,6 +301,11 @@ let test ~path =
("Definition " ^ path ^ " " ^ string_of_int line ^ ":"
^ string_of_int col);
definition ~path ~line ~col
| "typ" ->
print_endline
("TypeDefinition " ^ path ^ " " ^ string_of_int line ^ ":"
^ string_of_int col);
typeDefinition ~path ~line ~col
| "hov" ->
print_endline
("Hover " ^ path ^ " " ^ string_of_int line ^ ":"
Expand Down
23 changes: 23 additions & 0 deletions analysis/src/References.ml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,29 @@ let definitionForLocItem ~full:{file; package} locItem =
maybeLog ("Got stamp " ^ string_of_int stamp);
definition ~file:env.file ~package stamp tip)))

let typeDefinitionForLocItem ~full:{file; package} locItem =
match locItem.locType with
| Constant _ | TopLevelModule _ | LModule _ | TypeDefinition _ -> None
| Typed (_, typ, _) -> (
let env = SharedTypes.QueryEnv.fromFile file in
match Shared.digConstructor typ with
| None -> None
| Some path -> (
match ProcessCmt.resolveFromCompilerPath ~env ~package path with
| `Not_found -> None
| `Stamp stamp -> (
match Hashtbl.find_opt env.file.stamps.types stamp with
| None -> None
| Some declared -> Some (env.file.uri, declared.item.decl.type_loc))
| `Exported (env, name) -> (
match Hashtbl.find_opt env.exported.types name with
| None -> None
| Some stamp -> (
match Hashtbl.find_opt env.file.stamps.types stamp with
| None -> None
| Some declared -> Some (env.file.uri, declared.item.decl.type_loc))))
)

let isVisible (declared : _ SharedTypes.declared) =
declared.isExported
&&
Expand Down
4 changes: 4 additions & 0 deletions analysis/tests/src/Cross.res
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ let _ = RenameWithInterface.x

let _ = RenameWithInterface.x
// ^ren xPrime


let typeDef = {TypeDefinition.item: "foobar"}
// ^typ
24 changes: 24 additions & 0 deletions analysis/tests/src/TypeDefinition.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
type variant = Foo | Bar

type record = {item: string}

let x = Foo
// ^typ

let y = {item: "foo"}
// ^typ

type obj = {"foo": string}

let obj: obj = {"foo": "bar"}
// ^type

let f = r => r.item
// ^typ

let g = v =>
switch v {
// ^typ
| Foo => "Foo"
| Bar => "Bar"
}
3 changes: 3 additions & 0 deletions analysis/tests/src/expected/Cross.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ Rename tests/src/Cross.res 24:28 xPrime
}
]

TypeDefinition tests/src/Cross.res 28:5
{"uri": "TypeDefinition.res", "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 28}}}

15 changes: 15 additions & 0 deletions analysis/tests/src/expected/TypeDefinition.res.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
TypeDefinition tests/src/TypeDefinition.res 4:4
{"uri": "TypeDefinition.res", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 24}}}

TypeDefinition tests/src/TypeDefinition.res 7:4
{"uri": "TypeDefinition.res", "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 28}}}

TypeDefinition tests/src/TypeDefinition.res 12:4
{"uri": "TypeDefinition.res", "range": {"start": {"line": 10, "character": 0}, "end": {"line": 10, "character": 26}}}

TypeDefinition tests/src/TypeDefinition.res 15:13
{"uri": "TypeDefinition.res", "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 28}}}

TypeDefinition tests/src/TypeDefinition.res 19:9
{"uri": "TypeDefinition.res", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 24}}}

15 changes: 15 additions & 0 deletions server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ function definition(msg: p.RequestMessage) {
return response;
}

function typeDefinition(msg: p.RequestMessage) {
// https://microsoft.github.io/language-server-protocol/specification/specification-current/#textDocument_typeDefinition
let params = msg.params as p.TypeDefinitionParams;
let filePath = fileURLToPath(params.textDocument.uri);
let response = utils.runAnalysisCommand(
filePath,
["typeDefinition", filePath, params.position.line, params.position.character],
msg
);
return response;
}

function references(msg: p.RequestMessage) {
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
let params = msg.params as p.ReferenceParams;
Expand Down Expand Up @@ -620,6 +632,7 @@ function onMessage(msg: m.Message) {
documentFormattingProvider: true,
hoverProvider: true,
definitionProvider: true,
typeDefinitionProvider: true,
referencesProvider: true,
renameProvider: { prepareProvider: true },
documentSymbolProvider: false,
Expand Down Expand Up @@ -670,6 +683,8 @@ function onMessage(msg: m.Message) {
send(hover(msg));
} else if (msg.method === p.DefinitionRequest.method) {
send(definition(msg));
} else if (msg.method === p.TypeDefinitionRequest.method) {
send(typeDefinition(msg));
} else if (msg.method === p.ReferencesRequest.method) {
send(references(msg));
} else if (msg.method === p.PrepareRenameRequest.method) {
Expand Down