cluaupp 0.1.4 → 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 +21 -0
- package/README.md +12 -7
- package/bin/cluau.js +1 -1
- package/bin/cluaupp.js +1 -1
- package/docs/README.md +1 -1
- package/docs/architecture.md +52 -77
- package/docs/cli.md +29 -9
- package/docs/comparison.md +3 -3
- package/docs/config.md +6 -6
- package/docs/cpp-organization.md +2 -2
- package/docs/examples/index.md +2 -0
- package/docs/getting-started.md +7 -5
- package/docs/intellisense.md +49 -31
- package/docs/intro.md +2 -2
- package/docs/oop/file-tags.md +16 -17
- package/docs/oop/index.md +2 -2
- package/docs/oop/modules.md +3 -1
- package/docs/oop/services.md +7 -14
- package/docs/syntax.md +6 -5
- 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} +80 -33
- 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} +5 -6
- package/src/emitter/luau-codegen.ts +187 -0
- package/src/emitter/translators.ts +168 -0
- package/src/headers.ts +233 -0
- 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} +119 -46
- 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} +64 -32
- 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} +24 -213
- 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/cluaupp.config.json +2 -2
- package/templates/game/compile_flags.txt +1 -0
- package/templates/game/rokit.toml +5 -0
- package/templates/game/src/client/init.client.cpp +1 -0
- package/templates/game/src/server/leaderstats.server.cpp +1 -0
- package/src/api.js +0 -57
- package/src/cli.js +0 -481
- package/src/compile.js +0 -56
- 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/docs/oop/file-tags.md
CHANGED
|
@@ -16,34 +16,33 @@ The **filename** decides the Roblox instance. This is the same key idea as roblo
|
|
|
16
16
|
| `Boot.legacy.server.cpp` | Script | **Legacy** |
|
|
17
17
|
| `Boot.legacy.client.cpp` | LocalScript | Legacy |
|
|
18
18
|
| `Damage.cpp` (no tag) | **ModuleScript** | — |
|
|
19
|
+
| `LeaderstatsServer.h` | **ModuleScript** (types) | — |
|
|
20
|
+
| `LeaderstatsServer.cpp` (sibling of `.h`) | **ModuleScript** (`*Impl`) | — |
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## One file in, one file out
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
Rojo infers the instance from the filename key: `*.server.luau` is a Script, `*.client.luau` is a LocalScript, untagged `.luau` is a ModuleScript.
|
|
23
25
|
|
|
24
26
|
```
|
|
25
|
-
out/server/
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
src/server/boot/DataBoot.server.cpp → out/server/boot/DataBoot.server.luau
|
|
28
|
+
src/client/boot/DataBoot.client.cpp → out/client/boot/DataBoot.client.luau
|
|
29
|
+
src/shared/damage.cpp → out/shared/Damage.luau
|
|
30
|
+
src/server/services/leaderstats/LeaderstatsServer.h → LeaderstatsServer.luau (export type)
|
|
31
|
+
src/server/services/leaderstats/LeaderstatsServer.cpp → LeaderstatsServerImpl.luau
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
`.legacy.server.cpp`
|
|
31
|
-
|
|
32
|
-
`.client.cpp` stays `init.client.luau` (LocalScript). Do not add `init.meta.json` on the client boot.
|
|
34
|
+
`.legacy.server.cpp` still emits a Legacy Script (`boot.server.luau`). `.client.cpp` stays a LocalScript. Do not invent `init.meta.json` on the default 1:1 path.
|
|
33
35
|
|
|
34
36
|
## Where files live
|
|
35
37
|
|
|
36
38
|
```
|
|
37
|
-
src/server/.../*.server.cpp → out/server (ServerScriptService)
|
|
38
|
-
src/client/.../*.client.cpp → out/client (StarterPlayerScripts)
|
|
39
|
-
src/shared/.../*.cpp → out/shared (ReplicatedStorage)
|
|
39
|
+
src/server/.../*.server.cpp → out/server (ServerScriptService.Cluaupp)
|
|
40
|
+
src/client/.../*.client.cpp → out/client (StarterPlayerScripts.Cluaupp)
|
|
41
|
+
src/shared/.../*.cpp → out/shared (ReplicatedStorage.Cluaupp)
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
Name the **system**, not `init.server.cpp`. `LeaderstatsServer.server.cpp` and `DataBoot.server.cpp` are two
|
|
43
|
-
|
|
44
|
-
## Skip the planner
|
|
44
|
+
Name the **system**, not `init.server.cpp`. `LeaderstatsServer.server.cpp` and `DataBoot.server.cpp` are two files.
|
|
45
45
|
|
|
46
|
-
-
|
|
47
|
-
- `.legacy.server.cpp` / `.legacy.client.cpp` per file
|
|
46
|
+
## Opt-in planner
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
`"architecture": true` in `cluaupp.config.json` restores PascalCase service folders (`Main`, Controller, Types). Default is off.
|
package/docs/oop/index.md
CHANGED
|
@@ -11,12 +11,12 @@ The **live site** (not just these markdown files) is GitHub Pages:
|
|
|
11
11
|
- [Guide → OOP](https://kartzrbx.github.io/Cluaupp/guide/oop.html)
|
|
12
12
|
- [Examples](https://kartzrbx.github.io/Cluaupp/guide/examples.html)
|
|
13
13
|
|
|
14
|
-
Cluaupp does **not** compile custom C++ `class` types yet. “OOP” here is how you **lay out systems** so Studio gets
|
|
14
|
+
Cluaupp does **not** compile custom C++ `class` types yet. “OOP” here is how you **lay out systems** so Studio gets Script / LocalScript / ModuleScript from the filename tag — the same idea as roblox-ts. Flamework-style Start/Stop folders are opt-in (`"architecture": true`).
|
|
15
15
|
|
|
16
16
|
| Page | What you learn |
|
|
17
17
|
| --- | --- |
|
|
18
18
|
| [File tags](file-tags.md) | `.server` / `.client` / `.plugin` / `.legacy` / untagged |
|
|
19
|
-
| [Services](services.md) | One `.server.cpp` →
|
|
19
|
+
| [Services](services.md) | One `.server.cpp` → one `.server.luau` |
|
|
20
20
|
| [Modules](modules.md) | Untagged files, structs, named functions as methods |
|
|
21
21
|
|
|
22
22
|
Planner details: [Architecture](../architecture.md). Folder layout: [Organization](../cpp-organization.md). Full services: [Examples](../examples/index.md).
|
package/docs/oop/modules.md
CHANGED
|
@@ -25,7 +25,9 @@ int DoubleCoins(int coins) {
|
|
|
25
25
|
out/shared/util/Coins.luau -- ModuleScript, exported functions
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Quoted `#include "TemplateData.hpp"` is not inlined when the header has a sibling `.cpp` or is a shared module: `cluaupp build` emits `require(ReplicatedStorage.Cluaupp.constants.TemplateData)` / `require(ServerScriptService.Cluaupp.configurations.PlayerDataVersion)` (Rojo roots from `default.project.json`), never `script.Parent.Parent.shared`.
|
|
29
|
+
|
|
30
|
+
`.h` / `.hpp` are **type modules**. A service header becomes `export type Name = { init: (self: Name) -> (), … }` and a typed table. The sibling `.cpp` is the construction (`NameImpl.luau`); the header `require`s that impl and binds the functions. Data-only structs still emit a constructor so `TemplateData()` works. Untagged `.cpp` without a header is a ModuleScript other Luau can `require`. Prefer headers for the public type, tagged `.server.cpp` / `.client.cpp` for scripts, and the sibling `.cpp` for method bodies.
|
|
29
31
|
|
|
30
32
|
## Structs = data, not classes
|
|
31
33
|
|
package/docs/oop/services.md
CHANGED
|
@@ -5,7 +5,7 @@ sidebar_position: 3
|
|
|
5
5
|
|
|
6
6
|
# Services
|
|
7
7
|
|
|
8
|
-
Write **one tagged file per system**. Cluaupp
|
|
8
|
+
Write **one tagged file per system**. Cluaupp emits **one** Luau instance: `LeaderstatsServer.server.luau` from `LeaderstatsServer.server.cpp`. It does not invent Main / Controller / Types unless `"architecture": true`.
|
|
9
9
|
|
|
10
10
|
## Example: leaderstats
|
|
11
11
|
|
|
@@ -44,29 +44,22 @@ void init() {
|
|
|
44
44
|
Typical output:
|
|
45
45
|
|
|
46
46
|
```
|
|
47
|
-
out/server/LeaderstatsServer
|
|
48
|
-
init.luau -- Script, RunContext Server
|
|
49
|
-
init.meta.json
|
|
50
|
-
Main.luau -- Start / Stop
|
|
51
|
-
PlayersManager.luau -- PlayerAdded + Janitor
|
|
52
|
-
DataController.luau -- your WaitFor / GetChangedSignal
|
|
53
|
-
CacheController.luau -- if you create IntValue folders
|
|
54
|
-
LeaderstatsServerTypes.luau
|
|
47
|
+
out/server/services/leaderstats/LeaderstatsServer.server.luau
|
|
55
48
|
```
|
|
56
49
|
|
|
57
|
-
Your functions stay in
|
|
50
|
+
Your functions stay in that file. `init()` runs at the end. There is no fake `Main` that only forwards to a Controller.
|
|
58
51
|
|
|
59
52
|
## Lifecycle
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
You own `init` and Janitor cleanup in the same file. You do not write `class LeaderstatsServer` — name the **file** `LeaderstatsServer.server.cpp` and keep **functions** as the public API.
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
`"architecture": true` is the old ForeverHD split (`Main.Start` / `Main.Stop`, Managers, Types). Leave it off unless you want that.
|
|
64
57
|
|
|
65
58
|
## Boot vs gameplay
|
|
66
59
|
|
|
67
60
|
Keep DataService `Init` in `DataBoot.server.cpp` / `DataBoot.client.cpp`. Keep leaderstats / combat in their own `.server.cpp`. Services `WaitFor` after boot has run.
|
|
68
61
|
|
|
69
|
-
##
|
|
62
|
+
## Opt-in roles (`"architecture": true`)
|
|
70
63
|
|
|
71
64
|
| Your C++ | Generated role |
|
|
72
65
|
| --- | --- |
|
|
@@ -78,6 +71,6 @@ Keep DataService `Init` in `DataBoot.server.cpp` / `DataBoot.client.cpp`. Keep l
|
|
|
78
71
|
| `UserInputService` | `InputController` |
|
|
79
72
|
| wiring | `Main.Start` / `Main.Stop` |
|
|
80
73
|
|
|
81
|
-
A tiny `print` in `init.client.cpp` stays a single LocalScript.
|
|
74
|
+
A tiny `print` in `init.client.cpp` stays a single LocalScript.
|
|
82
75
|
|
|
83
76
|
Copy-paste: [Examples](../examples/index.md).
|
package/docs/syntax.md
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Cluaupp is not a full C++ compiler. It is a **subset** aimed at Roblox scripts, in the same spirit as roblox-ts (restricted TypeScript → Luau).
|
|
4
4
|
|
|
5
|
-
Generated Luau follows the current language: [
|
|
5
|
+
Generated Luau follows the current language: [`local`](https://luau.org/getting-started), `const`, and `const function`. Injected `require` / `GetService` lines are `const`. `--!strict` is emitted only when the file has `#pragma strict` (or `"strict": true` in config).
|
|
6
6
|
|
|
7
7
|
## Files
|
|
8
8
|
|
|
9
9
|
- Extensions: `.cpp`, `.h`, `.hpp` (also `.cc`, `.hh`)
|
|
10
|
-
- Quoted `#include "file.h"` is inlined
|
|
10
|
+
- Quoted `#include "file.h"` becomes a Rojo `require` (or is inlined for a header that belongs to the same `.cpp`)
|
|
11
11
|
- `#include <cluaupp/roblox.hpp>` and `<cluaupp/libs/*.hpp>` are IntelliSense only; library headers also inject `require(CluauppLibs.*)`
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- `#pragma once` is ignored
|
|
13
|
+
- `#pragma strict` / `#pragma nstrict` control `--!strict` for that compilation unit
|
|
14
|
+
- Function prototypes in a `.h` / `.hpp` become `export type` fields (`init: (self: Name) -> ()`). Only `.cpp` files emit function bodies.
|
|
14
15
|
|
|
15
16
|
## Functions
|
|
16
17
|
|
|
@@ -199,6 +200,6 @@ Full table and IntelliSense notes: [print and cout](print-cout.md).
|
|
|
199
200
|
|
|
200
201
|
## Not supported yet
|
|
201
202
|
|
|
202
|
-
Custom C++ classes, generic templates besides `GetService<T>`, pointer arithmetic, `std::`, overloading, macros (except
|
|
203
|
+
Custom C++ classes, generic templates besides `GetService<T>`, pointer arithmetic, `std::`, overloading, macros (except `#pragma strict` / `#pragma nstrict` / `#pragma once`).
|
|
203
204
|
|
|
204
205
|
If you need one of those patterns, open an issue with the C++ and the expected Luau.
|
|
@@ -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
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configurations": [
|
|
3
|
+
{
|
|
4
|
+
"name": "Cluaupp",
|
|
5
|
+
"compilerPath": "clang++",
|
|
6
|
+
"cStandard": "c17",
|
|
7
|
+
"cppStandard": "c++20",
|
|
8
|
+
"intelliSenseMode": "windows-clang-x64",
|
|
9
|
+
"includePath": [
|
|
10
|
+
"${workspaceFolder}/include",
|
|
11
|
+
"${workspaceFolder}/src"
|
|
12
|
+
],
|
|
13
|
+
"forcedInclude": [
|
|
14
|
+
"${workspaceFolder}/include/cluaupp/roblox.hpp"
|
|
15
|
+
],
|
|
16
|
+
"compileCommands": "${workspaceFolder}/compile_commands.json",
|
|
17
|
+
"browse": {
|
|
18
|
+
"path": [
|
|
19
|
+
"${workspaceFolder}/include",
|
|
20
|
+
"${workspaceFolder}/src"
|
|
21
|
+
],
|
|
22
|
+
"limitSymbolsToIncludedHeaders": true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"version": 4
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"C_Cpp.intelliSenseEngine": "Disabled",
|
|
3
|
+
"C_Cpp.default.cppStandard": "c++20",
|
|
4
|
+
"C_Cpp.default.cStandard": "c17",
|
|
5
|
+
"C_Cpp.default.compilerPath": "clang++",
|
|
6
|
+
"C_Cpp.default.intelliSenseMode": "windows-clang-x64",
|
|
7
|
+
"C_Cpp.default.includePath": [
|
|
8
|
+
"${workspaceFolder}/include",
|
|
9
|
+
"${workspaceFolder}/src"
|
|
10
|
+
],
|
|
11
|
+
"clangd.enable": true,
|
|
12
|
+
"clangd.arguments": [
|
|
13
|
+
"--compile-commands-dir=${workspaceFolder}",
|
|
14
|
+
"--header-insertion=never",
|
|
15
|
+
"--query-driver=**/clang++*,**/clang++.exe,**/g++*,**/g++.exe"
|
|
16
|
+
],
|
|
17
|
+
"files.associations": {
|
|
18
|
+
"*.hpp": "cpp",
|
|
19
|
+
"*.h": "cpp",
|
|
20
|
+
"*.server.cpp": "cpp",
|
|
21
|
+
"*.client.cpp": "cpp",
|
|
22
|
+
"*.plugin.cpp": "cpp",
|
|
23
|
+
"*.legacy.cpp": "cpp",
|
|
24
|
+
"*.legacy.server.cpp": "cpp",
|
|
25
|
+
"*.legacy.client.cpp": "cpp"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cluaupp-game",
|
|
3
|
+
"tree": {
|
|
4
|
+
"$className": "DataModel",
|
|
5
|
+
"ServerScriptService": {
|
|
6
|
+
"$className": "ServerScriptService",
|
|
7
|
+
"Cluaupp": {
|
|
8
|
+
"$path": "out/server"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"ReplicatedStorage": {
|
|
12
|
+
"$className": "ReplicatedStorage",
|
|
13
|
+
"Cluaupp": {
|
|
14
|
+
"$path": "out/shared"
|
|
15
|
+
},
|
|
16
|
+
"CluauppLibs": {
|
|
17
|
+
"$path": "libs"
|
|
18
|
+
},
|
|
19
|
+
"Packages": {
|
|
20
|
+
"$path": "Packages"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"StarterPlayer": {
|
|
24
|
+
"$className": "StarterPlayer",
|
|
25
|
+
"StarterPlayerScripts": {
|
|
26
|
+
"$className": "StarterPlayerScripts",
|
|
27
|
+
"Cluaupp": {
|
|
28
|
+
"$path": "out/client"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"HttpService": {
|
|
33
|
+
"$className": "HttpService",
|
|
34
|
+
"$properties": {
|
|
35
|
+
"HttpEnabled": true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#pragma strict
|
|
2
|
+
#include <cluaupp/roblox.hpp>
|
|
3
|
+
|
|
4
|
+
void init() {
|
|
5
|
+
auto* playerGui = GetService<Players>()->LocalPlayer->FindFirstChild("PlayerGui");
|
|
6
|
+
auto* screen = new ScreenGui();
|
|
7
|
+
screen->Name = "Hud";
|
|
8
|
+
auto* coins = new TextLabel();
|
|
9
|
+
coins->Name = "Coins";
|
|
10
|
+
coins->Parent = screen;
|
|
11
|
+
print("hud ready");
|
|
12
|
+
}
|