Skip to content

Commit a2c00e1

Browse files
committed
chore: Set up code completion request handling in LSP server
Signed-off-by: Roberto Raggi <[email protected]>
1 parent c3aaa48 commit a2c00e1

File tree

6 files changed

+282
-153
lines changed

6 files changed

+282
-153
lines changed

packages/cxx-gen-lsp/src/gen_requests_h.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// SOFTWARE.
2020

2121
import * as path from "node:path";
22-
import { MetaModel, toCppType, Request, Notification, isRequest } from "./MetaModel.js";
22+
import { MetaModel, toCppType, Request, Notification, isRequest, Property, Structure } from "./MetaModel.js";
2323
import { writeFileSync } from "node:fs";
2424
import { copyrightHeader } from "./copyrightHeader.js";
2525

@@ -96,9 +96,27 @@ export function gen_requests_h({ model, outputDirectory }: { model: MetaModel; o
9696
emit();
9797
emit(` auto id(std::variant<long, std::string> id) -> ${responseTypeName}&;`);
9898
emit();
99-
emit(` [[nodiscard]] auto result() const -> ${resultType};`);
100-
emit();
101-
emit(` auto result(${resultType} result) -> ${responseTypeName}&;`);
99+
100+
const structure: Structure = {
101+
name: responseTypeName,
102+
properties: [{ name: "result", type: request.result, optional: false }],
103+
};
104+
105+
structure.properties.forEach((property) => {
106+
const propertyName = property.name;
107+
const returnType = toCppType(property.type);
108+
emit();
109+
emit(` [[nodiscard ]]auto ${propertyName}() const -> ${returnType};`);
110+
if (property.type.kind === "or") {
111+
emit();
112+
emit(`template <typename T>`);
113+
emit(`[[nodiscard]] auto ${propertyName}() -> T {`);
114+
emit(` auto& value = (*repr_)["${propertyName}"];`);
115+
emit(` return T(value);`);
116+
emit(`}`);
117+
}
118+
});
119+
102120
emit(`};`);
103121
}
104122
});

src/lsp/cxx/lsp/cxx_document.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ void CxxDocument::cancel() {
202202

203203
auto CxxDocument::fileName() const -> const std::string& { return d->fileName; }
204204

205+
void CxxDocument::requestCodeCompletion(std::uint32_t line,
206+
std::uint32_t column) {
207+
auto& unit = d->unit;
208+
unit.preprocessor()->requestCodeCompletionAt(line, column);
209+
}
210+
205211
void CxxDocument::parse(std::string source) {
206212
d->configure();
207213

src/lsp/cxx/lsp/cxx_document.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class CxxDocument {
3939

4040
[[nodiscard]] auto fileName() const -> const std::string&;
4141

42+
void requestCodeCompletion(std::uint32_t line, std::uint32_t column);
43+
4244
void parse(std::string source);
4345

4446
[[nodiscard]] auto version() const -> long;

src/lsp/cxx/lsp/lsp_server.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,11 @@ void Server::operator()(InitializeRequest request) {
364364
capabilities.textDocumentSync(TextDocumentSyncKind::kIncremental);
365365
capabilities.documentSymbolProvider(true);
366366

367+
auto completionOptions =
368+
capabilities.completionProvider<CompletionOptions>();
369+
370+
completionOptions.triggerCharacters({":", ".", ">"});
371+
367372
sendToClient(response);
368373
});
369374
}
@@ -478,6 +483,37 @@ void Server::operator()(DocumentSymbolRequest request) {
478483
});
479484
}
480485

486+
void Server::operator()(CompletionRequest request) {
487+
logTrace(std::format("Did receive CompletionRequest"));
488+
489+
auto textDocument = request.params().textDocument();
490+
auto uri = textDocument.uri();
491+
auto id = request.id();
492+
auto line = request.params().position().line();
493+
auto column = request.params().position().character();
494+
495+
const auto& text = documentContents_.at(uri);
496+
auto value = text.value;
497+
498+
run([=, this, fileName = pathFromUri(uri)] {
499+
withUnsafeJson([&](json storage) {
500+
// the version is not relevant for code completion requests as we don't
501+
// need to store the document in the cache.
502+
auto cxxDocument = std::make_shared<CxxDocument>(cli, std::move(fileName),
503+
/*version=*/0);
504+
505+
// cxx expects 1-based line and column numbers
506+
cxxDocument->requestCodeCompletion(line + 1, column + 1);
507+
cxxDocument->parse(std::move(value));
508+
509+
CompletionResponse response(storage);
510+
response.id(request.id());
511+
auto completionItems = response.result<Vector<CompletionItem>>();
512+
sendToClient(response);
513+
});
514+
});
515+
}
516+
481517
void Server::operator()(CancelNotification notification) {
482518
const auto id = notification.params().id();
483519

src/lsp/cxx/lsp/lsp_server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Server {
5858
void operator()(DidChangeTextDocumentNotification notification);
5959

6060
void operator()(DocumentSymbolRequest request);
61+
void operator()(CompletionRequest request);
6162

6263
void operator()(SetTraceNotification notification);
6364

0 commit comments

Comments
 (0)