cluaupp 1.5.0 → 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.
Files changed (323) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +10 -5
  3. package/api/CHANGELOG.md +3 -0
  4. package/api/chat.js +74 -0
  5. package/api/fixtures/roblox/README.md +6 -0
  6. package/api/fixtures/roblox/aux/sample.d.luau +6 -0
  7. package/api/fixtures/roblox/mini/Mini-API-Dump.json +72 -0
  8. package/api/generated/bench-latest.json +39 -0
  9. package/api/generated/capability-profile.json +76 -0
  10. package/api/generated/lsp-index.json +1 -0
  11. package/api/generated/luau/classes.d.luau +11221 -0
  12. package/api/generated/luau/datatypes.d.luau +327 -0
  13. package/api/generated/luau/enums.d.luau +4918 -0
  14. package/api/generated/luau/globals.d.luau +12 -0
  15. package/api/manifests/roblox-target.manifest.json +22 -0
  16. package/api/normalized/roblox-target.profile.json +237461 -0
  17. package/api/overrides/classes.json +8 -0
  18. package/api/overrides/compatibility.json +9 -0
  19. package/api/overrides/datatypes.json +1579 -0
  20. package/api/overrides/enums.json +8 -0
  21. package/api/overrides/globals.json +8 -0
  22. package/api/overrides/type-mappings.json +9 -0
  23. package/api/roblox-api.lock.json +9 -0
  24. package/data/Mini-API-Dump.json +1 -0
  25. package/editors/vscode/README.md +12 -10
  26. package/editors/vscode/extension.js +82 -0
  27. package/editors/vscode/icons/axiom.svg +4 -0
  28. package/editors/vscode/icons/bloom.svg +5 -0
  29. package/editors/vscode/icons/helm.svg +4 -0
  30. package/editors/vscode/icons/hive.svg +5 -0
  31. package/editors/vscode/icons/mint.svg +4 -0
  32. package/editors/vscode/icons/shift.svg +6 -0
  33. package/editors/vscode/language-configuration-schema.json +24 -0
  34. package/editors/vscode/package.json +172 -12
  35. package/editors/vscode/snippets/axiom.json +12 -0
  36. package/editors/vscode/snippets/bloom.json +12 -0
  37. package/editors/vscode/snippets/helm.json +12 -0
  38. package/editors/vscode/snippets/hive.json +12 -0
  39. package/editors/vscode/snippets/mint.json +12 -0
  40. package/editors/vscode/snippets/shift.json +17 -0
  41. package/editors/vscode/syntaxes/axiom.tmLanguage.json +5 -0
  42. package/editors/vscode/syntaxes/bloom.tmLanguage.json +5 -0
  43. package/editors/vscode/syntaxes/helm.tmLanguage.json +5 -0
  44. package/editors/vscode/syntaxes/hive.tmLanguage.json +5 -0
  45. package/editors/vscode/syntaxes/mint.tmLanguage.json +5 -0
  46. package/editors/vscode/syntaxes/schema.tmLanguage.json +89 -0
  47. package/editors/vscode/syntaxes/shift.tmLanguage.json +5 -0
  48. package/examples/game/.cluaupp/compile-cache/ReplicatedStorage__Shared__Constants__Datas__TemplateData.clh.json +1 -0
  49. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Boot__DataBoot.server.clpp.json +1 -0
  50. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Configuration__ServerConfig.clp.json +1 -0
  51. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__Guard.server.clpp.json +1 -0
  52. package/examples/game/.cluaupp/compile-cache/ServerScriptService__Handlers__PlayerHandler.server.clpp.json +1 -0
  53. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterCharacterScripts__Character__CharacterReady.client.clpp.json +1 -0
  54. package/examples/game/.cluaupp/compile-cache/StarterPlayer__StarterPlayerScripts__Controllers__DataController.client.clpp.json +1 -0
  55. package/examples/game/.cluaupp/compile-cache/index.json +12 -0
  56. package/examples/game/.cluaupp/datamodel-profile.json +94 -0
  57. package/examples/game/.vscode/settings.json +12 -1
  58. package/examples/game/include/clpp/datatypes.clh +337 -373
  59. package/examples/game/include/clpp/generated/datamodel.clh +25 -0
  60. package/examples/game/include/clpp/generated/enums.clh +1 -1
  61. package/examples/game/include/clpp/generated/instances.clh +41135 -41064
  62. package/examples/game/include/clpp/libs/axiom.clh +1 -1
  63. package/examples/game/include/clpp/libs/math.clh +14 -0
  64. package/examples/game/include/clpp/libs/spring.clh +17 -0
  65. package/examples/game/include/clpp/libs/ward.clh +1 -0
  66. package/examples/game/include/clpp/roblox.clh +3 -4
  67. package/examples/game/libs/ArrayIndexer/init.luau +209 -0
  68. package/examples/game/libs/Axiom/init.luau +608 -0
  69. package/examples/game/libs/Bloom/init.luau +433 -0
  70. package/examples/game/libs/Coil/init.luau +215 -0
  71. package/examples/game/libs/Crest/init.luau +426 -0
  72. package/examples/game/libs/Echo/init.luau +417 -0
  73. package/examples/game/libs/Ember/init.luau +365 -0
  74. package/examples/game/libs/Flare/init.luau +717 -0
  75. package/examples/game/libs/Gleam/init.luau +729 -0
  76. package/examples/game/libs/Guide/init.luau +215 -0
  77. package/examples/game/libs/Helm/init.luau +377 -0
  78. package/examples/game/libs/Hive/init.luau +241 -0
  79. package/examples/game/libs/Keep/Client.luau +114 -0
  80. package/examples/game/libs/Keep/Data.luau +883 -0
  81. package/examples/game/libs/Keep/Engine.luau +211 -0
  82. package/examples/game/libs/Keep/Enum.luau +6 -0
  83. package/examples/game/libs/Keep/Enums.luau +10 -0
  84. package/examples/game/libs/Keep/Path.luau +236 -0
  85. package/examples/game/libs/Keep/Replicator.luau +298 -0
  86. package/examples/game/libs/Keep/Server.luau +251 -0
  87. package/examples/game/libs/Keep/Store.luau +652 -0
  88. package/examples/game/libs/Keep/Trade.luau +455 -0
  89. package/examples/game/libs/Keep/init.luau +205 -0
  90. package/examples/game/libs/Lens/init.luau +609 -0
  91. package/examples/game/libs/Mint/init.luau +279 -0
  92. package/examples/game/libs/Net/init.luau +156 -0
  93. package/examples/game/libs/Net/src/codec.luau +224 -0
  94. package/examples/game/libs/Occlude/init.luau +117 -0
  95. package/examples/game/libs/Pin/init.luau +309 -0
  96. package/examples/game/libs/Promise/LICENSE +21 -0
  97. package/examples/game/libs/Promise/_impl/LICENSE +21 -0
  98. package/examples/game/libs/Promise/_impl/init.lua +1991 -0
  99. package/examples/game/libs/Promise/init.lua +1990 -0
  100. package/examples/game/libs/Promise/init.luau +13 -0
  101. package/examples/game/libs/Promise/types.luau +46 -0
  102. package/examples/game/libs/Roster/init.luau +686 -0
  103. package/examples/game/libs/SOURCES.md +31 -0
  104. package/examples/game/libs/Shift/init.luau +238 -0
  105. package/examples/game/libs/Spark/init.luau +487 -0
  106. package/examples/game/libs/Stage/init.luau +178 -0
  107. package/examples/game/libs/Sweep/init.luau +259 -0
  108. package/examples/game/libs/Trace/init.luau +213 -0
  109. package/examples/game/libs/Ward/init.luau +211 -0
  110. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau +29 -0
  111. package/examples/game/out/ReplicatedStorage/Shared/Constants/Datas/TemplateData.luau.map.json +13 -0
  112. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau +83 -0
  113. package/examples/game/out/ReplicatedStorage/Shared/Net/Net.luau.map.json +13 -0
  114. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau +18 -0
  115. package/examples/game/out/ServerScriptService/Boot/DataBoot.server.luau.map.json +13 -0
  116. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau +14 -0
  117. package/examples/game/out/ServerScriptService/Configuration/ServerConfig.luau.map.json +13 -0
  118. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau +15 -0
  119. package/examples/game/out/ServerScriptService/Handlers/Guard.server.luau.map.json +13 -0
  120. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau +50 -0
  121. package/examples/game/out/ServerScriptService/Handlers/PlayerHandler.server.luau.map.json +13 -0
  122. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau +12 -0
  123. package/examples/game/out/StarterPlayer/StarterCharacterScripts/Character/CharacterReady.client.luau.map.json +13 -0
  124. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau +16 -0
  125. package/examples/game/out/StarterPlayer/StarterPlayerScripts/Controllers/DataController.client.luau.map.json +13 -0
  126. package/examples/game/src/ReplicatedStorage/Shared/Net/Net.clh +26 -0
  127. package/examples/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
  128. package/examples/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  129. package/examples/game/stylua.toml +9 -0
  130. package/generated/api/build-profile.js +115 -0
  131. package/generated/api/cache.js +44 -0
  132. package/generated/api/coverage.js +32 -0
  133. package/generated/api/diff.js +125 -0
  134. package/generated/api/generators/clpp-headers.js +353 -0
  135. package/generated/api/generators/docs-reference.js +7 -0
  136. package/generated/api/generators/lsp-index.js +81 -0
  137. package/generated/api/generators/luau-defs.js +94 -0
  138. package/generated/api/ide.js +76 -0
  139. package/generated/api/identifier.js +47 -0
  140. package/generated/api/index.js +324 -0
  141. package/generated/api/loader.js +57 -0
  142. package/generated/api/merge.js +88 -0
  143. package/generated/api/model.js +5 -0
  144. package/generated/api/normalize.js +231 -0
  145. package/generated/api/overrides-validate.js +58 -0
  146. package/generated/api/perf.js +12 -0
  147. package/generated/api/registry.js +136 -0
  148. package/generated/api/release.js +44 -0
  149. package/generated/api/resolver.js +250 -0
  150. package/generated/api/sources/aux-types-diff.js +75 -0
  151. package/generated/api/sources/client-tracker.js +11 -0
  152. package/generated/api/sources/creator-docs.js +42 -0
  153. package/generated/api/sources/luau-types.js +34 -0
  154. package/generated/api/sources/mini-dump.js +17 -0
  155. package/generated/api/sources/studio-api.js +8 -0
  156. package/generated/api/sources/studio-apiv2.js +11 -0
  157. package/generated/api/sources/studio-full-api.js +8 -0
  158. package/generated/api/studio-smoke.js +80 -0
  159. package/generated/api/type-parse.js +49 -0
  160. package/generated/api/understander.js +51 -0
  161. package/generated/api/validate.js +135 -0
  162. package/generated/api-cli.js +421 -0
  163. package/generated/cli.js +16 -5
  164. package/generated/clpp/contract.js +3 -3
  165. package/generated/clpp/format-luau.js +236 -0
  166. package/generated/clpp/index.js +13 -1
  167. package/generated/clpp/modules.js +227 -0
  168. package/generated/clpp/postprocess.js +86 -5
  169. package/generated/clpp/rewrite-janitor.js +145 -0
  170. package/generated/clpp/runner.js +14 -2
  171. package/generated/compile.js +82 -0
  172. package/generated/flare/parse.js +12 -1
  173. package/generated/intellisense.js +57 -1
  174. package/generated/native/index.js +217 -16
  175. package/generated/target/authority-check.js +136 -0
  176. package/generated/target/authority-graph.js +74 -0
  177. package/generated/target/build-cache.js +112 -0
  178. package/generated/target/capabilities.js +89 -0
  179. package/generated/target/capability-profile.js +30 -0
  180. package/generated/target/component-contracts.js +60 -0
  181. package/generated/target/context-check.js +160 -0
  182. package/generated/target/datamodel-check.js +170 -0
  183. package/generated/target/datamodel-generate.js +74 -0
  184. package/generated/target/datamodel.js +233 -0
  185. package/generated/target/diagnostics.js +63 -0
  186. package/generated/target/doctor.js +152 -0
  187. package/generated/target/flare-version.js +58 -0
  188. package/generated/target/get-service.js +69 -0
  189. package/generated/target/lifetime-check.js +47 -0
  190. package/generated/target/luau-stamp.js +39 -0
  191. package/generated/target/optimizer-advise.js +88 -0
  192. package/generated/target/optimizer-apply.js +44 -0
  193. package/generated/target/optimizer-soa.js +254 -0
  194. package/generated/target/parallel-check.js +136 -0
  195. package/generated/target/pgo.js +148 -0
  196. package/generated/target/project-docs.js +69 -0
  197. package/generated/target/project-graph.js +71 -0
  198. package/generated/target/roblox.js +63 -0
  199. package/generated/target/security-check.js +41 -0
  200. package/generated/target/source-map.js +25 -0
  201. package/generated/target/studio-bridge.js +112 -0
  202. package/generated/utils/project.js +178 -8
  203. package/generated/utils/rojo-mapper.js +11 -3
  204. package/include/clpp/datatypes.clh +337 -373
  205. package/include/clpp/generated/enums.clh +1 -1
  206. package/include/clpp/generated/instances.clh +41135 -41064
  207. package/include/clpp/libs/axiom.clh +1 -1
  208. package/include/clpp/libs/hive.clh +1 -0
  209. package/include/clpp/libs/keep.clh +2 -0
  210. package/include/clpp/libs/math.clh +14 -0
  211. package/include/clpp/libs/spring.clh +17 -0
  212. package/include/clpp/libs/ward.clh +1 -0
  213. package/include/clpp/roblox.clh +3 -4
  214. package/package.json +10 -3
  215. package/plugins/CluauppNav/Plugin.luau +207 -0
  216. package/plugins/CluauppNav/ProfileLogger.luau +27 -0
  217. package/plugins/CluauppNav/README.md +24 -0
  218. package/runtime/Axiom/init.luau +10 -7
  219. package/runtime/Coil/init.luau +8 -2
  220. package/runtime/Crest/init.luau +1 -0
  221. package/runtime/Flare/init.luau +2 -1
  222. package/runtime/Gleam/init.luau +15 -4
  223. package/runtime/Hive/init.luau +36 -14
  224. package/runtime/Pin/init.luau +5 -2
  225. package/runtime/Roster/init.luau +2 -0
  226. package/runtime/Spark/init.luau +3 -0
  227. package/runtime/Sweep/init.luau +2 -0
  228. package/runtime/Trace/init.luau +3 -0
  229. package/runtime/Ward/init.luau +38 -5
  230. package/scripts/postinstall-editor.js +17 -0
  231. package/skills/README.md +13 -0
  232. package/skills/clpp-hive-flare/SKILL.md +79 -0
  233. package/skills/clpp-language/SKILL.md +123 -0
  234. package/skills/clpp-language/compiler.md +89 -0
  235. package/skills/clpp-style/SKILL.md +95 -0
  236. package/src/api/build-profile.ts +138 -0
  237. package/src/api/cache.ts +45 -0
  238. package/src/api/coverage.ts +46 -0
  239. package/src/api/diff.ts +143 -0
  240. package/src/api/generators/clpp-headers.ts +377 -0
  241. package/src/api/generators/docs-reference.ts +11 -0
  242. package/src/api/generators/lsp-index.ts +106 -0
  243. package/src/api/generators/luau-defs.ts +98 -0
  244. package/src/api/ide.ts +87 -0
  245. package/src/api/identifier.ts +47 -0
  246. package/src/api/index.ts +269 -0
  247. package/src/api/loader.ts +60 -0
  248. package/src/api/merge.ts +126 -0
  249. package/src/api/model.ts +283 -0
  250. package/src/api/normalize.ts +257 -0
  251. package/src/api/overrides-validate.ts +58 -0
  252. package/src/api/perf.ts +15 -0
  253. package/src/api/registry.ts +162 -0
  254. package/src/api/release.ts +47 -0
  255. package/src/api/resolver.ts +255 -0
  256. package/src/api/sources/aux-types-diff.ts +81 -0
  257. package/src/api/sources/client-tracker.ts +10 -0
  258. package/src/api/sources/creator-docs.ts +37 -0
  259. package/src/api/sources/luau-types.ts +30 -0
  260. package/src/api/sources/mini-dump.ts +50 -0
  261. package/src/api/sources/studio-api.ts +7 -0
  262. package/src/api/sources/studio-apiv2.ts +10 -0
  263. package/src/api/sources/studio-full-api.ts +7 -0
  264. package/src/api/studio-smoke.ts +82 -0
  265. package/src/api/type-parse.ts +48 -0
  266. package/src/api/understander.ts +72 -0
  267. package/src/api/validate.ts +160 -0
  268. package/src/api-cli.ts +493 -0
  269. package/src/api.generated.js +37 -22
  270. package/src/cli.ts +21 -6
  271. package/src/clpp/contract.ts +34 -3
  272. package/src/clpp/format-luau.ts +262 -0
  273. package/src/clpp/index.ts +13 -2
  274. package/src/clpp/modules.ts +252 -0
  275. package/src/clpp/postprocess.ts +100 -5
  276. package/src/clpp/rewrite-janitor.ts +156 -0
  277. package/src/clpp/runner.ts +14 -2
  278. package/src/compile.ts +87 -0
  279. package/src/flare/parse.ts +14 -1
  280. package/src/flare/types.ts +2 -0
  281. package/src/intellisense.ts +58 -1
  282. package/src/native/index.ts +225 -16
  283. package/src/target/authority-check.ts +162 -0
  284. package/src/target/authority-graph.ts +80 -0
  285. package/src/target/build-cache.ts +129 -0
  286. package/src/target/capabilities.ts +115 -0
  287. package/src/target/capability-profile.ts +25 -0
  288. package/src/target/component-contracts.ts +64 -0
  289. package/src/target/context-check.ts +177 -0
  290. package/src/target/datamodel-check.ts +188 -0
  291. package/src/target/datamodel-generate.ts +78 -0
  292. package/src/target/datamodel.ts +261 -0
  293. package/src/target/diagnostics.ts +67 -0
  294. package/src/target/doctor.ts +171 -0
  295. package/src/target/flare-version.ts +61 -0
  296. package/src/target/get-service.ts +85 -0
  297. package/src/target/lifetime-check.ts +45 -0
  298. package/src/target/luau-stamp.ts +33 -0
  299. package/src/target/optimizer-advise.ts +93 -0
  300. package/src/target/optimizer-apply.ts +63 -0
  301. package/src/target/optimizer-soa.ts +270 -0
  302. package/src/target/parallel-check.ts +135 -0
  303. package/src/target/pgo.ts +157 -0
  304. package/src/target/project-docs.ts +68 -0
  305. package/src/target/project-graph.ts +75 -0
  306. package/src/target/roblox.ts +78 -0
  307. package/src/target/security-check.ts +40 -0
  308. package/src/target/source-map.ts +36 -0
  309. package/src/target/studio-bridge.ts +140 -0
  310. package/src/types.ts +14 -0
  311. package/src/utils/project.ts +183 -9
  312. package/src/utils/rojo-mapper.ts +12 -3
  313. package/stylua.toml +9 -0
  314. package/templates/game/.vscode/settings.json +7 -1
  315. package/templates/game/include/clpp/datatypes.clh +337 -373
  316. package/templates/game/include/clpp/generated/enums.clh +1 -1
  317. package/templates/game/include/clpp/generated/instances.clh +41135 -41064
  318. package/templates/game/include/clpp/libs/axiom.clh +1 -1
  319. package/templates/game/include/clpp/libs/ward.clh +1 -0
  320. package/templates/game/include/clpp/roblox.clh +3 -4
  321. package/templates/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
  322. package/templates/game/src/ServerScriptService/Handlers/PlayerHandler.server.clpp +1 -1
  323. package/templates/game/stylua.toml +9 -0
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rewriteSweepJanitor = rewriteSweepJanitor;
4
+ const HEADER = /^(?:const function |function )([A-Za-z0-9_]+)(?::([A-Za-z0-9_]+))?\(([^)]*)\)[^\n]*\n/gm;
5
+ const INSTANCE_TYPES = new Set([
6
+ "Instance",
7
+ "Part",
8
+ "BasePart",
9
+ "Model",
10
+ "Player",
11
+ "ScreenGui",
12
+ "GuiObject",
13
+ "TextButton",
14
+ "TextLabel",
15
+ "ImageLabel",
16
+ "Frame",
17
+ "Tool",
18
+ "Humanoid",
19
+ "Folder",
20
+ "ValueBase",
21
+ "IntValue",
22
+ "StringValue",
23
+ "BoolValue",
24
+ ]);
25
+ function parseParams(sig) {
26
+ const out = [];
27
+ for (const piece of String(sig).split(",")) {
28
+ const match = piece.trim().match(/^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([A-Za-z_][A-Za-z0-9_]*)/);
29
+ if (match) {
30
+ out.push({ name: match[1], type: match[2] });
31
+ }
32
+ }
33
+ return out;
34
+ }
35
+ function connectRoots(body) {
36
+ const roots = [];
37
+ const seen = new Set();
38
+ const re = /__janitor:Add\(([A-Za-z_][A-Za-z0-9_]*)/g;
39
+ let match = re.exec(body);
40
+ while (match) {
41
+ const name = match[1];
42
+ if (!seen.has(name)) {
43
+ seen.add(name);
44
+ roots.push(name);
45
+ }
46
+ match = re.exec(body);
47
+ }
48
+ return roots;
49
+ }
50
+ function linkTarget(params, body) {
51
+ const roots = connectRoots(body);
52
+ for (const root of roots) {
53
+ const param = params.find((item) => item.name === root && INSTANCE_TYPES.has(item.type));
54
+ if (param) {
55
+ return param.name;
56
+ }
57
+ }
58
+ const fallback = params.find((item) => INSTANCE_TYPES.has(item.type));
59
+ return fallback ? fallback.name : null;
60
+ }
61
+ function splitSelfGuard(body) {
62
+ const match = body.match(/^(\tif not \(self[\s\S]*?\n\tend\n)/);
63
+ if (!match) {
64
+ return { guard: "", rest: body };
65
+ }
66
+ return { guard: match[1], rest: body.slice(match[1].length) };
67
+ }
68
+ function hoistSelf() {
69
+ return [
70
+ "\tlocal __janitor = self.janitor",
71
+ "\tif not __janitor then",
72
+ "\t\t__janitor = Janitor.new()",
73
+ "\t\tself.janitor = __janitor",
74
+ "\tend",
75
+ "",
76
+ ].join("\n");
77
+ }
78
+ function hoistLink(name) {
79
+ return ["\tlocal __janitor = Janitor.new()", `\t__janitor:LinkToInstance(${name})`, ""].join("\n");
80
+ }
81
+ function hoistModule() {
82
+ return [
83
+ "\tif not __cluauppSweep then",
84
+ "\t\t__cluauppSweep = Janitor.new()",
85
+ "\tend",
86
+ "\tlocal __janitor = __cluauppSweep",
87
+ "",
88
+ ].join("\n");
89
+ }
90
+ function rewriteBody(params, body, isMethod) {
91
+ if (!/^[ \t]*local __janitor = Janitor\.new\(\)\s*\n/m.test(body)) {
92
+ return { body, moduleSweep: false };
93
+ }
94
+ if (/__janitor:LinkToInstance\(/.test(body)) {
95
+ return { body, moduleSweep: false };
96
+ }
97
+ const stripped = body.replace(/^[ \t]*local __janitor = Janitor\.new\(\)\s*\n/m, "");
98
+ const parsed = parseParams(params);
99
+ const link = linkTarget(parsed, stripped);
100
+ if (link) {
101
+ const pieces = splitSelfGuard(stripped);
102
+ return { body: `${pieces.guard}${hoistLink(link)}${pieces.rest}`, moduleSweep: false };
103
+ }
104
+ if (isMethod) {
105
+ const pieces = splitSelfGuard(stripped);
106
+ return { body: `${pieces.guard}${hoistSelf()}${pieces.rest}`, moduleSweep: false };
107
+ }
108
+ const pieces = splitSelfGuard(stripped);
109
+ return { body: `${pieces.guard}${hoistModule()}${pieces.rest}`, moduleSweep: true };
110
+ }
111
+ function rewriteSweepJanitor(luau) {
112
+ const source = String(luau);
113
+ HEADER.lastIndex = 0;
114
+ const matches = [...source.matchAll(HEADER)];
115
+ if (matches.length === 0) {
116
+ return source;
117
+ }
118
+ let out = source.slice(0, matches[0].index);
119
+ let needsModule = false;
120
+ for (let i = 0; i < matches.length; i += 1) {
121
+ const match = matches[i];
122
+ const header = match[0];
123
+ const method = match[2];
124
+ const params = match[3] || "";
125
+ const isMethod = Boolean(method);
126
+ const bodyStart = (match.index || 0) + header.length;
127
+ const bodyEnd = i + 1 < matches.length ? matches[i + 1].index : source.length;
128
+ const rawBody = source.slice(bodyStart, bodyEnd);
129
+ const rewritten = rewriteBody(params, rawBody, isMethod);
130
+ if (rewritten.moduleSweep) {
131
+ needsModule = true;
132
+ }
133
+ out += header + rewritten.body;
134
+ }
135
+ if (needsModule && !/\blocal __cluauppSweep\b/.test(out)) {
136
+ const inject = "local __cluauppSweep = nil\n";
137
+ if (/const Janitor = require[^\n]*\n/.test(out)) {
138
+ out = out.replace(/const Janitor = require[^\n]*\n/, (line) => `${line}${inject}`);
139
+ }
140
+ else {
141
+ out = inject + out;
142
+ }
143
+ }
144
+ return out;
145
+ }
@@ -29,10 +29,10 @@ function cmpSemver(a, b) {
29
29
  return a.major - b.major || a.minor - b.minor || a.patch - b.patch;
30
30
  }
31
31
  function minClpp() {
32
- return parseSemver(contract_js_1.MIN_CLPP_VERSION) || { major: 0, minor: 3, patch: 2 };
32
+ return parseSemver(contract_js_1.MIN_CLPP_VERSION) || { major: 0, minor: 8, patch: 0 };
33
33
  }
34
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/download/v0.3.2/clpp-setup.exe or set CLPP / CLPP_PATH.`;
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
36
  }
37
37
  function probeVersion(bin) {
38
38
  const result = (0, node_child_process_1.spawnSync)(bin, ["--version"], { encoding: "utf8", windowsHide: true });
@@ -170,6 +170,12 @@ function compileViaClpp(request) {
170
170
  source: request.source,
171
171
  fileName: request.fileName,
172
172
  strict: request.strict ?? null,
173
+ optimize: request.optimize ?? true,
174
+ targetProfilePath: request.targetProfilePath ?? null,
175
+ targetCacheDir: request.targetCacheDir ?? null,
176
+ runContext: request.runContext ?? null,
177
+ capabilityProfilePath: request.capabilityProfilePath ?? null,
178
+ datamodelProfilePath: request.datamodelProfilePath ?? null,
173
179
  });
174
180
  const result = (0, node_child_process_1.spawnSync)(bin, ["api", "compile"], {
175
181
  input: payload,
@@ -222,6 +228,12 @@ function compileViaClppAsync(request) {
222
228
  source: request.source,
223
229
  fileName: request.fileName,
224
230
  strict: request.strict ?? null,
231
+ optimize: request.optimize ?? true,
232
+ targetProfilePath: request.targetProfilePath ?? null,
233
+ targetCacheDir: request.targetCacheDir ?? null,
234
+ runContext: request.runContext ?? null,
235
+ capabilityProfilePath: request.capabilityProfilePath ?? null,
236
+ datamodelProfilePath: request.datamodelProfilePath ?? null,
225
237
  }));
226
238
  });
227
239
  }
@@ -7,28 +7,106 @@ exports.compileSource = compileSource;
7
7
  exports.compileService = compileService;
8
8
  exports.compileServiceAsync = compileServiceAsync;
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
+ const node_fs_1 = __importDefault(require("node:fs"));
10
11
  const runner_js_1 = require("./clpp/runner.js");
11
12
  const postprocess_js_1 = require("./clpp/postprocess.js");
12
13
  const paths_js_1 = require("./clpp/paths.js");
14
+ const package_info_js_1 = require("./package-info.js");
15
+ const roblox_js_1 = require("./target/roblox.js");
16
+ const capability_profile_js_1 = require("./target/capability-profile.js");
17
+ const context_check_js_1 = require("./target/context-check.js");
18
+ const datamodel_js_1 = require("./target/datamodel.js");
19
+ const datamodel_check_js_1 = require("./target/datamodel-check.js");
20
+ const datamodel_generate_js_1 = require("./target/datamodel-generate.js");
21
+ const parallel_check_js_1 = require("./target/parallel-check.js");
22
+ const authority_check_js_1 = require("./target/authority-check.js");
23
+ const get_service_js_1 = require("./target/get-service.js");
24
+ function defaultTargetProfilePath() {
25
+ const cached = node_path_1.default.join(package_info_js_1.projectRoot, "api", "normalized", "roblox-target.profile.json");
26
+ if (node_fs_1.default.existsSync(cached)) {
27
+ return cached.replace(/\\/g, "/");
28
+ }
29
+ return undefined;
30
+ }
31
+ function ensureCapabilityProfile() {
32
+ const file = (0, capability_profile_js_1.capabilityProfilePath)();
33
+ if (!node_fs_1.default.existsSync(file)) {
34
+ (0, capability_profile_js_1.writeCapabilityProfile)();
35
+ }
36
+ return file.replace(/\\/g, "/");
37
+ }
38
+ function resolveGameRoot(options) {
39
+ const start = options.rootDir
40
+ ? node_path_1.default.resolve(options.rootDir)
41
+ : options.filePath
42
+ ? node_path_1.default.dirname(node_path_1.default.resolve(options.filePath))
43
+ : process.cwd();
44
+ let dir = start;
45
+ for (let i = 0; i < 8; i++) {
46
+ if (node_fs_1.default.existsSync(node_path_1.default.join(dir, "default.project.json")) || node_fs_1.default.existsSync(node_path_1.default.join(dir, "default.project.jsonc"))) {
47
+ return dir;
48
+ }
49
+ const parent = node_path_1.default.dirname(dir);
50
+ if (parent === dir) {
51
+ break;
52
+ }
53
+ dir = parent;
54
+ }
55
+ return options.rootDir ? node_path_1.default.resolve(options.rootDir) : process.cwd();
56
+ }
57
+ function ensureDatamodel(options) {
58
+ const root = resolveGameRoot(options);
59
+ const written = (0, datamodel_generate_js_1.writeDatamodelArtifacts)(root);
60
+ if (written) {
61
+ return { profilePath: written.profilePath.replace(/\\/g, "/"), profile: written.profile };
62
+ }
63
+ return { profile: (0, datamodel_js_1.buildDatamodelProfile)(root) };
64
+ }
13
65
  function compileArgs(source, fileName, options) {
14
66
  const relative = (options.relativeName || fileName || "input.clpp").replace(/\\/g, "/");
15
67
  const outName = options.outName || (0, paths_js_1.toLuauPath)(relative);
16
68
  const header = options.filePath ? (0, paths_js_1.siblingHeader)(options.filePath) : null;
17
69
  const skipInit = options.skipInit === true || (0, postprocess_js_1.shouldSkipInit)(relative, Boolean(header));
18
70
  const diskPath = options.filePath ? node_path_1.default.resolve(options.filePath) : null;
71
+ const runContext = (0, roblox_js_1.runContextFromFileName)(relative);
72
+ const dm = ensureDatamodel(options);
73
+ const gameRoot = resolveGameRoot(options);
19
74
  return {
20
75
  request: {
21
76
  source,
22
77
  fileName: diskPath ? diskPath.replace(/\\/g, "/") : relative,
23
78
  strict: options.strict,
79
+ optimize: options.optimize !== false,
24
80
  cwd: diskPath ? node_path_1.default.dirname(diskPath) : options.srcDir,
81
+ targetProfilePath: defaultTargetProfilePath(),
82
+ targetCacheDir: node_path_1.default.join(package_info_js_1.projectRoot, "api", ".cache").replace(/\\/g, "/"),
83
+ runContext,
84
+ capabilityProfilePath: ensureCapabilityProfile(),
85
+ datamodelProfilePath: dm.profilePath,
25
86
  },
26
87
  relative,
27
88
  outName,
28
89
  skipInit,
29
90
  options,
91
+ datamodel: dm.profile,
92
+ gameRoot,
93
+ policy: (0, authority_check_js_1.loadPlatformPolicy)(gameRoot),
30
94
  };
31
95
  }
96
+ function enforcePlatform(source, relative, args) {
97
+ const profile = (0, capability_profile_js_1.loadCapabilityProfile)();
98
+ (0, context_check_js_1.assertContextSafe)(source, relative, profile);
99
+ const warnings = (0, context_check_js_1.listContextWarnings)(source, relative, profile);
100
+ if (warnings.length) {
101
+ console.warn((0, context_check_js_1.formatContextViolations)(relative, warnings));
102
+ }
103
+ if (args.datamodel) {
104
+ (0, datamodel_check_js_1.assertDatamodelSafe)(source, args.datamodel);
105
+ }
106
+ (0, parallel_check_js_1.assertParallelSafe)(source, relative);
107
+ (0, authority_check_js_1.assertAuthoritySafe)(source, relative, args.policy);
108
+ (0, get_service_js_1.assertGetServiceSafe)(source, relative);
109
+ }
32
110
  function finishArtifact(artifact, relative, outName, options, skipInit, source) {
33
111
  const luau = (0, postprocess_js_1.clppLuauToGame)(artifact, {
34
112
  relativeName: relative,
@@ -38,6 +116,8 @@ function finishArtifact(artifact, relative, outName, options, skipInit, source)
38
116
  strict: options.strict,
39
117
  skipInit,
40
118
  source,
119
+ nativeHints: artifact.nativeHints,
120
+ layoutHints: artifact.layoutHints,
41
121
  });
42
122
  return {
43
123
  kind: (0, paths_js_1.emitKind)(relative),
@@ -51,11 +131,13 @@ function compileSource(source, fileName, options = {}) {
51
131
  }
52
132
  function compileService(source, fileName, options = {}) {
53
133
  const args = compileArgs(source, fileName, options);
134
+ enforcePlatform(source, args.relative, args);
54
135
  const artifact = (0, runner_js_1.compileViaClpp)(args.request);
55
136
  return finishArtifact(artifact, args.relative, args.outName, args.options, args.skipInit, source);
56
137
  }
57
138
  async function compileServiceAsync(source, fileName, options = {}) {
58
139
  const args = compileArgs(source, fileName, options);
140
+ enforcePlatform(source, args.relative, args);
59
141
  const artifact = await (0, runner_js_1.compileViaClppAsync)(args.request);
60
142
  return finishArtifact(artifact, args.relative, args.outName, args.options, args.skipInit, source);
61
143
  }
@@ -72,6 +72,7 @@ function parseSide(raw, file, line) {
72
72
  function parseFlare(source, filePath, defaultName) {
73
73
  const file = filePath.replace(/\\/g, "/");
74
74
  let name = defaultName;
75
+ let version;
75
76
  const packets = [];
76
77
  const queries = [];
77
78
  let packetId = 1;
@@ -83,6 +84,11 @@ function parseFlare(source, filePath, defaultName) {
83
84
  if (!line || line.startsWith("#") || line.startsWith("//")) {
84
85
  continue;
85
86
  }
87
+ const verStmt = line.match(/^version\s+(\d+)\s*;?$/i);
88
+ if (verStmt) {
89
+ version = Number(verStmt[1]);
90
+ continue;
91
+ }
86
92
  const opt = line.match(/^opt\s+name\s*=\s*(.+)$/i);
87
93
  if (opt) {
88
94
  const value = opt[1].trim().replace(/^["']|["']$/g, "");
@@ -92,6 +98,11 @@ function parseFlare(source, filePath, defaultName) {
92
98
  name = value;
93
99
  continue;
94
100
  }
101
+ const optVer = line.match(/^opt\s+version\s*=\s*(\d+)\s*;?$/i);
102
+ if (optVer) {
103
+ version = Number(optVer[1]);
104
+ continue;
105
+ }
95
106
  const packet = line.match(new RegExp(`^packet\\s+(${exports.FLARE_IDENT})\\s*\\((.*)\\)\\s+from\\s+(Client|Server)(?:\\s+(unreliable|reliable))?\\s*$`, "i"));
96
107
  if (packet) {
97
108
  const reliable = String(packet[4] || "reliable").toLowerCase() !== "unreliable";
@@ -127,5 +138,5 @@ function parseFlare(source, filePath, defaultName) {
127
138
  if (packets.length === 0 && queries.length === 0) {
128
139
  fail(file, 1, "schema is empty — add a packet or query");
129
140
  }
130
- return { name, sourcePath: file, packets, queries };
141
+ return { name, sourcePath: file, version, packets, queries };
131
142
  }
@@ -16,6 +16,7 @@ const package_info_js_1 = require("./package-info.js");
16
16
  const contract_js_1 = require("./clpp/contract.js");
17
17
  const runner_js_1 = require("./clpp/runner.js");
18
18
  const paths_js_1 = require("./clpp/paths.js");
19
+ const editor_install_js_1 = require("./editor-install.js");
19
20
  function copyDir(from, to) {
20
21
  node_fs_1.default.mkdirSync(to, { recursive: true });
21
22
  for (const entry of node_fs_1.default.readdirSync(from, { withFileTypes: true })) {
@@ -82,10 +83,24 @@ function writeVscode(root) {
82
83
  "*.client.clpp": "clpp",
83
84
  "*.plugin.clpp": "clpp",
84
85
  "*.flare": "flare",
86
+ "*.hive": "hive",
87
+ "*.mint": "mint",
88
+ "*.bloom": "bloom",
89
+ "*.helm": "helm",
90
+ "*.shift": "shift",
91
+ "*.axiom": "axiom",
85
92
  };
86
93
  writeJson(settingsPath, {
87
94
  ...current,
88
95
  "files.associations": associations,
96
+ "[luau]": {
97
+ ...((current["[luau]"] && typeof current["[luau]"] === "object" && !Array.isArray(current["[luau]"]))
98
+ ? current["[luau]"]
99
+ : {}),
100
+ "editor.insertSpaces": false,
101
+ "editor.tabSize": 4,
102
+ "editor.detectIndentation": false,
103
+ },
89
104
  });
90
105
  const extensionsPath = node_path_1.default.join(root, ".vscode", "extensions.json");
91
106
  const extensions = readJsonObject(extensionsPath);
@@ -100,8 +115,31 @@ function diagnosticsFor(_source, _fileName) {
100
115
  // from the editor — that duplicates source=clpp and freezes on every keystroke.
101
116
  return [];
102
117
  }
118
+ function writeStylua(root) {
119
+ const dest = node_path_1.default.join(root, "stylua.toml");
120
+ const body = `# cluaupp roblox luau
121
+ syntax = "Luau"
122
+ column_width = 120
123
+ line_endings = "Unix"
124
+ indent_type = "Tabs"
125
+ indent_width = 4
126
+ quote_style = "AutoPreferDouble"
127
+ call_parentheses = "Always"
128
+ collapse_simple_statement = "Never"
129
+ `;
130
+ if (node_fs_1.default.existsSync(dest)) {
131
+ const existing = node_fs_1.default.readFileSync(dest, "utf8");
132
+ if (!existing.includes("cluaupp roblox luau") && existing.trim() !== "") {
133
+ return;
134
+ }
135
+ }
136
+ if (!node_fs_1.default.existsSync(dest) || node_fs_1.default.readFileSync(dest, "utf8") !== body) {
137
+ node_fs_1.default.writeFileSync(dest, body, "utf8");
138
+ }
139
+ }
103
140
  function syncEditorSupport(root, _config = {}) {
104
141
  writeVscode(root);
142
+ writeStylua(root);
105
143
  }
106
144
  function installEditorExtension(cluauppRoot = package_info_js_1.projectRoot) {
107
145
  const from = node_path_1.default.join(cluauppRoot, "editors", "vscode");
@@ -116,6 +154,16 @@ function installEditorExtension(cluauppRoot = package_info_js_1.projectRoot) {
116
154
  continue;
117
155
  }
118
156
  node_fs_1.default.mkdirSync(home, { recursive: true });
157
+ try {
158
+ for (const name of node_fs_1.default.readdirSync(home)) {
159
+ if (name.startsWith("kartzdev.cluaupp-flare-") && name !== id) {
160
+ node_fs_1.default.rmSync(node_path_1.default.join(home, name), { recursive: true, force: true });
161
+ }
162
+ }
163
+ }
164
+ catch {
165
+ // ignore prune errors
166
+ }
119
167
  const dest = node_path_1.default.join(home, id);
120
168
  copyDir(from, dest);
121
169
  node_fs_1.default.writeFileSync(node_path_1.default.join(dest, "cluaupp.root"), node_path_1.default.resolve(cluauppRoot), "utf8");
@@ -132,12 +180,20 @@ function installEditorExtension(cluauppRoot = package_info_js_1.projectRoot) {
132
180
  }
133
181
  installed.push(dest);
134
182
  }
183
+ const bin = (0, editor_install_js_1.editorBin)();
184
+ if (bin && installed[0]) {
185
+ (0, node_child_process_1.spawnSync)(bin, ["--install-extension", installed[0], "--force"], {
186
+ encoding: "utf8",
187
+ windowsHide: true,
188
+ timeout: 120000,
189
+ });
190
+ }
135
191
  return installed;
136
192
  }
137
193
  async function installEditorSupport() {
138
194
  const local = installEditorExtension();
139
195
  if (local.length > 0) {
140
- console.log("cluaupp: Flare IntelliSense installed");
196
+ console.log("cluaupp: schema IntelliSense installed (.flare .hive .mint .bloom .helm .shift .axiom)");
141
197
  for (const dest of local) {
142
198
  console.log(" ", dest);
143
199
  }