@tilua/compiler 2.0.0 → 2.1.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/dist/{chunk-KG6W5XKA.js → chunk-TBSJRVKA.js} +97 -20
- package/dist/cli.cjs +96 -19
- package/dist/cli.js +1 -1
- package/dist/index.cjs +96 -19
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -1929,7 +1929,7 @@ async function loadLowerings(modules) {
|
|
|
1929
1929
|
}
|
|
1930
1930
|
|
|
1931
1931
|
// src/bundle.ts
|
|
1932
|
-
import { readFileSync } from "fs";
|
|
1932
|
+
import { readFileSync, statSync } from "fs";
|
|
1933
1933
|
import { dirname, relative, resolve as resolve2 } from "path";
|
|
1934
1934
|
import {
|
|
1935
1935
|
parse,
|
|
@@ -2222,7 +2222,22 @@ ${G} = {
|
|
|
2222
2222
|
}
|
|
2223
2223
|
`;
|
|
2224
2224
|
}
|
|
2225
|
+
function stampOf(file) {
|
|
2226
|
+
try {
|
|
2227
|
+
const at = statSync(file);
|
|
2228
|
+
return `${at.size}:${at.mtimeMs}`;
|
|
2229
|
+
} catch {
|
|
2230
|
+
return void 0;
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
var parsedFiles = /* @__PURE__ */ new Map();
|
|
2225
2234
|
function parseFile(file, diagnostics, directives) {
|
|
2235
|
+
const stamp = stampOf(file);
|
|
2236
|
+
const cached = stamp !== void 0 ? parsedFiles.get(file) : void 0;
|
|
2237
|
+
if (cached && cached.stamp === stamp) {
|
|
2238
|
+
directives.set(file, cached.directives);
|
|
2239
|
+
return { program: cached.program, text: cached.text };
|
|
2240
|
+
}
|
|
2226
2241
|
let text;
|
|
2227
2242
|
try {
|
|
2228
2243
|
text = readFileSync(file, "utf8");
|
|
@@ -2232,7 +2247,9 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2232
2247
|
}
|
|
2233
2248
|
try {
|
|
2234
2249
|
const program2 = parse(text);
|
|
2235
|
-
|
|
2250
|
+
const found = directivesOf(text);
|
|
2251
|
+
directives.set(file, found);
|
|
2252
|
+
if (stamp !== void 0) parsedFiles.set(file, { stamp, program: program2, text, directives: found });
|
|
2236
2253
|
return { program: program2, text };
|
|
2237
2254
|
} catch (error) {
|
|
2238
2255
|
if (error instanceof ParseError || error instanceof LexError) {
|
|
@@ -2246,22 +2263,93 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2246
2263
|
function importedSpecifiers(program2) {
|
|
2247
2264
|
return program2.body.statements.flatMap((s) => s.type === "ImportStatement" || s.type === "ExportAllStatement" || s.type === "ExportNamedStatement" && s.source ? [s.source.value] : []);
|
|
2248
2265
|
}
|
|
2266
|
+
var libraryCache = /* @__PURE__ */ new Map();
|
|
2267
|
+
function parsedLibrary(file) {
|
|
2268
|
+
let stamp;
|
|
2269
|
+
try {
|
|
2270
|
+
const at = statSync(file);
|
|
2271
|
+
stamp = `${at.size}:${at.mtimeMs}`;
|
|
2272
|
+
} catch {
|
|
2273
|
+
stamp = "";
|
|
2274
|
+
}
|
|
2275
|
+
const cached = libraryCache.get(file);
|
|
2276
|
+
if (cached && cached.stamp === stamp) return cached.program;
|
|
2277
|
+
const program2 = parse(readFileSync(file, "utf8"));
|
|
2278
|
+
libraryCache.set(file, { stamp, program: program2 });
|
|
2279
|
+
return program2;
|
|
2280
|
+
}
|
|
2281
|
+
var moduleAnalyses = /* @__PURE__ */ new Map();
|
|
2249
2282
|
function analyzeModules(modules, config) {
|
|
2250
2283
|
const out = [];
|
|
2251
2284
|
const analyses = /* @__PURE__ */ new Map();
|
|
2252
2285
|
const libraries = config ? resolveTypeLibraries(config) : { files: [], lowerings: [], problems: [] };
|
|
2253
2286
|
for (const p of libraries.problems) out.push({ file: p.file, message: p.message, line: p.line ?? 1, column: p.column ?? 1, category: "config" });
|
|
2254
|
-
const libs = libraries.files.map(
|
|
2287
|
+
const libs = libraries.files.map(parsedLibrary);
|
|
2255
2288
|
const globals = libs.flatMap((lib) => lib.body.statements.flatMap((s) => s.type === "DeclareStatement" ? [s.name] : []));
|
|
2256
2289
|
const byFile = new Map(modules.map((m) => [m.file, m]));
|
|
2257
2290
|
const exportsCache = /* @__PURE__ */ new Map();
|
|
2258
2291
|
const inProgress = /* @__PURE__ */ new Set();
|
|
2292
|
+
const analyzed = /* @__PURE__ */ new Map();
|
|
2293
|
+
let partials = 0;
|
|
2294
|
+
const readWhile = /* @__PURE__ */ new Map();
|
|
2295
|
+
const settingFor = `${libraries.files.join("|")}#${config?.directory ?? ""}#${JSON.stringify(config?.paths ?? {})}`;
|
|
2296
|
+
const analyzeModule = (file, program2) => {
|
|
2297
|
+
const done = analyzed.get(file);
|
|
2298
|
+
if (done) return done;
|
|
2299
|
+
const remembered = moduleAnalyses.get(file);
|
|
2300
|
+
if (remembered && remembered.setting === settingFor && libs.length === remembered.libs.length && remembered.libs.every((lib, i) => lib === libs[i]) && remembered.program === program2 && [...remembered.read].every(([read, stamp]) => stampOf(read) === stamp)) {
|
|
2301
|
+
analyzed.set(file, remembered.result);
|
|
2302
|
+
readWhile.set(file, remembered.read);
|
|
2303
|
+
return remembered.result;
|
|
2304
|
+
}
|
|
2305
|
+
const scopes = analyzeScopes(program2, { builtinGlobals: globals, reportUndeclared: libs.length > 0 });
|
|
2306
|
+
const said = [];
|
|
2307
|
+
for (const d of scopes.diagnostics) {
|
|
2308
|
+
if (d.kind !== "undeclared") continue;
|
|
2309
|
+
said.push({ file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2310
|
+
}
|
|
2311
|
+
const before = partials;
|
|
2312
|
+
const types = analyzeTypes(program2, scopes, {
|
|
2313
|
+
libs,
|
|
2314
|
+
resolveModule: resolverFor(file),
|
|
2315
|
+
reportUnknownTypes: libs.length > 0
|
|
2316
|
+
});
|
|
2317
|
+
for (const d of types.diagnostics) {
|
|
2318
|
+
const at = d.node;
|
|
2319
|
+
said.push({ file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2320
|
+
}
|
|
2321
|
+
const result = { types, diagnostics: said };
|
|
2322
|
+
if (partials === before) {
|
|
2323
|
+
analyzed.set(file, result);
|
|
2324
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2325
|
+
const own = stampOf(file);
|
|
2326
|
+
if (own !== void 0) read.set(file, own);
|
|
2327
|
+
readWhile.set(file, read);
|
|
2328
|
+
if ([...read.values()].every((stamp) => stamp !== void 0)) {
|
|
2329
|
+
moduleAnalyses.set(file, { setting: settingFor, libs: [...libs], program: program2, read, result });
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
return result;
|
|
2333
|
+
};
|
|
2259
2334
|
const resolverFor = (file) => (specifier) => {
|
|
2260
2335
|
const target = resolveModulePath(file, specifier, config);
|
|
2261
2336
|
if (!target) return void 0;
|
|
2262
|
-
|
|
2337
|
+
const noteRead = () => {
|
|
2338
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2339
|
+
readWhile.set(file, read);
|
|
2340
|
+
const stamp = stampOf(target);
|
|
2341
|
+
if (stamp !== void 0) read.set(target, stamp);
|
|
2342
|
+
for (const [below, belowStamp] of readWhile.get(target) ?? []) read.set(below, belowStamp);
|
|
2343
|
+
};
|
|
2344
|
+
if (inProgress.has(target)) {
|
|
2345
|
+
partials++;
|
|
2346
|
+
return { values: /* @__PURE__ */ new Map(), types: /* @__PURE__ */ new Map(), partial: true };
|
|
2347
|
+
}
|
|
2263
2348
|
const cached = exportsCache.get(target);
|
|
2264
|
-
if (cached)
|
|
2349
|
+
if (cached) {
|
|
2350
|
+
noteRead();
|
|
2351
|
+
return cached;
|
|
2352
|
+
}
|
|
2265
2353
|
let program2 = byFile.get(target)?.program;
|
|
2266
2354
|
if (!program2) {
|
|
2267
2355
|
try {
|
|
@@ -2273,30 +2361,19 @@ function analyzeModules(modules, config) {
|
|
|
2273
2361
|
inProgress.add(target);
|
|
2274
2362
|
try {
|
|
2275
2363
|
const scopes = analyzeScopes(program2, { builtinGlobals: globals });
|
|
2276
|
-
const types = analyzeTypes(program2, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2364
|
+
const types = byFile.has(target) ? analyzeModule(target, program2).types : analyzeTypes(program2, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2277
2365
|
const exports = moduleExports(program2, scopes, types, resolverFor(target));
|
|
2278
2366
|
exportsCache.set(target, exports);
|
|
2367
|
+
noteRead();
|
|
2279
2368
|
return exports;
|
|
2280
2369
|
} finally {
|
|
2281
2370
|
inProgress.delete(target);
|
|
2282
2371
|
}
|
|
2283
2372
|
};
|
|
2284
2373
|
for (const module of modules) {
|
|
2285
|
-
const
|
|
2286
|
-
for (const d of scopes.diagnostics) {
|
|
2287
|
-
if (d.kind !== "undeclared") continue;
|
|
2288
|
-
out.push({ file: module.file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2289
|
-
}
|
|
2290
|
-
const types = analyzeTypes(module.program, scopes, {
|
|
2291
|
-
libs,
|
|
2292
|
-
resolveModule: resolverFor(module.file),
|
|
2293
|
-
reportUnknownTypes: libs.length > 0
|
|
2294
|
-
});
|
|
2374
|
+
const { types, diagnostics } = analyzeModule(module.file, module.program);
|
|
2295
2375
|
analyses.set(module.file, types);
|
|
2296
|
-
|
|
2297
|
-
const at = d.node;
|
|
2298
|
-
out.push({ file: module.file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2299
|
-
}
|
|
2376
|
+
out.push(...diagnostics);
|
|
2300
2377
|
}
|
|
2301
2378
|
return { types: analyses, diagnostics: out, lowerings: [...libraries.lowerings] };
|
|
2302
2379
|
}
|
package/dist/cli.cjs
CHANGED
|
@@ -2216,7 +2216,22 @@ ${G} = {
|
|
|
2216
2216
|
}
|
|
2217
2217
|
`;
|
|
2218
2218
|
}
|
|
2219
|
+
function stampOf(file) {
|
|
2220
|
+
try {
|
|
2221
|
+
const at = (0, import_node_fs.statSync)(file);
|
|
2222
|
+
return `${at.size}:${at.mtimeMs}`;
|
|
2223
|
+
} catch {
|
|
2224
|
+
return void 0;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
var parsedFiles = /* @__PURE__ */ new Map();
|
|
2219
2228
|
function parseFile(file, diagnostics, directives) {
|
|
2229
|
+
const stamp = stampOf(file);
|
|
2230
|
+
const cached = stamp !== void 0 ? parsedFiles.get(file) : void 0;
|
|
2231
|
+
if (cached && cached.stamp === stamp) {
|
|
2232
|
+
directives.set(file, cached.directives);
|
|
2233
|
+
return { program: cached.program, text: cached.text };
|
|
2234
|
+
}
|
|
2220
2235
|
let text;
|
|
2221
2236
|
try {
|
|
2222
2237
|
text = (0, import_node_fs.readFileSync)(file, "utf8");
|
|
@@ -2226,7 +2241,9 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2226
2241
|
}
|
|
2227
2242
|
try {
|
|
2228
2243
|
const program = (0, import_parser3.parse)(text);
|
|
2229
|
-
|
|
2244
|
+
const found = (0, import_parser3.directivesOf)(text);
|
|
2245
|
+
directives.set(file, found);
|
|
2246
|
+
if (stamp !== void 0) parsedFiles.set(file, { stamp, program, text, directives: found });
|
|
2230
2247
|
return { program, text };
|
|
2231
2248
|
} catch (error) {
|
|
2232
2249
|
if (error instanceof import_parser3.ParseError || error instanceof import_parser3.LexError) {
|
|
@@ -2240,22 +2257,93 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2240
2257
|
function importedSpecifiers(program) {
|
|
2241
2258
|
return program.body.statements.flatMap((s) => s.type === "ImportStatement" || s.type === "ExportAllStatement" || s.type === "ExportNamedStatement" && s.source ? [s.source.value] : []);
|
|
2242
2259
|
}
|
|
2260
|
+
var libraryCache = /* @__PURE__ */ new Map();
|
|
2261
|
+
function parsedLibrary(file) {
|
|
2262
|
+
let stamp;
|
|
2263
|
+
try {
|
|
2264
|
+
const at = (0, import_node_fs.statSync)(file);
|
|
2265
|
+
stamp = `${at.size}:${at.mtimeMs}`;
|
|
2266
|
+
} catch {
|
|
2267
|
+
stamp = "";
|
|
2268
|
+
}
|
|
2269
|
+
const cached = libraryCache.get(file);
|
|
2270
|
+
if (cached && cached.stamp === stamp) return cached.program;
|
|
2271
|
+
const program = (0, import_parser3.parse)((0, import_node_fs.readFileSync)(file, "utf8"));
|
|
2272
|
+
libraryCache.set(file, { stamp, program });
|
|
2273
|
+
return program;
|
|
2274
|
+
}
|
|
2275
|
+
var moduleAnalyses = /* @__PURE__ */ new Map();
|
|
2243
2276
|
function analyzeModules(modules, config2) {
|
|
2244
2277
|
const out2 = [];
|
|
2245
2278
|
const analyses = /* @__PURE__ */ new Map();
|
|
2246
2279
|
const libraries = config2 ? (0, import_parser3.resolveTypeLibraries)(config2) : { files: [], lowerings: [], problems: [] };
|
|
2247
2280
|
for (const p of libraries.problems) out2.push({ file: p.file, message: p.message, line: p.line ?? 1, column: p.column ?? 1, category: "config" });
|
|
2248
|
-
const libs = libraries.files.map(
|
|
2281
|
+
const libs = libraries.files.map(parsedLibrary);
|
|
2249
2282
|
const globals = libs.flatMap((lib) => lib.body.statements.flatMap((s) => s.type === "DeclareStatement" ? [s.name] : []));
|
|
2250
2283
|
const byFile = new Map(modules.map((m) => [m.file, m]));
|
|
2251
2284
|
const exportsCache = /* @__PURE__ */ new Map();
|
|
2252
2285
|
const inProgress = /* @__PURE__ */ new Set();
|
|
2286
|
+
const analyzed = /* @__PURE__ */ new Map();
|
|
2287
|
+
let partials = 0;
|
|
2288
|
+
const readWhile = /* @__PURE__ */ new Map();
|
|
2289
|
+
const settingFor = `${libraries.files.join("|")}#${config2?.directory ?? ""}#${JSON.stringify(config2?.paths ?? {})}`;
|
|
2290
|
+
const analyzeModule = (file, program) => {
|
|
2291
|
+
const done = analyzed.get(file);
|
|
2292
|
+
if (done) return done;
|
|
2293
|
+
const remembered = moduleAnalyses.get(file);
|
|
2294
|
+
if (remembered && remembered.setting === settingFor && libs.length === remembered.libs.length && remembered.libs.every((lib, i) => lib === libs[i]) && remembered.program === program && [...remembered.read].every(([read, stamp]) => stampOf(read) === stamp)) {
|
|
2295
|
+
analyzed.set(file, remembered.result);
|
|
2296
|
+
readWhile.set(file, remembered.read);
|
|
2297
|
+
return remembered.result;
|
|
2298
|
+
}
|
|
2299
|
+
const scopes = (0, import_parser3.analyzeScopes)(program, { builtinGlobals: globals, reportUndeclared: libs.length > 0 });
|
|
2300
|
+
const said = [];
|
|
2301
|
+
for (const d of scopes.diagnostics) {
|
|
2302
|
+
if (d.kind !== "undeclared") continue;
|
|
2303
|
+
said.push({ file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2304
|
+
}
|
|
2305
|
+
const before = partials;
|
|
2306
|
+
const types = (0, import_parser3.analyzeTypes)(program, scopes, {
|
|
2307
|
+
libs,
|
|
2308
|
+
resolveModule: resolverFor(file),
|
|
2309
|
+
reportUnknownTypes: libs.length > 0
|
|
2310
|
+
});
|
|
2311
|
+
for (const d of types.diagnostics) {
|
|
2312
|
+
const at = d.node;
|
|
2313
|
+
said.push({ file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2314
|
+
}
|
|
2315
|
+
const result = { types, diagnostics: said };
|
|
2316
|
+
if (partials === before) {
|
|
2317
|
+
analyzed.set(file, result);
|
|
2318
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2319
|
+
const own = stampOf(file);
|
|
2320
|
+
if (own !== void 0) read.set(file, own);
|
|
2321
|
+
readWhile.set(file, read);
|
|
2322
|
+
if ([...read.values()].every((stamp) => stamp !== void 0)) {
|
|
2323
|
+
moduleAnalyses.set(file, { setting: settingFor, libs: [...libs], program, read, result });
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
return result;
|
|
2327
|
+
};
|
|
2253
2328
|
const resolverFor = (file) => (specifier) => {
|
|
2254
2329
|
const target = (0, import_parser3.resolveModulePath)(file, specifier, config2);
|
|
2255
2330
|
if (!target) return void 0;
|
|
2256
|
-
|
|
2331
|
+
const noteRead = () => {
|
|
2332
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2333
|
+
readWhile.set(file, read);
|
|
2334
|
+
const stamp = stampOf(target);
|
|
2335
|
+
if (stamp !== void 0) read.set(target, stamp);
|
|
2336
|
+
for (const [below, belowStamp] of readWhile.get(target) ?? []) read.set(below, belowStamp);
|
|
2337
|
+
};
|
|
2338
|
+
if (inProgress.has(target)) {
|
|
2339
|
+
partials++;
|
|
2340
|
+
return { values: /* @__PURE__ */ new Map(), types: /* @__PURE__ */ new Map(), partial: true };
|
|
2341
|
+
}
|
|
2257
2342
|
const cached = exportsCache.get(target);
|
|
2258
|
-
if (cached)
|
|
2343
|
+
if (cached) {
|
|
2344
|
+
noteRead();
|
|
2345
|
+
return cached;
|
|
2346
|
+
}
|
|
2259
2347
|
let program = byFile.get(target)?.program;
|
|
2260
2348
|
if (!program) {
|
|
2261
2349
|
try {
|
|
@@ -2267,30 +2355,19 @@ function analyzeModules(modules, config2) {
|
|
|
2267
2355
|
inProgress.add(target);
|
|
2268
2356
|
try {
|
|
2269
2357
|
const scopes = (0, import_parser3.analyzeScopes)(program, { builtinGlobals: globals });
|
|
2270
|
-
const types = (0, import_parser3.analyzeTypes)(program, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2358
|
+
const types = byFile.has(target) ? analyzeModule(target, program).types : (0, import_parser3.analyzeTypes)(program, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2271
2359
|
const exports2 = (0, import_parser3.moduleExports)(program, scopes, types, resolverFor(target));
|
|
2272
2360
|
exportsCache.set(target, exports2);
|
|
2361
|
+
noteRead();
|
|
2273
2362
|
return exports2;
|
|
2274
2363
|
} finally {
|
|
2275
2364
|
inProgress.delete(target);
|
|
2276
2365
|
}
|
|
2277
2366
|
};
|
|
2278
2367
|
for (const module2 of modules) {
|
|
2279
|
-
const
|
|
2280
|
-
for (const d of scopes.diagnostics) {
|
|
2281
|
-
if (d.kind !== "undeclared") continue;
|
|
2282
|
-
out2.push({ file: module2.file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2283
|
-
}
|
|
2284
|
-
const types = (0, import_parser3.analyzeTypes)(module2.program, scopes, {
|
|
2285
|
-
libs,
|
|
2286
|
-
resolveModule: resolverFor(module2.file),
|
|
2287
|
-
reportUnknownTypes: libs.length > 0
|
|
2288
|
-
});
|
|
2368
|
+
const { types, diagnostics } = analyzeModule(module2.file, module2.program);
|
|
2289
2369
|
analyses.set(module2.file, types);
|
|
2290
|
-
|
|
2291
|
-
const at = d.node;
|
|
2292
|
-
out2.push({ file: module2.file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2293
|
-
}
|
|
2370
|
+
out2.push(...diagnostics);
|
|
2294
2371
|
}
|
|
2295
2372
|
return { types: analyses, diagnostics: out2, lowerings: [...libraries.lowerings] };
|
|
2296
2373
|
}
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -2240,7 +2240,22 @@ ${G} = {
|
|
|
2240
2240
|
}
|
|
2241
2241
|
`;
|
|
2242
2242
|
}
|
|
2243
|
+
function stampOf(file) {
|
|
2244
|
+
try {
|
|
2245
|
+
const at = (0, import_node_fs.statSync)(file);
|
|
2246
|
+
return `${at.size}:${at.mtimeMs}`;
|
|
2247
|
+
} catch {
|
|
2248
|
+
return void 0;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
var parsedFiles = /* @__PURE__ */ new Map();
|
|
2243
2252
|
function parseFile(file, diagnostics, directives) {
|
|
2253
|
+
const stamp = stampOf(file);
|
|
2254
|
+
const cached = stamp !== void 0 ? parsedFiles.get(file) : void 0;
|
|
2255
|
+
if (cached && cached.stamp === stamp) {
|
|
2256
|
+
directives.set(file, cached.directives);
|
|
2257
|
+
return { program: cached.program, text: cached.text };
|
|
2258
|
+
}
|
|
2244
2259
|
let text;
|
|
2245
2260
|
try {
|
|
2246
2261
|
text = (0, import_node_fs.readFileSync)(file, "utf8");
|
|
@@ -2250,7 +2265,9 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2250
2265
|
}
|
|
2251
2266
|
try {
|
|
2252
2267
|
const program2 = (0, import_parser3.parse)(text);
|
|
2253
|
-
|
|
2268
|
+
const found = (0, import_parser3.directivesOf)(text);
|
|
2269
|
+
directives.set(file, found);
|
|
2270
|
+
if (stamp !== void 0) parsedFiles.set(file, { stamp, program: program2, text, directives: found });
|
|
2254
2271
|
return { program: program2, text };
|
|
2255
2272
|
} catch (error) {
|
|
2256
2273
|
if (error instanceof import_parser3.ParseError || error instanceof import_parser3.LexError) {
|
|
@@ -2264,22 +2281,93 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2264
2281
|
function importedSpecifiers(program2) {
|
|
2265
2282
|
return program2.body.statements.flatMap((s) => s.type === "ImportStatement" || s.type === "ExportAllStatement" || s.type === "ExportNamedStatement" && s.source ? [s.source.value] : []);
|
|
2266
2283
|
}
|
|
2284
|
+
var libraryCache = /* @__PURE__ */ new Map();
|
|
2285
|
+
function parsedLibrary(file) {
|
|
2286
|
+
let stamp;
|
|
2287
|
+
try {
|
|
2288
|
+
const at = (0, import_node_fs.statSync)(file);
|
|
2289
|
+
stamp = `${at.size}:${at.mtimeMs}`;
|
|
2290
|
+
} catch {
|
|
2291
|
+
stamp = "";
|
|
2292
|
+
}
|
|
2293
|
+
const cached = libraryCache.get(file);
|
|
2294
|
+
if (cached && cached.stamp === stamp) return cached.program;
|
|
2295
|
+
const program2 = (0, import_parser3.parse)((0, import_node_fs.readFileSync)(file, "utf8"));
|
|
2296
|
+
libraryCache.set(file, { stamp, program: program2 });
|
|
2297
|
+
return program2;
|
|
2298
|
+
}
|
|
2299
|
+
var moduleAnalyses = /* @__PURE__ */ new Map();
|
|
2267
2300
|
function analyzeModules(modules, config) {
|
|
2268
2301
|
const out = [];
|
|
2269
2302
|
const analyses = /* @__PURE__ */ new Map();
|
|
2270
2303
|
const libraries = config ? (0, import_parser3.resolveTypeLibraries)(config) : { files: [], lowerings: [], problems: [] };
|
|
2271
2304
|
for (const p of libraries.problems) out.push({ file: p.file, message: p.message, line: p.line ?? 1, column: p.column ?? 1, category: "config" });
|
|
2272
|
-
const libs = libraries.files.map(
|
|
2305
|
+
const libs = libraries.files.map(parsedLibrary);
|
|
2273
2306
|
const globals = libs.flatMap((lib) => lib.body.statements.flatMap((s) => s.type === "DeclareStatement" ? [s.name] : []));
|
|
2274
2307
|
const byFile = new Map(modules.map((m) => [m.file, m]));
|
|
2275
2308
|
const exportsCache = /* @__PURE__ */ new Map();
|
|
2276
2309
|
const inProgress = /* @__PURE__ */ new Set();
|
|
2310
|
+
const analyzed = /* @__PURE__ */ new Map();
|
|
2311
|
+
let partials = 0;
|
|
2312
|
+
const readWhile = /* @__PURE__ */ new Map();
|
|
2313
|
+
const settingFor = `${libraries.files.join("|")}#${config?.directory ?? ""}#${JSON.stringify(config?.paths ?? {})}`;
|
|
2314
|
+
const analyzeModule = (file, program2) => {
|
|
2315
|
+
const done = analyzed.get(file);
|
|
2316
|
+
if (done) return done;
|
|
2317
|
+
const remembered = moduleAnalyses.get(file);
|
|
2318
|
+
if (remembered && remembered.setting === settingFor && libs.length === remembered.libs.length && remembered.libs.every((lib, i) => lib === libs[i]) && remembered.program === program2 && [...remembered.read].every(([read, stamp]) => stampOf(read) === stamp)) {
|
|
2319
|
+
analyzed.set(file, remembered.result);
|
|
2320
|
+
readWhile.set(file, remembered.read);
|
|
2321
|
+
return remembered.result;
|
|
2322
|
+
}
|
|
2323
|
+
const scopes = (0, import_parser3.analyzeScopes)(program2, { builtinGlobals: globals, reportUndeclared: libs.length > 0 });
|
|
2324
|
+
const said = [];
|
|
2325
|
+
for (const d of scopes.diagnostics) {
|
|
2326
|
+
if (d.kind !== "undeclared") continue;
|
|
2327
|
+
said.push({ file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2328
|
+
}
|
|
2329
|
+
const before = partials;
|
|
2330
|
+
const types = (0, import_parser3.analyzeTypes)(program2, scopes, {
|
|
2331
|
+
libs,
|
|
2332
|
+
resolveModule: resolverFor(file),
|
|
2333
|
+
reportUnknownTypes: libs.length > 0
|
|
2334
|
+
});
|
|
2335
|
+
for (const d of types.diagnostics) {
|
|
2336
|
+
const at = d.node;
|
|
2337
|
+
said.push({ file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2338
|
+
}
|
|
2339
|
+
const result = { types, diagnostics: said };
|
|
2340
|
+
if (partials === before) {
|
|
2341
|
+
analyzed.set(file, result);
|
|
2342
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2343
|
+
const own = stampOf(file);
|
|
2344
|
+
if (own !== void 0) read.set(file, own);
|
|
2345
|
+
readWhile.set(file, read);
|
|
2346
|
+
if ([...read.values()].every((stamp) => stamp !== void 0)) {
|
|
2347
|
+
moduleAnalyses.set(file, { setting: settingFor, libs: [...libs], program: program2, read, result });
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
return result;
|
|
2351
|
+
};
|
|
2277
2352
|
const resolverFor = (file) => (specifier) => {
|
|
2278
2353
|
const target = (0, import_parser3.resolveModulePath)(file, specifier, config);
|
|
2279
2354
|
if (!target) return void 0;
|
|
2280
|
-
|
|
2355
|
+
const noteRead = () => {
|
|
2356
|
+
const read = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2357
|
+
readWhile.set(file, read);
|
|
2358
|
+
const stamp = stampOf(target);
|
|
2359
|
+
if (stamp !== void 0) read.set(target, stamp);
|
|
2360
|
+
for (const [below, belowStamp] of readWhile.get(target) ?? []) read.set(below, belowStamp);
|
|
2361
|
+
};
|
|
2362
|
+
if (inProgress.has(target)) {
|
|
2363
|
+
partials++;
|
|
2364
|
+
return { values: /* @__PURE__ */ new Map(), types: /* @__PURE__ */ new Map(), partial: true };
|
|
2365
|
+
}
|
|
2281
2366
|
const cached = exportsCache.get(target);
|
|
2282
|
-
if (cached)
|
|
2367
|
+
if (cached) {
|
|
2368
|
+
noteRead();
|
|
2369
|
+
return cached;
|
|
2370
|
+
}
|
|
2283
2371
|
let program2 = byFile.get(target)?.program;
|
|
2284
2372
|
if (!program2) {
|
|
2285
2373
|
try {
|
|
@@ -2291,30 +2379,19 @@ function analyzeModules(modules, config) {
|
|
|
2291
2379
|
inProgress.add(target);
|
|
2292
2380
|
try {
|
|
2293
2381
|
const scopes = (0, import_parser3.analyzeScopes)(program2, { builtinGlobals: globals });
|
|
2294
|
-
const types = (0, import_parser3.analyzeTypes)(program2, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2382
|
+
const types = byFile.has(target) ? analyzeModule(target, program2).types : (0, import_parser3.analyzeTypes)(program2, scopes, { libs, resolveModule: resolverFor(target), diagnostics: false });
|
|
2295
2383
|
const exports2 = (0, import_parser3.moduleExports)(program2, scopes, types, resolverFor(target));
|
|
2296
2384
|
exportsCache.set(target, exports2);
|
|
2385
|
+
noteRead();
|
|
2297
2386
|
return exports2;
|
|
2298
2387
|
} finally {
|
|
2299
2388
|
inProgress.delete(target);
|
|
2300
2389
|
}
|
|
2301
2390
|
};
|
|
2302
2391
|
for (const module2 of modules) {
|
|
2303
|
-
const
|
|
2304
|
-
for (const d of scopes.diagnostics) {
|
|
2305
|
-
if (d.kind !== "undeclared") continue;
|
|
2306
|
-
out.push({ file: module2.file, message: d.message, line: d.node.line.start, column: d.node.column.start, category: "type" });
|
|
2307
|
-
}
|
|
2308
|
-
const types = (0, import_parser3.analyzeTypes)(module2.program, scopes, {
|
|
2309
|
-
libs,
|
|
2310
|
-
resolveModule: resolverFor(module2.file),
|
|
2311
|
-
reportUnknownTypes: libs.length > 0
|
|
2312
|
-
});
|
|
2392
|
+
const { types, diagnostics } = analyzeModule(module2.file, module2.program);
|
|
2313
2393
|
analyses.set(module2.file, types);
|
|
2314
|
-
|
|
2315
|
-
const at = d.node;
|
|
2316
|
-
out.push({ file: module2.file, message: d.message, line: at.line.start, column: at.column.start, category: "type" });
|
|
2317
|
-
}
|
|
2394
|
+
out.push(...diagnostics);
|
|
2318
2395
|
}
|
|
2319
2396
|
return { types: analyses, diagnostics: out, lowerings: [...libraries.lowerings] };
|
|
2320
2397
|
}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tilua/compiler",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Compiles tilua to Luau: lowers the @tilua/parser AST to a luau-parser AST and prints it",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"type": "module",
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"luau-parser": "^1.0.3",
|
|
40
|
-
"@tilua/parser": "^2.
|
|
40
|
+
"@tilua/parser": "^2.1.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.20.2",
|