cluaupp 0.2.3 → 1.0.0

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +10 -79
  2. package/README.md +42 -88
  3. package/docs/README.md +13 -21
  4. package/docs/architecture.md +13 -76
  5. package/docs/cli.md +12 -64
  6. package/docs/comparison.md +6 -24
  7. package/docs/config.md +6 -7
  8. package/docs/examples/combat.md +19 -227
  9. package/docs/examples/hud.md +13 -81
  10. package/docs/examples/index.md +9 -16
  11. package/docs/getting-started.md +20 -137
  12. package/docs/intellisense.md +5 -41
  13. package/docs/intro.md +16 -15
  14. package/docs/migration.md +38 -0
  15. package/docs/oop/file-tags.md +12 -36
  16. package/docs/oop/index.md +8 -14
  17. package/docs/syntax.md +54 -236
  18. package/editors/vscode/extension.js +1 -1
  19. package/editors/vscode/package.json +4 -4
  20. package/examples/README.md +5 -7
  21. package/examples/game/.vscode/extensions.json +0 -3
  22. package/examples/game/.vscode/settings.json +6 -14
  23. package/examples/game/src/client/hud.client.clpp +54 -0
  24. package/examples/game/src/client/init.client.clpp +6 -0
  25. package/examples/game/src/server/combat.server.clpp +85 -0
  26. package/examples/game/src/server/leaderstats.server.clpp +28 -0
  27. package/examples/game/src/shared/PlayerData.clh +20 -0
  28. package/examples/game/src/shared/config.clp +6 -0
  29. package/examples/game/src/shared/features.clp +88 -0
  30. package/generated/cli.js +40 -24
  31. package/generated/clpp/contract.js +5 -0
  32. package/generated/clpp/index.js +27 -0
  33. package/generated/clpp/paths.js +121 -0
  34. package/generated/clpp/postprocess.js +78 -0
  35. package/generated/clpp/runner.js +102 -0
  36. package/generated/compile.js +26 -138
  37. package/generated/intellisense.js +38 -157
  38. package/generated/libs.js +1 -1
  39. package/generated/lsp.js +1 -8
  40. package/generated/preprocess.js +8 -179
  41. package/generated/system-understander.js +1 -1
  42. package/generated/transpile.js +3 -50
  43. package/generated/utils/project.js +13 -28
  44. package/include/{cluaupp/datatypes.hpp → clpp/datatypes.clh} +1 -1
  45. package/include/{cluaupp/generated/instances.hpp → clpp/generated/instances.clh} +1 -1
  46. package/include/{cluaupp/libs/chrono.hpp → clpp/libs/chrono.clh} +9 -9
  47. package/include/{cluaupp/libs/cmdr.hpp → clpp/libs/cmdr.clh} +4 -4
  48. package/include/{cluaupp/libs/dataservice.hpp → clpp/libs/dataservice.clh} +8 -15
  49. package/include/{cluaupp/libs/display.hpp → clpp/libs/display.clh} +1 -2
  50. package/include/{cluaupp/libs/ezvisual.hpp → clpp/libs/ezvisual.clh} +1 -3
  51. package/include/{cluaupp/libs/formatnumber.hpp → clpp/libs/formatnumber.clh} +2 -3
  52. package/include/{cluaupp/libs/fusion.hpp → clpp/libs/fusion.clh} +5 -5
  53. package/include/{cluaupp/libs/iris.hpp → clpp/libs/iris.clh} +2 -2
  54. package/include/{cluaupp/libs/janitor.hpp → clpp/libs/janitor.clh} +1 -2
  55. package/include/{cluaupp/libs/module3d.hpp → clpp/libs/module3d.clh} +2 -4
  56. package/include/{cluaupp/libs/net.hpp → clpp/libs/net.clh} +2 -4
  57. package/include/{cluaupp/libs/promise.hpp → clpp/libs/promise.clh} +1 -4
  58. package/include/{cluaupp/libs/spring.hpp → clpp/libs/spring.clh} +1 -2
  59. package/include/{cluaupp/libs/statemachine.hpp → clpp/libs/statemachine.clh} +2 -3
  60. package/include/{cluaupp/libs/stickybillboard.hpp → clpp/libs/stickybillboard.clh} +1 -2
  61. package/include/{cluaupp/libs/topbarplus.hpp → clpp/libs/topbarplus.clh} +3 -4
  62. package/include/clpp/libs.clh +24 -0
  63. package/include/clpp/roblox.clh +31 -0
  64. package/package.json +7 -14
  65. package/src/cli.ts +39 -25
  66. package/src/clpp/contract.ts +39 -0
  67. package/src/clpp/index.ts +18 -0
  68. package/src/clpp/paths.ts +117 -0
  69. package/src/clpp/postprocess.ts +93 -0
  70. package/src/clpp/runner.ts +102 -0
  71. package/src/compile.ts +26 -149
  72. package/src/intellisense.ts +36 -165
  73. package/src/libs.ts +1 -1
  74. package/src/lsp.ts +1 -5
  75. package/src/preprocess.ts +8 -180
  76. package/src/system-understander.ts +1 -1
  77. package/src/transpile.ts +9 -52
  78. package/src/utils/project.ts +12 -28
  79. package/templates/game/.vscode/extensions.json +0 -3
  80. package/templates/game/.vscode/settings.json +6 -14
  81. package/templates/game/src/client/init.client.clpp +6 -0
  82. package/templates/game/src/server/leaderstats.server.clpp +29 -0
  83. package/templates/game/src/shared/config.clp +6 -0
  84. package/examples/game/.clangd +0 -25
  85. package/examples/game/compile_flags.txt +0 -6
  86. package/examples/game/src/client/hud.client.cpp +0 -12
  87. package/examples/game/src/client/init.client.cpp +0 -6
  88. package/examples/game/src/server/combat.server.cpp +0 -23
  89. package/examples/game/src/server/leaderstats.server.cpp +0 -29
  90. package/examples/game/src/shared/config.cpp +0 -5
  91. package/examples/game/src/shared/config.h +0 -5
  92. package/include/cluaupp/libs.hpp +0 -25
  93. package/include/cluaupp/roblox.hpp +0 -47
  94. package/src/architecture.ts +0 -500
  95. package/src/ast.ts +0 -37
  96. package/src/emit.ts +0 -609
  97. package/src/emitter/luau-codegen.ts +0 -187
  98. package/src/emitter/translators.ts +0 -168
  99. package/src/headers.ts +0 -233
  100. package/src/layout.ts +0 -114
  101. package/src/lex.ts +0 -158
  102. package/src/parse.ts +0 -729
  103. package/src/parser/collector.ts +0 -148
  104. package/src/parser/index.ts +0 -27
  105. package/src/tree-sitter-cpp.d.ts +0 -4
  106. package/src/understand.ts +0 -322
  107. package/templates/game/src/client/init.client.cpp +0 -6
  108. package/templates/game/src/server/leaderstats.server.cpp +0 -29
  109. package/templates/game/src/shared/config.cpp +0 -5
  110. package/templates/game/src/shared/config.h +0 -5
  111. /package/include/{cluaupp/generated/enums.hpp → clpp/generated/enums.clh} +0 -0
  112. /package/include/{cluaupp/libs/math.hpp → clpp/libs/math.clh} +0 -0
  113. /package/include/{cluaupp/libs/twinkle.hpp → clpp/libs/twinkle.clh} +0 -0
  114. /package/include/{cluaupp/libs/vfx.hpp → clpp/libs/vfx.clh} +0 -0
@@ -1,181 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SOURCE_EXTS = void 0;
7
- exports.isSourceFile = isSourceFile;
8
- exports.isHeaderFile = isHeaderFile;
9
- exports.toLuauPath = toLuauPath;
10
- exports.isEngineStub = isEngineStub;
11
- exports.siblingImplementation = siblingImplementation;
12
- exports.siblingHeader = siblingHeader;
13
- exports.implOutName = implOutName;
14
- exports.resolveInclude = resolveInclude;
15
- exports.scanHeaderExports = scanHeaderExports;
16
- exports.applyPragmas = applyPragmas;
17
- exports.preprocess = preprocess;
18
- const node_fs_1 = __importDefault(require("node:fs"));
19
- const node_path_1 = __importDefault(require("node:path"));
20
- exports.SOURCE_EXTS = [".cpp", ".cc", ".cxx", ".c", ".h", ".hpp", ".hh"];
21
- function isSourceFile(fileName) {
22
- return exports.SOURCE_EXTS.includes(node_path_1.default.extname(fileName).toLowerCase());
23
- }
24
- function isHeaderFile(fileName) {
25
- return [".h", ".hpp", ".hh"].includes(node_path_1.default.extname(fileName).toLowerCase());
26
- }
27
- function toLuauPath(filePath) {
28
- return filePath.replace(/\.(cpp|cc|cxx|c|h|hpp|hh)$/i, ".luau");
29
- }
30
- function isEngineStub(filePath) {
31
- const normalized = filePath.replace(/\\/g, "/").toLowerCase();
32
- return (normalized.includes("/include/cluaupp/") ||
33
- normalized.includes("/include/cluau/") ||
34
- normalized.endsWith("/roblox.hpp") ||
35
- normalized.endsWith("/roblox.h"));
36
- }
37
- function includeVariants(name) {
38
- const variants = [name];
39
- if (/\.h$/i.test(name)) {
40
- variants.push(name.replace(/\.h$/i, ".hpp"), name.replace(/\.h$/i, ".hh"));
41
- }
42
- else if (/\.hpp$/i.test(name)) {
43
- variants.push(name.replace(/\.hpp$/i, ".h"), name.replace(/\.hpp$/i, ".hh"));
44
- }
45
- else if (/\.hh$/i.test(name)) {
46
- variants.push(name.replace(/\.hh$/i, ".h"), name.replace(/\.hh$/i, ".hpp"));
47
- }
48
- return [...new Set(variants)];
49
- }
50
- function siblingImplementation(headerPath) {
51
- if (!headerPath || !isHeaderFile(headerPath)) {
52
- return null;
53
- }
54
- const base = headerPath.replace(/\.(h|hpp|hh)$/i, "");
55
- for (const ext of [".cpp", ".cc", ".cxx", ".c"]) {
56
- if (node_fs_1.default.existsSync(base + ext)) {
57
- return base + ext;
58
- }
59
- }
60
- return null;
61
- }
62
- function siblingHeader(implPath) {
63
- if (!implPath || isHeaderFile(implPath)) {
64
- return null;
65
- }
66
- const base = String(implPath).replace(/\.(cpp|cc|cxx|c)$/i, "");
67
- if (base === String(implPath)) {
68
- return null;
69
- }
70
- for (const ext of [".h", ".hpp", ".hh"]) {
71
- if (node_fs_1.default.existsSync(base + ext)) {
72
- return base + ext;
73
- }
74
- }
75
- return null;
76
- }
77
- function implOutName(rel) {
78
- return String(rel)
79
- .replace(/\\/g, "/")
80
- .replace(/\.(cpp|cc|cxx|c)$/i, "Impl.luau");
81
- }
82
- function resolveInclude(name, fromFile, includeDirs) {
83
- const bases = [node_path_1.default.dirname(fromFile), ...(includeDirs || [])];
84
- for (const base of bases) {
85
- for (const variant of includeVariants(name)) {
86
- const candidate = node_path_1.default.resolve(base, variant);
87
- if (node_fs_1.default.existsSync(candidate) && node_fs_1.default.statSync(candidate).isFile()) {
88
- return candidate;
89
- }
90
- }
91
- }
92
- return null;
93
- }
94
- function scanHeaderExports(source) {
95
- const consts = [];
96
- const structs = [];
97
- for (const match of String(source).matchAll(/\bconst\s+(?:int|bool|float|double|auto|string)\s+(\w+)/g)) {
98
- if (!consts.includes(match[1])) {
99
- consts.push(match[1]);
100
- }
101
- }
102
- for (const match of String(source).matchAll(/\bstruct\s+(\w+)/g)) {
103
- if (!structs.includes(match[1])) {
104
- structs.push(match[1]);
105
- }
106
- }
107
- const hasProtos = /\b(?:void|int|bool|float|double|auto|string|[\w:]+)\s+\w+\s*\([^;]*\)\s*;/.test(String(source));
108
- return { consts, structs, hasProtos };
109
- }
110
- function pushModuleInclude(options, resolved, impl) {
111
- options.moduleIncludes = options.moduleIncludes || [];
112
- const srcDir = options.srcDir || null;
113
- const moduleFile = impl || resolved;
114
- const rel = srcDir ? node_path_1.default.relative(srcDir, moduleFile).replace(/\\/g, "/") : node_path_1.default.basename(moduleFile);
115
- const headerText = node_fs_1.default.readFileSync(resolved, "utf8");
116
- options.moduleIncludes.push({
117
- name: node_path_1.default.basename(resolved).replace(/\.(h|hpp|hh)$/i, ""),
118
- outRel: rel.replace(/\.(cpp|cc|cxx|c|h|hpp|hh)$/i, ".luau"),
119
- header: resolved,
120
- impl: impl || null,
121
- exports: scanHeaderExports(headerText),
122
- });
123
- }
124
- function applyPragmas(source, options) {
125
- let nstrict = false;
126
- let strict = false;
127
- for (const line of String(source).split(/\r?\n/)) {
128
- if (/^\s*#\s*pragma\s+nstrict\b/i.test(line)) {
129
- nstrict = true;
130
- }
131
- else if (/^\s*#\s*pragma\s+strict\b/i.test(line)) {
132
- strict = true;
133
- }
134
- }
135
- if (nstrict) {
136
- options.strict = false;
137
- }
138
- else if (strict) {
139
- options.strict = true;
140
- }
141
- }
142
- function preprocess(source, filePath, options = {}) {
143
- if (!options.pragmaResolved) {
144
- options.pragmaResolved = true;
145
- applyPragmas(source, options);
146
- }
147
- const seen = options.seen || new Set();
148
- options.seen = seen;
149
- const includeDirs = options.includeDirs || [];
150
- const resolvedSelf = filePath ? node_path_1.default.resolve(filePath) : null;
151
- if (resolvedSelf) {
152
- seen.add(resolvedSelf);
153
- }
154
- const lines = String(source).split(/\r?\n/);
155
- const out = [];
156
- for (const line of lines) {
157
- const quoted = line.match(/^\s*#\s*include\s+"([^"]+)"/);
158
- if (quoted) {
159
- const resolved = resolveInclude(quoted[1], filePath || process.cwd(), includeDirs);
160
- if (!resolved || isEngineStub(resolved) || seen.has(resolved)) {
161
- continue;
162
- }
163
- const impl = siblingImplementation(resolved);
164
- const including = filePath ? node_path_1.default.resolve(filePath) : null;
165
- const ownHeader = Boolean(impl && including && node_path_1.default.resolve(impl) === including);
166
- if (!ownHeader) {
167
- pushModuleInclude(options, resolved, impl);
168
- continue;
169
- }
170
- seen.add(resolved);
171
- const inner = node_fs_1.default.readFileSync(resolved, "utf8");
172
- out.push(preprocess(inner, resolved, { ...options, seen }));
173
- continue;
174
- }
175
- if (/^\s*#\s*include\s+</.test(line)) {
176
- continue;
177
- }
178
- out.push(line);
179
- }
180
- return out.join("\n");
181
- }
3
+ exports.siblingHeader = exports.toLuauPath = exports.isEngineStub = exports.isHeaderFile = exports.isSourceFile = exports.SOURCE_EXTS = void 0;
4
+ var paths_js_1 = require("./clpp/paths.js");
5
+ Object.defineProperty(exports, "SOURCE_EXTS", { enumerable: true, get: function () { return paths_js_1.SOURCE_EXTS; } });
6
+ Object.defineProperty(exports, "isSourceFile", { enumerable: true, get: function () { return paths_js_1.isSourceFile; } });
7
+ Object.defineProperty(exports, "isHeaderFile", { enumerable: true, get: function () { return paths_js_1.isHeaderFile; } });
8
+ Object.defineProperty(exports, "isEngineStub", { enumerable: true, get: function () { return paths_js_1.isEngineStub; } });
9
+ Object.defineProperty(exports, "toLuauPath", { enumerable: true, get: function () { return paths_js_1.toLuauPath; } });
10
+ Object.defineProperty(exports, "siblingHeader", { enumerable: true, get: function () { return paths_js_1.siblingHeader; } });
@@ -11,7 +11,7 @@ exports.scoreIntents = scoreIntents;
11
11
  exports.determineArchitecture = determineArchitecture;
12
12
  exports.understandSystem = understandSystem;
13
13
  const node_path_1 = __importDefault(require("node:path"));
14
- const EXT = "(cpp|cc|cxx|c|h|hpp|hh)";
14
+ const EXT = "(clpp|clp|clh)";
15
15
  const EXT_REGEX = new RegExp(`\\.${EXT}$`, "i");
16
16
  const SCORE_THRESHOLD = 2;
17
17
  const TREE_NAME_TYPES = new Set([
@@ -3,64 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.collectState = collectState;
7
6
  exports.transpileSource = transpileSource;
8
7
  exports.outputNameFor = outputNameFor;
9
8
  const node_path_1 = __importDefault(require("node:path"));
10
- const collector_js_1 = require("./parser/collector.js");
11
- const index_js_1 = require("./parser/index.js");
12
- const luau_codegen_js_1 = require("./emitter/luau-codegen.js");
13
9
  const compile_js_1 = require("./compile.js");
14
- const system_understander_js_1 = require("./system-understander.js");
15
- function shouldMerge(name, contents) {
16
- const file = String(name || "").replace(/\\/g, "/");
17
- if (/\.json$/i.test(file) || /\.meta\.json$/i.test(file)) {
18
- return false;
19
- }
20
- const trimmed = String(contents || "").trim();
21
- return !(trimmed.startsWith("{") || trimmed.startsWith("["));
22
- }
23
- function collectState(source, mapper, options) {
24
- const tree = (0, index_js_1.parseCpp)(source);
25
- if (!tree) {
26
- const state = luau_codegen_js_1.LuauCodeEmitter.emptyState(options.strict === true);
27
- return state;
28
- }
29
- const collector = new collector_js_1.ASTCollector(mapper, {
30
- fileName: options.relativeName || options.filePath || "input.cpp",
31
- sourcePath: options.filePath,
32
- srcDir: options.srcDir,
33
- outDir: options.outDir,
34
- strict: options.strict,
35
- });
36
- const state = collector.collect(tree.rootNode);
37
- const report = (0, system_understander_js_1.determineArchitecture)(options.relativeName || options.filePath || "input.cpp", null, tree.rootNode);
38
- for (const service of report.injectedServices) {
39
- state.robloxServices.add(service);
40
- }
41
- for (const line of report.reasoning) {
42
- state.headerLines.push(`-- ${line}`);
43
- }
44
- return state;
45
- }
46
- function transpileSource(source, fileName, options, mapper) {
47
- const state = collectState(source, mapper, options);
48
- if (state.strict) {
49
- options.strict = true;
50
- }
51
- const compiled = (0, compile_js_1.compileService)(source, fileName, options);
52
- return {
53
- ...compiled,
54
- files: compiled.files.map((file) => ({
55
- ...file,
56
- contents: shouldMerge(file.name, file.contents) ? luau_codegen_js_1.LuauCodeEmitter.merge(state, file.contents) : file.contents,
57
- })),
58
- };
10
+ function transpileSource(source, fileName, options, _mapper) {
11
+ return (0, compile_js_1.compileService)(source, fileName, options);
59
12
  }
60
13
  function outputNameFor(inputFile, outputPath) {
61
14
  if (/\.luau$/i.test(outputPath)) {
62
15
  return outputPath;
63
16
  }
64
- const base = node_path_1.default.basename(inputFile).replace(/\.(cpp|cc|cxx|c|h|hpp|hh)$/i, ".luau");
17
+ const base = node_path_1.default.basename(inputFile).replace(/\.(clpp|clp|clh)$/i, ".luau");
65
18
  return node_path_1.default.join(outputPath, base);
66
19
  }
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.collectSourcesFiles = void 0;
6
7
  exports.loadConfig = loadConfig;
7
8
  exports.collectCpp = collectCpp;
8
9
  exports.build = build;
@@ -11,7 +12,7 @@ exports.watch = watch;
11
12
  const node_fs_1 = __importDefault(require("node:fs"));
12
13
  const node_path_1 = __importDefault(require("node:path"));
13
14
  const package_info_js_1 = require("../package-info.js");
14
- const preprocess_js_1 = require("../preprocess.js");
15
+ const paths_js_1 = require("../clpp/paths.js");
15
16
  const intellisense_js_1 = require("../intellisense.js");
16
17
  const process_orchestrator_js_1 = require("./process-orchestrator.js");
17
18
  const rojo_mapper_js_1 = require("./rojo-mapper.js");
@@ -142,27 +143,16 @@ function copyRuntime(dest) {
142
143
  syncDir(runtime, node_path_1.default.join(dest, "libs"));
143
144
  }
144
145
  function copyHeaders(dest) {
145
- const from = node_path_1.default.join(__dirname, "..", "..", "include", "cluaupp");
146
+ const from = node_path_1.default.join(__dirname, "..", "..", "include", "clpp");
146
147
  if (!node_fs_1.default.existsSync(from)) {
147
148
  return;
148
149
  }
149
- syncDir(from, node_path_1.default.join(dest, "include", "cluaupp"));
150
+ syncDir(from, node_path_1.default.join(dest, "include", "clpp"));
150
151
  }
151
152
  function collectCpp(dir, files = []) {
152
- if (!node_fs_1.default.existsSync(dir)) {
153
- return files;
154
- }
155
- for (const entry of node_fs_1.default.readdirSync(dir, { withFileTypes: true })) {
156
- const full = node_path_1.default.join(dir, entry.name);
157
- if (entry.isDirectory()) {
158
- collectCpp(full, files);
159
- }
160
- else if ((0, preprocess_js_1.isSourceFile)(entry.name)) {
161
- files.push(full);
162
- }
163
- }
164
- return files;
153
+ return (0, paths_js_1.collectSources)(dir, files);
165
154
  }
155
+ exports.collectSourcesFiles = paths_js_1.collectSources;
166
156
  function collectFiles(dir, files = []) {
167
157
  if (!node_fs_1.default.existsSync(dir)) {
168
158
  return files;
@@ -186,9 +176,9 @@ function posixRel(from, file) {
186
176
  return node_path_1.default.relative(from, file).replace(/\\/g, "/");
187
177
  }
188
178
  function sourcePrefixes(rel) {
189
- const noExt = rel.replace(/\.(cpp|cc|cxx|c|h|hpp|hh)$/i, "");
179
+ const noExt = rel.replace(/\.(clpp|clp|clh)$/i, "");
190
180
  const noTag = noExt.replace(/\.(server|client)$/i, "");
191
- return [...new Set([noExt, noTag, (0, preprocess_js_1.toLuauPath)(rel).replace(/\\/g, "/")])];
181
+ return [...new Set([noExt, noTag, (0, paths_js_1.toLuauPath)(rel).replace(/\\/g, "/")])];
192
182
  }
193
183
  function matchesPrefix(relOut, prefixes) {
194
184
  const n = relOut.replace(/\\/g, "/").toLowerCase();
@@ -253,7 +243,7 @@ function createMapper(root, config, rojoPath) {
253
243
  }
254
244
  function compileProject(root, config, mapper) {
255
245
  const srcDir = node_path_1.default.join(root, config.rootDir);
256
- const files = collectCpp(srcDir);
246
+ const files = (0, paths_js_1.collectSources)(srcDir);
257
247
  const jobs = [];
258
248
  const errors = [];
259
249
  for (const file of files) {
@@ -264,7 +254,7 @@ function compileProject(root, config, mapper) {
264
254
  ...config,
265
255
  filePath: file,
266
256
  relativeName: rel,
267
- outName: (0, preprocess_js_1.toLuauPath)(rel),
257
+ outName: (0, paths_js_1.toLuauPath)(rel),
268
258
  architecture: config.architecture === true,
269
259
  includeDirs: [node_path_1.default.dirname(file), srcDir, node_path_1.default.join(root, "include")],
270
260
  srcDir,
@@ -341,8 +331,8 @@ function build(root, options = {}) {
341
331
  ensureVendor(root);
342
332
  }
343
333
  const srcDir = node_path_1.default.join(root, config.rootDir);
344
- if (!node_fs_1.default.existsSync(srcDir) || collectCpp(srcDir).length === 0) {
345
- console.error("no .cpp/.h/.hpp files in", config.rootDir);
334
+ if (!node_fs_1.default.existsSync(srcDir) || (0, paths_js_1.collectSources)(srcDir).length === 0) {
335
+ console.error("no .clpp/.clp/.clh files in", config.rootDir);
346
336
  if (!holdOnError) {
347
337
  pruneOut(root, config, new Set(), []);
348
338
  }
@@ -400,16 +390,11 @@ async function init(dest) {
400
390
  copyDir(include, node_path_1.default.join(target, "include"));
401
391
  copyRuntime(target);
402
392
  (0, intellisense_js_1.syncEditorSupport)(target);
403
- const installed = await (0, intellisense_js_1.installEditorSupport)();
404
393
  console.log("Cluaupp ready in", target);
394
+ console.log(" clpp install (CL++ highlighting + IntelliSense)");
405
395
  console.log(" rokit install");
406
396
  console.log(" cluaupp build");
407
397
  console.log(" rojo serve");
408
- if (installed.local.length ||
409
- (installed.clangd && (installed.clangd.status === "installed" || installed.clangd.status === "already")) ||
410
- (installed.llvm && (installed.llvm.status === "installed" || installed.llvm.status === "already"))) {
411
- console.log(" reload Cursor (Ctrl+Shift+P → Developer: Reload Window)");
412
- }
413
398
  }
414
399
  function pidAlive(pid) {
415
400
  try {
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #include <cluaupp/generated/enums.hpp>
2
+ #include <clpp/generated/enums.clh>
3
3
  using Enum::EasingStyle;
4
4
  using Enum::EasingDirection;
5
5
  using Enum::Material;
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #include <cluaupp/datatypes.hpp>
2
+ #include <clpp/datatypes.clh>
3
3
 
4
4
  struct Object;
5
5
  struct AnimatedImageTrack;
@@ -1,15 +1,15 @@
1
1
  #pragma once
2
2
 
3
3
  // Parihsz/Chrono — custom character replication, vendored into CluauppLibs.Chrono
4
- class ChronoHolder {};
5
- class ChronoEntity {};
6
- class ChronoStats {};
7
- class ChronoConfig {};
8
- class ChronoReplicationRules {};
9
- class ChronoEvents {};
10
- class ChronoSnapshots {};
11
- class ChronoServerClock {};
12
- class ChronoPlayer {};
4
+ struct ChronoHolder {};
5
+ struct ChronoEntity {};
6
+ struct ChronoStats {};
7
+ struct ChronoConfig {};
8
+ struct ChronoReplicationRules {};
9
+ struct ChronoEvents {};
10
+ struct ChronoSnapshots {};
11
+ struct ChronoServerClock {};
12
+ struct ChronoPlayer {};
13
13
 
14
14
  namespace Chrono {
15
15
  void Start();
@@ -1,10 +1,10 @@
1
1
  #pragma once
2
2
 
3
3
  // evaera/Cmdr — vendored into CluauppLibs.Cmdr (server). Client: Cmdr.CmdrClient
4
- class CmdrType {};
5
- class CmdrCommand {};
6
- class CmdrRegistry {};
7
- class CmdrDispatcher {};
4
+ struct CmdrType {};
5
+ struct CmdrCommand {};
6
+ struct CmdrRegistry {};
7
+ struct CmdrDispatcher {};
8
8
 
9
9
  namespace Cmdr {
10
10
  void RegisterDefaultCommands();
@@ -3,14 +3,11 @@
3
3
  // KartzRbx/DataServiceV2 — https://github.com/KartzRbx/DataServiceV2
4
4
  // Runtime: CluauppLibs.DataService
5
5
  //
6
- // Real surface (not Get(player, path)):
7
- // DataService.Server / DataService.Client / DataService.Paths / DataService.Enum
8
- // local data = Server:WaitFor(player)
9
- // data:Get(Paths.Currencies.Coins)
10
- // data:GetChangedSignal(path):Connect(function(newValue, oldValue) end)
6
+ // Real surface:
7
+ // DataService:Server / DataService:Client / DataService:Paths / DataService:Enum
11
8
 
12
- class DataPath {};
13
- class DataProfile {};
9
+ struct DataPath {};
10
+ struct DataProfile {};
14
11
 
15
12
  struct DataBufferStats {
16
13
  double Bytes;
@@ -45,8 +42,7 @@ struct DataServiceOptions {
45
42
  bool AutoCreateMissingTables;
46
43
  };
47
44
 
48
- class Data {
49
- public:
45
+ struct Data {
50
46
  RBXScriptSignal Changed;
51
47
  bool Destroyed;
52
48
 
@@ -112,8 +108,7 @@ public:
112
108
  void Destroy();
113
109
  };
114
110
 
115
- class DataServiceServer {
116
- public:
111
+ struct DataServiceServer {
117
112
  DataPath Paths;
118
113
  template <typename T>
119
114
  DataServiceServer* Init(DataServiceOptions<T> options);
@@ -126,8 +121,7 @@ public:
126
121
  void Destroy();
127
122
  };
128
123
 
129
- class DataServiceClient {
130
- public:
124
+ struct DataServiceClient {
131
125
  DataPath Paths;
132
126
  Data* Init();
133
127
  Data* WaitForData();
@@ -136,8 +130,7 @@ public:
136
130
  void Destroy();
137
131
  };
138
132
 
139
- class DataService {
140
- public:
133
+ struct DataService {
141
134
  static DataServiceServer Server;
142
135
  static DataServiceClient Client;
143
136
  static DataPath Paths;
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // nightcycle/display — pretty-print Luau values (Rust Display-style).
4
- // Vendored into CluauppLibs.Display with nightcycle/option bundled.
5
- class DisplayBuilder {};
4
+ struct DisplayBuilder {};
6
5
 
7
6
  namespace Display {
8
7
  DisplayBuilder* builder();
@@ -1,9 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // arxkdev/ezVisualz — EasyVisuals, vendored into CluauppLibs.EzVisualz
4
- // Effect.new(gui, "Rainbow", speed, size)
5
- class EzVisualz {
6
- public:
4
+ struct EzVisualz {
7
5
  static EzVisualz* new_(GuiObject* target, string effectType);
8
6
  static EzVisualz* new_(GuiObject* target, string effectType, double speed, double size);
9
7
  void Play();
@@ -1,9 +1,8 @@
1
1
  #pragma once
2
2
 
3
3
  // Blockzez/RobloxFormatNumber — vendored into CluauppLibs.FormatNumber
4
- // Abbreviate / Comma / Compact are Cluaupp helpers over Simple.FormatCompact.
5
- class FormatNumberMain {};
6
- class FormatNumberSimple {};
4
+ struct FormatNumberMain {};
5
+ struct FormatNumberSimple {};
7
6
 
8
7
  namespace FormatNumber {
9
8
  string Abbreviate(double value);
@@ -1,11 +1,11 @@
1
1
  #pragma once
2
2
 
3
3
  // dphfox/Fusion 0.4 — vendored into CluauppLibs.Fusion
4
- class FusionScope {};
5
- class FusionState {};
6
- class FusionKey {};
7
- class FusionObserver {};
8
- class FusionContextual {};
4
+ struct FusionScope {};
5
+ struct FusionState {};
6
+ struct FusionKey {};
7
+ struct FusionObserver {};
8
+ struct FusionContextual {};
9
9
 
10
10
  namespace Fusion {
11
11
  FusionScope scoped();
@@ -1,8 +1,8 @@
1
1
  #pragma once
2
2
 
3
3
  // SirMallard/Iris — vendored into CluauppLibs.Iris
4
- class IrisWidget {};
5
- class IrisState {};
4
+ struct IrisWidget {};
5
+ struct IrisState {};
6
6
 
7
7
  namespace Iris {
8
8
  void Init();
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // howmanysmall/Janitor — vendored into CluauppLibs.Janitor
4
- class Janitor {
5
- public:
4
+ struct Janitor {
6
5
  bool CurrentlyCleaning;
7
6
  bool SuppressInstanceReDestroy;
8
7
  bool UnsafeThreadCleanup;
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // TheNexusAvenger/Module3D — ViewportFrame adorn, vendored into CluauppLibs.Module3D
4
- class Model3D {
5
- public:
4
+ struct Model3D {
6
5
  Model* Object3D;
7
6
  GuiObject* AdornFrame;
8
7
  Camera* Camera;
@@ -18,8 +17,7 @@ public:
18
17
  void End();
19
18
  };
20
19
 
21
- class Module3D {
22
- public:
20
+ struct Module3D {
23
21
  static Model3D* new_(Instance* model);
24
22
  static Model3D* Attach3D(GuiObject* frame, Instance* model);
25
23
  };
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // Buffer-packed RemoteEvent / RemoteFunction. Names are unique per game.
4
- class NetEvent {
5
- public:
4
+ struct NetEvent {
6
5
  void Fire(Player* player);
7
6
  template <typename A>
8
7
  void Fire(Player* player, A a);
@@ -23,8 +22,7 @@ public:
23
22
  void On(void (*callback)());
24
23
  };
25
24
 
26
- class NetFunction {
27
- public:
25
+ struct NetFunction {
28
26
  void On(void (*callback)());
29
27
  template <typename R>
30
28
  R Invoke(Player* player);
@@ -1,9 +1,6 @@
1
1
  #pragma once
2
-
3
2
  // evaera/roblox-lua-promise — vendored into CluauppLibs.Promise
4
- // C++ Then/Catch/Await/Cancel map onto andThen/catch/await/cancel.
5
- class Promise {
6
- public:
3
+ struct Promise {
7
4
  Promise(void (*executor)());
8
5
  template <typename T>
9
6
  static Promise* resolve(T value);
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // nightcycle/spring — Fraktality-style damped spring, vendored into CluauppLibs.Spring
4
- class Spring {
5
- public:
4
+ struct Spring {
6
5
  double Damping;
7
6
  double Frequency;
8
7
  double Goal;
@@ -1,10 +1,9 @@
1
1
  #pragma once
2
2
 
3
3
  // Prooheckcp/RobloxStateMachine — vendored into CluauppLibs.StateMachine
4
- class StateData {};
4
+ struct StateData {};
5
5
 
6
- class StateMachine {
7
- public:
6
+ struct StateMachine {
8
7
  static StateMachine* new_(string initial);
9
8
  static StateData* LoadDirectory(Instance* directory);
10
9
  void ChangeState(string name);
@@ -1,8 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  // Cluaupp StickyBillboard — BillboardGui that stays on an adornee.
4
- class StickyBillboard {
5
- public:
4
+ struct StickyBillboard {
6
5
  static StickyBillboard* new_(Instance* adornee, GuiObject* gui);
7
6
  void SetText(string text);
8
7
  void SetEnabled(bool enabled);