cluaupp 0.2.3 → 1.0.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 +10 -79
- package/README.md +42 -88
- package/docs/README.md +13 -21
- package/docs/architecture.md +13 -76
- package/docs/cli.md +12 -64
- package/docs/comparison.md +6 -24
- package/docs/config.md +6 -7
- package/docs/examples/combat.md +19 -227
- package/docs/examples/hud.md +13 -81
- package/docs/examples/index.md +9 -16
- package/docs/getting-started.md +20 -137
- package/docs/intellisense.md +5 -41
- package/docs/intro.md +16 -15
- package/docs/migration.md +38 -0
- package/docs/oop/file-tags.md +12 -36
- package/docs/oop/index.md +8 -14
- package/docs/syntax.md +54 -236
- package/editors/vscode/extension.js +1 -1
- package/editors/vscode/package.json +4 -4
- package/examples/README.md +5 -7
- package/examples/game/.vscode/extensions.json +0 -3
- package/examples/game/.vscode/settings.json +6 -14
- package/examples/game/src/client/hud.client.clpp +54 -0
- package/examples/game/src/client/init.client.clpp +6 -0
- package/examples/game/src/server/combat.server.clpp +85 -0
- package/examples/game/src/server/leaderstats.server.clpp +28 -0
- package/examples/game/src/shared/PlayerData.clh +20 -0
- package/examples/game/src/shared/config.clp +6 -0
- package/examples/game/src/shared/features.clp +88 -0
- package/generated/cli.js +40 -24
- package/generated/clpp/contract.js +5 -0
- package/generated/clpp/index.js +27 -0
- package/generated/clpp/paths.js +121 -0
- package/generated/clpp/postprocess.js +78 -0
- package/generated/clpp/runner.js +102 -0
- package/generated/compile.js +26 -138
- package/generated/intellisense.js +38 -157
- package/generated/libs.js +1 -1
- package/generated/lsp.js +1 -8
- package/generated/preprocess.js +8 -179
- package/generated/system-understander.js +1 -1
- package/generated/transpile.js +3 -50
- package/generated/utils/project.js +13 -28
- package/include/{cluaupp/datatypes.hpp → clpp/datatypes.clh} +1 -1
- package/include/{cluaupp/generated/instances.hpp → clpp/generated/instances.clh} +1 -1
- package/include/{cluaupp/libs/chrono.hpp → clpp/libs/chrono.clh} +9 -9
- package/include/{cluaupp/libs/cmdr.hpp → clpp/libs/cmdr.clh} +4 -4
- package/include/{cluaupp/libs/dataservice.hpp → clpp/libs/dataservice.clh} +8 -15
- package/include/{cluaupp/libs/display.hpp → clpp/libs/display.clh} +1 -2
- package/include/{cluaupp/libs/ezvisual.hpp → clpp/libs/ezvisual.clh} +1 -3
- package/include/{cluaupp/libs/formatnumber.hpp → clpp/libs/formatnumber.clh} +2 -3
- package/include/{cluaupp/libs/fusion.hpp → clpp/libs/fusion.clh} +5 -5
- package/include/{cluaupp/libs/iris.hpp → clpp/libs/iris.clh} +2 -2
- package/include/{cluaupp/libs/janitor.hpp → clpp/libs/janitor.clh} +1 -2
- package/include/{cluaupp/libs/module3d.hpp → clpp/libs/module3d.clh} +2 -4
- package/include/{cluaupp/libs/net.hpp → clpp/libs/net.clh} +2 -4
- package/include/{cluaupp/libs/promise.hpp → clpp/libs/promise.clh} +1 -4
- package/include/{cluaupp/libs/spring.hpp → clpp/libs/spring.clh} +1 -2
- package/include/{cluaupp/libs/statemachine.hpp → clpp/libs/statemachine.clh} +2 -3
- package/include/{cluaupp/libs/stickybillboard.hpp → clpp/libs/stickybillboard.clh} +1 -2
- package/include/{cluaupp/libs/topbarplus.hpp → clpp/libs/topbarplus.clh} +3 -4
- package/include/clpp/libs.clh +24 -0
- package/include/clpp/roblox.clh +31 -0
- package/package.json +7 -14
- package/src/cli.ts +39 -25
- package/src/clpp/contract.ts +39 -0
- package/src/clpp/index.ts +18 -0
- package/src/clpp/paths.ts +117 -0
- package/src/clpp/postprocess.ts +93 -0
- package/src/clpp/runner.ts +102 -0
- package/src/compile.ts +26 -149
- package/src/intellisense.ts +36 -165
- package/src/libs.ts +1 -1
- package/src/lsp.ts +1 -5
- package/src/preprocess.ts +8 -180
- package/src/system-understander.ts +1 -1
- package/src/transpile.ts +9 -52
- package/src/utils/project.ts +12 -28
- package/templates/game/.vscode/extensions.json +0 -3
- package/templates/game/.vscode/settings.json +6 -14
- package/templates/game/src/client/init.client.clpp +6 -0
- package/templates/game/src/server/leaderstats.server.clpp +29 -0
- package/templates/game/src/shared/config.clp +6 -0
- package/examples/game/.clangd +0 -25
- package/examples/game/compile_flags.txt +0 -6
- package/examples/game/src/client/hud.client.cpp +0 -12
- package/examples/game/src/client/init.client.cpp +0 -6
- package/examples/game/src/server/combat.server.cpp +0 -23
- package/examples/game/src/server/leaderstats.server.cpp +0 -29
- package/examples/game/src/shared/config.cpp +0 -5
- package/examples/game/src/shared/config.h +0 -5
- package/include/cluaupp/libs.hpp +0 -25
- package/include/cluaupp/roblox.hpp +0 -47
- package/src/architecture.ts +0 -500
- package/src/ast.ts +0 -37
- package/src/emit.ts +0 -609
- package/src/emitter/luau-codegen.ts +0 -187
- package/src/emitter/translators.ts +0 -168
- package/src/headers.ts +0 -233
- package/src/layout.ts +0 -114
- package/src/lex.ts +0 -158
- package/src/parse.ts +0 -729
- package/src/parser/collector.ts +0 -148
- package/src/parser/index.ts +0 -27
- package/src/tree-sitter-cpp.d.ts +0 -4
- package/src/understand.ts +0 -322
- package/templates/game/src/client/init.client.cpp +0 -6
- package/templates/game/src/server/leaderstats.server.cpp +0 -29
- package/templates/game/src/shared/config.cpp +0 -5
- package/templates/game/src/shared/config.h +0 -5
- /package/include/{cluaupp/generated/enums.hpp → clpp/generated/enums.clh} +0 -0
- /package/include/{cluaupp/libs/math.hpp → clpp/libs/math.clh} +0 -0
- /package/include/{cluaupp/libs/twinkle.hpp → clpp/libs/twinkle.clh} +0 -0
- /package/include/{cluaupp/libs/vfx.hpp → clpp/libs/vfx.clh} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasClpp = hasClpp;
|
|
4
|
+
exports.resolveClppBinary = resolveClppBinary;
|
|
5
|
+
exports.compileViaClpp = compileViaClpp;
|
|
6
|
+
exports.clppManifest = clppManifest;
|
|
7
|
+
exports.clppVersion = clppVersion;
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const contract_js_1 = require("./contract.js");
|
|
10
|
+
const MISSING_CLPP = `cluaupp: clpp not found. ${contract_js_1.CLPP_INSTALL_HINT}`;
|
|
11
|
+
function whichClpp() {
|
|
12
|
+
if (process.env.CLPP_PATH) {
|
|
13
|
+
return process.env.CLPP_PATH;
|
|
14
|
+
}
|
|
15
|
+
const finder = process.platform === "win32" ? "where" : "which";
|
|
16
|
+
const found = (0, node_child_process_1.spawnSync)(finder, ["clpp"], { encoding: "utf8", windowsHide: true });
|
|
17
|
+
if (found.status !== 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const line = String(found.stdout || "")
|
|
21
|
+
.split(/\r?\n/)
|
|
22
|
+
.map((item) => item.trim())
|
|
23
|
+
.find((item) => item.length > 0);
|
|
24
|
+
return line || "clpp";
|
|
25
|
+
}
|
|
26
|
+
function hasClpp() {
|
|
27
|
+
return Boolean(whichClpp());
|
|
28
|
+
}
|
|
29
|
+
function resolveClppBinary() {
|
|
30
|
+
const bin = whichClpp();
|
|
31
|
+
if (!bin) {
|
|
32
|
+
throw new Error(MISSING_CLPP);
|
|
33
|
+
}
|
|
34
|
+
return bin;
|
|
35
|
+
}
|
|
36
|
+
function parseArtifact(stdout, fileName, fallbackError) {
|
|
37
|
+
const text = String(stdout || "").trim();
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(text);
|
|
40
|
+
if (parsed && typeof parsed === "object") {
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// fall through
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
luau: "",
|
|
50
|
+
fileName,
|
|
51
|
+
outputHint: "",
|
|
52
|
+
scriptKind: null,
|
|
53
|
+
isScript: false,
|
|
54
|
+
isHeader: false,
|
|
55
|
+
rojoClass: "ModuleScript",
|
|
56
|
+
libraries: [],
|
|
57
|
+
error: fallbackError || "clpp returned invalid JSON",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function compileViaClpp(request) {
|
|
61
|
+
const bin = resolveClppBinary();
|
|
62
|
+
const payload = JSON.stringify({
|
|
63
|
+
source: request.source,
|
|
64
|
+
fileName: request.fileName,
|
|
65
|
+
strict: request.strict,
|
|
66
|
+
});
|
|
67
|
+
const result = (0, node_child_process_1.spawnSync)(bin, ["api", "compile"], {
|
|
68
|
+
input: payload,
|
|
69
|
+
encoding: "utf8",
|
|
70
|
+
cwd: request.cwd,
|
|
71
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
72
|
+
windowsHide: true,
|
|
73
|
+
});
|
|
74
|
+
const stderr = String(result.stderr || "").trim();
|
|
75
|
+
const artifact = parseArtifact(result.stdout, request.fileName, stderr || result.error?.message || "clpp api compile failed");
|
|
76
|
+
if (!artifact.ok) {
|
|
77
|
+
throw new Error(artifact.error || stderr || `clpp failed (${result.status})`);
|
|
78
|
+
}
|
|
79
|
+
return artifact;
|
|
80
|
+
}
|
|
81
|
+
function clppManifest() {
|
|
82
|
+
const bin = resolveClppBinary();
|
|
83
|
+
const result = (0, node_child_process_1.spawnSync)(bin, ["api", "manifest"], {
|
|
84
|
+
encoding: "utf8",
|
|
85
|
+
windowsHide: true,
|
|
86
|
+
});
|
|
87
|
+
if (result.status !== 0) {
|
|
88
|
+
throw new Error(String(result.stderr || result.error?.message || "clpp api manifest failed"));
|
|
89
|
+
}
|
|
90
|
+
return JSON.parse(result.stdout);
|
|
91
|
+
}
|
|
92
|
+
function clppVersion() {
|
|
93
|
+
const bin = whichClpp();
|
|
94
|
+
if (!bin) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const result = (0, node_child_process_1.spawnSync)(bin, ["--version"], { encoding: "utf8", windowsHide: true });
|
|
98
|
+
if (result.status !== 0) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return String(result.stdout || "").trim() || null;
|
|
102
|
+
}
|
package/generated/compile.js
CHANGED
|
@@ -5,149 +5,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.compileSource = compileSource;
|
|
7
7
|
exports.compileService = compileService;
|
|
8
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const libs_js_1 = require("./libs.js");
|
|
14
|
-
const architecture_js_1 = require("./architecture.js");
|
|
15
|
-
const headers_js_1 = require("./headers.js");
|
|
16
|
-
function shouldAttachRequires(name, contents) {
|
|
17
|
-
const file = String(name || "").replace(/\\/g, "/");
|
|
18
|
-
if (/\.json$/i.test(file) || /\.meta\.json$/i.test(file)) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
const trimmed = String(contents || "").trim();
|
|
22
|
-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
function attachRequires(contents, source, ast, options, outName) {
|
|
28
|
-
if (!shouldAttachRequires(outName, contents)) {
|
|
29
|
-
return contents;
|
|
30
|
-
}
|
|
31
|
-
const libraries = String(contents).includes("CluauppLibs") ? [] : (0, libs_js_1.collectLibraries)(source, ast);
|
|
32
|
-
return (0, libs_js_1.insertPreamble)(contents, options.moduleIncludes || [], libraries, outName);
|
|
33
|
-
}
|
|
34
|
-
function posixRel(from, file) {
|
|
35
|
-
return node_path_1.default.relative(from, file).replace(/\\/g, "/");
|
|
36
|
-
}
|
|
37
|
-
function declKey(decl) {
|
|
38
|
-
return `${decl.owner || ""}::${decl.name}`;
|
|
39
|
-
}
|
|
40
|
-
function mergeSiblingImpl(ast, implPath, options) {
|
|
41
|
-
const implOptions = {
|
|
42
|
-
...options,
|
|
43
|
-
moduleIncludes: [],
|
|
44
|
-
seen: new Set(),
|
|
45
|
-
pragmaResolved: false,
|
|
46
|
-
};
|
|
47
|
-
const prepared = (0, preprocess_js_1.preprocess)(node_fs_1.default.readFileSync(implPath, "utf8"), implPath, implOptions);
|
|
48
|
-
const implAst = (0, parse_js_1.parse)(prepared, node_path_1.default.basename(implPath));
|
|
49
|
-
if (!Array.isArray(ast.body)) {
|
|
50
|
-
ast.body = [];
|
|
51
|
-
}
|
|
52
|
-
const existing = new Set((ast.body || [])
|
|
53
|
-
.filter((decl) => decl && (decl.type === "function" || decl.type === "proto") && decl.name)
|
|
54
|
-
.map(declKey));
|
|
55
|
-
for (const decl of implAst.body || []) {
|
|
56
|
-
if ((decl.type !== "function" && decl.type !== "proto") || !decl.name) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const key = declKey(decl);
|
|
60
|
-
if (existing.has(key)) {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
existing.add(key);
|
|
64
|
-
ast.body.push({
|
|
65
|
-
type: "proto",
|
|
66
|
-
name: decl.name,
|
|
67
|
-
owner: decl.owner,
|
|
68
|
-
returnType: decl.returnType,
|
|
69
|
-
params: decl.params,
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function wireHeaderImpl(ast, fileName, options) {
|
|
74
|
-
const headerPath = options.filePath || null;
|
|
75
|
-
const impl = headerPath ? (0, preprocess_js_1.siblingImplementation)(headerPath) : null;
|
|
76
|
-
if (!impl) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
mergeSiblingImpl(ast, impl, options);
|
|
80
|
-
const typeName = (0, headers_js_1.primaryHeaderName)(ast, options.relativeName || fileName);
|
|
81
|
-
const implRel = options.srcDir ? posixRel(options.srcDir, impl) : node_path_1.default.basename(impl).replace(/\\/g, "/");
|
|
82
|
-
const implOut = (0, preprocess_js_1.implOutName)(implRel);
|
|
83
|
-
options.headerImplName = `${typeName}Module`;
|
|
84
|
-
options.moduleIncludes = options.moduleIncludes || [];
|
|
85
|
-
if (!options.moduleIncludes.some((spec) => spec.name === options.headerImplName)) {
|
|
86
|
-
options.moduleIncludes.push({
|
|
87
|
-
name: options.headerImplName,
|
|
88
|
-
outRel: implOut,
|
|
89
|
-
exports: { consts: [], structs: [] },
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function compileHeader(source, fileName, options, ast) {
|
|
94
|
-
wireHeaderImpl(ast, fileName, options);
|
|
95
|
-
const rel = (options.relativeName || fileName || "header.h").replace(/\\/g, "/");
|
|
96
|
-
const outName = (0, preprocess_js_1.toLuauPath)(rel);
|
|
97
|
-
const luau = attachRequires((0, headers_js_1.emitHeaderModule)(ast, options), source, ast, options, outName);
|
|
98
|
-
return {
|
|
99
|
-
kind: "module",
|
|
100
|
-
plan: { kind: "module", strict: options.strict === true },
|
|
101
|
-
files: [{ name: outName, contents: luau }],
|
|
102
|
-
stale: [],
|
|
103
|
-
};
|
|
104
|
-
}
|
|
9
|
+
const runner_js_1 = require("./clpp/runner.js");
|
|
10
|
+
const postprocess_js_1 = require("./clpp/postprocess.js");
|
|
11
|
+
const paths_js_1 = require("./clpp/paths.js");
|
|
105
12
|
function compileSource(source, fileName, options = {}) {
|
|
106
|
-
|
|
107
|
-
opts.moduleIncludes = opts.moduleIncludes || [];
|
|
108
|
-
const prepared = (0, preprocess_js_1.preprocess)(source, opts.filePath || null, opts);
|
|
109
|
-
const ast = (0, parse_js_1.parse)(prepared, fileName || "input.cpp");
|
|
110
|
-
if ((0, preprocess_js_1.isHeaderFile)(fileName || "") || (0, preprocess_js_1.isHeaderFile)(opts.filePath || "")) {
|
|
111
|
-
return compileHeader(source, fileName || "header.h", opts, ast).files[0].contents;
|
|
112
|
-
}
|
|
113
|
-
const luau = (0, emit_js_1.emit)(ast, opts);
|
|
114
|
-
return attachRequires(luau, source, ast, opts, opts.outName || fileName || "input.cpp");
|
|
13
|
+
return compileService(source, fileName, options).files[0]?.contents ?? "";
|
|
115
14
|
}
|
|
116
15
|
function compileService(source, fileName, options = {}) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
16
|
+
const relative = (options.relativeName || fileName || "input.clpp").replace(/\\/g, "/");
|
|
17
|
+
const outName = options.outName || (0, paths_js_1.toLuauPath)(relative);
|
|
18
|
+
const header = options.filePath ? (0, paths_js_1.siblingHeader)(options.filePath) : null;
|
|
19
|
+
const skipInit = options.skipInit === true || (0, postprocess_js_1.shouldSkipInit)(relative, Boolean(header));
|
|
20
|
+
const diskPath = options.filePath ? node_path_1.default.resolve(options.filePath) : null;
|
|
21
|
+
const artifact = (0, runner_js_1.compileViaClpp)({
|
|
22
|
+
source,
|
|
23
|
+
fileName: diskPath ? diskPath.replace(/\\/g, "/") : relative,
|
|
24
|
+
strict: options.strict,
|
|
25
|
+
cwd: diskPath ? node_path_1.default.dirname(diskPath) : options.srcDir,
|
|
26
|
+
});
|
|
27
|
+
const luau = (0, postprocess_js_1.clppLuauToGame)(artifact, {
|
|
28
|
+
relativeName: relative,
|
|
29
|
+
outName,
|
|
30
|
+
srcDir: options.srcDir,
|
|
31
|
+
rootDir: options.rootDir,
|
|
32
|
+
strict: options.strict,
|
|
33
|
+
skipInit,
|
|
133
34
|
});
|
|
134
|
-
if (planned.files) {
|
|
135
|
-
return {
|
|
136
|
-
...planned,
|
|
137
|
-
files: planned.files.map((file) => ({
|
|
138
|
-
...file,
|
|
139
|
-
contents: attachRequires(file.contents, source, ast, opts, file.name),
|
|
140
|
-
})),
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
const luau = attachRequires((0, emit_js_1.emit)(ast, opts), source, ast, opts, planned.outName || opts.outName || fileName || "input.cpp");
|
|
144
|
-
const name = planned.outName ||
|
|
145
|
-
opts.outName ||
|
|
146
|
-
String(fileName || "input.cpp").replace(/\.(cpp|cc|cxx|c|h|hpp|hh)$/i, ".luau");
|
|
147
35
|
return {
|
|
148
|
-
kind:
|
|
149
|
-
plan:
|
|
150
|
-
files: [{ name, contents: luau }],
|
|
151
|
-
stale:
|
|
36
|
+
kind: (0, paths_js_1.emitKind)(relative),
|
|
37
|
+
plan: { kind: (0, paths_js_1.emitKind)(relative), strict: options.strict === true },
|
|
38
|
+
files: [{ name: outName, contents: luau }],
|
|
39
|
+
stale: [],
|
|
152
40
|
};
|
|
153
41
|
}
|
|
@@ -3,9 +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.
|
|
7
|
-
exports.writeCompileCommands = writeCompileCommands;
|
|
8
|
-
exports.writeClangd = writeClangd;
|
|
6
|
+
exports.isClppSource = void 0;
|
|
9
7
|
exports.diagnosticsFor = diagnosticsFor;
|
|
10
8
|
exports.syncEditorSupport = syncEditorSupport;
|
|
11
9
|
exports.installEditorExtension = installEditorExtension;
|
|
@@ -13,57 +11,11 @@ exports.installEditorSupport = installEditorSupport;
|
|
|
13
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
12
|
const node_os_1 = __importDefault(require("node:os"));
|
|
15
13
|
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
-
const
|
|
17
|
-
const preprocess_js_1 = require("./preprocess.js");
|
|
18
|
-
const editor_install_js_1 = require("./editor-install.js");
|
|
14
|
+
const node_child_process_1 = require("node:child_process");
|
|
19
15
|
const package_info_js_1 = require("./package-info.js");
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function collectFiles(dir, files = []) {
|
|
24
|
-
if (!node_fs_1.default.existsSync(dir)) {
|
|
25
|
-
return files;
|
|
26
|
-
}
|
|
27
|
-
for (const entry of node_fs_1.default.readdirSync(dir, { withFileTypes: true })) {
|
|
28
|
-
const full = node_path_1.default.join(dir, entry.name);
|
|
29
|
-
if (entry.isDirectory()) {
|
|
30
|
-
collectFiles(full, files);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
files.push(full);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return files;
|
|
37
|
-
}
|
|
38
|
-
function isCppFile(file) {
|
|
39
|
-
return /\.(cpp|cc|cxx|c|h|hpp|hh)$/i.test(file);
|
|
40
|
-
}
|
|
41
|
-
function clangCompileArgs(root) {
|
|
42
|
-
const absRoot = posix(node_path_1.default.resolve(root));
|
|
43
|
-
const absInclude = posix(node_path_1.default.join(absRoot, "include"));
|
|
44
|
-
const absSrc = posix(node_path_1.default.join(absRoot, "src"));
|
|
45
|
-
const roblox = posix(node_path_1.default.join(absInclude, "cluaupp", "roblox.hpp"));
|
|
46
|
-
return [
|
|
47
|
-
"-xc++",
|
|
48
|
-
"-std=c++20",
|
|
49
|
-
"-ferror-limit=0",
|
|
50
|
-
"-I" + absInclude,
|
|
51
|
-
"-I" + absSrc,
|
|
52
|
-
"-Iinclude",
|
|
53
|
-
"-Isrc",
|
|
54
|
-
"-include",
|
|
55
|
-
roblox,
|
|
56
|
-
];
|
|
57
|
-
}
|
|
58
|
-
function compileCommandEntry(root, file) {
|
|
59
|
-
const absRoot = posix(node_path_1.default.resolve(root));
|
|
60
|
-
const absFile = posix(node_path_1.default.resolve(file));
|
|
61
|
-
return {
|
|
62
|
-
directory: absRoot,
|
|
63
|
-
file: absFile,
|
|
64
|
-
arguments: [clangPath(), ...clangCompileArgs(root), "-c", absFile],
|
|
65
|
-
};
|
|
66
|
-
}
|
|
16
|
+
const contract_js_1 = require("./clpp/contract.js");
|
|
17
|
+
const runner_js_1 = require("./clpp/runner.js");
|
|
18
|
+
const paths_js_1 = require("./clpp/paths.js");
|
|
67
19
|
function copyDir(from, to) {
|
|
68
20
|
node_fs_1.default.mkdirSync(to, { recursive: true });
|
|
69
21
|
for (const entry of node_fs_1.default.readdirSync(from, { withFileTypes: true })) {
|
|
@@ -93,16 +45,6 @@ function uniqueStrings(...lists) {
|
|
|
93
45
|
}
|
|
94
46
|
return out;
|
|
95
47
|
}
|
|
96
|
-
function stripCppToolsSettings(current) {
|
|
97
|
-
const next = {};
|
|
98
|
-
for (const [key, value] of Object.entries(current)) {
|
|
99
|
-
if (key === "C_Cpp" || key.startsWith("C_Cpp.")) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
next[key] = value;
|
|
103
|
-
}
|
|
104
|
-
return next;
|
|
105
|
-
}
|
|
106
48
|
function readJsonObject(file) {
|
|
107
49
|
if (!node_fs_1.default.existsSync(file)) {
|
|
108
50
|
return {};
|
|
@@ -114,7 +56,7 @@ function readJsonObject(file) {
|
|
|
114
56
|
}
|
|
115
57
|
}
|
|
116
58
|
catch {
|
|
117
|
-
// ignore
|
|
59
|
+
// ignore
|
|
118
60
|
}
|
|
119
61
|
return {};
|
|
120
62
|
}
|
|
@@ -126,58 +68,6 @@ function writeJson(file, value) {
|
|
|
126
68
|
}
|
|
127
69
|
node_fs_1.default.writeFileSync(file, json, "utf8");
|
|
128
70
|
}
|
|
129
|
-
function clangdEditorArgs() {
|
|
130
|
-
return [
|
|
131
|
-
"--compile-commands-dir=${workspaceFolder}",
|
|
132
|
-
"--header-insertion=never",
|
|
133
|
-
"--query-driver=**/clang++*,**/clang++.exe,**/g++*,**/g++.exe",
|
|
134
|
-
];
|
|
135
|
-
}
|
|
136
|
-
function clangPath() {
|
|
137
|
-
return (0, editor_install_js_1.findClangPlusPlus)() || "clang++";
|
|
138
|
-
}
|
|
139
|
-
function writeCompileCommands(root, srcDir) {
|
|
140
|
-
const files = collectFiles(srcDir).filter((file) => isCppFile(file)).sort();
|
|
141
|
-
const json = `${JSON.stringify(files.map((file) => compileCommandEntry(root, file)), null, "\t")}\n`;
|
|
142
|
-
const dest = node_path_1.default.join(root, "compile_commands.json");
|
|
143
|
-
if (node_fs_1.default.existsSync(dest) && node_fs_1.default.readFileSync(dest, "utf8") === json) {
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
node_fs_1.default.writeFileSync(dest, json, "utf8");
|
|
147
|
-
return true;
|
|
148
|
-
}
|
|
149
|
-
function writeClangd(root) {
|
|
150
|
-
const flags = clangCompileArgs(root)
|
|
151
|
-
.map((flag) => ` - ${flag}`)
|
|
152
|
-
.join("\n");
|
|
153
|
-
const contents = `CompileFlags:
|
|
154
|
-
CompilationDatabase: .
|
|
155
|
-
Add:
|
|
156
|
-
${flags}
|
|
157
|
-
|
|
158
|
-
Diagnostics:
|
|
159
|
-
Suppress: '*'
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
If:
|
|
163
|
-
PathMatch: .*\\.(cpp|cc|cxx|c|h|hpp|hh)$
|
|
164
|
-
CompileFlags:
|
|
165
|
-
Add:
|
|
166
|
-
- -xc++
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
If:
|
|
170
|
-
PathMatch: (out|libs)/.*
|
|
171
|
-
Index:
|
|
172
|
-
Background: Skip
|
|
173
|
-
`;
|
|
174
|
-
const dest = node_path_1.default.join(root, ".clangd");
|
|
175
|
-
if (node_fs_1.default.existsSync(dest) && node_fs_1.default.readFileSync(dest, "utf8") === contents) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
node_fs_1.default.writeFileSync(dest, contents, "utf8");
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
71
|
function writeVscode(root) {
|
|
182
72
|
const settingsPath = node_path_1.default.join(root, ".vscode", "settings.json");
|
|
183
73
|
const current = readJsonObject(settingsPath);
|
|
@@ -185,61 +75,44 @@ function writeVscode(root) {
|
|
|
185
75
|
...((current["files.associations"] && typeof current["files.associations"] === "object" && !Array.isArray(current["files.associations"]))
|
|
186
76
|
? current["files.associations"]
|
|
187
77
|
: {}),
|
|
188
|
-
"*.
|
|
189
|
-
"*.
|
|
190
|
-
"*.
|
|
191
|
-
"*.
|
|
192
|
-
"*.
|
|
193
|
-
"*.
|
|
194
|
-
"*.legacy.server.cpp": "cpp",
|
|
195
|
-
"*.legacy.client.cpp": "cpp",
|
|
78
|
+
"*.clpp": "clpp",
|
|
79
|
+
"*.clp": "clpp",
|
|
80
|
+
"*.clh": "clpp",
|
|
81
|
+
"*.server.clpp": "clpp",
|
|
82
|
+
"*.client.clpp": "clpp",
|
|
83
|
+
"*.plugin.clpp": "clpp",
|
|
196
84
|
};
|
|
197
85
|
writeJson(settingsPath, {
|
|
198
|
-
...
|
|
199
|
-
"clangd.enable": true,
|
|
200
|
-
"clangd.arguments": clangdEditorArgs(),
|
|
86
|
+
...current,
|
|
201
87
|
"files.associations": associations,
|
|
202
88
|
});
|
|
203
89
|
const extensionsPath = node_path_1.default.join(root, ".vscode", "extensions.json");
|
|
204
90
|
const extensions = readJsonObject(extensionsPath);
|
|
205
91
|
writeJson(extensionsPath, {
|
|
206
92
|
...extensions,
|
|
207
|
-
recommendations: uniqueStrings(extensions.recommendations
|
|
93
|
+
recommendations: uniqueStrings(extensions.recommendations),
|
|
208
94
|
unwantedRecommendations: uniqueStrings(extensions.unwantedRecommendations, ["ms-vscode.cpptools"]),
|
|
209
95
|
});
|
|
210
|
-
const props = node_path_1.default.join(root, ".vscode", "c_cpp_properties.json");
|
|
211
|
-
if (node_fs_1.default.existsSync(props)) {
|
|
212
|
-
node_fs_1.default.unlinkSync(props);
|
|
213
|
-
}
|
|
214
96
|
}
|
|
215
|
-
function diagnosticsFor(source, fileName
|
|
97
|
+
function diagnosticsFor(source, fileName) {
|
|
98
|
+
if (!(0, runner_js_1.hasClpp)()) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
216
101
|
try {
|
|
217
|
-
|
|
218
|
-
(0, parse_js_1.parse)(prepared, fileName || "input.cpp");
|
|
102
|
+
(0, runner_js_1.compileViaClpp)({ source, fileName: fileName || "input.clpp" });
|
|
219
103
|
return [];
|
|
220
104
|
}
|
|
221
105
|
catch (err) {
|
|
222
|
-
const
|
|
223
|
-
const message = error.message ? String(error.message) : "parse error";
|
|
106
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
224
107
|
const match = message.match(/:(\d+):(\d+):\s*(.*)$/);
|
|
225
108
|
if (match) {
|
|
226
109
|
return [{ line: Number(match[1]), col: Number(match[2]), message: match[3], severity: "error" }];
|
|
227
110
|
}
|
|
228
|
-
return [{ line:
|
|
111
|
+
return [{ line: 1, col: 1, message, severity: "error" }];
|
|
229
112
|
}
|
|
230
113
|
}
|
|
231
|
-
function syncEditorSupport(root,
|
|
232
|
-
const srcDir = node_path_1.default.join(root, config.rootDir || "src");
|
|
233
|
-
if (node_fs_1.default.existsSync(srcDir)) {
|
|
234
|
-
writeCompileCommands(root, srcDir);
|
|
235
|
-
}
|
|
236
|
-
writeClangd(root);
|
|
114
|
+
function syncEditorSupport(root, _config = {}) {
|
|
237
115
|
writeVscode(root);
|
|
238
|
-
const flags = ["-xc++", "-std=c++20", "-ferror-limit=0", "-Iinclude", "-Isrc", "-include", "include/cluaupp/roblox.hpp"].join("\n") + "\n";
|
|
239
|
-
const flagsFile = node_path_1.default.join(root, "compile_flags.txt");
|
|
240
|
-
if (!node_fs_1.default.existsSync(flagsFile) || node_fs_1.default.readFileSync(flagsFile, "utf8") !== flags) {
|
|
241
|
-
node_fs_1.default.writeFileSync(flagsFile, flags, "utf8");
|
|
242
|
-
}
|
|
243
116
|
}
|
|
244
117
|
function installEditorExtension(cluauppRoot = package_info_js_1.projectRoot) {
|
|
245
118
|
const from = node_path_1.default.join(cluauppRoot, "editors", "vscode");
|
|
@@ -261,12 +134,20 @@ function installEditorExtension(cluauppRoot = package_info_js_1.projectRoot) {
|
|
|
261
134
|
}
|
|
262
135
|
return installed;
|
|
263
136
|
}
|
|
264
|
-
async function installEditorSupport(
|
|
265
|
-
const local = installEditorExtension(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
137
|
+
async function installEditorSupport() {
|
|
138
|
+
const local = installEditorExtension();
|
|
139
|
+
if ((0, runner_js_1.hasClpp)()) {
|
|
140
|
+
const result = (0, node_child_process_1.spawnSync)("clpp", ["install"], { encoding: "utf8", windowsHide: true });
|
|
141
|
+
if (result.status === 0) {
|
|
142
|
+
console.log(String(result.stderr || result.stdout || "clpp install ok").trim());
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log("cluaupp:", contract_js_1.CLPP_INSTALL_HINT);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log("cluaupp:", contract_js_1.CLPP_INSTALL_HINT);
|
|
150
|
+
}
|
|
151
|
+
return { local };
|
|
272
152
|
}
|
|
153
|
+
exports.isClppSource = paths_js_1.isSourceFile;
|
package/generated/libs.js
CHANGED
|
@@ -259,7 +259,7 @@ function walk(node, visit) {
|
|
|
259
259
|
function modulesFromIncludes(source) {
|
|
260
260
|
const found = new Set();
|
|
261
261
|
for (const line of String(source).split(/\r?\n/)) {
|
|
262
|
-
const match = line.match(/^\s*#\s*include\s+<cluaupp\/(?:libs\/)?([A-Za-z0-9]+)\.hpp>/);
|
|
262
|
+
const match = line.match(/^\s*#\s*include\s+<(?:clpp|cluaupp)\/(?:libs\/)?([A-Za-z0-9]+)\.(?:clh|hpp)>/);
|
|
263
263
|
if (!match) {
|
|
264
264
|
continue;
|
|
265
265
|
}
|
package/generated/lsp.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.start = start;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
4
|
const node_1 = require("vscode-languageserver/node");
|
|
9
5
|
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
10
6
|
const intellisense_js_1 = require("./intellisense.js");
|
|
@@ -28,10 +24,7 @@ function start(options = {}) {
|
|
|
28
24
|
}));
|
|
29
25
|
const publish = (document) => {
|
|
30
26
|
const file = uriPath(document.uri);
|
|
31
|
-
const items = (0, intellisense_js_1.diagnosticsFor)(document.getText(), file
|
|
32
|
-
filePath: file,
|
|
33
|
-
includeDirs: [node_path_1.default.dirname(file), node_path_1.default.join(projectRoot, "src"), node_path_1.default.join(projectRoot, "include")],
|
|
34
|
-
});
|
|
27
|
+
const items = (0, intellisense_js_1.diagnosticsFor)(document.getText(), file);
|
|
35
28
|
connection.sendDiagnostics({
|
|
36
29
|
uri: document.uri,
|
|
37
30
|
diagnostics: items.map((item) => ({
|