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.
- package/CHANGELOG.md +12 -0
- package/README.md +6 -1
- package/bin/cluau.js +1 -1
- package/bin/cluaupp.js +1 -1
- package/docs/architecture.md +26 -1
- package/docs/cli.md +27 -6
- package/docs/examples/index.md +2 -0
- package/docs/getting-started.md +5 -4
- package/docs/intellisense.md +49 -31
- package/docs/intro.md +1 -1
- package/editors/vscode/extension.js +97 -146
- package/editors/vscode/package.json +6 -6
- package/examples/README.md +18 -0
- package/examples/game/.clangd +25 -0
- package/examples/game/.vscode/c_cpp_properties.json +27 -0
- package/examples/game/.vscode/extensions.json +5 -0
- package/examples/game/.vscode/settings.json +27 -0
- package/examples/game/Packages/.gitkeep +0 -0
- package/examples/game/cluaupp.config.json +6 -0
- package/examples/game/compile_flags.txt +6 -0
- package/examples/game/default.project.json +39 -0
- package/examples/game/package.json +9 -0
- package/examples/game/rokit.toml +5 -0
- package/examples/game/src/client/hud.client.cpp +12 -0
- package/{src → examples/game/src}/client/init.client.cpp +1 -0
- package/examples/game/src/server/combat.server.cpp +23 -0
- package/{src → examples/game/src}/server/leaderstats.server.cpp +1 -0
- package/examples/game/wally.toml +11 -0
- package/generated/api.js +51 -0
- package/generated/architecture.js +473 -0
- package/generated/ast.js +2 -0
- package/generated/cli.js +191 -0
- package/generated/compile.js +115 -0
- package/generated/editor-install.js +170 -0
- package/generated/emit.js +503 -0
- package/generated/emitter/luau-codegen.js +167 -0
- package/generated/emitter/translators.js +164 -0
- package/generated/headers.js +220 -0
- package/generated/index.html +49 -0
- package/generated/intellisense.js +277 -0
- package/generated/layout.js +112 -0
- package/generated/lex.js +146 -0
- package/generated/libs.js +484 -0
- package/generated/lsp.js +55 -0
- package/generated/package-info.js +11 -0
- package/generated/parse.js +607 -0
- package/generated/parser/collector.js +100 -0
- package/generated/parser/index.js +30 -0
- package/generated/preprocess.js +181 -0
- package/generated/system-understander.js +443 -0
- package/generated/transpile.js +66 -0
- package/generated/types.js +2 -0
- package/generated/understand.js +298 -0
- package/generated/utils/process-orchestrator.js +63 -0
- package/generated/utils/project.js +491 -0
- package/generated/utils/rojo-mapper.js +181 -0
- package/generated/utils/safe-paths.js +104 -0
- package/package.json +25 -8
- package/src/api.ts +53 -0
- package/src/{architecture.js → architecture.ts} +9 -10
- package/src/ast.ts +37 -0
- package/src/cli.ts +214 -0
- package/src/compile.ts +118 -0
- package/src/editor-install.ts +182 -0
- package/src/{emit.js → emit.ts} +4 -5
- package/src/emitter/luau-codegen.ts +187 -0
- package/src/emitter/translators.ts +168 -0
- package/src/{headers.js → headers.ts} +4 -5
- package/src/intellisense.ts +286 -0
- package/src/{layout.js → layout.ts} +114 -129
- package/src/{lex.js → lex.ts} +4 -6
- package/src/{libs.js → libs.ts} +9 -4
- package/src/lsp.ts +60 -0
- package/src/package-info.ts +7 -0
- package/src/{parse.js → parse.ts} +3 -4
- package/src/parser/collector.ts +115 -0
- package/src/parser/index.ts +27 -0
- package/src/{preprocess.js → preprocess.ts} +22 -37
- package/src/system-understander.ts +501 -0
- package/src/transpile.ts +64 -0
- package/src/tree-sitter-cpp.d.ts +4 -0
- package/src/types.ts +81 -0
- package/src/{understand.js → understand.ts} +19 -210
- package/src/utils/process-orchestrator.ts +72 -0
- package/src/utils/project.ts +506 -0
- package/src/utils/rojo-mapper.ts +190 -0
- package/src/utils/safe-paths.ts +98 -0
- package/templates/game/.clangd +9 -0
- package/templates/game/.vscode/c_cpp_properties.json +1 -1
- package/templates/game/.vscode/extensions.json +5 -6
- package/templates/game/.vscode/settings.json +7 -6
- package/templates/game/compile_flags.txt +1 -0
- package/templates/game/rokit.toml +5 -0
- package/src/api.js +0 -57
- package/src/cli.js +0 -473
- package/src/compile.js +0 -110
- package/src/editor-install.js +0 -218
- package/src/intellisense.js +0 -1368
- package/src/lsp.js +0 -227
- /package/{src → examples/game/src}/shared/config.cpp +0 -0
- /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
package/bin/cluaupp.js
CHANGED
package/docs/architecture.md
CHANGED
|
@@ -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 < 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
|
|
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
|
|
29
|
-
- `#include "file.h"` becomes `require(
|
|
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
|
|
68
|
-
npm
|
|
69
|
-
npm run
|
|
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
|
```
|
package/docs/examples/index.md
CHANGED
|
@@ -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
|
package/docs/getting-started.md
CHANGED
|
@@ -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
|
-
-
|
|
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
|
|
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
|
|
package/docs/intellisense.md
CHANGED
|
@@ -1,31 +1,49 @@
|
|
|
1
|
-
# IntelliSense
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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-
|
|
3
|
-
"displayName": "Cluaupp
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "0.
|
|
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
|
-
"
|
|
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:
|
|
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
|