Skip to content

Commit 4f2a658

Browse files
committed
chore: Add support for LSP string enumerations
Signed-off-by: Roberto Raggi <[email protected]>
1 parent e4872d7 commit 4f2a658

File tree

7 files changed

+450
-44
lines changed

7 files changed

+450
-44
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ export function gen_enums_cc({ model, outputDirectory }: { model: MetaModel; out
3434
emit(copyrightHeader);
3535
emit();
3636
emit(`#include <cxx/lsp/enums.h>`);
37+
emit(`#include <unordered_map>`);
38+
emit(`#include <format>`);
3739
emit();
3840

3941
emit(`namespace cxx::lsp {`);
@@ -58,7 +60,30 @@ export function gen_enums_cc({ model, outputDirectory }: { model: MetaModel; out
5860
emit(`}`);
5961
});
6062

63+
const stringEnums = model.enumerations.filter((enumeration) => enumeration.type.name === "string");
64+
6165
emit();
66+
emit(`namespace string_enums {`);
67+
stringEnums.forEach((enumeration) => {
68+
emit();
69+
emit(`auto parse${enumeration.name}(std::string_view name) -> std::optional<${enumeration.name}> {`);
70+
emit(` static std::unordered_map<std::string_view, ${enumeration.name}> map{`);
71+
enumeration.values.forEach((enumerator) => {
72+
const enumeratorName = getEnumeratorName(enumerator);
73+
const text = enumeration.type.name === "string" ? enumerator.value : enumerator.name;
74+
emit(` {"${text}", ${enumeration.name}::${enumeratorName}},`);
75+
});
76+
emit(` };`);
77+
emit(` const auto it = map.find(name);`);
78+
emit(` if (it != map.end()) `);
79+
emit(` return it->second;`);
80+
emit(` return std::nullopt;`);
81+
emit(`}`);
82+
});
83+
emit();
84+
emit(`} // namespace string_enums`);
85+
emit();
86+
6287
emit(`} // namespace cxx::lsp`);
6388

6489
const outputFile = path.join(outputDirectory, "enums.cc");

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export function gen_enums_h({ model, outputDirectory }: { model: MetaModel; outp
3636
emit(`#pragma once`);
3737
emit();
3838
emit(`#include <string>`);
39+
emit(`#include <string_view>`);
40+
emit(`#include <optional>`);
3941
emit(`#include <cxx/lsp/fwd.h>`);
4042
emit();
4143
emit(`namespace cxx::lsp {`);
@@ -56,6 +58,16 @@ export function gen_enums_h({ model, outputDirectory }: { model: MetaModel; outp
5658
emit(`auto to_string(${enumeration.name} value) -> std::string;`);
5759
});
5860
emit();
61+
62+
const stringEnums = model.enumerations.filter((enumeration) => enumeration.type.name === "string");
63+
emit(`namespace string_enums {`);
64+
emit();
65+
stringEnums.forEach((enumeration) => {
66+
emit(`[[nodiscard]] auto parse${enumeration.name}(std::string_view name) -> std::optional<${enumeration.name}>;`);
67+
});
68+
emit(`} // namespace string_enums`);
69+
emit();
70+
5971
emit(`} // namespace cxx::lsp`);
6072

6173
const outputFile = path.join(outputDirectory, "enums.h");

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class TypeGenerator {
8080
this.emit(copyrightHeader);
8181
this.emit();
8282
this.emit(`#include <cxx/lsp/types.h>`);
83+
this.emit(`#include <cxx/lsp/enums.h>`);
8384
this.emit();
8485
this.emit(`namespace cxx::lsp {`);
8586
this.emit();
@@ -268,8 +269,12 @@ class TypeGenerator {
268269
}
269270

270271
// todo: string-like enumeration
271-
console.log(`string-like enumeration: ${property.type.name}`);
272-
return false;
272+
this.emit(`const auto enumValue = string_enums::parse${property.type.name}(value.get<std::string>());`);
273+
this.emit();
274+
this.emit(`if (enumValue.has_value()) return *enumValue;`);
275+
this.emit();
276+
this.emit(`lsp_runtime_error("invalid value for ${property.type.name} enumeration");`);
277+
return true;
273278
}
274279

275280
if (this.typeAliasByName.has(property.type.name)) {
@@ -377,8 +382,9 @@ class TypeGenerator {
377382
return true;
378383
}
379384

380-
// TODO: string-like enumeration
381-
return false;
385+
// string-like enumeration
386+
this.emit(`(*repr_)["${property.name}"] = to_string(${value});`);
387+
return true;
382388
}
383389

384390
if (this.structByName.has(property.type.name)) {

src/frontend/cxx/lsp_server.cc

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -444,16 +444,7 @@ void Server::operator()(const CancelNotification& notification) {
444444
void Server::operator()(const SetTraceNotification& notification) {
445445
logTrace(std::format("Did receive SetTraceNotification"));
446446

447-
// TODO: LSP string enumerations
448-
const auto traceValue =
449-
notification.params().get().at("value").get<std::string>();
450-
451-
if (traceValue == "messages")
452-
trace_ = TraceValue::kMessages;
453-
else if (traceValue == "verbose")
454-
trace_ = TraceValue::kVerbose;
455-
else
456-
trace_ = TraceValue::kOff;
447+
trace_ = notification.params().value();
457448
}
458449

459450
void Server::operator()(const LSPRequest& request) {

0 commit comments

Comments
 (0)