cluaupp 1.4.0 → 1.5.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 +13 -0
- package/README.md +2 -2
- package/editors/vscode/README.md +17 -0
- package/editors/vscode/extension.js +140 -21
- package/editors/vscode/icons/flare.svg +5 -0
- package/editors/vscode/language-configuration.json +21 -0
- package/editors/vscode/package.json +61 -7
- package/editors/vscode/snippets/flare.json +27 -0
- package/editors/vscode/syntaxes/flare.tmLanguage.json +75 -0
- package/examples/game/.vscode/extensions.json +3 -1
- package/examples/game/.vscode/settings.json +2 -1
- package/examples/game/include/clpp/libs/roster.clh +6 -0
- package/examples/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
- package/examples/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
- package/generated/cli.js +3 -3
- package/generated/flare/index.js +15 -3
- package/generated/flare/language.js +561 -0
- package/generated/flare/parse.js +7 -6
- package/generated/intellisense.js +20 -2
- package/generated/lsp.js +118 -7
- package/include/clpp/libs/roster.clh +6 -0
- package/package.json +1 -1
- package/runtime/Roster/init.luau +6 -0
- package/src/cli.ts +3 -3
- package/src/flare/index.ts +20 -1
- package/src/flare/language.ts +708 -0
- package/src/flare/parse.ts +6 -6
- package/src/intellisense.ts +19 -2
- package/src/lsp.ts +151 -8
- package/templates/game/.vscode/extensions.json +3 -1
- package/templates/game/.vscode/settings.json +2 -1
- package/templates/game/include/clpp/libs/roster.clh +6 -0
- package/templates/game/src/ReplicatedStorage/Shared/Net/Net.flare +5 -0
- package/templates/game/src/ServerScriptService/Boot/DataBoot.server.clpp +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 1.5.0
|
|
6
|
+
|
|
7
|
+
- **Flare IntelliSense** — VS Code / Cursor extension for `.flare` (highlighting, completions, hover, diagnostics, outline, snippets). `cluaupp intellisense` installs it; `cluaupp lsp` serves the same engine.
|
|
8
|
+
- **Roster** constructor is `new Roster()` / `new Roster(table)` (emits Luau `Roster.new`). `Find` is array search; dictionary keys use `Has` / `Set` / `Remove`.
|
|
9
|
+
- Init DataBoot builds `PlayerTemplate playerData = PlayerTemplate()` so Keep.Server.Init receives a table. Prefer CL++ **0.3.4** for nested template types and `Roster.new`.
|
|
10
|
+
|
|
11
|
+
## 1.4.1
|
|
12
|
+
|
|
13
|
+
- **`cluaupp init --help`** names the 1.4.0 service tree (`ReplicatedStorage`, `ServerScriptService`, `StarterPlayer`), not `src/server` / `src/client` / `src/shared`.
|
|
14
|
+
- Handbook: Flare **Ready / Welcome / Session** handshake, Connection example, and leftover CLI/path pages aligned with the service layout.
|
|
15
|
+
|
|
3
16
|
## 1.4.0
|
|
4
17
|
|
|
5
18
|
- **Init** writes a Roblox service tree (`ServerScriptService`, `ReplicatedStorage/Shared`, `StarterPlayer`, `ServerStorage`, `ReplicatedFirst`) with DataBoot + TemplateData. Breaking: no more `src/server` / `src/client` / `src/shared`.
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ void init() {
|
|
|
48
48
|
3. **`clpp` 0.3.2** on PATH from [CL++](https://github.com/KartzRbx/CLPP/releases/tag/v0.3.2) (`clpp-setup.exe` or `clpp setup`). Do not leave a cargo `clpp 0.1.0` first on PATH.
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
npm install -g cluaupp
|
|
51
|
+
npm install -g cluaupp@latest
|
|
52
52
|
clpp setup
|
|
53
53
|
npx cluaupp init my-game
|
|
54
54
|
cd my-game
|
|
@@ -71,7 +71,7 @@ cluaupp init [folder]
|
|
|
71
71
|
cluaupp build [folder]
|
|
72
72
|
cluaupp watch [folder]
|
|
73
73
|
cluaupp language # clpp api manifest
|
|
74
|
-
cluaupp intellisense #
|
|
74
|
+
cluaupp intellisense # Flare extension + clpp setup
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
`clpp` missing? Set `CLPP` / `CLPP_PATH` or install [CL++ 0.3.2](https://github.com/KartzRbx/CLPP/releases/tag/v0.3.2).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Cluaupp Flare
|
|
2
|
+
|
|
3
|
+
VS Code / Cursor language support for Cluaupp `.flare` schemas.
|
|
4
|
+
|
|
5
|
+
Installed by `cluaupp intellisense` into `~/.cursor/extensions` and `~/.vscode/extensions`.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Syntax highlighting (`packet`, `query`, types, `from Client|Server`)
|
|
10
|
+
- Completions and snippets (packet from Client/Server, query, `opt name`)
|
|
11
|
+
- Hover on types, keywords, and declared packets/queries (generated `Fire` / `Invoke` API)
|
|
12
|
+
- Live diagnostics from the same parser `cluaupp build` uses
|
|
13
|
+
- Outline (document symbols)
|
|
14
|
+
- Signature help inside `(Type name, …)`
|
|
15
|
+
- Quick fix when a type is misspelled
|
|
16
|
+
|
|
17
|
+
CL++ (`.clpp` / `.clp` / `.clh`) highlighting still comes from `clpp setup`.
|
|
@@ -4,7 +4,27 @@ const fs = require("fs");
|
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const vscode = require("vscode");
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const KIND = {
|
|
8
|
+
keyword: vscode.CompletionItemKind.Keyword,
|
|
9
|
+
type: vscode.CompletionItemKind.TypeParameter,
|
|
10
|
+
snippet: vscode.CompletionItemKind.Snippet,
|
|
11
|
+
value: vscode.CompletionItemKind.EnumMember,
|
|
12
|
+
field: vscode.CompletionItemKind.Field,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const SEVERITY = {
|
|
16
|
+
error: vscode.DiagnosticSeverity.Error,
|
|
17
|
+
warning: vscode.DiagnosticSeverity.Warning,
|
|
18
|
+
hint: vscode.DiagnosticSeverity.Hint,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const SYMBOL = {
|
|
22
|
+
packet: vscode.SymbolKind.Event,
|
|
23
|
+
query: vscode.SymbolKind.Method,
|
|
24
|
+
option: vscode.SymbolKind.Namespace,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function loadLanguage(context) {
|
|
8
28
|
const folders = vscode.workspace.workspaceFolders || [];
|
|
9
29
|
const workspaceFolder = folders[0] ? folders[0].uri.fsPath : null;
|
|
10
30
|
const rootFile = path.join(context.extensionPath, "cluaupp.root");
|
|
@@ -17,55 +37,154 @@ function loadEngine(context) {
|
|
|
17
37
|
roots.push(path.join(workspaceFolder, "node_modules", "cluaupp"));
|
|
18
38
|
}
|
|
19
39
|
roots.push(path.join(context.extensionPath, "..", ".."));
|
|
40
|
+
roots.push(path.join(context.extensionPath, "..", "..", ".."));
|
|
20
41
|
for (const root of roots) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
];
|
|
25
|
-
for (const engine of candidates) {
|
|
26
|
-
if (fs.existsSync(engine)) {
|
|
27
|
-
return { engine: require(engine), root, workspaceFolder, enginePath: engine };
|
|
28
|
-
}
|
|
42
|
+
const engine = path.join(root, "generated", "flare", "language.js");
|
|
43
|
+
if (fs.existsSync(engine)) {
|
|
44
|
+
return { language: require(engine), root, enginePath: engine };
|
|
29
45
|
}
|
|
30
46
|
}
|
|
31
|
-
throw new Error("Cluaupp
|
|
47
|
+
throw new Error("Cluaupp Flare language engine not found. Run `cluaupp intellisense` from a Cluaupp install.");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isFlareDoc(document) {
|
|
51
|
+
if (!document) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (document.languageId === "flare") {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return document.uri.fsPath.toLowerCase().endsWith(".flare");
|
|
32
58
|
}
|
|
33
59
|
|
|
34
60
|
function activate(context) {
|
|
35
61
|
let loaded;
|
|
36
62
|
try {
|
|
37
|
-
loaded =
|
|
63
|
+
loaded = loadLanguage(context);
|
|
38
64
|
} catch (err) {
|
|
39
65
|
vscode.window.showWarningMessage(String(err.message || err));
|
|
40
66
|
return;
|
|
41
67
|
}
|
|
42
68
|
|
|
43
|
-
const
|
|
44
|
-
context.subscriptions.push(
|
|
69
|
+
const collection = vscode.languages.createDiagnosticCollection("flare");
|
|
70
|
+
context.subscriptions.push(collection);
|
|
71
|
+
|
|
72
|
+
const selector = [{ language: "flare", scheme: "file" }, { pattern: "**/*.flare", scheme: "file" }];
|
|
45
73
|
|
|
46
|
-
const
|
|
47
|
-
if (!document
|
|
74
|
+
const refresh = (document) => {
|
|
75
|
+
if (!isFlareDoc(document)) {
|
|
48
76
|
return;
|
|
49
77
|
}
|
|
50
|
-
diagnostics.
|
|
78
|
+
const diagnostics = loaded.language.diagnoseFlare(document.getText(), document.uri.fsPath).map((item) => {
|
|
79
|
+
const range = new vscode.Range(item.line, item.start, item.line, Math.max(item.end, item.start + 1));
|
|
80
|
+
const diagnostic = new vscode.Diagnostic(range, item.message, SEVERITY[item.severity] ?? vscode.DiagnosticSeverity.Error);
|
|
81
|
+
diagnostic.source = "flare";
|
|
82
|
+
return diagnostic;
|
|
83
|
+
});
|
|
84
|
+
collection.set(document.uri, diagnostics);
|
|
51
85
|
};
|
|
52
86
|
|
|
53
87
|
context.subscriptions.push(
|
|
54
|
-
vscode.workspace.onDidOpenTextDocument(
|
|
88
|
+
vscode.workspace.onDidOpenTextDocument(refresh),
|
|
89
|
+
vscode.workspace.onDidChangeTextDocument((event) => refresh(event.document)),
|
|
90
|
+
vscode.workspace.onDidCloseTextDocument((document) => collection.delete(document.uri)),
|
|
55
91
|
vscode.commands.registerCommand("cluaupp.restartIntelliSense", () => {
|
|
56
92
|
try {
|
|
57
93
|
delete require.cache[require.resolve(loaded.enginePath)];
|
|
58
|
-
loaded =
|
|
59
|
-
|
|
60
|
-
|
|
94
|
+
loaded = loadLanguage(context);
|
|
95
|
+
collection.clear();
|
|
96
|
+
for (const document of vscode.workspace.textDocuments) {
|
|
97
|
+
refresh(document);
|
|
98
|
+
}
|
|
99
|
+
vscode.window.showInformationMessage("Cluaupp Flare IntelliSense reloaded.");
|
|
61
100
|
} catch (err) {
|
|
62
101
|
vscode.window.showErrorMessage(String(err.message || err));
|
|
63
102
|
}
|
|
64
103
|
}),
|
|
104
|
+
vscode.languages.registerCompletionItemProvider(
|
|
105
|
+
selector,
|
|
106
|
+
{
|
|
107
|
+
provideCompletionItems(document, position) {
|
|
108
|
+
return loaded.language.completionsAt(document.getText(), position.line, position.character).map((entry) => {
|
|
109
|
+
const item = new vscode.CompletionItem(entry.label, KIND[entry.kind]);
|
|
110
|
+
item.detail = entry.detail;
|
|
111
|
+
item.documentation = new vscode.MarkdownString(entry.documentation);
|
|
112
|
+
item.insertText = entry.snippet ? new vscode.SnippetString(entry.insertText) : entry.insertText;
|
|
113
|
+
item.sortText = entry.sortText;
|
|
114
|
+
return item;
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
" ",
|
|
119
|
+
"(",
|
|
120
|
+
",",
|
|
121
|
+
">",
|
|
122
|
+
"=",
|
|
123
|
+
),
|
|
124
|
+
vscode.languages.registerHoverProvider(selector, {
|
|
125
|
+
provideHover(document, position) {
|
|
126
|
+
const hover = loaded.language.hoverAt(document.getText(), position.line, position.character);
|
|
127
|
+
if (!hover) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const range = new vscode.Range(position.line, hover.start, position.line, hover.end);
|
|
131
|
+
return new vscode.Hover(new vscode.MarkdownString(hover.contents), range);
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
134
|
+
vscode.languages.registerDocumentSymbolProvider(selector, {
|
|
135
|
+
provideDocumentSymbols(document) {
|
|
136
|
+
return loaded.language.symbolsIn(document.getText()).map((symbol) => {
|
|
137
|
+
const range = new vscode.Range(symbol.line, 0, symbol.line, Math.max(symbol.end, 1));
|
|
138
|
+
const selection = new vscode.Range(symbol.line, symbol.start, symbol.line, Math.max(symbol.end, symbol.start + 1));
|
|
139
|
+
return new vscode.DocumentSymbol(symbol.name, symbol.detail, SYMBOL[symbol.kind], range, selection);
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
}),
|
|
143
|
+
vscode.languages.registerSignatureHelpProvider(
|
|
144
|
+
selector,
|
|
145
|
+
{
|
|
146
|
+
provideSignatureHelp(document, position) {
|
|
147
|
+
const signature = loaded.language.signatureAt(document.getText(), position.line, position.character);
|
|
148
|
+
if (!signature) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const help = new vscode.SignatureHelp();
|
|
152
|
+
const info = new vscode.SignatureInformation(signature.label, signature.documentation);
|
|
153
|
+
info.parameters = signature.parameters.map(
|
|
154
|
+
(parameter) => new vscode.ParameterInformation(parameter.label, parameter.documentation),
|
|
155
|
+
);
|
|
156
|
+
help.signatures = [info];
|
|
157
|
+
help.activeSignature = 0;
|
|
158
|
+
help.activeParameter = signature.activeParameter;
|
|
159
|
+
return help;
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
"(",
|
|
163
|
+
",",
|
|
164
|
+
),
|
|
165
|
+
vscode.languages.registerCodeActionsProvider(selector, {
|
|
166
|
+
provideCodeActions(document, _range, actionContext) {
|
|
167
|
+
const actions = [];
|
|
168
|
+
for (const diagnostic of actionContext.diagnostics) {
|
|
169
|
+
const match = String(diagnostic.message).match(/did you mean '([^']+)'/);
|
|
170
|
+
if (!match) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const edit = new vscode.WorkspaceEdit();
|
|
174
|
+
edit.replace(document.uri, diagnostic.range, match[1]);
|
|
175
|
+
const action = new vscode.CodeAction(`Replace with ${match[1]}`, vscode.CodeActionKind.QuickFix);
|
|
176
|
+
action.diagnostics = [diagnostic];
|
|
177
|
+
action.edit = edit;
|
|
178
|
+
action.isPreferred = true;
|
|
179
|
+
actions.push(action);
|
|
180
|
+
}
|
|
181
|
+
return actions;
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
65
184
|
);
|
|
66
185
|
|
|
67
186
|
for (const document of vscode.workspace.textDocuments) {
|
|
68
|
-
|
|
187
|
+
refresh(document);
|
|
69
188
|
}
|
|
70
189
|
}
|
|
71
190
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<rect width="32" height="32" rx="6" fill="#0F766E"/>
|
|
3
|
+
<path d="M8 22 L16 8 L24 22 Z" fill="none" stroke="#ECFDF5" stroke-width="2.2" stroke-linejoin="round"/>
|
|
4
|
+
<circle cx="16" cy="16" r="2.2" fill="#99F6E4"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"comments": {
|
|
3
|
+
"lineComment": "//"
|
|
4
|
+
},
|
|
5
|
+
"brackets": [
|
|
6
|
+
["(", ")"]
|
|
7
|
+
],
|
|
8
|
+
"autoClosingPairs": [
|
|
9
|
+
{ "open": "(", "close": ")" },
|
|
10
|
+
{ "open": "\"", "close": "\"" }
|
|
11
|
+
],
|
|
12
|
+
"surroundingPairs": [
|
|
13
|
+
["(", ")"],
|
|
14
|
+
["\"", "\""]
|
|
15
|
+
],
|
|
16
|
+
"wordPattern": "[A-Za-z_][A-Za-z0-9_]*",
|
|
17
|
+
"indentationRules": {
|
|
18
|
+
"increaseIndentPattern": "^\\s*(packet|query)\\b.*\\([^)]*$",
|
|
19
|
+
"decreaseIndentPattern": "^\\s*\\)"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,25 +1,79 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "cluaupp-
|
|
3
|
-
"displayName": "Cluaupp",
|
|
4
|
-
"description": "Cluaupp
|
|
5
|
-
"version": "1.
|
|
2
|
+
"name": "cluaupp-flare",
|
|
3
|
+
"displayName": "Cluaupp Flare",
|
|
4
|
+
"description": "IntelliSense for Cluaupp .flare network schemas: highlighting, completions, hover, diagnostics, outline, and snippets.",
|
|
5
|
+
"version": "1.5.0",
|
|
6
6
|
"publisher": "kartzdev",
|
|
7
7
|
"engines": {
|
|
8
8
|
"vscode": "^1.74.0"
|
|
9
9
|
},
|
|
10
10
|
"categories": [
|
|
11
|
+
"Programming Languages",
|
|
12
|
+
"Snippets",
|
|
11
13
|
"Linters"
|
|
12
14
|
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"flare",
|
|
17
|
+
"cluaupp",
|
|
18
|
+
"roblox",
|
|
19
|
+
"clpp"
|
|
20
|
+
],
|
|
13
21
|
"activationEvents": [
|
|
14
|
-
"onLanguage:
|
|
22
|
+
"onLanguage:flare",
|
|
23
|
+
"workspaceContains:**/*.flare"
|
|
15
24
|
],
|
|
16
25
|
"main": "./extension.js",
|
|
17
26
|
"contributes": {
|
|
27
|
+
"languages": [
|
|
28
|
+
{
|
|
29
|
+
"id": "flare",
|
|
30
|
+
"aliases": [
|
|
31
|
+
"Flare",
|
|
32
|
+
"flare"
|
|
33
|
+
],
|
|
34
|
+
"extensions": [
|
|
35
|
+
".flare"
|
|
36
|
+
],
|
|
37
|
+
"configuration": "./language-configuration.json",
|
|
38
|
+
"icon": {
|
|
39
|
+
"light": "./icons/flare.svg",
|
|
40
|
+
"dark": "./icons/flare.svg"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"grammars": [
|
|
45
|
+
{
|
|
46
|
+
"language": "flare",
|
|
47
|
+
"scopeName": "source.flare",
|
|
48
|
+
"path": "./syntaxes/flare.tmLanguage.json"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"snippets": [
|
|
52
|
+
{
|
|
53
|
+
"language": "flare",
|
|
54
|
+
"path": "./snippets/flare.json"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
18
57
|
"commands": [
|
|
19
58
|
{
|
|
20
59
|
"command": "cluaupp.restartIntelliSense",
|
|
21
|
-
"title": "Cluaupp: Reload
|
|
60
|
+
"title": "Cluaupp: Reload Flare IntelliSense"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"configurationDefaults": {
|
|
64
|
+
"files.associations": {
|
|
65
|
+
"*.flare": "flare"
|
|
66
|
+
},
|
|
67
|
+
"[flare]": {
|
|
68
|
+
"editor.quickSuggestions": {
|
|
69
|
+
"other": true,
|
|
70
|
+
"comments": false,
|
|
71
|
+
"strings": false
|
|
72
|
+
},
|
|
73
|
+
"editor.suggest.insertMode": "replace",
|
|
74
|
+
"editor.tabCompletion": "on",
|
|
75
|
+
"editor.wordBasedSuggestions": false
|
|
22
76
|
}
|
|
23
|
-
|
|
77
|
+
}
|
|
24
78
|
}
|
|
25
79
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Packet from Client": {
|
|
3
|
+
"prefix": ["packetc", "packet"],
|
|
4
|
+
"body": "packet ${1:Hit}(${2:Player} ${3:target}, ${4:i32} ${5:damage}) from Client",
|
|
5
|
+
"description": "Client → server packet (FireServer / Connect with Player first)"
|
|
6
|
+
},
|
|
7
|
+
"Packet from Server": {
|
|
8
|
+
"prefix": "packets",
|
|
9
|
+
"body": "packet ${1:Welcome}(${2:i32} ${3:userId}, ${4:f64} ${5:clock}) from Server",
|
|
10
|
+
"description": "Server → client packet (Fire recipient first, then schema fields)"
|
|
11
|
+
},
|
|
12
|
+
"Packet unreliable": {
|
|
13
|
+
"prefix": "packetu",
|
|
14
|
+
"body": "packet ${1:Spark}(${2:Vector3} ${3:pos}) from Server unreliable",
|
|
15
|
+
"description": "Unreliable server packet — visuals, not economy"
|
|
16
|
+
},
|
|
17
|
+
"Query RPC": {
|
|
18
|
+
"prefix": "query",
|
|
19
|
+
"body": "query ${1:Session}() -> ${2:i32}",
|
|
20
|
+
"description": "RPC query (Invoke / On, server must return)"
|
|
21
|
+
},
|
|
22
|
+
"opt name": {
|
|
23
|
+
"prefix": "opt",
|
|
24
|
+
"body": "opt name = ${1:Net}",
|
|
25
|
+
"description": "Generated module name (Net.clh / Net.Hit)"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
|
3
|
+
"name": "Flare",
|
|
4
|
+
"scopeName": "source.flare",
|
|
5
|
+
"patterns": [
|
|
6
|
+
{ "include": "#comments" },
|
|
7
|
+
{ "include": "#strings" },
|
|
8
|
+
{ "include": "#keywords" },
|
|
9
|
+
{ "include": "#types" },
|
|
10
|
+
{ "include": "#operators" },
|
|
11
|
+
{ "include": "#names" }
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"comments": {
|
|
15
|
+
"patterns": [
|
|
16
|
+
{
|
|
17
|
+
"name": "comment.line.double-slash.flare",
|
|
18
|
+
"match": "//.*$"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "comment.line.number-sign.flare",
|
|
22
|
+
"match": "#.*$"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"strings": {
|
|
27
|
+
"name": "string.quoted.double.flare",
|
|
28
|
+
"begin": "\"",
|
|
29
|
+
"end": "\""
|
|
30
|
+
},
|
|
31
|
+
"keywords": {
|
|
32
|
+
"patterns": [
|
|
33
|
+
{
|
|
34
|
+
"name": "keyword.declaration.flare",
|
|
35
|
+
"match": "\\b(packet|query|opt)\\b"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "keyword.other.flare",
|
|
39
|
+
"match": "\\b(from|name)\\b"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "constant.language.flare",
|
|
43
|
+
"match": "\\b(Client|Server)\\b"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "storage.modifier.flare",
|
|
47
|
+
"match": "\\b(unreliable|reliable)\\b"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"types": {
|
|
52
|
+
"name": "storage.type.flare",
|
|
53
|
+
"match": "\\b(u8|u16|u32|i8|i16|i32|int|f32|f64|float|double|number|bool|boolean|string|Vector3|Vector2|CFrame|Color3|UDim|UDim2|BrickColor|buffer|Instance|Player)\\b"
|
|
54
|
+
},
|
|
55
|
+
"operators": {
|
|
56
|
+
"patterns": [
|
|
57
|
+
{
|
|
58
|
+
"name": "keyword.operator.arrow.flare",
|
|
59
|
+
"match": "->"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "keyword.operator.assignment.flare",
|
|
63
|
+
"match": "="
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"names": {
|
|
68
|
+
"match": "\\b(packet|query)\\s+([A-Za-z_][A-Za-z0-9_]*)",
|
|
69
|
+
"captures": {
|
|
70
|
+
"1": { "name": "keyword.declaration.flare" },
|
|
71
|
+
"2": { "name": "entity.name.function.flare" }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
// Table = u16 count + key/value pairs. Array = u16 len + values. Methods also work as Roster::X(rawTable).
|
|
6
6
|
|
|
7
7
|
struct Roster {
|
|
8
|
+
// Construct with `new Roster()` / `new Roster(table)` — emits Luau Roster.new.
|
|
9
|
+
// `New` is the CL++ name because `new` is a keyword.
|
|
8
10
|
static Roster New();
|
|
11
|
+
static Roster New(auto initial);
|
|
9
12
|
|
|
10
13
|
int Size();
|
|
11
14
|
int Length();
|
|
@@ -13,6 +16,7 @@ struct Roster {
|
|
|
13
16
|
auto GetData();
|
|
14
17
|
|
|
15
18
|
auto At(int index);
|
|
19
|
+
// Array value search (1-based index). Dictionary keys: Has / Get / Set / Remove.
|
|
16
20
|
int Find(auto value);
|
|
17
21
|
int Find(auto value, int initPos);
|
|
18
22
|
int Find(auto value, int initPos, int maxPos);
|
|
@@ -23,6 +27,7 @@ struct Roster {
|
|
|
23
27
|
auto Shift();
|
|
24
28
|
int Unshift(auto value);
|
|
25
29
|
auto RemoveAt(int index);
|
|
30
|
+
Roster Remove(auto key);
|
|
26
31
|
|
|
27
32
|
Roster Map(func mapper);
|
|
28
33
|
Roster Filter(func predicate);
|
|
@@ -74,6 +79,7 @@ struct Roster {
|
|
|
74
79
|
static auto Shift(auto data);
|
|
75
80
|
static int Unshift(auto data, auto value);
|
|
76
81
|
static auto RemoveAt(auto data, int index);
|
|
82
|
+
static Roster Remove(auto data, auto key);
|
|
77
83
|
static Roster Map(auto data, func mapper);
|
|
78
84
|
static Roster Filter(auto data, func predicate);
|
|
79
85
|
static auto Reduce(auto data, func reducer, auto initial);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#include "../../ReplicatedStorage/Shared/Constants/Datas/TemplateData.clh"
|
|
5
5
|
|
|
6
6
|
void init() {
|
|
7
|
-
PlayerTemplate playerData;
|
|
7
|
+
PlayerTemplate playerData = PlayerTemplate();
|
|
8
8
|
Keep.Server.Init(DataServiceOptions {
|
|
9
9
|
.Template = playerData,
|
|
10
10
|
.StoreName = "PlayerData",
|
package/generated/cli.js
CHANGED
|
@@ -34,7 +34,7 @@ program
|
|
|
34
34
|
});
|
|
35
35
|
program
|
|
36
36
|
.command("init")
|
|
37
|
-
.description("create a game (
|
|
37
|
+
.description("create a game (ReplicatedStorage, ServerScriptService, StarterPlayer)")
|
|
38
38
|
.argument("[folder]", "destination folder", ".")
|
|
39
39
|
.action(async (folder) => {
|
|
40
40
|
try {
|
|
@@ -93,7 +93,7 @@ program
|
|
|
93
93
|
});
|
|
94
94
|
program
|
|
95
95
|
.command("lsp")
|
|
96
|
-
.description("Language server stdio
|
|
96
|
+
.description("Language server stdio — Flare `.flare` IntelliSense. CL++ still uses `clpp setup`.")
|
|
97
97
|
.argument("[folder]", "project folder", ".")
|
|
98
98
|
.action((folder) => {
|
|
99
99
|
(0, lsp_js_1.start)({ projectRoot: node_path_1.default.resolve(process.cwd(), folder) });
|
|
@@ -101,7 +101,7 @@ program
|
|
|
101
101
|
program
|
|
102
102
|
.command("intellisense")
|
|
103
103
|
.alias("intelisense")
|
|
104
|
-
.description("
|
|
104
|
+
.description("Install Flare IntelliSense and point CL++ at `clpp setup`")
|
|
105
105
|
.argument("[folder]", "project folder", ".")
|
|
106
106
|
.action(async (folder) => {
|
|
107
107
|
try {
|
package/generated/flare/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.FLARE_TYPE_DOCS = exports.FLARE_CANONICAL_TYPES = exports.symbolsIn = exports.signatureAt = exports.isFlareDocument = exports.hoverAt = exports.diagnoseFlare = exports.completionsAt = exports.analyzeFlare = exports.FLARE_IDENT = exports.FLARE_TYPE_ALIASES = exports.parseFlare = exports.emitFlareLuau = exports.emitFlareHeader = exports.emitFlare = void 0;
|
|
7
7
|
exports.isFlareFile = isFlareFile;
|
|
8
8
|
exports.isGeneratedHeader = isGeneratedHeader;
|
|
9
9
|
exports.collectFlareFiles = collectFlareFiles;
|
|
@@ -12,12 +12,24 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
12
12
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
13
|
const emit_js_1 = require("./emit.js");
|
|
14
14
|
const parse_js_1 = require("./parse.js");
|
|
15
|
-
var parse_js_2 = require("./parse.js");
|
|
16
|
-
Object.defineProperty(exports, "parseFlare", { enumerable: true, get: function () { return parse_js_2.parseFlare; } });
|
|
17
15
|
var emit_js_2 = require("./emit.js");
|
|
18
16
|
Object.defineProperty(exports, "emitFlare", { enumerable: true, get: function () { return emit_js_2.emitFlare; } });
|
|
19
17
|
Object.defineProperty(exports, "emitFlareHeader", { enumerable: true, get: function () { return emit_js_2.emitFlareHeader; } });
|
|
20
18
|
Object.defineProperty(exports, "emitFlareLuau", { enumerable: true, get: function () { return emit_js_2.emitFlareLuau; } });
|
|
19
|
+
var parse_js_2 = require("./parse.js");
|
|
20
|
+
Object.defineProperty(exports, "parseFlare", { enumerable: true, get: function () { return parse_js_2.parseFlare; } });
|
|
21
|
+
Object.defineProperty(exports, "FLARE_TYPE_ALIASES", { enumerable: true, get: function () { return parse_js_2.FLARE_TYPE_ALIASES; } });
|
|
22
|
+
Object.defineProperty(exports, "FLARE_IDENT", { enumerable: true, get: function () { return parse_js_2.FLARE_IDENT; } });
|
|
23
|
+
var language_js_1 = require("./language.js");
|
|
24
|
+
Object.defineProperty(exports, "analyzeFlare", { enumerable: true, get: function () { return language_js_1.analyzeFlare; } });
|
|
25
|
+
Object.defineProperty(exports, "completionsAt", { enumerable: true, get: function () { return language_js_1.completionsAt; } });
|
|
26
|
+
Object.defineProperty(exports, "diagnoseFlare", { enumerable: true, get: function () { return language_js_1.diagnoseFlare; } });
|
|
27
|
+
Object.defineProperty(exports, "hoverAt", { enumerable: true, get: function () { return language_js_1.hoverAt; } });
|
|
28
|
+
Object.defineProperty(exports, "isFlareDocument", { enumerable: true, get: function () { return language_js_1.isFlareDocument; } });
|
|
29
|
+
Object.defineProperty(exports, "signatureAt", { enumerable: true, get: function () { return language_js_1.signatureAt; } });
|
|
30
|
+
Object.defineProperty(exports, "symbolsIn", { enumerable: true, get: function () { return language_js_1.symbolsIn; } });
|
|
31
|
+
Object.defineProperty(exports, "FLARE_CANONICAL_TYPES", { enumerable: true, get: function () { return language_js_1.FLARE_CANONICAL_TYPES; } });
|
|
32
|
+
Object.defineProperty(exports, "FLARE_TYPE_DOCS", { enumerable: true, get: function () { return language_js_1.FLARE_TYPE_DOCS; } });
|
|
21
33
|
function isFlareFile(fileName) {
|
|
22
34
|
return node_path_1.default.extname(fileName).toLowerCase() === ".flare";
|
|
23
35
|
}
|