cluaupp 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +6 -1
  3. package/bin/cluau.js +1 -1
  4. package/bin/cluaupp.js +1 -1
  5. package/docs/architecture.md +26 -1
  6. package/docs/cli.md +27 -6
  7. package/docs/examples/index.md +2 -0
  8. package/docs/getting-started.md +5 -4
  9. package/docs/intellisense.md +49 -31
  10. package/docs/intro.md +1 -1
  11. package/editors/vscode/extension.js +97 -146
  12. package/editors/vscode/package.json +6 -6
  13. package/examples/README.md +18 -0
  14. package/examples/game/.clangd +25 -0
  15. package/examples/game/.vscode/c_cpp_properties.json +27 -0
  16. package/examples/game/.vscode/extensions.json +5 -0
  17. package/examples/game/.vscode/settings.json +27 -0
  18. package/examples/game/Packages/.gitkeep +0 -0
  19. package/examples/game/cluaupp.config.json +6 -0
  20. package/examples/game/compile_flags.txt +6 -0
  21. package/examples/game/default.project.json +39 -0
  22. package/examples/game/package.json +9 -0
  23. package/examples/game/rokit.toml +5 -0
  24. package/examples/game/src/client/hud.client.cpp +12 -0
  25. package/{src → examples/game/src}/client/init.client.cpp +1 -0
  26. package/examples/game/src/server/combat.server.cpp +23 -0
  27. package/{src → examples/game/src}/server/leaderstats.server.cpp +1 -0
  28. package/examples/game/wally.toml +11 -0
  29. package/generated/api.js +51 -0
  30. package/generated/architecture.js +473 -0
  31. package/generated/ast.js +2 -0
  32. package/generated/cli.js +191 -0
  33. package/generated/compile.js +115 -0
  34. package/generated/editor-install.js +170 -0
  35. package/generated/emit.js +503 -0
  36. package/generated/emitter/luau-codegen.js +167 -0
  37. package/generated/emitter/translators.js +164 -0
  38. package/generated/headers.js +220 -0
  39. package/generated/index.html +49 -0
  40. package/generated/intellisense.js +277 -0
  41. package/generated/layout.js +112 -0
  42. package/generated/lex.js +146 -0
  43. package/generated/libs.js +484 -0
  44. package/generated/lsp.js +55 -0
  45. package/generated/package-info.js +11 -0
  46. package/generated/parse.js +607 -0
  47. package/generated/parser/collector.js +100 -0
  48. package/generated/parser/index.js +30 -0
  49. package/generated/preprocess.js +181 -0
  50. package/generated/system-understander.js +443 -0
  51. package/generated/transpile.js +66 -0
  52. package/generated/types.js +2 -0
  53. package/generated/understand.js +298 -0
  54. package/generated/utils/process-orchestrator.js +63 -0
  55. package/generated/utils/project.js +491 -0
  56. package/generated/utils/rojo-mapper.js +181 -0
  57. package/generated/utils/safe-paths.js +104 -0
  58. package/package.json +25 -8
  59. package/src/api.ts +53 -0
  60. package/src/{architecture.js → architecture.ts} +9 -10
  61. package/src/ast.ts +37 -0
  62. package/src/cli.ts +214 -0
  63. package/src/compile.ts +118 -0
  64. package/src/editor-install.ts +182 -0
  65. package/src/{emit.js → emit.ts} +4 -5
  66. package/src/emitter/luau-codegen.ts +187 -0
  67. package/src/emitter/translators.ts +168 -0
  68. package/src/{headers.js → headers.ts} +4 -5
  69. package/src/intellisense.ts +286 -0
  70. package/src/{layout.js → layout.ts} +114 -129
  71. package/src/{lex.js → lex.ts} +4 -6
  72. package/src/{libs.js → libs.ts} +9 -4
  73. package/src/lsp.ts +60 -0
  74. package/src/package-info.ts +7 -0
  75. package/src/{parse.js → parse.ts} +3 -4
  76. package/src/parser/collector.ts +115 -0
  77. package/src/parser/index.ts +27 -0
  78. package/src/{preprocess.js → preprocess.ts} +22 -37
  79. package/src/system-understander.ts +501 -0
  80. package/src/transpile.ts +64 -0
  81. package/src/tree-sitter-cpp.d.ts +4 -0
  82. package/src/types.ts +81 -0
  83. package/src/{understand.js → understand.ts} +19 -210
  84. package/src/utils/process-orchestrator.ts +72 -0
  85. package/src/utils/project.ts +506 -0
  86. package/src/utils/rojo-mapper.ts +190 -0
  87. package/src/utils/safe-paths.ts +98 -0
  88. package/templates/game/.clangd +9 -0
  89. package/templates/game/.vscode/c_cpp_properties.json +1 -1
  90. package/templates/game/.vscode/extensions.json +5 -6
  91. package/templates/game/.vscode/settings.json +7 -6
  92. package/templates/game/compile_flags.txt +1 -0
  93. package/templates/game/rokit.toml +5 -0
  94. package/src/api.js +0 -57
  95. package/src/cli.js +0 -473
  96. package/src/compile.js +0 -110
  97. package/src/editor-install.js +0 -218
  98. package/src/intellisense.js +0 -1368
  99. package/src/lsp.js +0 -227
  100. /package/{src → examples/game/src}/shared/config.cpp +0 -0
  101. /package/{src → examples/game/src}/shared/config.h +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.2.0
6
+
7
+ - CLI rewritten as a TypeScript collector-emitter pipeline: Tree-sitter collection, Rojo-mapped `require`s, ordered Luau blocks (Services → Requires → Types → Constants → Code), then optional StyLua / `luau-analyze`. Commands `init`, `build`, `watch`, `lsp`, and `intellisense` stay. `cluaupp build -i file.cpp -o out.luau --rojo default.project.json` is the single-file path.
8
+ - C++ IntelliSense is **clangd** only. The old tokenizer/`completeAt` engine is gone. Tree-sitter is the compiler frontend. `cluaupp lsp` publishes subset parse errors only.
9
+ - `SystemUnderstander` scans identifiers, scores Roblox intents, and stamps Controller / Manager / utility plus `GetService` injections. Filename tags still decide Script vs LocalScript vs ModuleScript.
10
+ - Sample game C++ lives in `examples/game/` (`src/server`, `src/client`, `src/shared`). Compiler `src/` is TypeScript only.
11
+ - CLI security: StyLua / luau-analyze via `spawn` without a shell; emitted paths cannot leave the project; `.env*` stays out of git and the npm pack.
12
+ - Docs / GitHub Pages: clangd, SystemUnderstander, one-file-out emit, `examples/game`. Rojo **7.7.0**.
13
+ - Tests cover `out/` tree, types, modules, path safety, and understander roles.
14
+
3
15
  ## 0.1.5
4
16
 
5
17
  - Default emit is one tagged `.cpp` → one `.server.luau` / `.client.luau`. `"architecture": true` keeps the old ForeverHD service folders.
package/README.md CHANGED
@@ -42,7 +42,7 @@ players.PlayerAdded:Connect(CreateLeaderstats)
42
42
 
43
43
  ## Install
44
44
 
45
- Node.js 18+ and [Rojo](https://rojo.space/) for Studio sync.
45
+ Node.js 18+ and [Rojo](https://rojo.space/) **7.7.0** for Studio sync (`rokit.toml` in the game template).
46
46
 
47
47
  ```bash
48
48
  npm install -g cluaupp
@@ -59,12 +59,15 @@ npx cluaupp init my-game
59
59
  ```bash
60
60
  cluaupp init my-game
61
61
  cd my-game
62
+ rokit install
62
63
  cluaupp build
63
64
  rojo serve
64
65
  ```
65
66
 
66
67
  Connect the Rojo plugin in Roblox Studio. Edit `src/**/*.{cpp,h,hpp}`, run `cluaupp watch` to rebuild on save.
67
68
 
69
+ C++ autocomplete is **clangd**, not a Cluaupp tokenizer and not Microsoft cpptools. Put `#include <cluaupp/roblox.hpp>` at the top of each script; `cluaupp init` writes `.clangd` / `compile_flags.txt` / `compile_commands.json` with `-Iinclude` so clangd finds that header. Tree-sitter is only used to compile. See [IntelliSense](docs/intellisense.md).
70
+
68
71
  ```
69
72
  src/server/*.server.cpp → out/server/*.server.luau Script
70
73
  src/client/*.client.cpp → out/client/*.client.luau LocalScript
@@ -73,6 +76,8 @@ src/shared/*.cpp → out/shared/*.luau ModuleScript
73
76
 
74
77
  Filename tags: `.server.cpp`, `.client.cpp`, `.legacy.server.cpp`, `.legacy.client.cpp`, or no tag (ModuleScript). One source file becomes one instance. Set `"architecture": true` only for the old PascalCase folder split. See [Architecture](docs/architecture.md) and [OOP structure](docs/oop/index.md).
75
78
 
79
+ Compiler TypeScript lives in `src/`. Sample game C++ is [`examples/game`](examples/game) (`src/server`, `src/client`, `src/shared`). `cluaupp init` still copies [`templates/game`](templates/game).
80
+
76
81
  ## Documentation
77
82
 
78
83
  | Guide | What it covers |
package/bin/cluau.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
 
4
- require("../src/cli.js");
4
+ require("../generated/cli.js");
package/bin/cluaupp.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
3
 
4
- require("../src/cli.js");
4
+ require("../generated/cli.js");
@@ -20,6 +20,31 @@ roblox-ts decides **what instance you get** from a filename **key** (the same id
20
20
 
21
21
  The ForeverHD-style folder split (`LeaderStats/Main.luau`, …) is **opt-in**: `"architecture": true`.
22
22
 
23
+ ## SystemUnderstander
24
+
25
+ Like [roblox-ts](https://github.com/roblox-ts/roblox-ts) (filename **key** first) and [roblox-cs](https://github.com/roblox-csharp/roblox-cs) (scan the AST, then decide), Cluaupp does **not** call a generative model. `src/system-understander.ts` walks the Tree-sitter tree, scores token density against Roblox engine services, and returns a report the emitter may stamp as comments / extra `GetService` lines.
26
+
27
+ | Step | What happens |
28
+ | --- | --- |
29
+ | `parseFileTag` | `.server.cpp` → Script / Server, `.client.cpp` → LocalScript / Client, no tag → ModuleScript |
30
+ | `namesIn` | identifiers, `GetService<T>`, `new Class`, string literals |
31
+ | `scoreIntents` | evidence count × side weight (server tokens count more on `.server.cpp`) |
32
+ | `determineArchitecture` | score &lt; 2 → utility Module; otherwise Knit-style Controller / Manager / Service. `players` / `cache` stay supporting if combat, UI, or net already has ≥ 2 tokens |
33
+
34
+ The **Rojo class never changes** because of a role. A HUD LocalScript can be classified as `ViewController` and still emit `hud.client.luau`. Sample sources: [examples/game](../examples/game).
35
+
36
+ ## Compiler pipeline
37
+
38
+ Cluaupp does not rewrite C++ as text. The CLI parses a Tree-sitter CST, collects symbols (`GetService<T>()`, `#include`, types, constants), then emits Luau in a fixed order:
39
+
40
+ 1. `game:GetService(...)`
41
+ 2. `require(...)` (Rojo `default.project.json` when present)
42
+ 3. types
43
+ 4. constants
44
+ 5. functions / script body
45
+
46
+ Formatting is delegated to StyLua; type sanity to `luau-analyze`. See [CLI](cli.md).
47
+
23
48
  ## File tags
24
49
 
25
50
  | Source | Meaning | Output |
@@ -42,7 +67,7 @@ Scripts and LocalScripts keep your functions and call `init()` at the end. Modul
42
67
 
43
68
  ## Opt-in: ForeverHD folders (`"architecture": true`)
44
69
 
45
- Set `"architecture": true` in `cluaupp.config.json` to restore the old planner: PascalCase service folders, `Main` / Managers / Controllers / Types, and `require(script.Main):Start()`.
70
+ Set `"architecture": true` in `cluaupp.config.json` to restore the old planner: PascalCase service folders, `Main` / Managers / Controllers / Types, and `require(script.Main):Start()`. Server folders emit `init.server.luau` plus a **pure JSON** `init.meta.json` with only `RunContext.Server` — never `className`, and never library `require` lines (Rojo 7.7 rejects both).
46
71
 
47
72
  ```
48
73
  filename key → server | client | module | legacy
package/docs/cli.md CHANGED
@@ -6,6 +6,8 @@ cluaupp <command> [folder]
6
6
 
7
7
  If `[folder]` is omitted, the current directory is used.
8
8
 
9
+ The compiler is a **collector-emitter** pipeline: Tree-sitter walks the C++ CST, Rojo maps `#include` to `require`, Luau is emitted in a fixed block order (Services → Requires → Types → Constants → Code), then StyLua / `luau-analyze` can run as post-process.
10
+
9
11
  ## `cluaupp init [folder]`
10
12
 
11
13
  Creates a game from the template:
@@ -13,8 +15,9 @@ Creates a game from the template:
13
15
  - `src/server`, `src/client`, `src/shared`
14
16
  - `cluaupp.config.json`
15
17
  - `default.project.json` (Rojo)
18
+ - `rokit.toml` (Rojo 7.7.0)
16
19
  - `include/cluaupp/roblox.hpp` (IntelliSense)
17
- - `.vscode/c_cpp_properties.json`
20
+ - `.vscode/` (clangd)
18
21
 
19
22
  ```bash
20
23
  cluaupp init .
@@ -25,8 +28,8 @@ cluaupp init my-game
25
28
 
26
29
  Transpiles `src/**/*.{cpp,h,hpp}` into `out/`. One tagged `.cpp` becomes one Luau instance (`leaderstats.server.luau`, `hud.client.luau`). Shared untagged files become ModuleScripts. Set `"architecture": true` for the old PascalCase service folders.
27
30
 
28
- - `--!strict` only with `#pragma strict` or `"strict": true`
29
- - `#include "file.h"` becomes `require(ReplicatedStorage.Cluaupp...)` / `require(ServerScriptService.Cluaupp...)` for shared/server modules
31
+ - `--!strict` only with `#pragma strict`, `"strict": true`, or `--strict` on the single-file path
32
+ - `#include "file.h"` becomes `require(...)` resolved from `default.project.json` when present
30
33
  - `#include <cluaupp/roblox.hpp>` is ignored
31
34
  - `.h` / `.hpp` emit a type ModuleScript (`export type` + typed table). A sibling `.cpp` becomes `*Impl.luau` (the construction); the header binds those functions.
32
35
  - A parse error exits with code 1 and `file:line:column`
@@ -36,12 +39,29 @@ Transpiles `src/**/*.{cpp,h,hpp}` into `out/`. One tagged `.cpp` becomes one Lua
36
39
  ```bash
37
40
  cluaupp build
38
41
  cluaupp build ./my-game
42
+ cluaupp build --format --analyze
43
+ ```
44
+
45
+ ### Single file
46
+
47
+ ```bash
48
+ cluaupp build --input ./src/server/boot.server.cpp --output ./out/boot.server.luau --rojo ./default.project.json
39
49
  ```
40
50
 
51
+ `--format` runs StyLua; `--analyze` runs `luau-analyze`. On the single-file path both run by default (warnings if the binaries are missing). On a project build they are opt-in.
52
+
41
53
  ## `cluaupp watch [folder]`
42
54
 
43
55
  Runs a compile (without copying `libs/`) and rebuilds when anything under `src/` changes, including deletes. Parse errors are printed; the watcher stays alive and **does not write `out/`** until the project compiles cleanly (Studio keeps the last good scripts). A second watcher in the same game exits. Deleted `.cpp` files prune their `out/` artifacts on the next successful compile.
44
56
 
57
+ ## `cluaupp lsp [folder]`
58
+
59
+ Stdio JSON-RPC for **Cluaupp subset diagnostics** only. Completion, hover, and definitions are clangd.
60
+
61
+ ## `cluaupp intellisense [folder]`
62
+
63
+ Writes `compile_commands.json`, `.clangd`, and `.vscode` for clangd, and installs LLVM clangd when needed.
64
+
45
65
  ## `cluaupp --version` / `cluaupp -v`
46
66
 
47
67
  Prints the npm package version.
@@ -64,7 +84,8 @@ Shows usage.
64
84
  In the Cluaupp development repo:
65
85
 
66
86
  ```bash
67
- npm run build # cluaupp build game
68
- npm run dev # watch + Rojo
69
- npm run stop # stop Rojo
87
+ npm run build:cli # compile the TypeScript CLI
88
+ npm test
89
+ npm run dev # local gitignored playground in game/ + Rojo
90
+ npm run stop # stop Rojo
70
91
  ```
@@ -7,6 +7,8 @@ sidebar_position: 1
7
7
 
8
8
  High-quality Cluaupp systems you can copy. Each page is a full service: C++ that the subset actually compiles, server authority, Janitor cleanup, and the file names Studio expects.
9
9
 
10
+ In this repo the live sample is [`examples/game`](../../examples/game) (`src/server`, `src/client`, `src/shared`). Compiler TypeScript is never mixed with game C++. `cluaupp init` still copies [`templates/game`](../../templates/game).
11
+
10
12
  These are **not** dumps of `int main()`. Entry is `void init()`. There are no lambdas and no custom C++ classes — named functions + structs.
11
13
 
12
14
  ## Suggested layout
@@ -5,8 +5,8 @@ Cluaupp installs from **npm**, the same channel as roblox-ts and most Roblox too
5
5
  ## Requirements
6
6
 
7
7
  - [Node.js](https://nodejs.org/) 18 or newer
8
- - [Rojo](https://rojo.space/) to sync `out/` into Studio
9
- - An editor with C++ IntelliSense (Cursor / VS Code + the C/C++ extension)
8
+ - [Rojo](https://rojo.space/) **7.7.0** to sync `out/` into Studio (`cluaupp init` writes `rokit.toml`; run `rokit install`)
9
+ - LLVM clangd for C++ IntelliSense (Cursor / VS Code installed by `cluaupp init`)
10
10
 
11
11
  ## Install the compiler
12
12
 
@@ -43,6 +43,7 @@ npm install --save-dev cluaupp
43
43
  ```bash
44
44
  cluaupp init my-game
45
45
  cd my-game
46
+ rokit install
46
47
  cluaupp build
47
48
  rojo serve
48
49
  ```
@@ -123,13 +124,13 @@ If a file defines `void init()`, Cluaupp calls `init()` at the end of the `.luau
123
124
 
124
125
  ## IntelliSense
125
126
 
126
- `cluaupp init` writes the C++ IntelliSense config and installs Microsoft `ms-vscode.cpptools` (via VSIX on Cursor). Then reload the window.
127
+ `cluaupp init` writes clangd config and installs LLVM `clang++` plus the clangd editor extension when missing. Then reload the window. Completion is clangd; Cluaupp does not index C++ itself.
127
128
 
128
129
  ```bash
129
130
  cluaupp intellisense
130
131
  ```
131
132
 
132
- `#include <cluaupp/roblox.hpp>` at the top of each source file. The header is **not** compiled to Luau.
133
+ `#include <cluaupp/roblox.hpp>` at the top of each source file. The header is **not** compiled to Luau. clangd learns that path from `-Iinclude` in `.clangd`, `compile_flags.txt`, and `compile_commands.json` — it does not read `c_cpp_properties.json`.
133
134
 
134
135
  See [IntelliSense](intellisense.md).
135
136
 
@@ -1,31 +1,49 @@
1
- # IntelliSense
2
-
3
- `cluaupp init` and `cluaupp intellisense` install the same setup that works in Cursor:
4
-
5
- 1. Microsoft [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) (`ms-vscode.cpptools`)
6
- 2. `.vscode/c_cpp_properties.json` — LLVM `clang++`, C++20, `include/` + `src/`, `compile_commands.json`
7
- 3. Forced include of `include/cluaupp/roblox.hpp` so `GetService`, `Player`, `Janitor` complete
8
- 4. The Cluaupp completion engine (Roblox APIs + your `struct`s)
9
-
10
- Cursor’s marketplace does not list `ms-vscode.cpptools`. Cluaupp downloads the official VSIX from [vscode-cpptools releases](https://github.com/microsoft/vscode-cpptools/releases) and runs `cursor --install-extension`.
11
-
12
- ## Install
13
-
14
- ```bash
15
- cluaupp intellisense
16
- ```
17
-
18
- Reload: Command Palette **Developer: Reload Window**. Status bar `{} C++` should read **IntelliSense: Ready**.
19
-
20
- `cluaupp build` / `watch` only refresh `compile_commands.json` (no download). They never keep deleted files in the compilation database.
21
-
22
- ## Config that ships
23
-
24
- | File | Role |
25
- | --- | --- |
26
- | `.vscode/c_cpp_properties.json` | compiler path, include path, `compileCommands` |
27
- | `.vscode/settings.json` | `C_Cpp.intelliSenseEngine: default`, `clangd.enable: false` |
28
- | `.vscode/extensions.json` | recommends `ms-vscode.cpptools` |
29
- | `compile_commands.json` | one entry per `src/` file |
30
-
31
- `#include <cluaupp/roblox.hpp>` at the top of each source file. The header is not compiled to Luau.
1
+ # IntelliSense
2
+
3
+ C++ completion, hover, and go-to-definition are **clangd**. Cluaupp does not ship a second completion engine.
4
+
5
+ `cluaupp init` / `cluaupp intellisense` install:
6
+
7
+ 1. [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) (`llvm-vs-code-extensions.vscode-clangd`)
8
+ 2. LLVM `clang++` when missing (Windows: `winget install --id LLVM.LLVM -e`)
9
+ 3. `.clangd`, `compile_flags.txt`, and `compile_commands.json` so clangd finds `include/` (clangd does **not** read `.vscode/c_cpp_properties.json`)
10
+ 4. Forced include of `include/cluaupp/roblox.hpp` so `GetService`, `Player`, `Janitor` complete from the real C++ stubs
11
+
12
+ Tree-sitter is the **compiler** frontend (collect → emit Luau). It is not an editor language server. A homemade tokenizer in the CLI would fight clangd — that path is gone.
13
+
14
+ Microsoft `ms-vscode.cpptools` is **not** used. Two C++ engines in the same window fight; Cluaupp disables the Microsoft engine (`C_Cpp.intelliSenseEngine: Disabled`).
15
+
16
+ `cluaupp lsp` only publishes **subset parse errors** (code that clangd may accept as C++ but Cluaupp will not transpile).
17
+
18
+ ## Headers clangd must see
19
+
20
+ `#include <cluaupp/roblox.hpp>` resolves only if `-Iinclude` is on the clangd compile flags. That maps to `include/cluaupp/roblox.hpp`. Angle-bracket includes are ignored by the transpiler.
21
+
22
+ `cluaupp init` / `build` / `watch` / `intellisense` rewrite:
23
+
24
+ - `-Iinclude` and `-Isrc`
25
+ - `-include include/cluaupp/roblox.hpp`
26
+ - one `compile_commands.json` entry per file under `src/`
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ cluaupp intellisense
32
+ ```
33
+
34
+ Reload: Command Palette → **Developer: Reload Window**. clangd should attach to `.cpp` files.
35
+
36
+ `cluaupp build` / `watch` only refresh `compile_commands.json` (no download). They never keep deleted files in the compilation database.
37
+
38
+ ## Config that ships
39
+
40
+ | File | Role |
41
+ | --- | --- |
42
+ | `.vscode/c_cpp_properties.json` | compiler path (unused by clangd; kept if someone re-enables cpptools) |
43
+ | `.vscode/settings.json` | `C_Cpp.intelliSenseEngine: Disabled`, `clangd.enable: true`, `--compile-commands-dir` |
44
+ | `.vscode/extensions.json` | recommends `llvm-vs-code-extensions.vscode-clangd` |
45
+ | `.clangd` | C++20, `-Iinclude`, skip `out/` and `libs/` |
46
+ | `compile_flags.txt` | fallback flags if a file is not yet in `compile_commands.json` |
47
+ | `compile_commands.json` | one entry per `src/` file |
48
+
49
+ `#include <cluaupp/roblox.hpp>` at the top of each source file. The header is not compiled to Luau.
package/docs/intro.md CHANGED
@@ -12,7 +12,7 @@ This site is built with [Moonwave](https://eryn.io/moonwave/) for local markdown
12
12
  ## What you get
13
13
 
14
14
  1. A compiler (`cluaupp init` / `build` / `watch`)
15
- 2. Headers for IntelliSense (`#include <cluaupp/roblox.hpp>`)
15
+ 2. Headers for **clangd** (`#include <cluaupp/roblox.hpp>`)
16
16
  3. First-party libraries in `ReplicatedStorage.CluauppLibs`
17
17
  4. Wally wrappers for DataServiceV2, Fusion, Cmdr, EzVisualz, TopbarPlus, and the rest of your stack
18
18
 
@@ -1,146 +1,97 @@
1
- "use strict";
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const vscode = require("vscode");
6
-
7
- function loadEngine(context) {
8
- const folders = vscode.workspace.workspaceFolders || [];
9
- const workspaceFolder = folders[0] ? folders[0].uri.fsPath : null;
10
- const rootFile = path.join(context.extensionPath, "cluaupp.root");
11
- const roots = [];
12
- if (fs.existsSync(rootFile)) {
13
- roots.push(fs.readFileSync(rootFile, "utf8").trim());
14
- }
15
- if (workspaceFolder) {
16
- roots.push(path.join(workspaceFolder, "..", "Cluaupp"));
17
- roots.push(path.join(workspaceFolder, "node_modules", "cluaupp"));
18
- }
19
- roots.push(path.join(context.extensionPath, "..", ".."));
20
- for (const root of roots) {
21
- const engine = path.join(root, "src", "intellisense.js");
22
- if (fs.existsSync(engine)) {
23
- return { engine: require(engine), root, workspaceFolder };
24
- }
25
- }
26
- throw new Error("Cluaupp IntelliSense engine not found. Run `cluaupp intellisense` in the game folder.");
27
- }
28
-
29
- function kindOf(kind) {
30
- const map = {
31
- method: vscode.CompletionItemKind.Method,
32
- function: vscode.CompletionItemKind.Function,
33
- constructor: vscode.CompletionItemKind.Constructor,
34
- property: vscode.CompletionItemKind.Property,
35
- variable: vscode.CompletionItemKind.Variable,
36
- class: vscode.CompletionItemKind.Class,
37
- enum: vscode.CompletionItemKind.Enum,
38
- keyword: vscode.CompletionItemKind.Keyword,
39
- event: vscode.CompletionItemKind.Event,
40
- file: vscode.CompletionItemKind.File,
41
- };
42
- return map[kind] || vscode.CompletionItemKind.Text;
43
- }
44
-
45
- function activate(context) {
46
- let loaded;
47
- try {
48
- loaded = loadEngine(context);
49
- } catch (err) {
50
- vscode.window.showWarningMessage(String(err.message || err));
51
- return;
52
- }
53
-
54
- const selector = { language: "cpp", scheme: "file" };
55
- const diagnostics = vscode.languages.createDiagnosticCollection("cluaupp");
56
- context.subscriptions.push(diagnostics);
57
-
58
- const optionsFor = (document) => ({
59
- projectRoot: loaded.workspaceFolder || path.dirname(document.uri.fsPath),
60
- file: document.uri.fsPath,
61
- filePath: document.uri.fsPath,
62
- includeDirs: [
63
- path.dirname(document.uri.fsPath),
64
- path.join(loaded.workspaceFolder || "", "src"),
65
- path.join(loaded.workspaceFolder || "", "include"),
66
- ],
67
- });
68
-
69
- const refreshDiagnostics = (document) => {
70
- if (!document || document.languageId !== "cpp") {
71
- return;
72
- }
73
- const items = loaded.engine.diagnosticsFor(document.getText(), document.uri.fsPath, optionsFor(document));
74
- diagnostics.set(
75
- document.uri,
76
- items.map((item) => {
77
- const line = Math.max(0, (item.line || 1) - 1);
78
- const col = Math.max(0, (item.col || 1) - 1);
79
- const range = new vscode.Range(line, col, line, col + 1);
80
- return new vscode.Diagnostic(range, item.message, vscode.DiagnosticSeverity.Error);
81
- }),
82
- );
83
- };
84
-
85
- context.subscriptions.push(
86
- vscode.languages.registerCompletionItemProvider(
87
- selector,
88
- {
89
- provideCompletionItems(document, position) {
90
- const offset = document.offsetAt(position);
91
- const items = loaded.engine.completeAt(document.getText(), offset, optionsFor(document));
92
- return items.map((item) => {
93
- const completion = new vscode.CompletionItem(item.name, kindOf(item.kind));
94
- completion.detail = item.detail || item.type || "";
95
- completion.sortText = `${item.kind === "keyword" ? "2" : "0"}_${item.name}`;
96
- completion.insertText = item.name;
97
- return completion;
98
- });
99
- },
100
- },
101
- ".",
102
- ":",
103
- ">",
104
- "<",
105
- '"',
106
- "/",
107
- ),
108
- vscode.languages.registerHoverProvider(selector, {
109
- provideHover(document, position) {
110
- const hover = loaded.engine.hoverAt(document.getText(), document.offsetAt(position), optionsFor(document));
111
- if (!hover) {
112
- return null;
113
- }
114
- return new vscode.Hover(new vscode.MarkdownString(`**${hover.name}**\n\n\`${hover.detail || hover.type || ""}\``));
115
- },
116
- }),
117
- vscode.languages.registerDefinitionProvider(selector, {
118
- provideDefinition(document, position) {
119
- const def = loaded.engine.definitionAt(document.getText(), document.offsetAt(position), optionsFor(document));
120
- if (!def || !def.file) {
121
- return null;
122
- }
123
- return new vscode.Location(vscode.Uri.file(def.file), new vscode.Position(Math.max(0, (def.line || 1) - 1), 0));
124
- },
125
- }),
126
- vscode.workspace.onDidChangeTextDocument((event) => refreshDiagnostics(event.document)),
127
- vscode.workspace.onDidOpenTextDocument(refreshDiagnostics),
128
- vscode.commands.registerCommand("cluaupp.restartIntelliSense", () => {
129
- try {
130
- delete require.cache[require.resolve(path.join(loaded.root, "src", "intellisense.js"))];
131
- loaded = loadEngine(context);
132
- vscode.window.showInformationMessage("Cluaupp IntelliSense reloaded.");
133
- } catch (err) {
134
- vscode.window.showErrorMessage(String(err.message || err));
135
- }
136
- }),
137
- );
138
-
139
- for (const document of vscode.workspace.textDocuments) {
140
- refreshDiagnostics(document);
141
- }
142
- }
143
-
144
- function deactivate() {}
145
-
146
- module.exports = { activate, deactivate };
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const vscode = require("vscode");
6
+
7
+ function loadEngine(context) {
8
+ const folders = vscode.workspace.workspaceFolders || [];
9
+ const workspaceFolder = folders[0] ? folders[0].uri.fsPath : null;
10
+ const rootFile = path.join(context.extensionPath, "cluaupp.root");
11
+ const roots = [];
12
+ if (fs.existsSync(rootFile)) {
13
+ roots.push(fs.readFileSync(rootFile, "utf8").trim());
14
+ }
15
+ if (workspaceFolder) {
16
+ roots.push(path.join(workspaceFolder, "..", "Cluaupp"));
17
+ roots.push(path.join(workspaceFolder, "node_modules", "cluaupp"));
18
+ }
19
+ roots.push(path.join(context.extensionPath, "..", ".."));
20
+ for (const root of roots) {
21
+ const candidates = [
22
+ path.join(root, "generated", "intellisense.js"),
23
+ path.join(root, "src", "intellisense.js"),
24
+ ];
25
+ for (const engine of candidates) {
26
+ if (fs.existsSync(engine)) {
27
+ return { engine: require(engine), root, workspaceFolder, enginePath: engine };
28
+ }
29
+ }
30
+ }
31
+ throw new Error("Cluaupp diagnostics engine not found. Run `cluaupp intellisense` in the game folder.");
32
+ }
33
+
34
+ function activate(context) {
35
+ let loaded;
36
+ try {
37
+ loaded = loadEngine(context);
38
+ } catch (err) {
39
+ vscode.window.showWarningMessage(String(err.message || err));
40
+ return;
41
+ }
42
+
43
+ const diagnostics = vscode.languages.createDiagnosticCollection("cluaupp");
44
+ context.subscriptions.push(diagnostics);
45
+
46
+ const optionsFor = (document) => ({
47
+ projectRoot: loaded.workspaceFolder || path.dirname(document.uri.fsPath),
48
+ file: document.uri.fsPath,
49
+ filePath: document.uri.fsPath,
50
+ includeDirs: [
51
+ path.dirname(document.uri.fsPath),
52
+ path.join(loaded.workspaceFolder || "", "src"),
53
+ path.join(loaded.workspaceFolder || "", "include"),
54
+ ],
55
+ });
56
+
57
+ const refreshDiagnostics = (document) => {
58
+ if (!document || document.languageId !== "cpp") {
59
+ return;
60
+ }
61
+ if (typeof loaded.engine.diagnosticsFor !== "function") {
62
+ return;
63
+ }
64
+ const items = loaded.engine.diagnosticsFor(document.getText(), document.uri.fsPath, optionsFor(document));
65
+ diagnostics.set(
66
+ document.uri,
67
+ items.map((item) => {
68
+ const line = Math.max(0, (item.line || 1) - 1);
69
+ const col = Math.max(0, (item.col || 1) - 1);
70
+ const range = new vscode.Range(line, col, line, col + 1);
71
+ return new vscode.Diagnostic(range, item.message, vscode.DiagnosticSeverity.Error);
72
+ }),
73
+ );
74
+ };
75
+
76
+ context.subscriptions.push(
77
+ vscode.workspace.onDidChangeTextDocument((event) => refreshDiagnostics(event.document)),
78
+ vscode.workspace.onDidOpenTextDocument(refreshDiagnostics),
79
+ vscode.commands.registerCommand("cluaupp.restartIntelliSense", () => {
80
+ try {
81
+ delete require.cache[require.resolve(loaded.enginePath)];
82
+ loaded = loadEngine(context);
83
+ vscode.window.showInformationMessage("Cluaupp diagnostics reloaded. C++ completion is clangd.");
84
+ } catch (err) {
85
+ vscode.window.showErrorMessage(String(err.message || err));
86
+ }
87
+ }),
88
+ );
89
+
90
+ for (const document of vscode.workspace.textDocuments) {
91
+ refreshDiagnostics(document);
92
+ }
93
+ }
94
+
95
+ function deactivate() {}
96
+
97
+ module.exports = { activate, deactivate };
@@ -1,14 +1,14 @@
1
1
  {
2
- "name": "cluaupp-intellisense",
3
- "displayName": "Cluaupp IntelliSense",
4
- "description": "Completions, hover, and go-to-definition for Cluaupp C++ (Roblox APIs, DataService paths, project structs).",
5
- "version": "0.1.4",
2
+ "name": "cluaupp-diagnostics",
3
+ "displayName": "Cluaupp",
4
+ "description": "Cluaupp subset parse errors. C++ completion, hover, and go-to-definition come from clangd + include/cluaupp/roblox.hpp.",
5
+ "version": "0.2.0",
6
6
  "publisher": "kartzdev",
7
7
  "engines": {
8
8
  "vscode": "^1.74.0"
9
9
  },
10
10
  "categories": [
11
- "Programming Languages"
11
+ "Linters"
12
12
  ],
13
13
  "activationEvents": [
14
14
  "onLanguage:cpp"
@@ -18,7 +18,7 @@
18
18
  "commands": [
19
19
  {
20
20
  "command": "cluaupp.restartIntelliSense",
21
- "title": "Cluaupp: Restart IntelliSense"
21
+ "title": "Cluaupp: Reload subset diagnostics"
22
22
  }
23
23
  ]
24
24
  }
@@ -0,0 +1,18 @@
1
+ # Sample game
2
+
3
+ This is the C++ a Cluaupp game looks like — **not** the compiler.
4
+
5
+ | Folder | Rojo | Tag |
6
+ | --- | --- | --- |
7
+ | `src/server/*.server.cpp` | Script | server |
8
+ | `src/client/*.client.cpp` | LocalScript | client |
9
+ | `src/shared/*` | ModuleScript | none |
10
+
11
+ `src/` of **this repo** is the TypeScript CLI ([roblox-ts](https://github.com/roblox-ts/roblox-ts) does the same). The sample scripts live here so they never mix with `understand.ts`.
12
+
13
+ ```bash
14
+ cd examples/game
15
+ npx cluaupp build .
16
+ ```
17
+
18
+ `cluaupp init` copies `templates/game` (the slim scaffold). This folder adds combat / HUD so `SystemUnderstander` has real tokens to score.
@@ -0,0 +1,25 @@
1
+ CompileFlags:
2
+ CompilationDatabase: .
3
+ Add:
4
+ - -xc++
5
+ - -std=c++20
6
+ - -ferror-limit=0
7
+ - -Iinclude
8
+ - -Isrc
9
+ - -I../../include
10
+
11
+ Diagnostics:
12
+ Suppress: '*'
13
+
14
+ ---
15
+ If:
16
+ PathMatch: .*\.(cpp|cc|cxx|c|h|hpp|hh)$
17
+ CompileFlags:
18
+ Add:
19
+ - -xc++
20
+
21
+ ---
22
+ If:
23
+ PathMatch: (out|libs)/.*
24
+ Index:
25
+ Background: Skip