mirror of
https://github.com/c-cube/linol.git
synced 2025-12-09 20:55:43 -05:00
1522 lines
28 KiB
TypeScript
1522 lines
28 KiB
TypeScript
import outdent from "outdent";
|
|
import * as Protocol from "vscode-languageserver-protocol";
|
|
import * as Types from "vscode-languageserver-types";
|
|
import * as LanguageServer from "../src/LanguageServer";
|
|
|
|
describe("textDocument/foldingRange", () => {
|
|
let languageServer: LanguageServer.LanguageServer;
|
|
|
|
beforeEach(async () => {
|
|
languageServer = await LanguageServer.startAndInitialize();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await LanguageServer.exit(languageServer);
|
|
});
|
|
|
|
function openDocument(source: string) {
|
|
languageServer.sendNotification(
|
|
Protocol.DidOpenTextDocumentNotification.type,
|
|
{
|
|
textDocument: Types.TextDocumentItem.create(
|
|
"file:///test.ml",
|
|
"ocaml",
|
|
0,
|
|
source,
|
|
),
|
|
},
|
|
);
|
|
}
|
|
|
|
async function foldingRange() {
|
|
return languageServer.sendRequest("textDocument/foldingRange", {
|
|
textDocument: Types.TextDocumentIdentifier.create("file:///test.ml"),
|
|
});
|
|
}
|
|
|
|
it("returns folding ranges for `let`", async () => {
|
|
openDocument(outdent`
|
|
let a =
|
|
let b = 1
|
|
in
|
|
let c =
|
|
"foo"
|
|
in
|
|
()
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 9,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 3,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for open expressions", async () => {
|
|
openDocument(outdent`
|
|
open struct
|
|
let u =
|
|
()
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 2,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pexp_apply expressions", async () => {
|
|
openDocument(outdent`
|
|
Stdlib.print_endline "one
|
|
two
|
|
three"`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 2,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pexp_letop", async () => {
|
|
openDocument(outdent`
|
|
let () =
|
|
let+ outline =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two";
|
|
in
|
|
let symbol_info_of_outline_item =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two";`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 5,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pexp_newtype", async () => {
|
|
openDocument(outdent`
|
|
let magic_of_kind : type a . a ast_kind -> string =
|
|
let () =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two"
|
|
in ()`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for type_extension", async () => {
|
|
openDocument(outdent`
|
|
type t +=
|
|
| A
|
|
| B
|
|
|
|
module type Type = sig
|
|
type t +=
|
|
| A
|
|
| B
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 2,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 4,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 19,
|
|
"startLine": 4,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 7,
|
|
"startLine": 5,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for match expressions", async () => {
|
|
openDocument(outdent`
|
|
match
|
|
Some
|
|
"large expr"
|
|
with
|
|
| None ->
|
|
()
|
|
| Some _ ->
|
|
print_endline "foo";
|
|
print_endline "bar"
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 21,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 4,
|
|
},
|
|
{
|
|
"endCharacter": 21,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 8,
|
|
"startLine": 6,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for records", async () => {
|
|
openDocument(outdent`
|
|
type r = {
|
|
a: string;
|
|
b: int
|
|
}
|
|
|
|
let f
|
|
{ a;
|
|
b } =
|
|
{ a = a;
|
|
b = b + 1 }
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 1,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 15,
|
|
"endLine": 9,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 5,
|
|
},
|
|
{
|
|
"endCharacter": 11,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 6,
|
|
},
|
|
{
|
|
"endCharacter": 15,
|
|
"endLine": 9,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 8,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for classes", async () => {
|
|
openDocument(outdent`
|
|
class foobar =
|
|
let a =
|
|
let () = Stdlib.print_endline "" in
|
|
let () = Stdlib.print_endline "" in
|
|
let () = Stdlib.print_endline "" in
|
|
()
|
|
in
|
|
object
|
|
method add x y =
|
|
let z =
|
|
let a = 5 in
|
|
let b = 6 in
|
|
let () =
|
|
let () = Stdlib.print_endline "" in
|
|
let () = Stdlib.print_endline "" in
|
|
let () = Stdlib.print_endline "" in
|
|
()
|
|
in
|
|
a + b
|
|
in
|
|
x + y + z
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 21,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 21,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 21,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 7,
|
|
},
|
|
{
|
|
"endCharacter": 15,
|
|
"endLine": 20,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 8,
|
|
},
|
|
{
|
|
"endCharacter": 13,
|
|
"endLine": 18,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 9,
|
|
},
|
|
{
|
|
"endCharacter": 12,
|
|
"endLine": 16,
|
|
"kind": "region",
|
|
"startCharacter": 8,
|
|
"startLine": 12,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
it("returns folding ranges Pexp_while", async () => {
|
|
openDocument(outdent`
|
|
while true do
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two";
|
|
done
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges Pexp_for", async () => {
|
|
openDocument(outdent`
|
|
for j = 0 to Array.length index - 1 do
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two";
|
|
done;
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges Pexp_object", async () => {
|
|
openDocument(outdent`
|
|
object
|
|
method print =
|
|
Stdlib.print_enline "one";
|
|
Stdlib.print_enline "two";
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges Pexp_pack", async () => {
|
|
openDocument(outdent`
|
|
(module Set.Make (struct
|
|
type t = s
|
|
let compare = cmp
|
|
let print =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two"
|
|
end))
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 18,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 3,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges Pexp_letmodule", async () => {
|
|
openDocument(outdent`
|
|
let module W = Set.Make (struct
|
|
type t = s
|
|
|
|
let compare = cmp
|
|
|
|
let print =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two"
|
|
end)
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 25,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 5,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for value_description", async () => {
|
|
openDocument(outdent`
|
|
module Type : sig
|
|
val mk: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?text:text ->
|
|
?params:(core_type * (variance * injectivity)) list ->
|
|
?cstrs:(core_type * core_type * loc) list ->
|
|
?kind:type_kind -> ?priv:private_flag -> ?manifest:core_type -> str ->
|
|
type_declaration
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 14,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 20,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pstr_extension", async () => {
|
|
openDocument(outdent`
|
|
[%%expect{|
|
|
module type Module =
|
|
sig
|
|
module N : sig type t end
|
|
type t
|
|
end
|
|
|}]
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("traverses Pexp_lazy nodes", async () => {
|
|
openDocument(outdent`
|
|
let res =
|
|
lazy
|
|
(let () =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two"
|
|
in
|
|
())
|
|
in
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 33,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 2,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("traverses Pexp_letexception nodes", async () => {
|
|
openDocument(outdent`
|
|
let decode_map str =
|
|
let exception Shortcut of error_message in
|
|
let () =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two"
|
|
in
|
|
()
|
|
in
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 4,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 2,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("traverses Pexp_sequence nodes", async () => {
|
|
openDocument(outdent`
|
|
let a =
|
|
Stdlib.print_endline "";
|
|
let b =
|
|
5 + 3 in
|
|
b
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 9,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 2,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
it("supports if/else", async () => {
|
|
openDocument(outdent`
|
|
let fn a =
|
|
if a == true then
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
()
|
|
else
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
()
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 20,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 10,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 2,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 6,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 14,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 12,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 18,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 16,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("supports return type annotation", async () => {
|
|
openDocument(outdent`
|
|
let fn a b : int =
|
|
let result =
|
|
Stdlib.print_endline "";
|
|
a + b
|
|
in
|
|
result
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 9,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for try/with", async () => {
|
|
openDocument(outdent`
|
|
let result =
|
|
try
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
Some 6
|
|
with
|
|
| Not_found ->
|
|
let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
None
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 13,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 13,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 2,
|
|
},
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 13,
|
|
"kind": "region",
|
|
"startCharacter": 13,
|
|
"startLine": 8,
|
|
},
|
|
{
|
|
"endCharacter": 29,
|
|
"endLine": 11,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 9,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("traverses Pexp_construct", async () => {
|
|
openDocument(outdent`
|
|
let a =
|
|
Some
|
|
(let () =
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
in
|
|
5)
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 2,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for modules", async () => {
|
|
openDocument(outdent`
|
|
module type X = sig
|
|
type t =
|
|
| A
|
|
| B
|
|
| C
|
|
end
|
|
|
|
module X = struct
|
|
module type T = sig
|
|
module T1 : sig
|
|
type t =
|
|
| A
|
|
| B
|
|
| C
|
|
end
|
|
type t
|
|
val uri : t -> Uri.t
|
|
val dispose : t -> unit
|
|
end
|
|
|
|
module Y = struct
|
|
let bar a =
|
|
match a with
|
|
| None ->
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline "";
|
|
Stdlib.print_endline ""
|
|
| Some b ->
|
|
Stdlib.print_endline b;
|
|
Stdlib.print_endline b;
|
|
Stdlib.print_endline b
|
|
end
|
|
|
|
let foo () =
|
|
let x =
|
|
let y = 5 in
|
|
let z = 3 in
|
|
let open Stdlib in
|
|
let () =
|
|
let () = print_endline "" in
|
|
let () = print_endline "" in
|
|
let () = print_endline "" in
|
|
()
|
|
in
|
|
let open Promise.Syntax in
|
|
let%lwt result =
|
|
let a = 5 in
|
|
Promise.resolve a
|
|
in
|
|
let+ result_letop =
|
|
let a = 5 in
|
|
Promise.resolve a
|
|
in
|
|
z + y
|
|
in
|
|
x + 3
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 16,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 56,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 7,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 56,
|
|
"kind": "region",
|
|
"startCharacter": 11,
|
|
"startLine": 7,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 18,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 8,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 18,
|
|
"kind": "region",
|
|
"startCharacter": 18,
|
|
"startLine": 8,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 14,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 9,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 14,
|
|
"kind": "region",
|
|
"startCharacter": 16,
|
|
"startLine": 9,
|
|
},
|
|
{
|
|
"endCharacter": 11,
|
|
"endLine": 13,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 10,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 31,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 20,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 31,
|
|
"kind": "region",
|
|
"startCharacter": 13,
|
|
"startLine": 20,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 30,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 21,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 30,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 22,
|
|
},
|
|
{
|
|
"endCharacter": 31,
|
|
"endLine": 26,
|
|
"kind": "region",
|
|
"startCharacter": 12,
|
|
"startLine": 23,
|
|
},
|
|
{
|
|
"endCharacter": 30,
|
|
"endLine": 30,
|
|
"kind": "region",
|
|
"startCharacter": 14,
|
|
"startLine": 27,
|
|
},
|
|
{
|
|
"endCharacter": 9,
|
|
"endLine": 55,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 33,
|
|
},
|
|
{
|
|
"endCharacter": 11,
|
|
"endLine": 53,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 34,
|
|
},
|
|
{
|
|
"endCharacter": 10,
|
|
"endLine": 42,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 38,
|
|
},
|
|
{
|
|
"endCharacter": 25,
|
|
"endLine": 47,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 45,
|
|
},
|
|
{
|
|
"endCharacter": 11,
|
|
"endLine": 53,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 49,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("traverses Pstr_extension structure item", async () => {
|
|
openDocument(outdent`
|
|
let%expect_test "test from jsonrpc_test.ml" =
|
|
let a =
|
|
let b = 5 in
|
|
6 + 5
|
|
in
|
|
Stdlib.print_endline (string_of_int 5)
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 40,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 40,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 9,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for class_type", async () => {
|
|
openDocument(outdent`
|
|
class type foo_t =
|
|
object
|
|
inherit castable
|
|
method foo: string
|
|
end;;
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for class_type_field", async () => {
|
|
openDocument(outdent`
|
|
module type Type = sig
|
|
class reload_generic :
|
|
object
|
|
method select_operation :
|
|
Cmm.operation
|
|
-> Cmm.expression list
|
|
-> Debuginfo.t
|
|
-> Mach.operation * Cmm.expression list
|
|
end
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 9,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 9,
|
|
"kind": "region",
|
|
"startCharacter": 19,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 2,
|
|
},
|
|
{
|
|
"endCharacter": 47,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 3,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for class_description", async () => {
|
|
openDocument(outdent`
|
|
module type T = sig
|
|
class cse_generic :
|
|
object
|
|
end
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 3,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 16,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 2,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for class_expr", async () => {
|
|
openDocument(outdent`
|
|
class x =
|
|
object
|
|
val x = 3
|
|
val virtual x : t
|
|
val! mutable x = 3
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for class_type", async () => {
|
|
openDocument(outdent`
|
|
class type t =
|
|
object
|
|
val x : t
|
|
val mutable x : t
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 5,
|
|
"endLine": 4,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 1,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pmod_functor and Pmod_structure", async () => {
|
|
openDocument(outdent`
|
|
module M =
|
|
functor (M : S) ->
|
|
(val x)
|
|
(struct
|
|
type t = int
|
|
let x =
|
|
Stdlib.print_endline "one";
|
|
Stdlib.print_endline "two";
|
|
end)
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 8,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 10,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 3,
|
|
},
|
|
{
|
|
"endCharacter": 35,
|
|
"endLine": 7,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 5,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pmty_functor and Pmty_signature", async () => {
|
|
openDocument(outdent`
|
|
module type S =
|
|
functor (M : S) (_ : module type of M) ->
|
|
sig
|
|
type t =
|
|
| A
|
|
| B
|
|
end
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 0,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 10,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 18,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 7,
|
|
"endLine": 6,
|
|
"kind": "region",
|
|
"startCharacter": 4,
|
|
"startLine": 2,
|
|
},
|
|
{
|
|
"endCharacter": 11,
|
|
"endLine": 5,
|
|
"kind": "region",
|
|
"startCharacter": 6,
|
|
"startLine": 3,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("returns folding ranges for Pexp_ifthenelse", async () => {
|
|
openDocument(outdent`
|
|
if tool_name = "ocamldep" then
|
|
if is_self_reference ~input_name ~loc lid then
|
|
{type_decl with ptype_manifest = None}
|
|
else {type_decl with ptype_manifest = Some manifest}
|
|
else
|
|
let x =
|
|
let () = Stdlib.print_endline "one" in
|
|
let () = Stdlib.print_endline "two" in
|
|
()
|
|
in
|
|
let y =
|
|
let () = Stdlib.print_endline "one" in
|
|
let () = Stdlib.print_endline "two" in
|
|
()
|
|
in
|
|
()
|
|
`);
|
|
|
|
const result = await foldingRange();
|
|
expect(result).toMatchInlineSnapshot(`
|
|
[
|
|
{
|
|
"endCharacter": 54,
|
|
"endLine": 3,
|
|
"kind": "region",
|
|
"startCharacter": 3,
|
|
"startLine": 0,
|
|
},
|
|
{
|
|
"endCharacter": 42,
|
|
"endLine": 2,
|
|
"kind": "region",
|
|
"startCharacter": 5,
|
|
"startLine": 1,
|
|
},
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 8,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 5,
|
|
},
|
|
{
|
|
"endCharacter": 6,
|
|
"endLine": 13,
|
|
"kind": "region",
|
|
"startCharacter": 2,
|
|
"startLine": 10,
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
});
|