-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmoke.mjs
More file actions
124 lines (106 loc) · 3.04 KB
/
Copy pathsmoke.mjs
File metadata and controls
124 lines (106 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { spawn } from "node:child_process";
const doc = [
"@echo off",
"call :log hi",
"goto :eof",
"",
":log",
"echo %~1",
"exit /b 0",
].join("\n");
const uri = "file:///c:/tmp/sample.bat";
const server = spawn(process.execPath, [
import.meta.dirname + "/dist/server.js",
"--stdio",
]);
const send = (payload) => {
const body = JSON.stringify({ jsonrpc: "2.0", ...payload });
server.stdin.write(
"Content-Length: " + Buffer.byteLength(body) + "\r\n\r\n" + body,
);
};
let buffer = "";
const responses = new Map();
server.stdout.on("data", (chunk) => {
buffer += chunk.toString();
while (true) {
const headerEnd = buffer.indexOf("\r\n\r\n");
if (headerEnd < 0) return;
const length = Number(
buffer.slice(0, headerEnd).split("Content-Length:")[1].trim(),
);
const start = headerEnd + 4;
if (buffer.length < start + length) return;
const message = JSON.parse(buffer.slice(start, start + length));
buffer = buffer.slice(start + length);
if (message.id !== undefined) responses.set(message.id, message);
}
});
const waitFor = (id) =>
new Promise((resolve, reject) => {
const timer = setInterval(() => {
if (responses.has(id)) {
clearInterval(timer);
resolve(responses.get(id));
}
}, 20);
setTimeout(() => {
clearInterval(timer);
reject(new Error("timeout waiting for response " + id));
}, 8000);
});
const assert = (condition, message) => {
if (!condition) {
console.error("FAIL " + message);
server.kill();
process.exit(1);
}
console.log("ok " + message);
};
(async () => {
send({
id: 1,
method: "initialize",
params: { processId: null, rootUri: null, capabilities: {} },
});
const initialized = await waitFor(1);
const capabilities = initialized.result.capabilities;
assert(capabilities.definitionProvider, "definitionProvider advertised");
assert(capabilities.referencesProvider, "referencesProvider advertised");
assert(capabilities.renameProvider, "renameProvider advertised");
send({ method: "initialized", params: {} });
send({
method: "textDocument/didOpen",
params: { textDocument: { uri, languageId: "bat", version: 1, text: doc } },
});
send({
id: 2,
method: "textDocument/definition",
params: { textDocument: { uri }, position: { line: 1, character: 7 } },
});
const definition = await waitFor(2);
assert(definition.result, "definition returned for call :log");
assert(
definition.result.range.start.line === 4,
"definition points at line 4, got " + definition.result.range.start.line,
);
send({
id: 3,
method: "textDocument/references",
params: {
textDocument: { uri },
position: { line: 1, character: 7 },
context: { includeDeclaration: true },
},
});
const references = await waitFor(3);
assert(
references.result.length >= 2,
"found " + references.result.length + " references",
);
server.kill();
})().catch((error) => {
console.error("FAIL " + error.message);
server.kill();
process.exit(1);
});