cluaupp 1.4.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/README.md +10 -5
- package/api/CHANGELOG.md +3 -0
- package/api/chat.js +74 -0
- package/api/fixtures/roblox/README.md +6 -0
- package/api/fixtures/roblox/aux/sample.d.luau +6 -0
- package/api/fixtures/roblox/mini/Mini-API-Dump.json +72 -0
- package/api/generated/bench-latest.json +39 -0
- package/api/generated/capability-profile.json +76 -0
- package/api/generated/lsp-index.json +1 -0
- package/api/generated/luau/classes.d.luau +11221 -0
- package/api/generated/luau/datatypes.d.luau +327 -0
- package/api/generated/luau/enums.d.luau +4918 -0
- package/api/generated/luau/globals.d.luau +12 -0
- package/api/manifests/roblox-target.manifest.json +22 -0
- package/api/normalized/roblox-target.profile.json +237461 -0
- package/api/overrides/classes.json +8 -0
- package/api/overrides/compatibility.json +9 -0
- package/api/overrides/datatypes.json +1579 -0
- package/api/overrides/enums.json +8 -0
- package/api/overrides/globals.json +8 -0
- package/api/overrides/type-mappings.json +9 -0
- package/api/roblox-api.lock.json +9 -0
- package/data/Mini-API-Dump.json +1 -0
- package/editors/vscode/README.md +19 -0
- package/editors/vscode/extension.js +222 -21
- package/editors/vscode/icons/axiom.svg +4 -0
- package/editors/vscode/icons/bloom.svg +5 -0
- package/editors/vscode/icons/flare.svg +5 -0
- package/editors/vscode/icons/helm.svg +4 -0
- package/editors/vscode/icons/hive.svg +5 -0
- package/editors/vscode/icons/mint.svg +4 -0
- package/editors/vscode/icons/shift.svg +6 -0
- package/editors/vscode/language-configuration-schema.json +24 -0
- package/editors/vscode/language-configuration.json +21 -0
- package/editors/vscode/package.json +220 -6
- package/editors/vscode/snippets/axiom.json +12 -0
- package/editors/vscode/snippets/bloom.json +12 -0
- package/editors/vscode/snippets/flare.json +27 -0
- package/editors/vscode/snippets/helm.json +12 -0
- package/editors/vscode/snippets/hive.json +12 -0
- package/editors/vscode/snippets/mint.json +12 -0
- package/editors/vscode/snippets/shift.json +17 -0
- package/editors/vscode/syntaxes/axiom.tmLanguage.json +5 -0
- package/editors/vscode/syntaxes/bloom.tmLanguage.json +5 -0
- package/editors/vscode/syntaxes/flare.tmLanguage.json +75 -0
- package/editors/vscode/syntaxes/helm.tmLanguage.json +5 -0
- package/editors/vscode/syntaxes/hive.tmLanguage.json +5 -0
- package/editors/vscode/syntaxes/mint.tmLanguage.json +5 -0
- package/editors/vscode/syntaxes/schema.tmLanguage.json +89 -0
- package/editors/vscode/syntaxes/shift.tmLanguage.json +5 -0
- package/examples/game/.cluaupp/compile-cache/ReplicatedStorage__Shared__Constants__Datas__TemplateData.clh.json +1 -0
- package/examples/game/.cluaupp/compile-cache/ServerScriptService__Boot__DataBoot.server.clpp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/ServerScriptService__Configuration__ServerConfig.clp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__Guard.server.clpp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__PlayerHandler.server.clpp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterCharacterScripts__Character__CharacterReady.client.clpp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterPlayerScripts__Controllers__DataController.client.clpp.json +1 -0
- package/examples/game/.cluaupp/compile-cache/index.json +12 -0
- package/examples/game/.cluaupp/datamodel-profile.json +94 -0
- package/examples/game/.vscode/extensions.json +3 -1
- package/examples/game/.vscode/settings.json +13 -1
- package/examples/game/include/clpp/datatypes.clh +337 -373
- package/examples/game/include/clpp/generated/datamodel.clh +25 -0
- package/examples/game/include/clpp/generated/enums.clh +1 -1
- package/examples/game/include/clpp/generated/instances.clh +41135 -41064
- package/examples/game/include/clpp/libs/axiom.clh +1 -1
- package/examples/game/include/clpp/libs/math.clh +14 -0
- package/examples/game/include/clpp/libs/roster.clh +6 -0
- package/examples/game/include/clpp/libs/spring.clh +17 -0
- package/examples/game/include/clpp/libs/ward.clh +1 -0
- package/examples/game/include/clpp/roblox.clh +3 -4
- package/examples/game/libs/ArrayIndexer/init.luau +209 -0
- package/examples/game/libs/Axiom/init.luau +608 -0
- package/examples/game/libs/Bloom/init.luau +433 -0
- package/examples/game/libs/Coil/init.luau +215 -0
- package/examples/game/libs/Crest/init.luau +426 -0
- package/examples/game/libs/Echo/init.luau +417 -0
- package/examples/game/libs/Ember/init.luau +365 -0
- package/examples/game/libs/Flare/init.luau +717 -0
- package/examples/game/libs/Gleam/init.luau +729 -0
- package/examples/game/libs/Guide/init.luau +215 -0
- package/examples/game/libs/Helm/init.luau +377 -0
- package/examples/game/libs/Hive/init.luau +241 -0
- package/examples/game/libs/Keep/Client.luau +114 -0
- package/examples/game/libs/Keep/Data.luau +883 -0
- package/examples/game/libs/Keep/Engine.luau +211 -0
- package/examples/game/libs/Keep/Enum.luau +6 -0
- package/examples/game/libs/Keep/Enums.luau +10 -0
- package/examples/game/libs/Keep/Path.luau +236 -0
- package/examples/game/libs/Keep/Replicator.luau +298 -0
- package/examples/game/libs/Keep/Server.luau +251 -0
- package/examples/game/libs/Keep/Store.luau +652 -0
- package/examples/game/libs/Keep/Trade.luau +455 -0
- package/examples/game/libs/Keep/init.luau +205 -0
- package/examples/game/libs/Lens/init.luau +609 -0
- package/examples/game/libs/Mint/init.luau +279 -0
- package/examples/game/libs/Net/init.luau +156 -0
- package/examples/game/libs/Net/src/codec.luau +224 -0
- package/examples/game/libs/Occlude/init.luau +117 -0
- package/examples/game/libs/Pin/init.luau +309 -0
- package/examples/game/libs/Promise/LICENSE +21 -0
- package/examples/game/libs/Promise/_impl/LICENSE +21 -0
- package/examples/game/libs/Promise/_impl/init.lua +1991 -0
- package/examples/game/libs/Promise/init.lua +1990 -0
- package/examples/game/libs/Promise/init.luau +13 -0
- package/examples/game/libs/Promise/types.luau +46 -0
- package/examples/game/libs/Roster/init.luau +686 -0
- package/examples/game/libs/SOURCES.md +31 -0
- package/examples/game/libs/Shift/init.luau +238 -0
- package/examples/game/libs/Spark/init.luau +487 -0
- package/examples/game/libs/Stage/init.luau +178 -0
- package/examples/game/libs/Sweep/init.luau +259 -0
- package/examples/game/libs/Trace/init.luau +213 -0
- package/examples/game/libs/Ward/init.luau +211 -0
- package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau +29 -0
- package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau.map.json +13 -0
- package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau +83 -0
- package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau +18 -0
- package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau +14 -0
- package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau +15 -0
- package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau.map.json +13 -0
- package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau +50 -0
- package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau.map.json +13 -0
- package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau +12 -0
- package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau.map.json +13 -0
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau +16 -0
- package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau.map.json +13 -0
- package/examples/game/src/ReplicatedStorage/Shared/Net/Net.clh +26 -0
- package/examples/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
- package/examples/game/src/ServerScriptService/Boot/DataBoot.server.clpp +2 -2
- package/examples/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
- package/examples/game/stylua.toml +9 -0
- package/generated/api/build-profile.js +115 -0
- package/generated/api/cache.js +44 -0
- package/generated/api/coverage.js +32 -0
- package/generated/api/diff.js +125 -0
- package/generated/api/generators/clpp-headers.js +353 -0
- package/generated/api/generators/docs-reference.js +7 -0
- package/generated/api/generators/lsp-index.js +81 -0
- package/generated/api/generators/luau-defs.js +94 -0
- package/generated/api/ide.js +76 -0
- package/generated/api/identifier.js +47 -0
- package/generated/api/index.js +324 -0
- package/generated/api/loader.js +57 -0
- package/generated/api/merge.js +88 -0
- package/generated/api/model.js +5 -0
- package/generated/api/normalize.js +231 -0
- package/generated/api/overrides-validate.js +58 -0
- package/generated/api/perf.js +12 -0
- package/generated/api/registry.js +136 -0
- package/generated/api/release.js +44 -0
- package/generated/api/resolver.js +250 -0
- package/generated/api/sources/aux-types-diff.js +75 -0
- package/generated/api/sources/client-tracker.js +11 -0
- package/generated/api/sources/creator-docs.js +42 -0
- package/generated/api/sources/luau-types.js +34 -0
- package/generated/api/sources/mini-dump.js +17 -0
- package/generated/api/sources/studio-api.js +8 -0
- package/generated/api/sources/studio-apiv2.js +11 -0
- package/generated/api/sources/studio-full-api.js +8 -0
- package/generated/api/studio-smoke.js +80 -0
- package/generated/api/type-parse.js +49 -0
- package/generated/api/understander.js +51 -0
- package/generated/api/validate.js +135 -0
- package/generated/api-cli.js +421 -0
- package/generated/cli.js +17 -6
- package/generated/clpp/contract.js +3 -3
- package/generated/clpp/format-luau.js +236 -0
- package/generated/clpp/index.js +13 -1
- package/generated/clpp/modules.js +227 -0
- package/generated/clpp/postprocess.js +86 -5
- package/generated/clpp/rewrite-janitor.js +145 -0
- package/generated/clpp/runner.js +14 -2
- package/generated/compile.js +82 -0
- package/generated/flare/index.js +15 -3
- package/generated/flare/language.js +561 -0
- package/generated/flare/parse.js +19 -7
- package/generated/intellisense.js +76 -2
- package/generated/lsp.js +118 -7
- package/generated/native/index.js +217 -16
- package/generated/target/authority-check.js +136 -0
- package/generated/target/authority-graph.js +74 -0
- package/generated/target/build-cache.js +112 -0
- package/generated/target/capabilities.js +89 -0
- package/generated/target/capability-profile.js +30 -0
- package/generated/target/component-contracts.js +60 -0
- package/generated/target/context-check.js +160 -0
- package/generated/target/datamodel-check.js +170 -0
- package/generated/target/datamodel-generate.js +74 -0
- package/generated/target/datamodel.js +233 -0
- package/generated/target/diagnostics.js +63 -0
- package/generated/target/doctor.js +152 -0
- package/generated/target/flare-version.js +58 -0
- package/generated/target/get-service.js +69 -0
- package/generated/target/lifetime-check.js +47 -0
- package/generated/target/luau-stamp.js +39 -0
- package/generated/target/optimizer-advise.js +88 -0
- package/generated/target/optimizer-apply.js +44 -0
- package/generated/target/optimizer-soa.js +254 -0
- package/generated/target/parallel-check.js +136 -0
- package/generated/target/pgo.js +148 -0
- package/generated/target/project-docs.js +69 -0
- package/generated/target/project-graph.js +71 -0
- package/generated/target/roblox.js +63 -0
- package/generated/target/security-check.js +41 -0
- package/generated/target/source-map.js +25 -0
- package/generated/target/studio-bridge.js +112 -0
- package/generated/utils/project.js +178 -8
- package/generated/utils/rojo-mapper.js +11 -3
- package/include/clpp/datatypes.clh +337 -373
- package/include/clpp/generated/enums.clh +1 -1
- package/include/clpp/generated/instances.clh +41135 -41064
- package/include/clpp/libs/axiom.clh +1 -1
- package/include/clpp/libs/hive.clh +1 -0
- package/include/clpp/libs/keep.clh +2 -0
- package/include/clpp/libs/math.clh +14 -0
- package/include/clpp/libs/roster.clh +6 -0
- package/include/clpp/libs/spring.clh +17 -0
- package/include/clpp/libs/ward.clh +1 -0
- package/include/clpp/roblox.clh +3 -4
- package/package.json +10 -3
- package/plugins/CluauppNav/Plugin.luau +207 -0
- package/plugins/CluauppNav/ProfileLogger.luau +27 -0
- package/plugins/CluauppNav/README.md +24 -0
- package/runtime/Axiom/init.luau +10 -7
- package/runtime/Coil/init.luau +8 -2
- package/runtime/Crest/init.luau +1 -0
- package/runtime/Flare/init.luau +2 -1
- package/runtime/Gleam/init.luau +15 -4
- package/runtime/Hive/init.luau +36 -14
- package/runtime/Pin/init.luau +5 -2
- package/runtime/Roster/init.luau +8 -0
- package/runtime/Spark/init.luau +3 -0
- package/runtime/Sweep/init.luau +2 -0
- package/runtime/Trace/init.luau +3 -0
- package/runtime/Ward/init.luau +38 -5
- package/scripts/postinstall-editor.js +17 -0
- package/skills/README.md +13 -0
- package/skills/clpp-hive-flare/SKILL.md +79 -0
- package/skills/clpp-language/SKILL.md +123 -0
- package/skills/clpp-language/compiler.md +89 -0
- package/skills/clpp-style/SKILL.md +95 -0
- package/src/api/build-profile.ts +138 -0
- package/src/api/cache.ts +45 -0
- package/src/api/coverage.ts +46 -0
- package/src/api/diff.ts +143 -0
- package/src/api/generators/clpp-headers.ts +377 -0
- package/src/api/generators/docs-reference.ts +11 -0
- package/src/api/generators/lsp-index.ts +106 -0
- package/src/api/generators/luau-defs.ts +98 -0
- package/src/api/ide.ts +87 -0
- package/src/api/identifier.ts +47 -0
- package/src/api/index.ts +269 -0
- package/src/api/loader.ts +60 -0
- package/src/api/merge.ts +126 -0
- package/src/api/model.ts +283 -0
- package/src/api/normalize.ts +257 -0
- package/src/api/overrides-validate.ts +58 -0
- package/src/api/perf.ts +15 -0
- package/src/api/registry.ts +162 -0
- package/src/api/release.ts +47 -0
- package/src/api/resolver.ts +255 -0
- package/src/api/sources/aux-types-diff.ts +81 -0
- package/src/api/sources/client-tracker.ts +10 -0
- package/src/api/sources/creator-docs.ts +37 -0
- package/src/api/sources/luau-types.ts +30 -0
- package/src/api/sources/mini-dump.ts +50 -0
- package/src/api/sources/studio-api.ts +7 -0
- package/src/api/sources/studio-apiv2.ts +10 -0
- package/src/api/sources/studio-full-api.ts +7 -0
- package/src/api/studio-smoke.ts +82 -0
- package/src/api/type-parse.ts +48 -0
- package/src/api/understander.ts +72 -0
- package/src/api/validate.ts +160 -0
- package/src/api-cli.ts +493 -0
- package/src/api.generated.js +37 -22
- package/src/cli.ts +22 -7
- package/src/clpp/contract.ts +34 -3
- package/src/clpp/format-luau.ts +262 -0
- package/src/clpp/index.ts +13 -2
- package/src/clpp/modules.ts +252 -0
- package/src/clpp/postprocess.ts +100 -5
- package/src/clpp/rewrite-janitor.ts +156 -0
- package/src/clpp/runner.ts +14 -2
- package/src/compile.ts +87 -0
- package/src/flare/index.ts +20 -1
- package/src/flare/language.ts +708 -0
- package/src/flare/parse.ts +20 -7
- package/src/flare/types.ts +2 -0
- package/src/intellisense.ts +76 -2
- package/src/lsp.ts +151 -8
- package/src/native/index.ts +225 -16
- package/src/target/authority-check.ts +162 -0
- package/src/target/authority-graph.ts +80 -0
- package/src/target/build-cache.ts +129 -0
- package/src/target/capabilities.ts +115 -0
- package/src/target/capability-profile.ts +25 -0
- package/src/target/component-contracts.ts +64 -0
- package/src/target/context-check.ts +177 -0
- package/src/target/datamodel-check.ts +188 -0
- package/src/target/datamodel-generate.ts +78 -0
- package/src/target/datamodel.ts +261 -0
- package/src/target/diagnostics.ts +67 -0
- package/src/target/doctor.ts +171 -0
- package/src/target/flare-version.ts +61 -0
- package/src/target/get-service.ts +85 -0
- package/src/target/lifetime-check.ts +45 -0
- package/src/target/luau-stamp.ts +33 -0
- package/src/target/optimizer-advise.ts +93 -0
- package/src/target/optimizer-apply.ts +63 -0
- package/src/target/optimizer-soa.ts +270 -0
- package/src/target/parallel-check.ts +135 -0
- package/src/target/pgo.ts +157 -0
- package/src/target/project-docs.ts +68 -0
- package/src/target/project-graph.ts +75 -0
- package/src/target/roblox.ts +78 -0
- package/src/target/security-check.ts +40 -0
- package/src/target/source-map.ts +36 -0
- package/src/target/studio-bridge.ts +140 -0
- package/src/types.ts +14 -0
- package/src/utils/project.ts +183 -9
- package/src/utils/rojo-mapper.ts +12 -3
- package/stylua.toml +9 -0
- package/templates/game/.vscode/extensions.json +3 -1
- package/templates/game/.vscode/settings.json +8 -1
- package/templates/game/include/clpp/datatypes.clh +337 -373
- package/templates/game/include/clpp/generated/enums.clh +1 -1
- package/templates/game/include/clpp/generated/instances.clh +41135 -41064
- package/templates/game/include/clpp/libs/axiom.clh +1 -1
- package/templates/game/include/clpp/libs/roster.clh +6 -0
- package/templates/game/include/clpp/libs/ward.clh +1 -0
- package/templates/game/include/clpp/roblox.clh +3 -4
- package/templates/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
- package/templates/game/src/ServerScriptService/Boot/DataBoot.server.clpp +2 -2
- package/templates/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
- package/templates/game/stylua.toml +9 -0
package/src/flare/parse.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FlareField, FlareQuery, FlarePacket, FlareSchema, FlareSide, FlareType } from "./types.js";
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
export const FLARE_TYPE_ALIASES: Record<string, FlareType> = {
|
|
4
4
|
u8: "u8",
|
|
5
5
|
u16: "u16",
|
|
6
6
|
u32: "u32",
|
|
@@ -28,14 +28,14 @@ const TYPES: Record<string, FlareType> = {
|
|
|
28
28
|
Player: "Player",
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
export const FLARE_IDENT = "[A-Za-z_][A-Za-z0-9_]*";
|
|
32
32
|
|
|
33
33
|
function fail(file: string, line: number, message: string): never {
|
|
34
34
|
throw new Error(`cluaupp flare: ${file}:${line}: ${message}`);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function parseType(raw: string, file: string, line: number): FlareType {
|
|
38
|
-
const mapped =
|
|
38
|
+
const mapped = FLARE_TYPE_ALIASES[raw];
|
|
39
39
|
if (!mapped) {
|
|
40
40
|
fail(file, line, `unknown type '${raw}'`);
|
|
41
41
|
}
|
|
@@ -53,7 +53,7 @@ function parseFields(list: string, file: string, line: number): FlareField[] {
|
|
|
53
53
|
if (!piece) {
|
|
54
54
|
continue;
|
|
55
55
|
}
|
|
56
|
-
const match = piece.match(new RegExp(`^(${
|
|
56
|
+
const match = piece.match(new RegExp(`^(${FLARE_IDENT})\\s+(${FLARE_IDENT})$`));
|
|
57
57
|
if (!match) {
|
|
58
58
|
fail(file, line, `expected 'Type name' in '${piece}'`);
|
|
59
59
|
}
|
|
@@ -76,6 +76,7 @@ function parseSide(raw: string, file: string, line: number): FlareSide {
|
|
|
76
76
|
export function parseFlare(source: string, filePath: string, defaultName: string): FlareSchema {
|
|
77
77
|
const file = filePath.replace(/\\/g, "/");
|
|
78
78
|
let name = defaultName;
|
|
79
|
+
let version: number | undefined;
|
|
79
80
|
const packets: FlarePacket[] = [];
|
|
80
81
|
const queries: FlareQuery[] = [];
|
|
81
82
|
let packetId = 1;
|
|
@@ -89,6 +90,12 @@ export function parseFlare(source: string, filePath: string, defaultName: string
|
|
|
89
90
|
continue;
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
const verStmt = line.match(/^version\s+(\d+)\s*;?$/i);
|
|
94
|
+
if (verStmt) {
|
|
95
|
+
version = Number(verStmt[1]);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
92
99
|
const opt = line.match(/^opt\s+name\s*=\s*(.+)$/i);
|
|
93
100
|
if (opt) {
|
|
94
101
|
const value = opt[1].trim().replace(/^["']|["']$/g, "");
|
|
@@ -99,9 +106,15 @@ export function parseFlare(source: string, filePath: string, defaultName: string
|
|
|
99
106
|
continue;
|
|
100
107
|
}
|
|
101
108
|
|
|
109
|
+
const optVer = line.match(/^opt\s+version\s*=\s*(\d+)\s*;?$/i);
|
|
110
|
+
if (optVer) {
|
|
111
|
+
version = Number(optVer[1]);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
const packet = line.match(
|
|
103
116
|
new RegExp(
|
|
104
|
-
`^packet\\s+(${
|
|
117
|
+
`^packet\\s+(${FLARE_IDENT})\\s*\\((.*)\\)\\s+from\\s+(Client|Server)(?:\\s+(unreliable|reliable))?\\s*$`,
|
|
105
118
|
"i",
|
|
106
119
|
),
|
|
107
120
|
);
|
|
@@ -121,7 +134,7 @@ export function parseFlare(source: string, filePath: string, defaultName: string
|
|
|
121
134
|
continue;
|
|
122
135
|
}
|
|
123
136
|
|
|
124
|
-
const query = line.match(new RegExp(`^query\\s+(${
|
|
137
|
+
const query = line.match(new RegExp(`^query\\s+(${FLARE_IDENT})\\s*\\((.*)\\)\\s*->\\s*(${FLARE_IDENT})\\s*$`, "i"));
|
|
125
138
|
if (query) {
|
|
126
139
|
if (queryId > 255) {
|
|
127
140
|
fail(file, lineNo, "too many queries (max 255)");
|
|
@@ -143,5 +156,5 @@ export function parseFlare(source: string, filePath: string, defaultName: string
|
|
|
143
156
|
fail(file, 1, "schema is empty — add a packet or query");
|
|
144
157
|
}
|
|
145
158
|
|
|
146
|
-
return { name, sourcePath: file, packets, queries };
|
|
159
|
+
return { name, sourcePath: file, version, packets, queries };
|
|
147
160
|
}
|
package/src/flare/types.ts
CHANGED
package/src/intellisense.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { ProjectConfig } from "./types.js";
|
|
|
7
7
|
import { CLPP_INSTALL_HINT } from "./clpp/contract.js";
|
|
8
8
|
import { hasClpp } from "./clpp/runner.js";
|
|
9
9
|
import { isSourceFile } from "./clpp/paths.js";
|
|
10
|
+
import { editorBin } from "./editor-install.js";
|
|
10
11
|
|
|
11
12
|
export type CluauppDiagnostic = {
|
|
12
13
|
line: number;
|
|
@@ -82,17 +83,32 @@ function writeVscode(root: string): void {
|
|
|
82
83
|
"*.server.clpp": "clpp",
|
|
83
84
|
"*.client.clpp": "clpp",
|
|
84
85
|
"*.plugin.clpp": "clpp",
|
|
86
|
+
"*.flare": "flare",
|
|
87
|
+
"*.hive": "hive",
|
|
88
|
+
"*.mint": "mint",
|
|
89
|
+
"*.bloom": "bloom",
|
|
90
|
+
"*.helm": "helm",
|
|
91
|
+
"*.shift": "shift",
|
|
92
|
+
"*.axiom": "axiom",
|
|
85
93
|
};
|
|
86
94
|
writeJson(settingsPath, {
|
|
87
95
|
...current,
|
|
88
96
|
"files.associations": associations,
|
|
97
|
+
"[luau]": {
|
|
98
|
+
...((current["[luau]"] && typeof current["[luau]"] === "object" && !Array.isArray(current["[luau]"]))
|
|
99
|
+
? (current["[luau]"] as Record<string, unknown>)
|
|
100
|
+
: {}),
|
|
101
|
+
"editor.insertSpaces": false,
|
|
102
|
+
"editor.tabSize": 4,
|
|
103
|
+
"editor.detectIndentation": false,
|
|
104
|
+
},
|
|
89
105
|
});
|
|
90
106
|
|
|
91
107
|
const extensionsPath = path.join(root, ".vscode", "extensions.json");
|
|
92
108
|
const extensions = readJsonObject(extensionsPath);
|
|
93
109
|
writeJson(extensionsPath, {
|
|
94
110
|
...extensions,
|
|
95
|
-
recommendations: uniqueStrings(extensions.recommendations),
|
|
111
|
+
recommendations: uniqueStrings(extensions.recommendations, ["kartzdev.cluaupp-flare"]),
|
|
96
112
|
unwantedRecommendations: uniqueStrings(extensions.unwantedRecommendations, ["ms-vscode.cpptools"]),
|
|
97
113
|
});
|
|
98
114
|
}
|
|
@@ -103,8 +119,32 @@ export function diagnosticsFor(_source?: string, _fileName?: string): CluauppDia
|
|
|
103
119
|
return [];
|
|
104
120
|
}
|
|
105
121
|
|
|
122
|
+
function writeStylua(root: string): void {
|
|
123
|
+
const dest = path.join(root, "stylua.toml");
|
|
124
|
+
const body = `# cluaupp roblox luau
|
|
125
|
+
syntax = "Luau"
|
|
126
|
+
column_width = 120
|
|
127
|
+
line_endings = "Unix"
|
|
128
|
+
indent_type = "Tabs"
|
|
129
|
+
indent_width = 4
|
|
130
|
+
quote_style = "AutoPreferDouble"
|
|
131
|
+
call_parentheses = "Always"
|
|
132
|
+
collapse_simple_statement = "Never"
|
|
133
|
+
`;
|
|
134
|
+
if (fs.existsSync(dest)) {
|
|
135
|
+
const existing = fs.readFileSync(dest, "utf8");
|
|
136
|
+
if (!existing.includes("cluaupp roblox luau") && existing.trim() !== "") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!fs.existsSync(dest) || fs.readFileSync(dest, "utf8") !== body) {
|
|
141
|
+
fs.writeFileSync(dest, body, "utf8");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
106
145
|
export function syncEditorSupport(root: string, _config: Partial<ProjectConfig> = {}): void {
|
|
107
146
|
writeVscode(root);
|
|
147
|
+
writeStylua(root);
|
|
108
148
|
}
|
|
109
149
|
|
|
110
150
|
export function installEditorExtension(cluauppRoot = PACKAGE_ROOT): string[] {
|
|
@@ -112,7 +152,7 @@ export function installEditorExtension(cluauppRoot = PACKAGE_ROOT): string[] {
|
|
|
112
152
|
if (!fs.existsSync(from)) {
|
|
113
153
|
return [];
|
|
114
154
|
}
|
|
115
|
-
const id = `kartzdev.cluaupp-
|
|
155
|
+
const id = `kartzdev.cluaupp-flare-${pkg.version}`;
|
|
116
156
|
const homes = [path.join(os.homedir(), ".cursor", "extensions"), path.join(os.homedir(), ".vscode", "extensions")];
|
|
117
157
|
const installed: string[] = [];
|
|
118
158
|
for (const home of homes) {
|
|
@@ -120,16 +160,50 @@ export function installEditorExtension(cluauppRoot = PACKAGE_ROOT): string[] {
|
|
|
120
160
|
continue;
|
|
121
161
|
}
|
|
122
162
|
fs.mkdirSync(home, { recursive: true });
|
|
163
|
+
try {
|
|
164
|
+
for (const name of fs.readdirSync(home)) {
|
|
165
|
+
if (name.startsWith("kartzdev.cluaupp-flare-") && name !== id) {
|
|
166
|
+
fs.rmSync(path.join(home, name), { recursive: true, force: true });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} catch {
|
|
170
|
+
// ignore prune errors
|
|
171
|
+
}
|
|
123
172
|
const dest = path.join(home, id);
|
|
124
173
|
copyDir(from, dest);
|
|
125
174
|
fs.writeFileSync(path.join(dest, "cluaupp.root"), path.resolve(cluauppRoot), "utf8");
|
|
175
|
+
const manifestPath = path.join(dest, "package.json");
|
|
176
|
+
if (fs.existsSync(manifestPath)) {
|
|
177
|
+
try {
|
|
178
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")) as Record<string, unknown>;
|
|
179
|
+
manifest.version = pkg.version;
|
|
180
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, "\t")}\n`, "utf8");
|
|
181
|
+
} catch {
|
|
182
|
+
// keep the copied manifest
|
|
183
|
+
}
|
|
184
|
+
}
|
|
126
185
|
installed.push(dest);
|
|
127
186
|
}
|
|
187
|
+
|
|
188
|
+
const bin = editorBin();
|
|
189
|
+
if (bin && installed[0]) {
|
|
190
|
+
spawnSync(bin, ["--install-extension", installed[0], "--force"], {
|
|
191
|
+
encoding: "utf8",
|
|
192
|
+
windowsHide: true,
|
|
193
|
+
timeout: 120000,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
128
196
|
return installed;
|
|
129
197
|
}
|
|
130
198
|
|
|
131
199
|
export async function installEditorSupport() {
|
|
132
200
|
const local = installEditorExtension();
|
|
201
|
+
if (local.length > 0) {
|
|
202
|
+
console.log("cluaupp: schema IntelliSense installed (.flare .hive .mint .bloom .helm .shift .axiom)");
|
|
203
|
+
for (const dest of local) {
|
|
204
|
+
console.log(" ", dest);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
133
207
|
if (hasClpp()) {
|
|
134
208
|
const result = spawnSync("clpp", ["install"], { encoding: "utf8", windowsHide: true });
|
|
135
209
|
if (result.status === 0) {
|
package/src/lsp.ts
CHANGED
|
@@ -1,30 +1,173 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
CompletionItemKind,
|
|
3
|
+
DiagnosticSeverity,
|
|
4
|
+
MarkupKind,
|
|
5
|
+
ParameterInformation,
|
|
3
6
|
ProposedFeatures,
|
|
7
|
+
SignatureInformation,
|
|
8
|
+
SymbolKind,
|
|
4
9
|
TextDocuments,
|
|
5
10
|
TextDocumentSyncKind,
|
|
11
|
+
createConnection,
|
|
12
|
+
type CompletionItem,
|
|
13
|
+
type Diagnostic,
|
|
14
|
+
type DocumentSymbol,
|
|
15
|
+
type Hover,
|
|
16
|
+
type SignatureHelp,
|
|
6
17
|
} from "vscode-languageserver/node";
|
|
7
18
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
19
|
+
import {
|
|
20
|
+
completionsAt,
|
|
21
|
+
hoverAt,
|
|
22
|
+
isFlareDocument,
|
|
23
|
+
signatureAt,
|
|
24
|
+
symbolsIn,
|
|
25
|
+
diagnoseFlare,
|
|
26
|
+
type FlareCompletionKind,
|
|
27
|
+
type FlareSeverity,
|
|
28
|
+
} from "./flare/language.js";
|
|
8
29
|
import { pkg } from "./package-info.js";
|
|
9
30
|
|
|
31
|
+
const KIND: Record<FlareCompletionKind, CompletionItemKind> = {
|
|
32
|
+
keyword: CompletionItemKind.Keyword,
|
|
33
|
+
type: CompletionItemKind.TypeParameter,
|
|
34
|
+
snippet: CompletionItemKind.Snippet,
|
|
35
|
+
value: CompletionItemKind.EnumMember,
|
|
36
|
+
field: CompletionItemKind.Field,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const SEVERITY: Record<FlareSeverity, DiagnosticSeverity> = {
|
|
40
|
+
error: DiagnosticSeverity.Error,
|
|
41
|
+
warning: DiagnosticSeverity.Warning,
|
|
42
|
+
hint: DiagnosticSeverity.Hint,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const SYMBOL: Record<"packet" | "query" | "option", SymbolKind> = {
|
|
46
|
+
packet: SymbolKind.Event,
|
|
47
|
+
query: SymbolKind.Method,
|
|
48
|
+
option: SymbolKind.Namespace,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function flareDiagnostics(document: TextDocument): Diagnostic[] {
|
|
52
|
+
return diagnoseFlare(document.getText(), document.uri).map((item) => ({
|
|
53
|
+
range: {
|
|
54
|
+
start: { line: item.line, character: item.start },
|
|
55
|
+
end: { line: item.line, character: Math.max(item.end, item.start + 1) },
|
|
56
|
+
},
|
|
57
|
+
message: item.message,
|
|
58
|
+
severity: SEVERITY[item.severity],
|
|
59
|
+
source: "flare",
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
|
|
10
63
|
export function start(_options: { projectRoot?: string } = {}): void {
|
|
11
64
|
const connection = createConnection(ProposedFeatures.all);
|
|
12
65
|
const documents = new TextDocuments(TextDocument);
|
|
13
66
|
|
|
14
67
|
connection.onInitialize(() => ({
|
|
15
68
|
capabilities: {
|
|
16
|
-
textDocumentSync: TextDocumentSyncKind.
|
|
69
|
+
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
70
|
+
completionProvider: {
|
|
71
|
+
triggerCharacters: [" ", "(", ",", ">", "="],
|
|
72
|
+
resolveProvider: false,
|
|
73
|
+
},
|
|
74
|
+
hoverProvider: true,
|
|
75
|
+
documentSymbolProvider: true,
|
|
76
|
+
signatureHelpProvider: {
|
|
77
|
+
triggerCharacters: ["(", ","],
|
|
78
|
+
},
|
|
17
79
|
},
|
|
18
|
-
serverInfo: { name: "cluaupp", version: pkg.version },
|
|
80
|
+
serverInfo: { name: "cluaupp-flare", version: pkg.version },
|
|
19
81
|
}));
|
|
20
82
|
|
|
21
|
-
const
|
|
22
|
-
|
|
83
|
+
const publish = (document: TextDocument) => {
|
|
84
|
+
if (!isFlareDocument(document.uri)) {
|
|
85
|
+
connection.sendDiagnostics({ uri: document.uri, diagnostics: [] });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
connection.sendDiagnostics({ uri: document.uri, diagnostics: flareDiagnostics(document) });
|
|
23
89
|
};
|
|
24
90
|
|
|
25
|
-
documents.onDidOpen((event) =>
|
|
26
|
-
documents.onDidChangeContent((event) =>
|
|
27
|
-
documents.onDidClose((event) =>
|
|
91
|
+
documents.onDidOpen((event) => publish(event.document));
|
|
92
|
+
documents.onDidChangeContent((event) => publish(event.document));
|
|
93
|
+
documents.onDidClose((event) => {
|
|
94
|
+
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
connection.onCompletion((params): CompletionItem[] => {
|
|
98
|
+
const document = documents.get(params.textDocument.uri);
|
|
99
|
+
if (!document || !isFlareDocument(document.uri)) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
return completionsAt(document.getText(), params.position.line, params.position.character).map((item) => ({
|
|
103
|
+
label: item.label,
|
|
104
|
+
kind: KIND[item.kind],
|
|
105
|
+
detail: item.detail,
|
|
106
|
+
documentation: { kind: MarkupKind.Markdown, value: item.documentation },
|
|
107
|
+
insertText: item.insertText,
|
|
108
|
+
insertTextFormat: item.snippet ? 2 : 1,
|
|
109
|
+
sortText: item.sortText,
|
|
110
|
+
}));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
connection.onHover((params): Hover | null => {
|
|
114
|
+
const document = documents.get(params.textDocument.uri);
|
|
115
|
+
if (!document || !isFlareDocument(document.uri)) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const hover = hoverAt(document.getText(), params.position.line, params.position.character);
|
|
119
|
+
if (!hover) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
contents: { kind: MarkupKind.Markdown, value: hover.contents },
|
|
124
|
+
range: {
|
|
125
|
+
start: { line: params.position.line, character: hover.start },
|
|
126
|
+
end: { line: params.position.line, character: hover.end },
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
connection.onDocumentSymbol((params): DocumentSymbol[] => {
|
|
132
|
+
const document = documents.get(params.textDocument.uri);
|
|
133
|
+
if (!document || !isFlareDocument(document.uri)) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
return symbolsIn(document.getText()).map((symbol) => ({
|
|
137
|
+
name: symbol.name,
|
|
138
|
+
detail: symbol.detail,
|
|
139
|
+
kind: SYMBOL[symbol.kind],
|
|
140
|
+
range: {
|
|
141
|
+
start: { line: symbol.line, character: 0 },
|
|
142
|
+
end: { line: symbol.line, character: Math.max(symbol.end, 1) },
|
|
143
|
+
},
|
|
144
|
+
selectionRange: {
|
|
145
|
+
start: { line: symbol.line, character: symbol.start },
|
|
146
|
+
end: { line: symbol.line, character: Math.max(symbol.end, symbol.start + 1) },
|
|
147
|
+
},
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
connection.onSignatureHelp((params): SignatureHelp | null => {
|
|
152
|
+
const document = documents.get(params.textDocument.uri);
|
|
153
|
+
if (!document || !isFlareDocument(document.uri)) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const signature = signatureAt(document.getText(), params.position.line, params.position.character);
|
|
157
|
+
if (!signature) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
const info = SignatureInformation.create(
|
|
161
|
+
signature.label,
|
|
162
|
+
signature.documentation,
|
|
163
|
+
...signature.parameters.map((parameter) => ParameterInformation.create(parameter.label, parameter.documentation)),
|
|
164
|
+
);
|
|
165
|
+
return {
|
|
166
|
+
signatures: [info],
|
|
167
|
+
activeSignature: 0,
|
|
168
|
+
activeParameter: signature.activeParameter,
|
|
169
|
+
};
|
|
170
|
+
});
|
|
28
171
|
|
|
29
172
|
documents.listen(connection);
|
|
30
173
|
connection.listen();
|
package/src/native/index.ts
CHANGED
|
@@ -280,15 +280,14 @@ function compileHelm(source: string, file: string, defaultName: string): NativeE
|
|
|
280
280
|
id += 1;
|
|
281
281
|
}
|
|
282
282
|
const { headerRel, luauRel } = emitPaths(file, name);
|
|
283
|
-
const
|
|
284
|
-
.map((cmd) => {
|
|
285
|
-
const params = cmd.args.map((arg) => `${arg.type === "i32" ? "int" : arg.type} ${arg.name}`).join(", ");
|
|
286
|
-
return `\tvoid ${cmd.name}(${params});`;
|
|
287
|
-
})
|
|
283
|
+
const headerCmds = commands
|
|
284
|
+
.map((cmd, index) => `\t// command ${cmd.name} permission ${cmd.permission}\n\tconst int ${cmd.name} = ${index + 1};`)
|
|
288
285
|
.join("\n");
|
|
289
286
|
const header = `${headerBanner("helm")}
|
|
287
|
+
#include <clpp/libs/helm.clh>
|
|
290
288
|
namespace ${name} {
|
|
291
|
-
${
|
|
289
|
+
${headerCmds}
|
|
290
|
+
HelmSession Open(Player player);
|
|
292
291
|
}
|
|
293
292
|
`;
|
|
294
293
|
const rows = commands
|
|
@@ -417,7 +416,7 @@ function compileHive(source: string, file: string, defaultName: string): NativeE
|
|
|
417
416
|
#include <clpp/libs/hive.clh>
|
|
418
417
|
namespace ${name} {
|
|
419
418
|
${components.map((item, index) => `\tconst int ${item.name} = ${index + 1};`).join("\n")}
|
|
420
|
-
|
|
419
|
+
auto New();
|
|
421
420
|
}
|
|
422
421
|
`;
|
|
423
422
|
const rows = components
|
|
@@ -443,32 +442,242 @@ return ${name}
|
|
|
443
442
|
return { headerRel, headerPath: headerRel, header, luauRel, luau };
|
|
444
443
|
}
|
|
445
444
|
|
|
445
|
+
/** Mirrors Axiom.Groups + axiom.clh prototypes for IntelliSense on selected namespaces. */
|
|
446
|
+
const AXIOM_GROUP_DECLS: Record<string, string[]> = {
|
|
447
|
+
Scalar: [
|
|
448
|
+
"double Clamp(double value, double min, double max);",
|
|
449
|
+
"double Map(double value, double inMin, double inMax, double outMin, double outMax);",
|
|
450
|
+
"double Wrap(double value, double min, double max);",
|
|
451
|
+
"double Sign(double value);",
|
|
452
|
+
"double Round(double value);",
|
|
453
|
+
"double Round(double value, int digits);",
|
|
454
|
+
"double Snap(double value, double step);",
|
|
455
|
+
"double PingPong(double t, double length);",
|
|
456
|
+
"double Saturate(double value);",
|
|
457
|
+
"double Fract(double value);",
|
|
458
|
+
"double InvLerp(double from, double to, double value);",
|
|
459
|
+
"double Approach(double current, double target, double maxDelta);",
|
|
460
|
+
"bool IsFinite(double value);",
|
|
461
|
+
"double Abs(double value);",
|
|
462
|
+
"double Min(double a, double b);",
|
|
463
|
+
"double Max(double a, double b);",
|
|
464
|
+
"double Pow(double base, double exp);",
|
|
465
|
+
"double Sqrt(double value);",
|
|
466
|
+
"double Cbrt(double value);",
|
|
467
|
+
"double Hypot(double a, double b);",
|
|
468
|
+
"double Log(double value);",
|
|
469
|
+
"double Exp(double value);",
|
|
470
|
+
"double Smoothstep(double edge0, double edge1, double x);",
|
|
471
|
+
"double Smootherstep(double edge0, double edge1, double x);",
|
|
472
|
+
"double Gcd(double a, double b);",
|
|
473
|
+
"double Lcm(double a, double b);",
|
|
474
|
+
"bool IsEven(double value);",
|
|
475
|
+
"bool IsOdd(double value);",
|
|
476
|
+
"double Factorial(double n);",
|
|
477
|
+
"double Scale(double value, int index);",
|
|
478
|
+
],
|
|
479
|
+
Lerp: [
|
|
480
|
+
"double Lerp(double from, double to, double alpha);",
|
|
481
|
+
"double LerpClamped(double from, double to, double alpha);",
|
|
482
|
+
"Vector2 LerpVector2(Vector2 from, Vector2 to, double alpha);",
|
|
483
|
+
"Vector3 LerpVector3(Vector3 from, Vector3 to, double alpha);",
|
|
484
|
+
"Vector3 LerpVector(Vector3 from, Vector3 to, double alpha);",
|
|
485
|
+
"Color3 LerpColor3(Color3 from, Color3 to, double alpha);",
|
|
486
|
+
"CFrame LerpCFrame(CFrame from, CFrame to, double alpha);",
|
|
487
|
+
"UDim2 LerpUDim2(UDim2 from, UDim2 to, double alpha);",
|
|
488
|
+
"double LerpAngle(double from, double to, double alpha);",
|
|
489
|
+
"double Inverse(double from, double to, double value);",
|
|
490
|
+
],
|
|
491
|
+
Vector: [
|
|
492
|
+
"Vector3 Project(Vector3 a, Vector3 b);",
|
|
493
|
+
"Vector3 Reject(Vector3 a, Vector3 b);",
|
|
494
|
+
"Vector3 Reflect(Vector3 incident, Vector3 normal);",
|
|
495
|
+
"double Angle(Vector3 a, Vector3 b);",
|
|
496
|
+
"double Distance(Vector3 a, Vector3 b);",
|
|
497
|
+
"double Distance2(Vector2 a, Vector2 b);",
|
|
498
|
+
"CFrame Orthonormal(Vector3 forward);",
|
|
499
|
+
"CFrame Orthonormal(Vector3 forward, Vector3 up);",
|
|
500
|
+
"Vector3 Slerp(Vector3 a, Vector3 b, double t);",
|
|
501
|
+
"CFrame LookAt(Vector3 from, Vector3 look);",
|
|
502
|
+
],
|
|
503
|
+
CFrame: ["CFrame SlerpCFrame(CFrame a, CFrame b, double t);", "CFrame Flat(CFrame cf);"],
|
|
504
|
+
Easing: [
|
|
505
|
+
"double InSine(double t);",
|
|
506
|
+
"double OutSine(double t);",
|
|
507
|
+
"double InOutSine(double t);",
|
|
508
|
+
"double InQuad(double t);",
|
|
509
|
+
"double OutQuad(double t);",
|
|
510
|
+
"double InOutQuad(double t);",
|
|
511
|
+
"double InCubic(double t);",
|
|
512
|
+
"double OutCubic(double t);",
|
|
513
|
+
"double InOutCubic(double t);",
|
|
514
|
+
"double InQuart(double t);",
|
|
515
|
+
"double OutQuart(double t);",
|
|
516
|
+
"double InOutQuart(double t);",
|
|
517
|
+
"double InQuint(double t);",
|
|
518
|
+
"double OutQuint(double t);",
|
|
519
|
+
"double InOutQuint(double t);",
|
|
520
|
+
"double InExpo(double t);",
|
|
521
|
+
"double OutExpo(double t);",
|
|
522
|
+
"double InOutExpo(double t);",
|
|
523
|
+
"double InCirc(double t);",
|
|
524
|
+
"double OutCirc(double t);",
|
|
525
|
+
"double InOutCirc(double t);",
|
|
526
|
+
"double InBack(double t);",
|
|
527
|
+
"double OutBack(double t);",
|
|
528
|
+
"double InOutBack(double t);",
|
|
529
|
+
"double InElastic(double t);",
|
|
530
|
+
"double OutElastic(double t);",
|
|
531
|
+
"double InOutElastic(double t);",
|
|
532
|
+
"double InBounce(double t);",
|
|
533
|
+
"double OutBounce(double t);",
|
|
534
|
+
"double InOutBounce(double t);",
|
|
535
|
+
"double Linear(double t);",
|
|
536
|
+
],
|
|
537
|
+
Bezier: [
|
|
538
|
+
"Vector3 CubicBezier(double t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3);",
|
|
539
|
+
"Vector3 QuadraticBezier(double t, Vector3 p0, Vector3 p1, Vector3 p2);",
|
|
540
|
+
"CFrame Hover(double elapsed, Vector3 anchor, Vector3 look);",
|
|
541
|
+
"CFrame Float(double elapsed, Vector3 anchor, Vector3 look);",
|
|
542
|
+
"CFrame FloatSpin(double elapsed, CFrame anchor);",
|
|
543
|
+
],
|
|
544
|
+
Geometry: [
|
|
545
|
+
"bool AabbContains(Vector3 point, Vector3 min, Vector3 max);",
|
|
546
|
+
"bool SphereContains(Vector3 point, Vector3 center, double radius);",
|
|
547
|
+
"Vector3 RayPlane(Vector3 origin, Vector3 dir, Vector3 point, Vector3 normal);",
|
|
548
|
+
"Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c);",
|
|
549
|
+
"Vector3 ClosestPointOnSegment(Vector3 p, Vector3 a, Vector3 b);",
|
|
550
|
+
],
|
|
551
|
+
Trig: [
|
|
552
|
+
"double Deg(double rad);",
|
|
553
|
+
"double Rad(double deg);",
|
|
554
|
+
"double DeltaAngle(double from, double to);",
|
|
555
|
+
"double AngleDiff(double from, double to);",
|
|
556
|
+
"double DeltaAngleDegrees(double from, double to);",
|
|
557
|
+
"double NormalizeAngle(double angle);",
|
|
558
|
+
"double Sin(double x);",
|
|
559
|
+
"double Cos(double x);",
|
|
560
|
+
"double Tan(double x);",
|
|
561
|
+
"double Asin(double x);",
|
|
562
|
+
"double Acos(double x);",
|
|
563
|
+
"double Atan2(double y, double x);",
|
|
564
|
+
],
|
|
565
|
+
Probability: [
|
|
566
|
+
"double RandomRange(double min, double max);",
|
|
567
|
+
"double Random(double min, double max);",
|
|
568
|
+
"int Weighted(LuaArray<double> weights);",
|
|
569
|
+
"double Gaussian();",
|
|
570
|
+
"double Gaussian(double mean, double std);",
|
|
571
|
+
"double Average(LuaArray<double> values);",
|
|
572
|
+
"double Sum(LuaArray<double> values);",
|
|
573
|
+
],
|
|
574
|
+
Noise: [
|
|
575
|
+
"double HashU32(double n);",
|
|
576
|
+
"double Value1(double x);",
|
|
577
|
+
"double Value2(double x, double y);",
|
|
578
|
+
"double Value3(double x, double y, double z);",
|
|
579
|
+
],
|
|
580
|
+
Color: [
|
|
581
|
+
"Color3 FromHSV(double h, double s, double v);",
|
|
582
|
+
"Color3 Contrast(Color3 color, double amount);",
|
|
583
|
+
"Color3 LerpHSV(Color3 a, Color3 b, double t);",
|
|
584
|
+
],
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
function axiomFnDecls(): Record<string, string[]> {
|
|
588
|
+
const byFn: Record<string, string[]> = {};
|
|
589
|
+
for (const decls of Object.values(AXIOM_GROUP_DECLS)) {
|
|
590
|
+
for (const decl of decls) {
|
|
591
|
+
const match = decl.match(/\b([A-Za-z_][A-Za-z0-9_]*)\s*\(/);
|
|
592
|
+
if (!match) {
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
const fn = match[1];
|
|
596
|
+
if (!byFn[fn]) {
|
|
597
|
+
byFn[fn] = [];
|
|
598
|
+
}
|
|
599
|
+
byFn[fn].push(decl);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return byFn;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const AXIOM_FN_DECLS = axiomFnDecls();
|
|
606
|
+
|
|
607
|
+
function axiomHeaderBody(groups: string[], fns: string[], file: string, lineNo: number): string {
|
|
608
|
+
const decls: string[] = [];
|
|
609
|
+
const seen = new Set<string>();
|
|
610
|
+
const pushDecl = (decl: string) => {
|
|
611
|
+
if (seen.has(decl)) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
seen.add(decl);
|
|
615
|
+
decls.push(`\t${decl}`);
|
|
616
|
+
};
|
|
617
|
+
for (const group of groups) {
|
|
618
|
+
const key = Object.keys(AXIOM_GROUP_DECLS).find((name) => name.toLowerCase() === group.toLowerCase());
|
|
619
|
+
if (!key) {
|
|
620
|
+
fail(
|
|
621
|
+
file,
|
|
622
|
+
lineNo,
|
|
623
|
+
`unknown group "${group}" — use Scalar Lerp Vector CFrame Easing Bezier Geometry Trig Probability Noise Color`,
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
decls.push(`\t// group ${key}`);
|
|
627
|
+
for (const decl of AXIOM_GROUP_DECLS[key]) {
|
|
628
|
+
pushDecl(decl);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
for (const fn of fns) {
|
|
632
|
+
const key = Object.keys(AXIOM_FN_DECLS).find((name) => name.toLowerCase() === fn.toLowerCase());
|
|
633
|
+
if (!key) {
|
|
634
|
+
fail(file, lineNo, `unknown fn "${fn}" — use a name from axiom.clh (e.g. fn LerpVector2)`);
|
|
635
|
+
}
|
|
636
|
+
decls.push(`\t// fn ${key}`);
|
|
637
|
+
for (const decl of AXIOM_FN_DECLS[key]) {
|
|
638
|
+
pushDecl(decl);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return decls.join("\n");
|
|
642
|
+
}
|
|
643
|
+
|
|
446
644
|
function compileAxiom(source: string, file: string, defaultName: string): NativeEmit {
|
|
447
645
|
const { name, lines } = parseOptName(source, file, defaultName);
|
|
448
646
|
const groups: string[] = [];
|
|
647
|
+
const fns: string[] = [];
|
|
648
|
+
let lastLine = 1;
|
|
449
649
|
for (const tagged of lines) {
|
|
450
650
|
const [lineNoRaw, line] = tagged.split("\t");
|
|
451
651
|
const lineNo = Number(lineNoRaw);
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
652
|
+
lastLine = lineNo;
|
|
653
|
+
const groupMatch = line.match(new RegExp(`^group\\s+(${IDENT})\\s*$`, "i"));
|
|
654
|
+
if (groupMatch) {
|
|
655
|
+
groups.push(groupMatch[1]);
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
const fnMatch = line.match(new RegExp(`^fn\\s+(${IDENT})\\s*$`, "i"));
|
|
659
|
+
if (fnMatch) {
|
|
660
|
+
fns.push(fnMatch[1]);
|
|
661
|
+
continue;
|
|
455
662
|
}
|
|
456
|
-
|
|
663
|
+
fail(file, lineNo, `expected group Lerp or fn LerpVector2`);
|
|
457
664
|
}
|
|
458
|
-
if (groups.length === 0) {
|
|
459
|
-
fail(file, 1, "schema is empty — add group
|
|
665
|
+
if (groups.length === 0 && fns.length === 0) {
|
|
666
|
+
fail(file, 1, "schema is empty — add group Lerp or fn LerpVector2");
|
|
460
667
|
}
|
|
668
|
+
const body = axiomHeaderBody(groups, fns, file, lastLine);
|
|
669
|
+
const selectArgs = [...groups, ...fns].map((item) => `"${item}"`).join(", ");
|
|
461
670
|
const { headerRel, luauRel } = emitPaths(file, name);
|
|
462
671
|
const header = `${headerBanner("axiom")}
|
|
463
672
|
#include <clpp/libs/axiom.clh>
|
|
464
673
|
namespace ${name} {
|
|
465
|
-
${
|
|
674
|
+
${body}
|
|
466
675
|
}
|
|
467
676
|
`;
|
|
468
677
|
const luau = `${luauBanner()}local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
469
678
|
local Axiom = require(ReplicatedStorage.CluauppLibs.Axiom)
|
|
470
|
-
local ${name} = Axiom.Select({ ${
|
|
471
|
-
-- out/
|
|
679
|
+
local ${name} = Axiom.Select({ ${selectArgs} })
|
|
680
|
+
-- out/ binds: ${[...groups.map((g) => `group ${g}`), ...fns.map((f) => `fn ${f}`)].join(", ")}
|
|
472
681
|
return ${name}
|
|
473
682
|
`;
|
|
474
683
|
return { headerRel, headerPath: headerRel, header, luauRel, luau };
|