skir-cc-gen 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "skir-cc-gen",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "keywords": [],
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/gepheum/skir-cc-gen.git"
9
+ },
10
+ "license": "ISC",
11
+ "author": "Tyler Fibonacci <gepheum@gmail.com>",
12
+ "type": "module",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "module": "./dist/index.js",
19
+ "files": [
20
+ "dist",
21
+ "src",
22
+ "client"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc && cd e2e-test && skir gen && cd ..",
26
+ "copy-to-client": "cp e2e-test/skir.h client && cp e2e-test/skir.cc client && cp e2e-test/skir.testing.h client",
27
+ "copy-to-client:check": "diff -s e2e-test/skir.h client/skir.h && diff -s e2e-test/skir.cc client/skir.cc && diff -s e2e-test/skir.testing.h client/skir.testing.h",
28
+ "format-skir": "cd e2e-test && skir format && cd ..",
29
+ "format-skir:check": "cd e2e-test && skir format check && cd ..",
30
+ "format-cc": "find e2e-test -not -path 'e2e-test/skirout/*' \\( -iname '*.cc' -o -iname '*.h' \\) | xargs clang-format --Werror -i",
31
+ "format-cc:check": "find e2e-test -not -path 'e2e-test/skirout/*' \\( -iname '*.cc' -o -iname '*.h' \\) | xargs clang-format --dry-run --Werror -i",
32
+ "format": "prettier --write \"**/*.ts\" && npm run format-skir && npm run format-cc",
33
+ "format:check": "prettier --check \"**/*.ts\" && npm run format-skir:check && npm run format-cc:check",
34
+ "gen-clang-json": "cd e2e-test && bazel run @hedron_compile_commands//:refresh_all && cd ..",
35
+ "test-cc": "cd e2e-test && CC=clang BAZEL_COMPILER=llvm bazel test --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address --linkopt=-fsanitize=address --test_output=errors :all && cd ..",
36
+ "build-client": "cd client && bazel build :skir && bazel build :skir.testing && cd ..",
37
+ "test": "npm run build && npm run test-cc && npm run build-client",
38
+ "lint": "eslint src/**/*.ts",
39
+ "lint:fix": "eslint src/**/*.ts --fix"
40
+ },
41
+ "dependencies": {
42
+ "skir-internal": "^0.0.6"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^20.11.5",
46
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
47
+ "@typescript-eslint/parser": "^6.13.0",
48
+ "eslint": "^8.54.0",
49
+ "prettier": "^3.2.4",
50
+ "prettier-plugin-organize-imports": "^4.2.0",
51
+ "skir": "^0.0.5",
52
+ "ts-node": "^10.9.2",
53
+ "typescript": "^5.3.3"
54
+ }
55
+ }
@@ -0,0 +1,126 @@
1
+ import { Doc, Field, ResolvedType, convertCase } from "skir-internal";
2
+ import { TypeSpeller } from "./type_speller.js";
3
+
4
+ interface MutableEnumVariant {
5
+ /** As specified in the .skir file. */
6
+ readonly variantName: string;
7
+ /** Examples: "bool", "Foo". Empty if the variant is a constant. */
8
+ readonly valueType: string;
9
+ /** Examples: "bool", "foo::Foo". Empty if the variant is a constant. */
10
+ readonly valueTypeWithNamespace: string;
11
+ /** As specified in the .skir file. */
12
+ variantNumber: number;
13
+ /** Whether the variant is the special UNKNOWN variant. */
14
+ isUnknownVariant: boolean;
15
+ /** Examples: "k_variant", "wrap_variant". */
16
+ readonly structType: string;
17
+ /** Example: "wrap_variant_type". Empty if the variant is a constant. */
18
+ readonly typeAlias: string;
19
+ /** kVariant or wrap_variant. */
20
+ readonly identifier: string;
21
+ /** kConstVariant or kValVariant */
22
+ readonly kindEnumerator: string;
23
+ /**
24
+ * True if the variant is a wrapper and the value should be allocated on the heap.
25
+ */
26
+ readonly usePointer: boolean;
27
+ readonly doc: Doc;
28
+ }
29
+
30
+ export type EnumVariant = Readonly<MutableEnumVariant>;
31
+
32
+ export function getEnumVariants(
33
+ variants: readonly Field[],
34
+ typeSpeller: TypeSpeller,
35
+ ): readonly EnumVariant[] {
36
+ const result: MutableEnumVariant[] = [];
37
+ result.push(makeUnknownVariant());
38
+ for (const inVariant of variants) {
39
+ let outVariant: MutableEnumVariant;
40
+ if (inVariant.type) {
41
+ outVariant = makeWrapperVariant(inVariant, inVariant.doc, typeSpeller);
42
+ } else {
43
+ outVariant = makeConstantVariant(inVariant.name.text, inVariant.doc);
44
+ }
45
+ outVariant.variantNumber = inVariant.number;
46
+ result.push(outVariant);
47
+ }
48
+ return result;
49
+ }
50
+
51
+ function makeUnknownVariant(): MutableEnumVariant {
52
+ return {
53
+ variantName: "?",
54
+ valueType: "",
55
+ valueTypeWithNamespace: "",
56
+ variantNumber: 0,
57
+ isUnknownVariant: true,
58
+ structType: `k_unknown`,
59
+ typeAlias: "",
60
+ identifier: `kUnknown`,
61
+ kindEnumerator: `kUnknown`,
62
+ usePointer: false,
63
+ doc: { text: "", pieces: [] },
64
+ };
65
+ }
66
+
67
+ function makeConstantVariant(
68
+ variantName: string,
69
+ doc: Doc,
70
+ ): MutableEnumVariant {
71
+ const lowerUnderscore = convertCase(variantName, "lower_underscore");
72
+ const upperCamel = convertCase(variantName, "UpperCamel");
73
+ return {
74
+ variantName: variantName,
75
+ valueType: "",
76
+ valueTypeWithNamespace: "",
77
+ variantNumber: 0,
78
+ isUnknownVariant: false,
79
+ structType: `k_${lowerUnderscore}`,
80
+ typeAlias: "",
81
+ identifier: `k${upperCamel}`,
82
+ kindEnumerator: `k${upperCamel}Const`,
83
+ usePointer: false,
84
+ doc: doc,
85
+ };
86
+ }
87
+
88
+ function makeWrapperVariant(
89
+ variant: Field,
90
+ doc: Doc,
91
+ typeSpeller: TypeSpeller,
92
+ ): MutableEnumVariant {
93
+ const variantName = variant.name.text;
94
+ const upperCamel = convertCase(variantName, "UpperCamel");
95
+ const type = variant.type!;
96
+ return {
97
+ variantName: variantName,
98
+ valueType: typeSpeller.getCcType(type),
99
+ valueTypeWithNamespace: typeSpeller.getCcType(type, {
100
+ forceNamespace: true,
101
+ }),
102
+ variantNumber: 0,
103
+ isUnknownVariant: false,
104
+ structType: `wrap_${variantName}`,
105
+ typeAlias: `wrap_${variantName}_type`,
106
+ identifier: `wrap_${variantName}`,
107
+ kindEnumerator: `k${upperCamel}Wrapper`,
108
+ usePointer: usePointer(variant.type!),
109
+ doc: doc,
110
+ };
111
+ }
112
+
113
+ function usePointer(type: ResolvedType): boolean {
114
+ if (type.kind !== "primitive") return true;
115
+ switch (type.primitive) {
116
+ case "bool":
117
+ case "int32":
118
+ case "int64":
119
+ case "uint64":
120
+ case "float32":
121
+ case "float64":
122
+ case "timestamp":
123
+ return false;
124
+ }
125
+ return true;
126
+ }