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
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
2
|
+
/** Legacy adapter policy for CL++ 0.8.x. Requires an upstream compiler implementing the handshake. */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.CLPP_INSTALL_HINT = exports.MIN_CLPP_VERSION = void 0;
|
|
4
|
+
exports.CLPP_INSTALL_HINT = exports.CLPP_CONTRACT_VERSION = exports.CLPP_VERSION_RANGE = exports.MAX_CLPP_VERSION_EXCLUSIVE = exports.MIN_CLPP_VERSION = void 0;
|
|
5
5
|
exports.MIN_CLPP_VERSION = "0.8.0";
|
|
6
|
-
exports.
|
|
6
|
+
exports.MAX_CLPP_VERSION_EXCLUSIVE = "0.9.0";
|
|
7
|
+
exports.CLPP_VERSION_RANGE = ">=0.8.0 <0.9.0";
|
|
8
|
+
exports.CLPP_CONTRACT_VERSION = 1;
|
|
9
|
+
exports.CLPP_INSTALL_HINT = "Install the legacy Luau compiler >=0.8.0 <0.9.0 with contractVersion 1 (the CL++ VM is incompatible) (`clpp` from https://github.com/KartzRbx/CLPP/releases). Put it on PATH. Prefer `import { Name } from \"./x.clh\"` for language modules; angle `#include <clpp/…>` stays for host prelude. Override with CLPP or CLPP_PATH.";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCompilerVersion = parseCompilerVersion;
|
|
4
|
+
exports.acceptsCompilerVersion = acceptsCompilerVersion;
|
|
5
|
+
exports.validateCompilerHandshake = validateCompilerHandshake;
|
|
6
|
+
const contract_js_1 = require("./contract.js");
|
|
7
|
+
function parseCompilerVersion(text) {
|
|
8
|
+
const m = /^(?:clpp\s+|CL\+\+\s+)?(\d+)\.(\d+)\.(\d+)(?:-[\w.-]+)?(?:\+[\w.-]+)?$/i.exec(text.trim());
|
|
9
|
+
return m ? m.slice(1, 4).map(Number) : null;
|
|
10
|
+
}
|
|
11
|
+
function compare(a, b) {
|
|
12
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
|
|
13
|
+
}
|
|
14
|
+
function acceptsCompilerVersion(text) {
|
|
15
|
+
const v = parseCompilerVersion(text);
|
|
16
|
+
return !!v && compare(v, parseCompilerVersion(contract_js_1.MIN_CLPP_VERSION)) >= 0 && compare(v, parseCompilerVersion(contract_js_1.MAX_CLPP_VERSION_EXCLUSIVE)) < 0;
|
|
17
|
+
}
|
|
18
|
+
function validateCompilerHandshake(version, value) {
|
|
19
|
+
const fail = (reason) => { throw new Error(`cluaupp: incompatible clpp (${version || "unknown"}): ${reason}. Require Luau compiler ${contract_js_1.CLPP_VERSION_RANGE}, contractVersion ${contract_js_1.CLPP_CONTRACT_VERSION}. The clpp game VM cannot emit Roblox Luau. Set CLPP or CLPP_PATH to the Luau compiler.`); };
|
|
20
|
+
if (!acceptsCompilerVersion(version))
|
|
21
|
+
fail("unsupported version");
|
|
22
|
+
if (!value || typeof value !== "object")
|
|
23
|
+
fail("missing api manifest");
|
|
24
|
+
const m = value;
|
|
25
|
+
if (m.id !== "clpp" || m.name !== "CL++")
|
|
26
|
+
fail("wrong compiler identity");
|
|
27
|
+
if (m.contractVersion !== contract_js_1.CLPP_CONTRACT_VERSION)
|
|
28
|
+
fail("missing or unsupported contractVersion");
|
|
29
|
+
if (!acceptsCompilerVersion(m.version) || compare(parseCompilerVersion(version), parseCompilerVersion(m.version)) !== 0)
|
|
30
|
+
fail("binary and manifest versions disagree");
|
|
31
|
+
if (!Array.isArray(m.extensions) || ![".clpp", ".clp", ".clh"].every(x => m.extensions.includes(x)))
|
|
32
|
+
fail("missing source extensions");
|
|
33
|
+
if (!Array.isArray(m.tags) || ![["*.server.clpp", "server", "Script"], ["*.client.clpp", "client", "LocalScript"], ["*.clh", "header", "ModuleScript"]].every(([pattern, kind, cls]) => m.tags.some(t => t.pattern === pattern && t.scriptKind === kind && t.rojoClass === cls)))
|
|
34
|
+
fail("missing Roblox file tags");
|
|
35
|
+
return m;
|
|
36
|
+
}
|
|
@@ -135,19 +135,30 @@ function resolveLanguageDeps(source, fromFile, srcDir) {
|
|
|
135
135
|
return out;
|
|
136
136
|
}
|
|
137
137
|
/**
|
|
138
|
-
* Fingerprint source +
|
|
138
|
+
* Fingerprint source + transitive language deps so import/include edits invalidate incremental cache.
|
|
139
139
|
*/
|
|
140
140
|
function fingerprintSourceWithDeps(source, fromFile, configKey, srcDir, hashText) {
|
|
141
141
|
const parts = [configKey, source];
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
const seen = new Set([node_path_1.default.resolve(fromFile)]);
|
|
143
|
+
const visit = (text, file) => {
|
|
144
|
+
for (const ref of collectModuleRefs(text)) {
|
|
145
|
+
if (ref.angled)
|
|
146
|
+
continue;
|
|
147
|
+
const dep = resolveModuleFile(ref.modulePath, file, srcDir);
|
|
148
|
+
if (!dep) {
|
|
149
|
+
parts.push("\n//missing:" + file + ":" + ref.modulePath);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const key = node_path_1.default.resolve(dep);
|
|
153
|
+
if (seen.has(key))
|
|
154
|
+
continue;
|
|
155
|
+
seen.add(key);
|
|
156
|
+
const contents = node_fs_1.default.readFileSync(key, "utf8");
|
|
157
|
+
parts.push("\n//dep:" + key.replace(/\\/g, "/") + "\n", contents);
|
|
158
|
+
visit(contents, key);
|
|
149
159
|
}
|
|
150
|
-
}
|
|
160
|
+
};
|
|
161
|
+
visit(source, fromFile);
|
|
151
162
|
return hashText(parts.join(""));
|
|
152
163
|
}
|
|
153
164
|
/** Rewrite CL++ `script.Parent…Service…` walks to game-rooted requires. */
|
package/generated/clpp/runner.js
CHANGED
|
@@ -11,36 +11,68 @@ exports.compileViaClppAsync = compileViaClppAsync;
|
|
|
11
11
|
exports.clppManifest = clppManifest;
|
|
12
12
|
exports.clppVersion = clppVersion;
|
|
13
13
|
exports.clppInstalls = clppInstalls;
|
|
14
|
+
exports.clppCacheIdentity = clppCacheIdentity;
|
|
14
15
|
const node_child_process_1 = require("node:child_process");
|
|
15
16
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
16
17
|
const node_os_1 = __importDefault(require("node:os"));
|
|
17
18
|
const node_path_1 = __importDefault(require("node:path"));
|
|
18
19
|
const contract_js_1 = require("./contract.js");
|
|
20
|
+
const handshake_js_1 = require("./handshake.js");
|
|
19
21
|
const MISSING_CLPP = `cluaupp: clpp not found. ${contract_js_1.CLPP_INSTALL_HINT}`;
|
|
20
22
|
let cachedBin;
|
|
23
|
+
let cachedSelectionKey = "";
|
|
24
|
+
const contractSupport = new Map();
|
|
25
|
+
function binaryKey(bin) {
|
|
26
|
+
const stat = node_fs_1.default.statSync(bin);
|
|
27
|
+
return JSON.stringify([bin, stat.size, stat.mtimeMs]);
|
|
28
|
+
}
|
|
21
29
|
function parseSemver(text) {
|
|
22
|
-
const match = String(text).match(/(\d+)\.(\d+)
|
|
30
|
+
const match = String(text).match(/(\d+)\.(\d+)(?:\.(\d+))?/);
|
|
23
31
|
if (!match) {
|
|
24
32
|
return null;
|
|
25
33
|
}
|
|
26
|
-
return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3]) };
|
|
34
|
+
return { major: Number(match[1]), minor: Number(match[2]), patch: Number(match[3] || 0) };
|
|
27
35
|
}
|
|
28
36
|
function cmpSemver(a, b) {
|
|
29
37
|
return a.major - b.major || a.minor - b.minor || a.patch - b.patch;
|
|
30
38
|
}
|
|
31
|
-
function minClpp() {
|
|
32
|
-
return parseSemver(contract_js_1.MIN_CLPP_VERSION) || { major: 0, minor: 8, patch: 0 };
|
|
33
|
-
}
|
|
34
|
-
function tooOldMessage(bin, version) {
|
|
35
|
-
return `cluaupp: clpp ${version || "unknown"} is too old (${bin}). Need CL++ ${contract_js_1.MIN_CLPP_VERSION}+. Install https://github.com/KartzRbx/CLPP/releases or set CLPP / CLPP_PATH.`;
|
|
36
|
-
}
|
|
37
39
|
function probeVersion(bin) {
|
|
38
|
-
const result = (0, node_child_process_1.spawnSync)(bin, ["--version"], { encoding: "utf8", windowsHide: true });
|
|
40
|
+
const result = (0, node_child_process_1.spawnSync)(bin, ["--version"], { encoding: "utf8", windowsHide: true, timeout: 10_000 });
|
|
39
41
|
if (result.status !== 0) {
|
|
40
42
|
return null;
|
|
41
43
|
}
|
|
42
44
|
return String(result.stdout || result.stderr || "").trim() || null;
|
|
43
45
|
}
|
|
46
|
+
function handshake(bin) {
|
|
47
|
+
const key = binaryKey(bin);
|
|
48
|
+
const cached = contractSupport.get(key);
|
|
49
|
+
if (cached)
|
|
50
|
+
return cached;
|
|
51
|
+
const version = probeVersion(bin) || "";
|
|
52
|
+
let manifest;
|
|
53
|
+
// Reject the VM before asking it to compile or interpret any input.
|
|
54
|
+
if ((0, handshake_js_1.acceptsCompilerVersion)(version)) {
|
|
55
|
+
const result = (0, node_child_process_1.spawnSync)(bin, ["api", "manifest"], { encoding: "utf8", windowsHide: true, timeout: 10_000 });
|
|
56
|
+
if (result.status === 0) {
|
|
57
|
+
try {
|
|
58
|
+
manifest = JSON.parse(String(result.stdout || ""));
|
|
59
|
+
}
|
|
60
|
+
catch { }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const validated = (0, handshake_js_1.validateCompilerHandshake)(version, manifest);
|
|
64
|
+
contractSupport.set(key, validated);
|
|
65
|
+
return validated;
|
|
66
|
+
}
|
|
67
|
+
function supportsLuauContract(bin) {
|
|
68
|
+
try {
|
|
69
|
+
handshake(bin);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
44
76
|
function pushCandidate(out, seen, item) {
|
|
45
77
|
const value = String(item || "").trim();
|
|
46
78
|
if (!value) {
|
|
@@ -66,9 +98,12 @@ function listClppCandidates() {
|
|
|
66
98
|
const override = [];
|
|
67
99
|
pushCandidate(override, seen, process.env.CLPP);
|
|
68
100
|
pushCandidate(override, seen, process.env.CLPP_PATH);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
101
|
+
if (override.length > 0) {
|
|
102
|
+
for (const bin of override) {
|
|
103
|
+
if (!existsBin(bin))
|
|
104
|
+
throw new Error(`cluaupp: explicit CLPP/CLPP_PATH does not exist: ${bin}`);
|
|
105
|
+
}
|
|
106
|
+
return override;
|
|
72
107
|
}
|
|
73
108
|
const out = [];
|
|
74
109
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
@@ -97,7 +132,7 @@ function pickClppBinary() {
|
|
|
97
132
|
if (!fallback) {
|
|
98
133
|
fallback = bin;
|
|
99
134
|
}
|
|
100
|
-
if (!parsed) {
|
|
135
|
+
if (!parsed || !supportsLuauContract(bin)) {
|
|
101
136
|
continue;
|
|
102
137
|
}
|
|
103
138
|
if (!best || cmpSemver(parsed, best.parsed) > 0) {
|
|
@@ -107,9 +142,11 @@ function pickClppBinary() {
|
|
|
107
142
|
return best?.bin || fallback;
|
|
108
143
|
}
|
|
109
144
|
function whichClpp() {
|
|
110
|
-
|
|
145
|
+
const selectionKey = JSON.stringify([process.env.CLPP, process.env.CLPP_PATH, process.env.PATH]);
|
|
146
|
+
if (cachedBin !== undefined && selectionKey === cachedSelectionKey) {
|
|
111
147
|
return cachedBin;
|
|
112
148
|
}
|
|
149
|
+
cachedSelectionKey = selectionKey;
|
|
113
150
|
cachedBin = pickClppBinary();
|
|
114
151
|
return cachedBin;
|
|
115
152
|
}
|
|
@@ -121,18 +158,14 @@ function resolveClppBinary() {
|
|
|
121
158
|
if (!bin) {
|
|
122
159
|
throw new Error(MISSING_CLPP);
|
|
123
160
|
}
|
|
124
|
-
|
|
125
|
-
const parsed = parseSemver(version || "");
|
|
126
|
-
if (!parsed || cmpSemver(parsed, minClpp()) < 0) {
|
|
127
|
-
throw new Error(tooOldMessage(bin, version));
|
|
128
|
-
}
|
|
161
|
+
handshake(bin);
|
|
129
162
|
return bin;
|
|
130
163
|
}
|
|
131
164
|
function parseArtifact(stdout, fileName, fallbackError) {
|
|
132
165
|
const text = String(stdout || "").trim();
|
|
133
166
|
try {
|
|
134
167
|
const parsed = JSON.parse(text);
|
|
135
|
-
if (parsed && typeof parsed === "object") {
|
|
168
|
+
if (parsed && typeof parsed === "object" && typeof parsed.ok === "boolean" && typeof parsed.luau === "string" && typeof parsed.fileName === "string") {
|
|
136
169
|
return parsed;
|
|
137
170
|
}
|
|
138
171
|
}
|
|
@@ -158,7 +191,7 @@ function formatClppFailure(artifact, fallback) {
|
|
|
158
191
|
return diags
|
|
159
192
|
.map((d) => {
|
|
160
193
|
const where = `${artifact.fileName || "clpp"}:${d.line}:${d.column}`;
|
|
161
|
-
return `${where}: ${d.message}`;
|
|
194
|
+
return `${where}: ${d.severity}${d.code ? " [" + d.code + "]" : ""}: ${d.message}${d.help ? "\n " + d.help : ""}`;
|
|
162
195
|
})
|
|
163
196
|
.join("\n");
|
|
164
197
|
}
|
|
@@ -186,7 +219,7 @@ function compileViaClpp(request) {
|
|
|
186
219
|
});
|
|
187
220
|
const stderr = String(result.stderr || "").trim();
|
|
188
221
|
const artifact = parseArtifact(result.stdout, request.fileName, stderr || result.error?.message || "clpp api compile failed");
|
|
189
|
-
if (!artifact.ok) {
|
|
222
|
+
if (result.status !== 0 || result.error || !artifact.ok) {
|
|
190
223
|
throw new Error(formatClppFailure(artifact, stderr || result.error?.message || `clpp failed (${result.status})`));
|
|
191
224
|
}
|
|
192
225
|
return artifact;
|
|
@@ -218,7 +251,7 @@ function compileViaClppAsync(request) {
|
|
|
218
251
|
child.on("error", reject);
|
|
219
252
|
child.on("close", (code) => {
|
|
220
253
|
const artifact = parseArtifact(stdout, request.fileName, stderr.trim() || `clpp api compile failed (${code})`);
|
|
221
|
-
if (!artifact.ok) {
|
|
254
|
+
if (code !== 0 || !artifact.ok) {
|
|
222
255
|
reject(new Error(formatClppFailure(artifact, stderr.trim() || `clpp failed (${code})`)));
|
|
223
256
|
return;
|
|
224
257
|
}
|
|
@@ -239,14 +272,7 @@ function compileViaClppAsync(request) {
|
|
|
239
272
|
}
|
|
240
273
|
function clppManifest() {
|
|
241
274
|
const bin = resolveClppBinary();
|
|
242
|
-
|
|
243
|
-
encoding: "utf8",
|
|
244
|
-
windowsHide: true,
|
|
245
|
-
});
|
|
246
|
-
if (result.status !== 0) {
|
|
247
|
-
throw new Error(String(result.stderr || result.error?.message || "clpp api manifest failed"));
|
|
248
|
-
}
|
|
249
|
-
return JSON.parse(result.stdout);
|
|
275
|
+
return handshake(bin);
|
|
250
276
|
}
|
|
251
277
|
function clppVersion() {
|
|
252
278
|
const bin = whichClpp();
|
|
@@ -263,3 +289,8 @@ function clppInstalls() {
|
|
|
263
289
|
selected: bin === selected,
|
|
264
290
|
}));
|
|
265
291
|
}
|
|
292
|
+
/** Include the actual binary and handshake in incremental fingerprints. */
|
|
293
|
+
function clppCacheIdentity() {
|
|
294
|
+
const bin = resolveClppBinary();
|
|
295
|
+
return JSON.stringify([binaryKey(bin), handshake(bin)]);
|
|
296
|
+
}
|
package/generated/compile.js
CHANGED
|
@@ -21,6 +21,8 @@ const datamodel_generate_js_1 = require("./target/datamodel-generate.js");
|
|
|
21
21
|
const parallel_check_js_1 = require("./target/parallel-check.js");
|
|
22
22
|
const authority_check_js_1 = require("./target/authority-check.js");
|
|
23
23
|
const get_service_js_1 = require("./target/get-service.js");
|
|
24
|
+
const project_js_1 = require("./compiler/project.js");
|
|
25
|
+
const diagnostics_js_1 = require("./compiler/diagnostics.js");
|
|
24
26
|
function defaultTargetProfilePath() {
|
|
25
27
|
const cached = node_path_1.default.join(package_info_js_1.projectRoot, "api", "normalized", "roblox-target.profile.json");
|
|
26
28
|
if (node_fs_1.default.existsSync(cached)) {
|
|
@@ -122,7 +124,7 @@ function finishArtifact(artifact, relative, outName, options, skipInit, source)
|
|
|
122
124
|
return {
|
|
123
125
|
kind: (0, paths_js_1.emitKind)(relative),
|
|
124
126
|
plan: { kind: (0, paths_js_1.emitKind)(relative), strict: options.strict === true },
|
|
125
|
-
files: [{ name: outName, contents: luau }],
|
|
127
|
+
files: [{ name: outName, contents: luau, sourceMap: artifact.sourceMap, generatedSource: artifact.luau }],
|
|
126
128
|
stale: [],
|
|
127
129
|
};
|
|
128
130
|
}
|
|
@@ -130,14 +132,29 @@ function compileSource(source, fileName, options = {}) {
|
|
|
130
132
|
return compileService(source, fileName, options).files[0]?.contents ?? "";
|
|
131
133
|
}
|
|
132
134
|
function compileService(source, fileName, options = {}) {
|
|
135
|
+
if (/\.clp$/i.test(options.relativeName || fileName || "")) {
|
|
136
|
+
return compileModernSource(source, fileName, options);
|
|
137
|
+
}
|
|
133
138
|
const args = compileArgs(source, fileName, options);
|
|
134
139
|
enforcePlatform(source, args.relative, args);
|
|
135
140
|
const artifact = (0, runner_js_1.compileViaClpp)(args.request);
|
|
136
141
|
return finishArtifact(artifact, args.relative, args.outName, args.options, args.skipInit, source);
|
|
137
142
|
}
|
|
138
143
|
async function compileServiceAsync(source, fileName, options = {}) {
|
|
144
|
+
if (/\.clp$/i.test(options.relativeName || fileName || "")) {
|
|
145
|
+
return compileModernSource(source, fileName, options);
|
|
146
|
+
}
|
|
139
147
|
const args = compileArgs(source, fileName, options);
|
|
140
148
|
enforcePlatform(source, args.relative, args);
|
|
141
149
|
const artifact = await (0, runner_js_1.compileViaClppAsync)(args.request);
|
|
142
150
|
return finishArtifact(artifact, args.relative, args.outName, args.options, args.skipInit, source);
|
|
143
151
|
}
|
|
152
|
+
function compileModernSource(source, fileName, options) {
|
|
153
|
+
const relative = (options.relativeName || fileName || "input.clp").replace(/\\/g, "/");
|
|
154
|
+
const srcDir = options.srcDir || (options.filePath ? node_path_1.default.dirname(node_path_1.default.resolve(options.filePath)) : process.cwd());
|
|
155
|
+
const result = (0, project_js_1.compileSource)(source, relative, { srcDir, strict: options.strict === true, version: package_info_js_1.pkg.version });
|
|
156
|
+
if (result.luau === null) {
|
|
157
|
+
throw new Error(result.diagnostics.filter((d) => d.severity === "error").map((d) => (0, diagnostics_js_1.formatDiagnostic)(d, result.source)).join("\n") || `${relative}: Luau emission failed`);
|
|
158
|
+
}
|
|
159
|
+
return { kind: (0, paths_js_1.emitKind)(relative), files: [{ name: options.outName || (0, paths_js_1.toLuauPath)(relative), contents: result.luau, sourceMap: result.sourceMap, generatedSource: result.luau }], stale: [] };
|
|
160
|
+
}
|