Skip to content

Commit 9b9e4a6

Browse files
committed
chore: Generate classes for the LSP types
1 parent 8f71955 commit 9b9e4a6

File tree

18 files changed

+27784
-92
lines changed

18 files changed

+27784
-92
lines changed

CMakeLists.txt

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,38 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CXX_LIBCXX_WITH_CLANG)
4848
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
4949
endif()
5050

51-
# if CMAKE_SYSTEM_NAME is WASI disable the exceptions
51+
# if CMAKE_SYSTEM_NAME is WASI disable the exceptions, and the tests
5252
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
5353
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
54+
set(CXX_BUILD_TESTS OFF)
55+
56+
# set the executable suffix to .wasm
57+
set(CMAKE_EXECUTABLE_SUFFIX ".wasm")
5458
endif()
5559

56-
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
60+
#
61+
# google test
62+
#
63+
if(CXX_BUILD_TESTS)
64+
65+
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
66+
67+
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
5768

69+
FetchContent_Declare(
70+
googletest
71+
URL https://github.com/google/googletest/archive/refs/tags/v1.15.2.tar.gz
72+
)
73+
74+
FetchContent_MakeAvailable(googletest)
75+
76+
include(GoogleTest)
77+
78+
endif()
79+
80+
#
81+
# utfcpp
82+
#
5883
FetchContent_Declare(
5984
utfcpp
6085
URL https://github.com/nemtrif/utfcpp/archive/refs/tags/v4.0.5.tar.gz
@@ -64,6 +89,21 @@ FetchContent_Declare(
6489
FetchContent_MakeAvailable(utfcpp)
6590
FetchContent_GetProperties(utfcpp)
6691

92+
#
93+
# nlohmann_json
94+
#
95+
FetchContent_Declare(
96+
nlohmann_json
97+
URL https://github.com/nlohmann/json/releases/download/v3.11.3/include.zip
98+
URL_HASH SHA256=a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d
99+
)
100+
101+
FetchContent_MakeAvailable(nlohmann_json)
102+
103+
add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
104+
set_target_properties(nlohmann_json::nlohmann_json PROPERTIES
105+
INTERFACE_INCLUDE_DIRECTORIES "${nlohmann_json_SOURCE_DIR}/single_include")
106+
67107
FetchContent_Declare(
68108
wasi_sysroot
69109
URL https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sysroot-22.0.tar.gz

packages/cxx-gen-lsp/.prettierrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"printWidth": 120
3+
}

packages/cxx-gen-lsp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@
3333
"dependencies": {
3434
"prettier": "^3.3.3"
3535
}
36-
}
36+
}

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

Lines changed: 182 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,67 @@
1818
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919
// SOFTWARE.
2020

21-
export type Type = BaseType;
21+
export type Type =
22+
| BaseType
23+
| TupleType
24+
| OrType
25+
| AndType
26+
| ReferenceType
27+
| ArrayType
28+
| MapType
29+
| StringLiteralType
30+
| LiteralType;
2231

23-
export type BaseTypeName = "string" | "integer" | "uinteger";
32+
export type BaseTypeName = "null" | "string" | "integer" | "uinteger" | "decimal" | "boolean" | "DocumentUri" | "URI";
2433

2534
export type BaseType = {
2635
kind: "base";
2736
name: BaseTypeName;
2837
};
2938

39+
export type TupleType = {
40+
kind: "tuple";
41+
items: Type[];
42+
};
43+
44+
export type OrType = {
45+
kind: "or";
46+
items: Type[];
47+
};
48+
49+
export type AndType = {
50+
kind: "and";
51+
items: Type[];
52+
};
53+
54+
export type ReferenceType = {
55+
kind: "reference";
56+
name: string;
57+
};
58+
59+
export type ArrayType = {
60+
kind: "array";
61+
element: Type;
62+
};
63+
64+
export type MapType = {
65+
kind: "map";
66+
key: Type;
67+
value: Type;
68+
};
69+
70+
export type StringLiteralType = {
71+
kind: "stringLiteral";
72+
value: string;
73+
};
74+
75+
export type LiteralType = {
76+
kind: "literal";
77+
value: {
78+
properties: unknown[];
79+
};
80+
};
81+
3082
export type EnumerationValue = {
3183
name: string;
3284
value: string;
@@ -47,9 +99,25 @@ export type Notification = {};
4799

48100
export type Request = {};
49101

50-
export type Structure = {};
102+
export type Property = {
103+
documentation?: string;
104+
name: string;
105+
type: Type;
106+
optional?: boolean;
107+
};
108+
109+
export type Structure = {
110+
extends?: ReferenceType[];
111+
mixins?: ReferenceType[];
112+
name: string;
113+
properties: Property[];
114+
};
51115

52-
export type TypeAlias = {};
116+
export type TypeAlias = {
117+
documentation?: string;
118+
name: string;
119+
type: Type;
120+
};
53121

54122
export type MetaModel = {
55123
metaData: MetaData;
@@ -65,7 +133,7 @@ export function getEnumBaseType(enumeration: Enumeration) {
65133
case "integer":
66134
return " : int";
67135
case "uinteger":
68-
return " : unsigned int";
136+
return " : long";
69137
default:
70138
return "";
71139
}
@@ -80,12 +148,117 @@ export function getEnumeratorName(enumerator: EnumerationValue) {
80148
return `k${name}`;
81149
}
82150

83-
export function getEnumeratorInitializer(
84-
enumeration: Enumeration,
85-
enumerator: EnumerationValue
86-
) {
151+
export function getEnumeratorInitializer(enumeration: Enumeration, enumerator: EnumerationValue) {
87152
if (enumeration.type.name === "string") {
88153
return "";
89154
}
90155
return ` = ${enumerator.value}`;
91156
}
157+
158+
export function toCppType(type: Type): string {
159+
switch (type.kind) {
160+
case "base": {
161+
switch (type.name) {
162+
case "null":
163+
return "std::nullptr_t";
164+
case "string":
165+
return "std::string";
166+
case "integer":
167+
return "int";
168+
case "uinteger":
169+
return "long";
170+
case "decimal":
171+
return "double";
172+
case "boolean":
173+
return "bool";
174+
case "DocumentUri":
175+
return "std::string";
176+
case "URI":
177+
return "std::string";
178+
default:
179+
throw new Error(`Unknown base type: ${JSON.stringify(type)}`);
180+
} // switch type.name
181+
} // case "base"
182+
183+
case "stringLiteral":
184+
return "std::string";
185+
186+
case "literal":
187+
return "json";
188+
189+
case "reference":
190+
return type.name;
191+
192+
case "array":
193+
return `Vector<${toCppType(type.element)}>`;
194+
195+
case "map":
196+
return `Map<${toCppType(type.key)}, ${toCppType(type.value)}>`;
197+
198+
case "tuple":
199+
return `std::tuple<${type.items.map(toCppType).join(", ")}>`;
200+
201+
case "or":
202+
return `std::variant<std::monostate, ${type.items.map(toCppType).join(", ")}>`;
203+
204+
case "and":
205+
return `std::tuple<${type.items.map(toCppType).join(", ")}>`;
206+
207+
default:
208+
throw new Error(`Unknown type kind: ${JSON.stringify(type)}`);
209+
} // switch
210+
}
211+
212+
export function getStructureProperties(model: MetaModel, structure: Structure): Property[] {
213+
const structByName = new Map(model.structures.map((s) => [s.name, s]));
214+
const added = new Set<string>();
215+
return getStructurePropertiesHelper({ structure, added, structByName });
216+
}
217+
218+
function getStructurePropertiesHelper({
219+
structure,
220+
added,
221+
structByName,
222+
}: {
223+
structure: Structure;
224+
added: Set<string>;
225+
structByName: Map<string, Structure>;
226+
}): Property[] {
227+
const properties: Property[] = [];
228+
229+
for (const property of structure.properties) {
230+
if (added.has(property.name)) {
231+
continue;
232+
}
233+
added.add(property.name);
234+
properties.push(property);
235+
}
236+
237+
structure.extends?.forEach((ref) => {
238+
const extend = structByName.get(ref.name);
239+
240+
if (!extend) {
241+
throw new Error(`Unknown extends ${ref.name}`);
242+
}
243+
244+
properties.push(
245+
...getStructurePropertiesHelper({
246+
structure: extend,
247+
added,
248+
structByName,
249+
}),
250+
);
251+
});
252+
253+
structure.mixins?.forEach((ref) => {
254+
const mixin = structByName.get(ref.name);
255+
256+
if (!mixin) {
257+
throw new Error(`Unknown mixin ${ref.name}`);
258+
}
259+
260+
properties.push(...getStructurePropertiesHelper({ structure: mixin, added, structByName }));
261+
});
262+
263+
return properties;
264+
}

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

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,21 @@
2121
import { getEnumeratorName, MetaModel } from "./MetaModel.js";
2222

2323
import path from "node:path";
24-
import { writeFile } from "node:fs/promises";
24+
import { writeFileSync } from "node:fs";
2525
import { copyrightHeader } from "./copyrightHeader.js";
2626

27-
export async function gen_enums_cc({
28-
model,
29-
outputDirectory,
30-
}: {
31-
model: MetaModel;
32-
outputDirectory: string;
33-
}) {
27+
export function gen_enums_cc({ model, outputDirectory }: { model: MetaModel; outputDirectory: string }) {
3428
let out = "";
3529

3630
const emit = (s: string = "") => {
3731
out += `${s}\n`;
3832
};
3933

34+
emit(copyrightHeader);
35+
emit();
4036
emit(`#include <cxx/lsp/enums.h>`);
4137
emit();
38+
4239
emit(`namespace cxx::lsp {`);
4340

4441
model.enumerations.forEach((enumeration) => {
@@ -49,8 +46,7 @@ export async function gen_enums_cc({
4946
enumeration.values.forEach((enumerator) => {
5047
const enumeratorName = getEnumeratorName(enumerator);
5148

52-
const text =
53-
enumeration.type.name === "string" ? enumerator.value : enumerator.name;
49+
const text = enumeration.type.name === "string" ? enumerator.value : enumerator.name;
5450

5551
emit(` case ${enumeration.name}::${enumeratorName}:`);
5652
emit(` return "${text}";`);
@@ -64,5 +60,5 @@ export async function gen_enums_cc({
6460
emit(`} // namespace cxx::lsp`);
6561

6662
const outputFile = path.join(outputDirectory, "enums.cc");
67-
await writeFile(outputFile, out);
63+
writeFileSync(outputFile, out);
6864
}

0 commit comments

Comments
 (0)