Skip to content

Commit

Permalink
Merge pull request #294 from mnxn/go-to-declaration
Browse files Browse the repository at this point in the history
Implement TextDocumentDeclaration
  • Loading branch information
rgrinberg authored Nov 9, 2020
2 parents abbcae8 + d73095c commit 4a6e27d
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

- Add keyword completion

- Add go to declaration functionality to jump to a value's specification in a
.mli file (#294)

## Fixes

- #245: correctly use mutexes on OpenBSD (#264)
Expand Down
12 changes: 8 additions & 4 deletions ocaml-lsp-server/src/ocaml_lsp_server.ml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ let initialize_info : InitializeResult.t =
]
in
ServerCapabilities.create ~textDocumentSync ~hoverProvider:(`Bool true)
~definitionProvider:(`Bool true) ~typeDefinitionProvider:(`Bool true)
~completionProvider ~codeActionProvider ~codeLensProvider
~referencesProvider:(`Bool true) ~documentHighlightProvider:(`Bool true)
~declarationProvider:(`Bool true) ~definitionProvider:(`Bool true)
~typeDefinitionProvider:(`Bool true) ~completionProvider
~codeActionProvider ~codeLensProvider ~referencesProvider:(`Bool true)
~documentHighlightProvider:(`Bool true)
~documentFormattingProvider:(`Bool true)
~selectionRangeProvider:(`Bool true) ~documentSymbolProvider:(`Bool true)
~foldingRangeProvider:(`Bool true) ~experimental ~renameProvider ()
Expand Down Expand Up @@ -550,7 +551,10 @@ let ocaml_on_request :
let open Fiber.O in
let+ symbols = Document_symbol.run client_capabilities doc uri in
Ok (Some symbols, state)
| Client_request.TextDocumentDeclaration _ -> Fiber.return @@ Ok (None, state)
| Client_request.TextDocumentDeclaration { textDocument = { uri }; position }
->
definition_query state uri position (fun pos ->
Query_protocol.Locate (None, `MLI, pos))
| Client_request.TextDocumentDefinition { textDocument = { uri }; position }
->
definition_query state uri position (fun pos ->
Expand Down
2 changes: 2 additions & 0 deletions ocaml-lsp-server/test/e2e/__tests__/declaration_files/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(library
(name declaration_files))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(lang dune 2.5)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let x = 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
val x : int
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let y = Lib.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { promises as fs } from "fs";
import * as path from "path";
import * as child_process from "child_process";
import * as LanguageServer from "./../src/LanguageServer";
import * as Types from "vscode-languageserver-types";
import { testUri, toEqualUri } from "./../src/LanguageServer";
expect.extend({
toEqualUri,
});
declare global {
namespace jest {
interface Matchers<R> {
toEqualUri(uri: string): R;
}
}
}

describe("textDocument/declaration", () => {
let languageServer = null;

let testWorkspacePath = path.join(__dirname, "declaration_files/");

let createPathForFile = (filename: string) =>
path.join(testWorkspacePath, filename);

beforeEach(async () => {
languageServer = await LanguageServer.startAndInitialize();
});

afterEach(async () => {
await LanguageServer.exit(languageServer);
languageServer = null;
});

async function openDocument(filepath) {
let source = await fs.readFile(filepath);
await languageServer.sendNotification("textDocument/didOpen", {
textDocument: Types.TextDocumentItem.create(
testUri(filepath),
"ocaml",
0,
source.toString(),
),
});
}

async function queryDeclaration(filepath, position) {
return await languageServer.sendRequest("textDocument/declaration", {
textDocument: Types.TextDocumentIdentifier.create(testUri(filepath)),
position,
});
}

it("returns location of a declaration", async () => {
child_process.execSync("dune build", { cwd: testWorkspacePath });

await openDocument(createPathForFile("main.ml"));

let result = await queryDeclaration(
createPathForFile("main.ml"),
Types.Position.create(0, 13),
);

expect(result.length).toBe(1);
expect(result[0].range).toMatchObject({
end: { character: 0, line: 0 },
start: { character: 0, line: 0 },
});
expect(result[0].uri).toEqualUri(testUri(createPathForFile("lib.ml")));
});
});

0 comments on commit 4a6e27d

Please sign in to comment.