cluaupp 1.5.2 → 2.0.0-beta.2
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/CHANGELOG.md +8 -0
- package/README.md +29 -41
- package/api/generated/bench-latest.json +43 -21
- package/api/generated/lsp-index.json +1 -1
- package/api/manifests/roblox-target.manifest.json +5 -5
- package/api/normalized/roblox-target.profile.json +8729 -267
- package/api/roblox/luau-builtins.d.luau +185 -0
- package/api/roblox/surface.json +1 -0
- package/api/roblox-api.lock.json +11 -2
- package/bin/cluaupp.js +38 -0
- package/editors/vscode/README.md +1 -1
- package/editors/vscode/package.json +50 -15
- package/editors/vscode/snippets/flare.json +1 -1
- package/editors/vscode/snippets/hive.json +1 -1
- package/editors/vscode/syntaxes/clpp.tmLanguage.json +211 -0
- package/examples/README.md +9 -9
- package/examples/game/cluaupp.config.json +2 -2
- package/examples/game/default.project.json +4 -15
- package/examples/game/out/ReplicatedStorage/Shared/GameInfo.luau +8 -0
- package/examples/game/out/ReplicatedStorage/Shared/GameInfo.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Leaderstats.server.luau +26 -0
- package/examples/game/out/ServerScriptService/Leaderstats.server.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Main.server.luau +15 -0
- package/examples/game/out/ServerScriptService/Main.server.luau.map.json +13 -0
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Main.client.luau +10 -0
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Main.client.luau.map.json +13 -0
- package/examples/game/src/ReplicatedStorage/Shared/GameInfo.clp +1 -0
- package/examples/game/src/ServerScriptService/Leaderstats.server.clp +18 -0
- package/examples/game/src/ServerScriptService/Main.server.clp +9 -0
- package/examples/game/src/StarterPlayer/StarterPlayerScripts/Main.client.clp +4 -0
- package/generated/api/build-profile.js +1 -1
- package/generated/api/loader.js +2 -2
- package/generated/api/surface/build.js +328 -0
- package/generated/api/surface/luau-defs.js +595 -0
- package/generated/api/surface/model.js +8 -0
- package/generated/api-cli.js +2 -2
- package/generated/cli.js +18 -17
- package/generated/clpp/contract.js +6 -3
- package/generated/clpp/handshake.js +36 -0
- package/generated/clpp/modules.js +20 -9
- package/generated/clpp/runner.js +62 -31
- package/generated/compile.js +18 -1
- package/generated/compiler/ast.js +3 -0
- package/generated/compiler/checker/calls.js +999 -0
- package/generated/compiler/checker/checker.js +1215 -0
- package/generated/compiler/checker/exprs.js +791 -0
- package/generated/compiler/checker/flow.js +168 -0
- package/generated/compiler/checker/members.js +763 -0
- package/generated/compiler/checker/statements.js +792 -0
- package/generated/compiler/checker/symbols.js +90 -0
- package/generated/compiler/checker/typeops.js +348 -0
- package/generated/compiler/checker/yields.js +115 -0
- package/generated/compiler/diagnostics.js +138 -0
- package/generated/compiler/emit/emitter.js +2356 -0
- package/generated/compiler/emit/luau-types.js +137 -0
- package/generated/compiler/emit/names.js +130 -0
- package/generated/compiler/emit/runtime.js +432 -0
- package/generated/compiler/lexer.js +403 -0
- package/generated/compiler/parser.js +1881 -0
- package/generated/compiler/project.js +332 -0
- package/generated/compiler/roblox/api.js +388 -0
- package/generated/compiler/roblox/context.js +100 -0
- package/generated/compiler/source.js +59 -0
- package/generated/compiler/stdlib.js +232 -0
- package/generated/compiler/types.js +250 -0
- package/generated/intellisense.js +1 -15
- package/generated/lsp.js +1 -1
- package/generated/target/build-cache.js +4 -4
- package/generated/target/datamodel-generate.js +12 -0
- package/generated/target/gen-rojo-tree.js +15 -0
- package/generated/target/source-map.js +61 -8
- package/generated/target/studio-bridge.js +1 -0
- package/generated/utils/project.js +104 -31
- package/include/README.md +5 -0
- package/native/bin/.gitkeep +1 -0
- package/package.json +17 -6
- package/plugins/CluauppNav/Plugin.luau +28 -4
- package/rust/cluaupp/Cargo.lock +795 -0
- package/rust/cluaupp/Cargo.toml +17 -0
- package/rust/cluaupp/src/main.rs +717 -0
- package/scripts/postinstall-native.js +56 -0
- package/skills/README.md +3 -3
- package/skills/clpp-hive-flare/SKILL.md +30 -26
- package/skills/clpp-language/SKILL.md +67 -74
- package/skills/clpp-language/compiler.md +24 -36
- package/skills/clpp-style/SKILL.md +31 -44
- package/src/api/build-profile.ts +1 -1
- package/src/api/loader.ts +2 -2
- package/src/api/surface/build.ts +374 -0
- package/src/api/surface/luau-defs.ts +635 -0
- package/src/api/surface/model.ts +96 -0
- package/src/api-cli.ts +2 -2
- package/src/cli.ts +19 -18
- package/src/clpp/contract.ts +20 -3
- package/src/clpp/handshake.ts +25 -0
- package/src/clpp/modules.ts +17 -10
- package/src/clpp/runner.ts +52 -34
- package/src/compile.ts +20 -2
- package/src/compiler/ast.ts +336 -0
- package/src/compiler/checker/calls.ts +1025 -0
- package/src/compiler/checker/checker.ts +1352 -0
- package/src/compiler/checker/exprs.ts +805 -0
- package/src/compiler/checker/flow.ts +174 -0
- package/src/compiler/checker/members.ts +793 -0
- package/src/compiler/checker/statements.ts +802 -0
- package/src/compiler/checker/symbols.ts +219 -0
- package/src/compiler/checker/typeops.ts +355 -0
- package/src/compiler/checker/yields.ts +120 -0
- package/src/compiler/diagnostics.ts +163 -0
- package/src/compiler/emit/emitter.ts +2486 -0
- package/src/compiler/emit/luau-types.ts +143 -0
- package/src/compiler/emit/names.ts +130 -0
- package/src/compiler/emit/runtime.ts +438 -0
- package/src/compiler/lexer.ts +444 -0
- package/src/compiler/parser.ts +1943 -0
- package/src/compiler/project.ts +354 -0
- package/src/compiler/roblox/api.ts +408 -0
- package/src/compiler/roblox/context.ts +108 -0
- package/src/compiler/source.ts +67 -0
- package/src/compiler/stdlib.ts +256 -0
- package/src/compiler/types.ts +313 -0
- package/src/intellisense.ts +1 -13
- package/src/lsp.ts +1 -1
- package/src/target/build-cache.ts +5 -8
- package/src/target/datamodel-generate.ts +12 -1
- package/src/target/gen-rojo-tree.ts +15 -0
- package/src/target/source-map.ts +65 -27
- package/src/target/studio-bridge.ts +3 -0
- package/src/types.ts +3 -0
- package/src/utils/project.ts +99 -37
- package/templates/README.md +7 -0
- package/templates/{game → game-modern}/cluaupp.config.json +2 -2
- package/templates/{game → game-modern}/package.json +1 -2
- package/templates/game-modern/rokit.toml +2 -0
- package/templates/game-modern/src/ReplicatedStorage/Shared/GameInfo.clp +1 -0
- package/templates/game-modern/src/ServerScriptService/Handlers/Guard.server.clp +4 -0
- package/templates/game-modern/src/ServerScriptService/Main.server.clp +8 -0
- package/templates/game-modern/src/StarterPlayer/StarterPlayerScripts/Main.client.clp +4 -0
- package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau +0 -29
- package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau.map.json +0 -13
- package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau +0 -83
- package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau.map.json +0 -13
- package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau +0 -18
- package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau.map.json +0 -13
- package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau +0 -14
- package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau.map.json +0 -13
- package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau +0 -15
- package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau.map.json +0 -13
- package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau +0 -50
- package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau.map.json +0 -13
- package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau +0 -12
- package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau.map.json +0 -13
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau +0 -16
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau.map.json +0 -13
- package/examples/game/src/Client/Controllers/DataController.client.clpp +0 -7
- package/examples/game/src/Client/Main.client.clpp +0 -4
- package/examples/game/src/Declarations/Net.flare +0 -5
- package/examples/game/src/Include/GameTypes.clh +0 -40
- package/examples/game/src/Modules/Core/Guard.server.clpp +0 -7
- package/examples/game/src/Modules/Core/PlayerHandler.server.clpp +0 -23
- package/examples/game/src/Server/Boot/DataBoot.server.clpp +0 -13
- package/examples/game/src/Server/Main.server.clpp +0 -4
- package/templates/game/.clangd +0 -25
- package/templates/game/.vscode/extensions.json +0 -8
- package/templates/game/.vscode/settings.json +0 -17
- package/templates/game/Packages/.gitkeep +0 -0
- package/templates/game/compile_flags.txt +0 -6
- package/templates/game/default.project.json +0 -41
- package/templates/game/include/clpp/datatypes.clh +0 -575
- package/templates/game/include/clpp/generated/enums.clh +0 -4920
- package/templates/game/include/clpp/generated/instances.clh +0 -87182
- package/templates/game/include/clpp/libs/arrayindexer.clh +0 -12
- package/templates/game/include/clpp/libs/axiom.clh +0 -154
- package/templates/game/include/clpp/libs/bloom.clh +0 -58
- package/templates/game/include/clpp/libs/coil.clh +0 -37
- package/templates/game/include/clpp/libs/crest.clh +0 -22
- package/templates/game/include/clpp/libs/echo.clh +0 -52
- package/templates/game/include/clpp/libs/ember.clh +0 -17
- package/templates/game/include/clpp/libs/flare.clh +0 -65
- package/templates/game/include/clpp/libs/gleam.clh +0 -111
- package/templates/game/include/clpp/libs/guide.clh +0 -42
- package/templates/game/include/clpp/libs/helm.clh +0 -31
- package/templates/game/include/clpp/libs/hive.clh +0 -20
- package/templates/game/include/clpp/libs/keep.clh +0 -158
- package/templates/game/include/clpp/libs/lens.clh +0 -24
- package/templates/game/include/clpp/libs/mint.clh +0 -28
- package/templates/game/include/clpp/libs/net.clh +0 -31
- package/templates/game/include/clpp/libs/occlude.clh +0 -15
- package/templates/game/include/clpp/libs/pin.clh +0 -28
- package/templates/game/include/clpp/libs/promise.clh +0 -24
- package/templates/game/include/clpp/libs/roster.clh +0 -123
- package/templates/game/include/clpp/libs/shift.clh +0 -22
- package/templates/game/include/clpp/libs/spark.clh +0 -28
- package/templates/game/include/clpp/libs/stage.clh +0 -23
- package/templates/game/include/clpp/libs/sweep.clh +0 -23
- package/templates/game/include/clpp/libs/trace.clh +0 -18
- package/templates/game/include/clpp/libs/ward.clh +0 -19
- package/templates/game/include/clpp/libs.clh +0 -31
- package/templates/game/include/clpp/roblox.clh +0 -41
- package/templates/game/rokit.toml +0 -5
- package/templates/game/src/Client/Controllers/DataController.client.clpp +0 -7
- package/templates/game/src/Client/Main.client.clpp +0 -4
- package/templates/game/src/Declarations/Net.flare +0 -5
- package/templates/game/src/Include/GameTypes.clh +0 -40
- package/templates/game/src/Modules/Core/Guard.server.clpp +0 -7
- package/templates/game/src/Modules/Core/PlayerHandler.server.clpp +0 -24
- package/templates/game/src/Server/Boot/DataBoot.server.clpp +0 -13
- package/templates/game/src/Server/Main.server.clpp +0 -4
- package/templates/game/stylua.toml +0 -9
- package/templates/game/wally.toml +0 -12
|
@@ -3,23 +3,76 @@ 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.remapSourceLines = remapSourceLines;
|
|
7
|
+
exports.embedSourceMap = embedSourceMap;
|
|
6
8
|
exports.writeSourceMap = writeSourceMap;
|
|
7
|
-
/**
|
|
9
|
+
/** Compiler coordinates are retained only for lines that survive host transformations. */
|
|
8
10
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
/** LCS alignment: inserted headers and removed lines never become fake source locations. */
|
|
13
|
+
function remapSourceLines(original, generated, mappings = []) {
|
|
14
|
+
const a = original.split(/\r?\n/);
|
|
15
|
+
const b = generated.split(/\r?\n/);
|
|
16
|
+
if (original === generated)
|
|
17
|
+
return mappings.map(m => ({ ...m }));
|
|
18
|
+
// Avoid unbounded memory for generated bundles. An absent map is safer than a wrong one.
|
|
19
|
+
if (a.length * b.length > 4_000_000)
|
|
20
|
+
return [];
|
|
21
|
+
const widths = b.length + 1;
|
|
22
|
+
const dp = new Uint32Array((a.length + 1) * widths);
|
|
23
|
+
for (let i = a.length - 1; i >= 0; i--)
|
|
24
|
+
for (let j = b.length - 1; j >= 0; j--) {
|
|
25
|
+
dp[i * widths + j] = a[i].trim() === b[j].trim() ? 1 + dp[(i + 1) * widths + j + 1] : Math.max(dp[(i + 1) * widths + j], dp[i * widths + j + 1]);
|
|
26
|
+
}
|
|
27
|
+
const translated = new Map();
|
|
28
|
+
let i = 0, j = 0;
|
|
29
|
+
while (i < a.length && j < b.length) {
|
|
30
|
+
if (a[i].trim() === b[j].trim()) {
|
|
31
|
+
translated.set(i + 1, j + 1);
|
|
32
|
+
i++;
|
|
33
|
+
j++;
|
|
34
|
+
}
|
|
35
|
+
else if (dp[(i + 1) * widths + j] >= dp[i * widths + j + 1])
|
|
36
|
+
i++;
|
|
37
|
+
else
|
|
38
|
+
j++;
|
|
39
|
+
}
|
|
40
|
+
return mappings.flatMap(m => {
|
|
41
|
+
const line = translated.get(m.luauLine);
|
|
42
|
+
if (!line || !Number.isInteger(m.clppLine) || m.clppLine < 1)
|
|
43
|
+
return [];
|
|
44
|
+
// Formatting can move columns; do not invent a column in that case.
|
|
45
|
+
const exact = a[m.luauLine - 1] === b[line - 1];
|
|
46
|
+
const { luauColumn, ...rest } = m;
|
|
47
|
+
return [{ ...rest, luauLine: line, ...(exact && luauColumn ? { luauColumn } : {}) }];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function embedSourceMap(luau, lines) {
|
|
51
|
+
if (!lines.length)
|
|
52
|
+
return { contents: luau, lines: [] };
|
|
53
|
+
const shifted = lines.map(m => ({ ...m, luauLine: m.luauLine + 1 }));
|
|
54
|
+
// Preserve Luau directives at the start of the file.
|
|
55
|
+
const parts = luau.split(/\r?\n/);
|
|
56
|
+
let index = 0;
|
|
57
|
+
while (index < parts.length && parts[index].startsWith("--!"))
|
|
58
|
+
index++;
|
|
59
|
+
const adjusted = shifted.map((m, i) => ({ ...m, luauLine: lines[i].luauLine > index ? m.luauLine : lines[i].luauLine }));
|
|
60
|
+
parts.splice(index, 0, "-- cluaupp-map: " + JSON.stringify(adjusted));
|
|
61
|
+
return { contents: parts.join("\n"), lines: adjusted };
|
|
62
|
+
}
|
|
10
63
|
function writeSourceMap(opts) {
|
|
64
|
+
const lines = opts.lines || [];
|
|
65
|
+
const source = opts.sourceClppRel.replace(/\\/g, "/");
|
|
11
66
|
const map = {
|
|
12
67
|
version: 1,
|
|
13
68
|
file: node_path_1.default.basename(opts.outLuauPath),
|
|
14
69
|
sourceRoot: opts.projectRoot.replace(/\\/g, "/"),
|
|
15
|
-
sources: [
|
|
16
|
-
|
|
17
|
-
cluaupp: {
|
|
18
|
-
source: opts.sourceClppRel.replace(/\\/g, "/"),
|
|
19
|
-
generated: node_path_1.default.relative(opts.projectRoot, opts.outLuauPath).replace(/\\/g, "/"),
|
|
20
|
-
},
|
|
70
|
+
sources: [...new Set([source, ...lines.map(m => m.file)])],
|
|
71
|
+
cluaupp: { source, generated: node_path_1.default.relative(opts.projectRoot, opts.outLuauPath).replace(/\\/g, "/"), lines },
|
|
21
72
|
};
|
|
22
73
|
const mapPath = opts.outLuauPath + ".map.json";
|
|
23
|
-
|
|
74
|
+
const contents = JSON.stringify(map, null, "\t") + "\n";
|
|
75
|
+
if (!node_fs_1.default.existsSync(mapPath) || node_fs_1.default.readFileSync(mapPath, "utf8") !== contents)
|
|
76
|
+
node_fs_1.default.writeFileSync(mapPath, contents, "utf8");
|
|
24
77
|
return mapPath;
|
|
25
78
|
}
|
|
@@ -13,6 +13,7 @@ exports.watch = watch;
|
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
15
|
const package_info_js_1 = require("../package-info.js");
|
|
16
|
+
const runner_js_1 = require("../clpp/runner.js");
|
|
16
17
|
const postprocess_js_1 = require("../clpp/postprocess.js");
|
|
17
18
|
const paths_js_1 = require("../clpp/paths.js");
|
|
18
19
|
const index_js_1 = require("../flare/index.js");
|
|
@@ -33,6 +34,8 @@ const datamodel_js_1 = require("../target/datamodel.js");
|
|
|
33
34
|
const gen_rojo_tree_js_1 = require("../target/gen-rojo-tree.js");
|
|
34
35
|
const build_cache_js_1 = require("../target/build-cache.js");
|
|
35
36
|
const modules_js_1 = require("../clpp/modules.js");
|
|
37
|
+
const project_js_1 = require("../compiler/project.js");
|
|
38
|
+
const diagnostics_js_1 = require("../compiler/diagnostics.js");
|
|
36
39
|
function readProjectConfig(file) {
|
|
37
40
|
const raw = JSON.parse(node_fs_1.default.readFileSync(file, "utf8"));
|
|
38
41
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -322,6 +325,10 @@ function compileOptions(root, config, file, rel) {
|
|
|
322
325
|
outDir: config.outDir,
|
|
323
326
|
};
|
|
324
327
|
}
|
|
328
|
+
function needsLegacyHeaders(srcDir) {
|
|
329
|
+
const sources = (0, paths_js_1.collectSources)(srcDir);
|
|
330
|
+
return sources.some(file => /\.clpp$/i.test(file)) || !sources.some(file => /\.clp$/i.test(file));
|
|
331
|
+
}
|
|
325
332
|
function compileSchemaJobs(root, config, srcDir) {
|
|
326
333
|
const jobs = [];
|
|
327
334
|
const errors = [];
|
|
@@ -336,7 +343,8 @@ function compileSchemaJobs(root, config, srcDir) {
|
|
|
336
343
|
if (!(0, safe_paths_js_1.isInside)(node_path_1.default.resolve(root, config.rootDir), headerDest) && !(0, safe_paths_js_1.isInside)(srcDir, headerDest)) {
|
|
337
344
|
throw new Error(`cluaupp schema: skip unsafe header ${emit.headerRel}`);
|
|
338
345
|
}
|
|
339
|
-
|
|
346
|
+
if (needsLegacyHeaders(srcDir))
|
|
347
|
+
writeTextIfChanged(headerDest, emit.header);
|
|
340
348
|
jobs.push({
|
|
341
349
|
rel,
|
|
342
350
|
files: [{ name: emit.luauRel, contents: emit.luau }],
|
|
@@ -364,7 +372,8 @@ function compileFlareJobs(root, config, srcDir) {
|
|
|
364
372
|
if (!(0, safe_paths_js_1.isInside)(node_path_1.default.resolve(root, config.rootDir), headerDest) && !(0, safe_paths_js_1.isInside)(srcDir, headerDest)) {
|
|
365
373
|
throw new Error(`cluaupp flare: skip unsafe header ${emit.headerRel}`);
|
|
366
374
|
}
|
|
367
|
-
|
|
375
|
+
if (needsLegacyHeaders(srcDir))
|
|
376
|
+
writeTextIfChanged(headerDest, emit.header);
|
|
368
377
|
jobs.push({
|
|
369
378
|
rel,
|
|
370
379
|
files: [{ name: emit.luauRel, contents: emit.luau }],
|
|
@@ -377,25 +386,61 @@ function compileFlareJobs(root, config, srcDir) {
|
|
|
377
386
|
}
|
|
378
387
|
return { jobs, errors };
|
|
379
388
|
}
|
|
380
|
-
function configFingerprint(config) {
|
|
389
|
+
function configFingerprint(root, config, rojoPath) {
|
|
390
|
+
const inputs = [node_path_1.default.resolve(root, rojoPath || "default.project.json"), node_path_1.default.join(root, "cluaupp.platform.json"), node_path_1.default.join(root, "cluaupp.profile.json"), node_path_1.default.join(package_info_js_1.projectRoot, "api", "normalized", "roblox-target.profile.json"), node_path_1.default.join(package_info_js_1.projectRoot, "api", "generated", "capability-profile.json"), node_path_1.default.join(package_info_js_1.projectRoot, "api", "roblox-api.lock.json")];
|
|
381
391
|
return JSON.stringify({
|
|
382
392
|
strict: config.strict === true,
|
|
383
393
|
architecture: config.architecture === true,
|
|
384
394
|
rootDir: config.rootDir,
|
|
385
395
|
outDir: config.outDir,
|
|
386
396
|
v: package_info_js_1.pkg.version,
|
|
397
|
+
rules: config.rules,
|
|
398
|
+
components: config.components,
|
|
399
|
+
inputs: inputs.map(file => [file, node_fs_1.default.existsSync(file) ? (0, build_cache_js_1.hashText)(node_fs_1.default.readFileSync(file, "utf8")) : null]),
|
|
387
400
|
});
|
|
388
401
|
}
|
|
402
|
+
function compileClpJobs(root, config, srcDir) {
|
|
403
|
+
const compiler = new project_js_1.ProjectCompiler({ root, srcDir, strict: config.strict === true, version: package_info_js_1.pkg.version });
|
|
404
|
+
const jobs = [];
|
|
405
|
+
const errors = [];
|
|
406
|
+
for (const result of compiler.compileAll()) {
|
|
407
|
+
if (result.luau === null) {
|
|
408
|
+
const diagnostics = result.diagnostics.filter((d) => d.severity === "error");
|
|
409
|
+
errors.push({
|
|
410
|
+
rel: result.rel,
|
|
411
|
+
prefixes: sourcePrefixes(result.rel),
|
|
412
|
+
message: diagnostics.map((d) => (0, diagnostics_js_1.formatDiagnostic)(d, result.source)).join("\n") || `${result.rel}: Luau emission failed`,
|
|
413
|
+
});
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
jobs.push({ rel: result.rel, files: [{ name: result.outRel, contents: result.luau, sourceMap: result.sourceMap, generatedSource: result.luau }], stale: [] });
|
|
417
|
+
}
|
|
418
|
+
return { jobs, errors };
|
|
419
|
+
}
|
|
389
420
|
function compileProject(root, config, mapper, options = {}) {
|
|
390
421
|
const srcDir = node_path_1.default.join(root, config.rootDir);
|
|
391
422
|
const schema = compileSchemaJobs(root, config, srcDir);
|
|
392
423
|
const files = (0, paths_js_1.collectSources)(srcDir);
|
|
393
|
-
const
|
|
394
|
-
const
|
|
424
|
+
const legacyFiles = files.filter((file) => !file.toLowerCase().endsWith(".clp"));
|
|
425
|
+
const clp = compileClpJobs(root, config, srcDir);
|
|
426
|
+
const jobs = [...schema.jobs, ...clp.jobs];
|
|
427
|
+
const errors = [...schema.errors, ...clp.errors];
|
|
395
428
|
const incremental = options.incremental !== false;
|
|
396
|
-
|
|
429
|
+
let cfgKey = configFingerprint(root, config, options.rojo);
|
|
430
|
+
if (legacyFiles.length) {
|
|
431
|
+
try {
|
|
432
|
+
cfgKey += (0, runner_js_1.clppCacheIdentity)();
|
|
433
|
+
}
|
|
434
|
+
catch (err) {
|
|
435
|
+
for (const file of legacyFiles) {
|
|
436
|
+
const rel = posixRel(srcDir, file);
|
|
437
|
+
errors.push({ rel, prefixes: sourcePrefixes(rel), message: err.message });
|
|
438
|
+
}
|
|
439
|
+
return { files, jobs, errors };
|
|
440
|
+
}
|
|
441
|
+
}
|
|
397
442
|
let cacheHits = 0;
|
|
398
|
-
for (const file of
|
|
443
|
+
for (const file of legacyFiles) {
|
|
399
444
|
const source = node_fs_1.default.readFileSync(file, "utf8");
|
|
400
445
|
const rel = posixRel(srcDir, file);
|
|
401
446
|
const sourceHash = (0, modules_js_1.fingerprintSourceWithDeps)(source, file, cfgKey, srcDir, build_cache_js_1.hashText);
|
|
@@ -424,7 +469,7 @@ function compileProject(root, config, mapper, options = {}) {
|
|
|
424
469
|
}
|
|
425
470
|
}
|
|
426
471
|
if (cacheHits > 0) {
|
|
427
|
-
console.log(`cluaupp: incremental cache hit ${cacheHits}/${
|
|
472
|
+
console.log(`cluaupp: incremental cache hit ${cacheHits}/${legacyFiles.length}`);
|
|
428
473
|
}
|
|
429
474
|
return { files, jobs, errors };
|
|
430
475
|
}
|
|
@@ -432,13 +477,27 @@ async function compileProjectAsync(root, config, mapper, options = {}) {
|
|
|
432
477
|
const srcDir = node_path_1.default.join(root, config.rootDir);
|
|
433
478
|
const schema = compileSchemaJobs(root, config, srcDir);
|
|
434
479
|
const files = (0, paths_js_1.collectSources)(srcDir);
|
|
435
|
-
const
|
|
436
|
-
const
|
|
480
|
+
const legacyFiles = files.filter((file) => !file.toLowerCase().endsWith(".clp"));
|
|
481
|
+
const clp = compileClpJobs(root, config, srcDir);
|
|
482
|
+
const jobs = [...schema.jobs, ...clp.jobs];
|
|
483
|
+
const errors = [...schema.errors, ...clp.errors];
|
|
437
484
|
const incremental = options.incremental !== false;
|
|
438
|
-
|
|
485
|
+
let cfgKey = configFingerprint(root, config, options.rojo);
|
|
486
|
+
if (legacyFiles.length) {
|
|
487
|
+
try {
|
|
488
|
+
cfgKey += (0, runner_js_1.clppCacheIdentity)();
|
|
489
|
+
}
|
|
490
|
+
catch (err) {
|
|
491
|
+
for (const file of legacyFiles) {
|
|
492
|
+
const rel = posixRel(srcDir, file);
|
|
493
|
+
errors.push({ rel, prefixes: sourcePrefixes(rel), message: err.message });
|
|
494
|
+
}
|
|
495
|
+
return { files, jobs, errors };
|
|
496
|
+
}
|
|
497
|
+
}
|
|
439
498
|
const concurrency = options.jobs ?? (0, build_cache_js_1.defaultJobCount)();
|
|
440
499
|
let cacheHits = 0;
|
|
441
|
-
const compiled = await (0, build_cache_js_1.mapPool)(
|
|
500
|
+
const compiled = await (0, build_cache_js_1.mapPool)(legacyFiles, concurrency, async (file) => {
|
|
442
501
|
const source = node_fs_1.default.readFileSync(file, "utf8");
|
|
443
502
|
const rel = posixRel(srcDir, file);
|
|
444
503
|
const sourceHash = (0, modules_js_1.fingerprintSourceWithDeps)(source, file, cfgKey, srcDir, build_cache_js_1.hashText);
|
|
@@ -495,9 +554,9 @@ async function compileProjectAsync(root, config, mapper, options = {}) {
|
|
|
495
554
|
}
|
|
496
555
|
}
|
|
497
556
|
if (cacheHits > 0) {
|
|
498
|
-
console.log(`cluaupp: incremental cache hit ${cacheHits}/${
|
|
557
|
+
console.log(`cluaupp: incremental cache hit ${cacheHits}/${legacyFiles.length} (jobs=${concurrency})`);
|
|
499
558
|
}
|
|
500
|
-
else if (
|
|
559
|
+
else if (legacyFiles.length > 1 && concurrency > 1) {
|
|
501
560
|
console.log(`cluaupp: parallel compile jobs=${concurrency}`);
|
|
502
561
|
}
|
|
503
562
|
return { files, jobs, errors };
|
|
@@ -536,7 +595,19 @@ function writeJobs(root, config, jobs, format) {
|
|
|
536
595
|
if (/\.luau$/i.test(dest)) {
|
|
537
596
|
const srcFile = node_path_1.default.join(root, config.rootDir, job.rel);
|
|
538
597
|
const clppSource = node_fs_1.default.existsSync(srcFile) ? node_fs_1.default.readFileSync(srcFile, "utf8") : undefined;
|
|
539
|
-
contents = (0, luau_stamp_js_1.stampLuauFromClpp)((0, postprocess_js_1.rewriteClppEmit)(contents),
|
|
598
|
+
contents = (0, luau_stamp_js_1.stampLuauFromClpp)(/\.clp$/i.test(job.rel) ? contents : (0, postprocess_js_1.rewriteClppEmit)(contents), posixRel(root, srcFile), clppSource);
|
|
599
|
+
}
|
|
600
|
+
let lines = (artifact.sourceMap || []).map(m => ({ ...m, file: node_path_1.default.isAbsolute(m.file) ? posixRel(root, m.file) : node_path_1.default.posix.join(config.rootDir.replace(/\\/g, "/"), m.file) }));
|
|
601
|
+
if (format && /\.luau$/i.test(dest)) {
|
|
602
|
+
writeTextIfChanged(dest, contents);
|
|
603
|
+
process_orchestrator_js_1.ProcessOrchestrator.formatWithStyLuaSync(dest);
|
|
604
|
+
contents = node_fs_1.default.readFileSync(dest, "utf8");
|
|
605
|
+
}
|
|
606
|
+
if (/\.luau$/i.test(dest)) {
|
|
607
|
+
lines = (0, source_map_js_1.remapSourceLines)(artifact.generatedSource || artifact.contents, contents, lines);
|
|
608
|
+
const embedded = (0, source_map_js_1.embedSourceMap)(contents, lines);
|
|
609
|
+
contents = embedded.contents;
|
|
610
|
+
lines = embedded.lines;
|
|
540
611
|
}
|
|
541
612
|
const changed = writeTextIfChanged(dest, contents);
|
|
542
613
|
written.add(resolveKey(dest));
|
|
@@ -546,14 +617,12 @@ function writeJobs(root, config, jobs, format) {
|
|
|
546
617
|
if (/\.luau$/i.test(dest)) {
|
|
547
618
|
const mapPath = (0, source_map_js_1.writeSourceMap)({
|
|
548
619
|
outLuauPath: dest,
|
|
549
|
-
sourceClppRel: job.rel,
|
|
620
|
+
sourceClppRel: node_path_1.default.posix.join(config.rootDir.replace(/\\/g, "/"), job.rel),
|
|
550
621
|
projectRoot: root,
|
|
622
|
+
lines,
|
|
551
623
|
});
|
|
552
624
|
written.add(resolveKey(mapPath));
|
|
553
625
|
}
|
|
554
|
-
if (format && /\.luau$/i.test(dest)) {
|
|
555
|
-
process_orchestrator_js_1.ProcessOrchestrator.formatWithStyLuaSync(dest);
|
|
556
|
-
}
|
|
557
626
|
}
|
|
558
627
|
for (const stale of job.stale || []) {
|
|
559
628
|
const dest = outDest(root, config, stale);
|
|
@@ -568,7 +637,10 @@ function writeJobs(root, config, jobs, format) {
|
|
|
568
637
|
}
|
|
569
638
|
function ensureVendor(root) {
|
|
570
639
|
copyRuntime(root);
|
|
571
|
-
|
|
640
|
+
const config = loadConfig(root);
|
|
641
|
+
if ((0, paths_js_1.collectSources)(node_path_1.default.join(root, config.rootDir)).some(file => /\.clpp$/i.test(file))) {
|
|
642
|
+
copyHeaders(root);
|
|
643
|
+
}
|
|
572
644
|
}
|
|
573
645
|
function finishBuild(root, config, compiled, options) {
|
|
574
646
|
const exitOnError = options.exitOnError !== false;
|
|
@@ -697,10 +769,15 @@ async function buildAsync(root, options = {}) {
|
|
|
697
769
|
}
|
|
698
770
|
async function init(dest) {
|
|
699
771
|
const target = (0, safe_paths_js_1.assertInitDest)(dest);
|
|
700
|
-
|
|
701
|
-
|
|
772
|
+
if (node_fs_1.default.existsSync(node_path_1.default.join(target, "cluaupp.config.json")) || node_fs_1.default.existsSync(node_path_1.default.join(target, "src"))) {
|
|
773
|
+
throw new Error("cluaupp init: project already exists; choose a new folder. Existing .clpp/.clh sources require migration, not another init.");
|
|
774
|
+
}
|
|
775
|
+
const template = node_path_1.default.join(__dirname, "..", "..", "templates", "game-modern");
|
|
702
776
|
copyDir(template, target);
|
|
703
|
-
|
|
777
|
+
const packageFile = node_path_1.default.join(target, "package.json");
|
|
778
|
+
const projectPackage = JSON.parse(node_fs_1.default.readFileSync(packageFile, "utf8"));
|
|
779
|
+
projectPackage.devDependencies = { ...projectPackage.devDependencies, cluaupp: package_info_js_1.pkg.version };
|
|
780
|
+
node_fs_1.default.writeFileSync(packageFile, JSON.stringify(projectPackage, null, "\t") + "\n");
|
|
704
781
|
const skills = node_path_1.default.join(__dirname, "..", "..", "skills");
|
|
705
782
|
if (node_fs_1.default.existsSync(skills)) {
|
|
706
783
|
copyDir(skills, node_path_1.default.join(target, ".cursor", "skills"));
|
|
@@ -709,17 +786,13 @@ async function init(dest) {
|
|
|
709
786
|
const initConfig = loadConfig(target);
|
|
710
787
|
syncRojoTree(target, initConfig);
|
|
711
788
|
(0, intellisense_js_1.syncEditorSupport)(target);
|
|
712
|
-
|
|
713
|
-
(0, intellisense_js_1.installEditorExtension)();
|
|
714
|
-
}
|
|
715
|
-
catch {
|
|
716
|
-
// editor homes may be missing in CI
|
|
717
|
-
}
|
|
789
|
+
// CL++ 0.10 owns its editor extension; project init only writes associations.
|
|
718
790
|
console.log("Cluaupp ready in", target);
|
|
719
|
-
console.log("
|
|
791
|
+
console.log(" CL++ 0.10 editor extension provides syntax highlighting; Cluaupp compiles Roblox .clp files");
|
|
720
792
|
console.log(" cluaupp intellisense (schema .flare .hive .mint .bloom .helm .shift .axiom)");
|
|
721
793
|
console.log(" rokit install");
|
|
722
|
-
console.log("
|
|
794
|
+
console.log(" npm install");
|
|
795
|
+
console.log(" npm run build");
|
|
723
796
|
console.log(" rojo serve");
|
|
724
797
|
}
|
|
725
798
|
function pidAlive(pid) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Legacy CL++ headers
|
|
2
|
+
|
|
3
|
+
The .clh files in this directory use the legacy .clpp compiler syntax. They are preserved for the explicit legacy adapter and API projection tests. They are not modules for modern .clp programs, and modern cluaupp init and build do not copy them into a project.
|
|
4
|
+
|
|
5
|
+
Modern Roblox code uses link @clpp.roblox; and libraries use link @clpp.libs.Ward as Ward; (replace Ward with the runtime library). The API types come from the registry. Changing .clh to .clp does not migrate the syntax. Generated schema bindings still need modern type projections; legacy headers are not advertised as modern bindings.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cluaupp",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
|
+
"description": "Roblox target for CL++: compile .clp to Luau with Rojo and CluauppLibs.",
|
|
5
5
|
"author": "KartzDev",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"bin",
|
|
18
18
|
"src",
|
|
19
19
|
"generated",
|
|
20
|
+
"rust",
|
|
21
|
+
"native",
|
|
20
22
|
"include",
|
|
21
23
|
"templates",
|
|
22
24
|
"examples",
|
|
@@ -27,6 +29,7 @@
|
|
|
27
29
|
"data",
|
|
28
30
|
"plugins",
|
|
29
31
|
"scripts/postinstall-editor.js",
|
|
32
|
+
"scripts/postinstall-native.js",
|
|
30
33
|
"README.md",
|
|
31
34
|
"LICENSE",
|
|
32
35
|
"CHANGELOG.md",
|
|
@@ -40,11 +43,14 @@
|
|
|
40
43
|
"cluau": "node bin/cluaupp.js",
|
|
41
44
|
"build": "tsc",
|
|
42
45
|
"build:cli": "tsc",
|
|
46
|
+
"build:native": "cargo build --release --manifest-path rust/cluaupp/Cargo.toml",
|
|
43
47
|
"dev:cli": "tsx src/cli.ts",
|
|
44
48
|
"prepare": "tsc",
|
|
45
|
-
"postinstall": "node scripts/postinstall-editor.js",
|
|
46
|
-
"test": "node test/security.test.js && node test/understander.test.js && node test/out.test.js && node test/types.test.js && node test/modules.test.js && node test/modules-import.test.js && node test/gen-rojo-tree.test.js && node test/get-service.test.js && node test/clpp.test.js && node test/flare.test.js && node test/native.test.js && node test/postprocess.test.js && node test/api.test.js && node test/api-reuse.test.js && node test/context-safety.test.js && node test/datamodel.test.js && node test/platform-analyzers.test.js && node test/platform-extras.test.js && node test/generator.test.js && node test/studio/smoke.test.js",
|
|
49
|
+
"postinstall": "node scripts/postinstall-native.js && node scripts/postinstall-editor.js",
|
|
50
|
+
"test": "node test/cli-modern.test.js && node test/handshake.test.js && node test/source-map.test.js && node test/cache-invalidation.test.js && node test/package.test.js && node test/security.test.js && node test/understander.test.js && node test/modern-clp.test.js && node test/out.test.js && node test/types.test.js && node test/modules.test.js && node test/modules-import.test.js && node test/gen-rojo-tree.test.js && node test/get-service.test.js && node test/clpp.test.js && node test/flare.test.js && node test/native.test.js && node test/postprocess.test.js && node test/api.test.js && node test/api-reuse.test.js && node test/context-safety.test.js && node test/datamodel.test.js && node test/platform-analyzers.test.js && node test/platform-extras.test.js && node test/generator.test.js && node test/studio/smoke.test.js",
|
|
47
51
|
"test:clpp-contract": "node test/clpp.test.js",
|
|
52
|
+
"test:modern": "node test/modern-clp.test.js",
|
|
53
|
+
"bench": "node scripts/bench-site.cjs",
|
|
48
54
|
"generate-api": "node scripts/generate-api.js",
|
|
49
55
|
"vendor-libs": "node scripts/vendor-libs.js",
|
|
50
56
|
"build:libs": "node scripts/sync-packages.js",
|
|
@@ -52,10 +58,15 @@
|
|
|
52
58
|
"site:dev": "npm run dev -w @cluaupp/docs",
|
|
53
59
|
"dev": "node scripts/dev.js",
|
|
54
60
|
"stop": "node scripts/stop.js",
|
|
55
|
-
"prepublishOnly": "tsc && npm test"
|
|
61
|
+
"prepublishOnly": "npm run setup:runtime && tsc && node generated/cli.js api generate && node generated/cli.js api verify && npm test && npm run test:runtime && npm run test:release",
|
|
62
|
+
"api:surface": "tsx scripts/build-surface.ts",
|
|
63
|
+
"test:handshake": "node test/handshake.test.js",
|
|
64
|
+
"test:runtime": "node scripts/test-runtime.cjs",
|
|
65
|
+
"test:release": "node scripts/test-release.cjs",
|
|
66
|
+
"setup:runtime": "node scripts/setup-runtime.cjs"
|
|
56
67
|
},
|
|
57
68
|
"engines": {
|
|
58
|
-
"node": ">=
|
|
69
|
+
"node": ">=22.12.0"
|
|
59
70
|
},
|
|
60
71
|
"keywords": [
|
|
61
72
|
"luau",
|
|
@@ -91,6 +91,26 @@ local function findSourceComment(source: string): string?
|
|
|
91
91
|
return nil
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
-- Only exact compiler locations are used. Headers/helpers stay unmapped.
|
|
95
|
+
local function mappedLocation(source: string, generatedLine: number): (string?, number?, number?)
|
|
96
|
+
for line in string.gmatch(source, "[^\r\n]+") do
|
|
97
|
+
local raw = string.match(line, "^%-%-%s*cluaupp%-map:%s*(.+)$")
|
|
98
|
+
if raw then
|
|
99
|
+
local ok, entries = pcall(function() return HttpService:JSONDecode(raw) end)
|
|
100
|
+
if ok and type(entries) == "table" then
|
|
101
|
+
for _, entry in entries do
|
|
102
|
+
if entry.luauLine == generatedLine and type(entry.file) == "string" and type(entry.clppLine) == "number" then
|
|
103
|
+
return entry.file, entry.clppLine, entry.clppColumn
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
return nil, nil, nil
|
|
108
|
+
end
|
|
109
|
+
if not string.match(line, "^%-%-") then break end
|
|
110
|
+
end
|
|
111
|
+
return nil, nil, nil
|
|
112
|
+
end
|
|
113
|
+
|
|
94
114
|
local function currentClppPath(): (string?, LuaSourceContainer?)
|
|
95
115
|
local sel = Selection:Get()
|
|
96
116
|
local scriptInst = sel[1]
|
|
@@ -186,15 +206,19 @@ ScriptContext.Error:Connect(function(message, stack, scriptInst)
|
|
|
186
206
|
local ok, source = pcall(function()
|
|
187
207
|
return (scriptInst :: LuaSourceContainer).Source
|
|
188
208
|
end)
|
|
189
|
-
local
|
|
190
|
-
local
|
|
191
|
-
|
|
209
|
+
local line = tonumber(string.match(tostring(message), ":(%d+):")) or tonumber(string.match(stack or "", ":(%d+)"))
|
|
210
|
+
local clpp, sourceLine, sourceColumn
|
|
211
|
+
if ok and typeof(source) == "string" and line then
|
|
212
|
+
clpp, sourceLine, sourceColumn = mappedLocation(source, line)
|
|
213
|
+
end
|
|
214
|
+
local text = string.format("[error] %s\n luau: %s\n clpp: %s:%d", tostring(message), scriptInst:GetFullName(), tostring(clpp or "(unmapped)"), sourceLine or 0)
|
|
192
215
|
appendLog(text, Color3.fromRGB(255, 120, 120))
|
|
193
216
|
if clpp then
|
|
194
217
|
postBridge({
|
|
195
218
|
type = "error",
|
|
196
219
|
path = clpp,
|
|
197
|
-
line =
|
|
220
|
+
line = sourceLine,
|
|
221
|
+
column = sourceColumn,
|
|
198
222
|
message = tostring(message),
|
|
199
223
|
instancePath = scriptInst:GetFullName(),
|
|
200
224
|
})
|