@tilua/compiler 2.3.0 → 3.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/dist/{chunk-HE6YH7U3.js → chunk-X4DM2BX2.js} +179 -62
- package/dist/cli.cjs +187 -66
- package/dist/cli.js +1 -1
- package/dist/index.cjs +187 -66
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/package.json +4 -3
- package/runtime/array.luau +179 -0
- package/runtime/object.luau +54 -0
- package/runtime/string.luau +119 -0
|
@@ -21,10 +21,10 @@ var nil = () => ({ type: "NilLiteral", ...span() });
|
|
|
21
21
|
var boolean = (value) => ({ type: "BooleanLiteral", value, ...span() });
|
|
22
22
|
var number = (value, raw = String(value)) => ({ type: "NumberLiteral", value, raw, ...span() });
|
|
23
23
|
var string = (value) => ({ type: "StringLiteral", value, raw: "", ...span() });
|
|
24
|
-
var member = (
|
|
25
|
-
var index = (
|
|
24
|
+
var member = (object2, property) => isLuauName(property) ? { type: "MemberExpression", object: object2, property: identifier(property), ...span() } : index(object2, string(property));
|
|
25
|
+
var index = (object2, key) => ({ type: "IndexExpression", object: object2, index: key, ...span() });
|
|
26
26
|
var call = (callee, args) => ({ type: "CallExpression", callee, arguments: args, ...span() });
|
|
27
|
-
var methodCall = (
|
|
27
|
+
var methodCall = (object2, method, args) => ({ type: "MethodCallExpression", object: object2, method: identifier(method), arguments: args, ...span() });
|
|
28
28
|
var functionExpression = (func) => ({ type: "FunctionExpression", func, ...span() });
|
|
29
29
|
var binary = (operator, left, right) => ({ type: "BinaryExpression", operator, left, right, ...span() });
|
|
30
30
|
var unary = (operator, argument) => ({ type: "UnaryExpression", operator, argument, ...span() });
|
|
@@ -140,6 +140,62 @@ var Names = class _Names {
|
|
|
140
140
|
}
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
+
// src/language.ts
|
|
144
|
+
import { readFileSync } from "fs";
|
|
145
|
+
var read = (name) => readFileSync(new URL(`../runtime/${name}`, import.meta.url), "utf8");
|
|
146
|
+
var implemented = (source) => new Set([...source.matchAll(/function __NAME__\.(\w+)/g)].map((m) => m[1]));
|
|
147
|
+
var array = read("array.luau");
|
|
148
|
+
var string2 = read("string.luau");
|
|
149
|
+
var object = read("object.luau");
|
|
150
|
+
var arrayMethods = implemented(array);
|
|
151
|
+
var stringMethods = implemented(string2);
|
|
152
|
+
var objectMethods = implemented(object);
|
|
153
|
+
function every(type, is, seen = /* @__PURE__ */ new Set()) {
|
|
154
|
+
if (!type || seen.has(type)) return false;
|
|
155
|
+
seen.add(type);
|
|
156
|
+
if (type.kind === "union") {
|
|
157
|
+
return type.types.filter((m) => !(m.kind === "primitive" && m.name === "nil")).every((m) => every(m, is, seen));
|
|
158
|
+
}
|
|
159
|
+
if (type.kind === "typeParam") return every(type.constraint, is, seen);
|
|
160
|
+
return is(type);
|
|
161
|
+
}
|
|
162
|
+
var isArray = (type) => every(type, (t) => t.kind === "array" || t.kind === "tuple");
|
|
163
|
+
var isString = (type) => every(type, (t) => t.kind === "primitive" && t.name === "string" || t.kind === "literal" && t.base === "string" || t.kind === "templateLiteral");
|
|
164
|
+
function objectKeys(type) {
|
|
165
|
+
const members = type?.kind === "union" ? type.types : type ? [type] : [];
|
|
166
|
+
const orders = [];
|
|
167
|
+
let open = false;
|
|
168
|
+
for (const member2 of members) {
|
|
169
|
+
const keys = [];
|
|
170
|
+
for (const part of member2.kind === "intersection" ? member2.types : [member2]) {
|
|
171
|
+
if (part.kind !== "object") continue;
|
|
172
|
+
for (const key of part.properties.keys()) if (!keys.includes(key)) keys.push(key);
|
|
173
|
+
if (part.indexer) open = true;
|
|
174
|
+
}
|
|
175
|
+
orders.push(keys);
|
|
176
|
+
}
|
|
177
|
+
const order = JSON.stringify(orders[0] ?? []);
|
|
178
|
+
const known = orders.length && orders.every((keys) => JSON.stringify(keys) === order) ? `{ ${orders[0].map((key) => JSON.stringify(key)).join(", ")} }` : "nil";
|
|
179
|
+
return { known, open: String(open) };
|
|
180
|
+
}
|
|
181
|
+
var plugin = {
|
|
182
|
+
runtime: { array, string: string2, object },
|
|
183
|
+
methodCall({ method, receiver, use }) {
|
|
184
|
+
if (isString(receiver)) {
|
|
185
|
+
return stringMethods.has(method) ? { callee: `${use("string")}.${method}` } : void 0;
|
|
186
|
+
}
|
|
187
|
+
if (isArray(receiver)) {
|
|
188
|
+
return arrayMethods.has(method) ? { callee: `${use("array")}.${method}` } : void 0;
|
|
189
|
+
}
|
|
190
|
+
if (objectMethods.has(method)) {
|
|
191
|
+
const keys = objectKeys(receiver);
|
|
192
|
+
return { callee: `${use("object")}.${method}`, prepend: [keys.known, keys.open] };
|
|
193
|
+
}
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
var languageLowering = { plugin, from: "tilua" };
|
|
198
|
+
|
|
143
199
|
// src/lower.ts
|
|
144
200
|
function lower(program2, scopes, options = {}) {
|
|
145
201
|
return new Lowerer(program2, scopes, options).run();
|
|
@@ -323,21 +379,34 @@ var Lowerer = class {
|
|
|
323
379
|
if (id === void 0) return node.name;
|
|
324
380
|
return this.scopes.bindings.get(id)?.kind === "global" ? node.name : void 0;
|
|
325
381
|
}
|
|
326
|
-
/**
|
|
327
|
-
*
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
382
|
+
/** The language's own lowering, then each library's, in load order. A
|
|
383
|
+
* runtime is named by its lowering's place here (`loweringRuntime`). */
|
|
384
|
+
get lowerings() {
|
|
385
|
+
return this.allLowerings ??= [languageLowering, ...this.options.lowerings ?? []];
|
|
386
|
+
}
|
|
387
|
+
allLowerings;
|
|
388
|
+
/** What `receiver:method(...)` becomes, when Luau alone would not run it.
|
|
389
|
+
*
|
|
390
|
+
* A method the receiver's metatable gave it — the analyzer says so, and
|
|
391
|
+
* whose metatable it was (`methodSources`) — is asked of whoever declared
|
|
392
|
+
* that metatable, and only them: the language lowers its own
|
|
393
|
+
* (`names:filter(f)` becomes a call into its runtime), a library its own,
|
|
394
|
+
* and one the program declared is taken at its word. Any other method is
|
|
395
|
+
* a member of the receiver's own, which a library may still claim
|
|
396
|
+
* (`console:log`), the last library loaded first. No answer leaves an
|
|
397
|
+
* ordinary Luau method call: `text:upper()` reaches Lua's own. */
|
|
331
398
|
loweredMethodCall(node) {
|
|
332
|
-
const lowerings = this.
|
|
333
|
-
|
|
399
|
+
const lowerings = this.lowerings;
|
|
400
|
+
const source = this.options.types?.methodSources.get(node);
|
|
401
|
+
const asked = source?.origin === "language" ? [0] : source?.origin === "library" ? lowerings.flatMap((l, i) => l.library === source.library ? [i] : []) : source?.origin === "program" ? [] : lowerings.map((_, i) => i).slice(1).reverse();
|
|
402
|
+
if (!asked.some((i) => lowerings[i].plugin.methodCall)) return void 0;
|
|
334
403
|
const receiver = this.options.types?.typeOf.get(node.object);
|
|
335
404
|
const receiverGlobal = this.globalName(node.object);
|
|
336
405
|
const info = this.lazyArguments(node.arguments);
|
|
337
|
-
for (
|
|
338
|
-
const
|
|
339
|
-
if (!
|
|
340
|
-
const answer =
|
|
406
|
+
for (const i of asked) {
|
|
407
|
+
const plugin2 = lowerings[i].plugin;
|
|
408
|
+
if (!plugin2.methodCall) continue;
|
|
409
|
+
const answer = plugin2.methodCall({
|
|
341
410
|
method: node.method.name,
|
|
342
411
|
receiver,
|
|
343
412
|
receiverGlobal,
|
|
@@ -360,15 +429,15 @@ var Lowerer = class {
|
|
|
360
429
|
}
|
|
361
430
|
/** What a library says a call to a global — `print(x)` — is. */
|
|
362
431
|
loweredGlobalCall(node) {
|
|
363
|
-
const lowerings = this.
|
|
432
|
+
const lowerings = this.lowerings;
|
|
364
433
|
if (!lowerings?.some((l) => l.plugin.globalCall)) return void 0;
|
|
365
434
|
const name = this.globalName(node.callee);
|
|
366
435
|
if (name === void 0) return void 0;
|
|
367
436
|
const info = this.lazyArguments(node.arguments);
|
|
368
437
|
for (let i = lowerings.length - 1; i >= 0; i--) {
|
|
369
|
-
const
|
|
370
|
-
if (!
|
|
371
|
-
const answer =
|
|
438
|
+
const plugin2 = lowerings[i].plugin;
|
|
439
|
+
if (!plugin2.globalCall) continue;
|
|
440
|
+
const answer = plugin2.globalCall({
|
|
372
441
|
name,
|
|
373
442
|
at: this.callSite(node.callee),
|
|
374
443
|
get arguments() {
|
|
@@ -382,7 +451,7 @@ var Lowerer = class {
|
|
|
382
451
|
}
|
|
383
452
|
/** What a library says a global read as a value — `local p = print` — is. */
|
|
384
453
|
loweredGlobalValue(node) {
|
|
385
|
-
const lowerings = this.
|
|
454
|
+
const lowerings = this.lowerings;
|
|
386
455
|
if (!lowerings?.some((l) => l.plugin.globalValue)) return void 0;
|
|
387
456
|
const name = this.globalName(node);
|
|
388
457
|
if (name === void 0) return void 0;
|
|
@@ -412,7 +481,7 @@ var Lowerer = class {
|
|
|
412
481
|
try {
|
|
413
482
|
return parseExpressionFromSource(source);
|
|
414
483
|
} catch (error) {
|
|
415
|
-
this.report(node, `'${this.
|
|
484
|
+
this.report(node, `'${this.lowerings[index2].from}' lowered this to Luau that does not parse: ${JSON.stringify(source)} (${error.message})`);
|
|
416
485
|
return void 0;
|
|
417
486
|
}
|
|
418
487
|
}
|
|
@@ -433,8 +502,8 @@ var Lowerer = class {
|
|
|
433
502
|
], true)));
|
|
434
503
|
}
|
|
435
504
|
for (const { index: index2, runtime: runtime2, name } of this.loweringUsed) {
|
|
436
|
-
const { plugin, from } = this.
|
|
437
|
-
const source =
|
|
505
|
+
const { plugin: plugin2, from } = this.lowerings[index2];
|
|
506
|
+
const source = plugin2.runtime?.[runtime2];
|
|
438
507
|
if (source === void 0) {
|
|
439
508
|
this.diagnostics.push({
|
|
440
509
|
message: `'${from}' asked for a runtime it does not have: '${runtime2}'`,
|
|
@@ -769,6 +838,7 @@ var Lowerer = class {
|
|
|
769
838
|
case "ExportTypeAliasStatement":
|
|
770
839
|
case "DeclareStatement":
|
|
771
840
|
case "DeclareClassStatement":
|
|
841
|
+
case "DeclareMetatableStatement":
|
|
772
842
|
case "ErrorStatement":
|
|
773
843
|
return [];
|
|
774
844
|
case "VariableDeclaration":
|
|
@@ -846,12 +916,13 @@ var Lowerer = class {
|
|
|
846
916
|
}];
|
|
847
917
|
case "GenericForStatement": {
|
|
848
918
|
const prelude = [];
|
|
919
|
+
const variable = declared(node.variable);
|
|
849
920
|
let item;
|
|
850
|
-
if (
|
|
851
|
-
item = this.name(
|
|
921
|
+
if (variable.type === "IdentifierPattern") {
|
|
922
|
+
item = this.name(variable.name);
|
|
852
923
|
} else {
|
|
853
924
|
item = this.names.fresh("item");
|
|
854
|
-
prelude.push(...this.destructure(
|
|
925
|
+
prelude.push(...this.destructure(variable, identifier(item), "declare"));
|
|
855
926
|
}
|
|
856
927
|
const form = this.options.types?.loops.get(node) ?? { walks: "values", viaIter: false };
|
|
857
928
|
let source = this.expression(node.iterator);
|
|
@@ -1118,7 +1189,7 @@ end
|
|
|
1118
1189
|
* level, where every name is declared up front — nothing is declared,
|
|
1119
1190
|
* only assigned. */
|
|
1120
1191
|
variableDeclaration(node, mode) {
|
|
1121
|
-
const target = node.name;
|
|
1192
|
+
const target = declared(node.name);
|
|
1122
1193
|
if (!node.init) {
|
|
1123
1194
|
const names = identifierPatterns(target);
|
|
1124
1195
|
if (mode === "declare") return [local(names.map((p) => this.name(p.name)), [])];
|
|
@@ -1160,6 +1231,12 @@ end
|
|
|
1160
1231
|
const reads = [];
|
|
1161
1232
|
const after = [];
|
|
1162
1233
|
const bind = (target, value, fallback) => {
|
|
1234
|
+
if (target.type === "MemberExpression" || target.type === "IndexExpression") {
|
|
1235
|
+
const reference = this.expression(target);
|
|
1236
|
+
reads.push({ name: "", target: reference, value, temp: false });
|
|
1237
|
+
if (fallback) after.push(this.defaultValue(reference, fallback));
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1163
1240
|
if (target.type === "IdentifierPattern") {
|
|
1164
1241
|
const name2 = this.name(target.name);
|
|
1165
1242
|
const reference = mode === "declare" ? identifier(name2) : this.reference(target);
|
|
@@ -1232,6 +1309,11 @@ end
|
|
|
1232
1309
|
* a temporary that a nested pattern then destructures (`then`). The
|
|
1233
1310
|
* statement creating it is pushed onto `after`. */
|
|
1234
1311
|
restTarget(target, initial, mode, after) {
|
|
1312
|
+
if (target.type === "MemberExpression" || target.type === "IndexExpression") {
|
|
1313
|
+
const reference = this.expression(target);
|
|
1314
|
+
after.push(assign([reference], [initial]));
|
|
1315
|
+
return { target: reference, then: [] };
|
|
1316
|
+
}
|
|
1235
1317
|
if (target.type === "IdentifierPattern") {
|
|
1236
1318
|
if (mode === "declare") {
|
|
1237
1319
|
const name2 = this.name(target.name);
|
|
@@ -1357,11 +1439,11 @@ end
|
|
|
1357
1439
|
callValues(node) {
|
|
1358
1440
|
const chain = optionalChain(node);
|
|
1359
1441
|
if (chain) return this.optionalChainExpression(chain);
|
|
1360
|
-
const
|
|
1361
|
-
if (node.type === "CallExpression" &&
|
|
1362
|
-
return this.link(node, this.reference(
|
|
1442
|
+
const object2 = linkObject(node);
|
|
1443
|
+
if (node.type === "CallExpression" && object2.type === "Identifier") {
|
|
1444
|
+
return this.link(node, this.reference(object2));
|
|
1363
1445
|
}
|
|
1364
|
-
return this.link(node, this.expression(
|
|
1446
|
+
return this.link(node, this.expression(object2));
|
|
1365
1447
|
}
|
|
1366
1448
|
/** A call is one value in tilua, and Luau would hand on every value one
|
|
1367
1449
|
* returns in the last place of an argument list or a `return`: it is
|
|
@@ -1380,11 +1462,13 @@ end
|
|
|
1380
1462
|
* the last value of a list expands, so the whole list is built as an
|
|
1381
1463
|
* array first and that is what expands. A call written last is one
|
|
1382
1464
|
* value — see `keptToOne`. */
|
|
1383
|
-
arguments(
|
|
1465
|
+
arguments(written) {
|
|
1466
|
+
const { items: list, many } = packs(written);
|
|
1384
1467
|
const spreads = list.filter((a) => a.type === "SpreadElement");
|
|
1385
1468
|
if (!spreads.length) {
|
|
1386
1469
|
const lowered = list.map((a) => this.expression(a));
|
|
1387
|
-
|
|
1470
|
+
const last2 = list.length - 1;
|
|
1471
|
+
return lowered.length && !many.has(list[last2]) ? [...lowered.slice(0, -1), this.keptToOne(lowered[last2])] : lowered;
|
|
1388
1472
|
}
|
|
1389
1473
|
const unpack = (value) => call(member(this.builtin("table"), "unpack"), [value]);
|
|
1390
1474
|
const last = list[list.length - 1];
|
|
@@ -1398,16 +1482,16 @@ end
|
|
|
1398
1482
|
}))];
|
|
1399
1483
|
}
|
|
1400
1484
|
/** One link of an access chain, read from `object`. */
|
|
1401
|
-
link(node,
|
|
1485
|
+
link(node, object2) {
|
|
1402
1486
|
switch (node.type) {
|
|
1403
1487
|
case "MemberExpression":
|
|
1404
|
-
return member(
|
|
1488
|
+
return member(object2, node.property.name);
|
|
1405
1489
|
case "IndexExpression":
|
|
1406
|
-
return index(
|
|
1490
|
+
return index(object2, this.expression(node.index));
|
|
1407
1491
|
case "CallExpression": {
|
|
1408
1492
|
const lowered = this.loweredGlobalCall(node);
|
|
1409
1493
|
const args = this.arguments(node.arguments);
|
|
1410
|
-
if (!lowered) return call(
|
|
1494
|
+
if (!lowered) return call(object2, args);
|
|
1411
1495
|
return call(calleePath(lowered.callee), [...lowered.prepend, ...args]);
|
|
1412
1496
|
}
|
|
1413
1497
|
case "MethodCallExpression": {
|
|
@@ -1416,14 +1500,14 @@ end
|
|
|
1416
1500
|
if (lowered) {
|
|
1417
1501
|
return call(calleePath(lowered.callee), [
|
|
1418
1502
|
...lowered.prepend,
|
|
1419
|
-
...lowered.passReceiver ? [
|
|
1503
|
+
...lowered.passReceiver ? [object2] : [],
|
|
1420
1504
|
...args
|
|
1421
1505
|
]);
|
|
1422
1506
|
}
|
|
1423
1507
|
if (!isLuauName(node.method.name)) {
|
|
1424
1508
|
this.report(node.method, `'${node.method.name}' is a Luau keyword and cannot be called with ':'`);
|
|
1425
1509
|
}
|
|
1426
|
-
return methodCall(
|
|
1510
|
+
return methodCall(object2, node.method.name, args);
|
|
1427
1511
|
}
|
|
1428
1512
|
}
|
|
1429
1513
|
}
|
|
@@ -1444,8 +1528,8 @@ end
|
|
|
1444
1528
|
}
|
|
1445
1529
|
return out;
|
|
1446
1530
|
}
|
|
1447
|
-
applySegment(segment,
|
|
1448
|
-
return segment.reduce((value, link) => this.link(link, value),
|
|
1531
|
+
applySegment(segment, object2) {
|
|
1532
|
+
return segment.reduce((value, link) => this.link(link, value), object2);
|
|
1449
1533
|
}
|
|
1450
1534
|
/** `a?.b:m()` as a statement:
|
|
1451
1535
|
* `do local ref = a if ref ~= nil then ref.b:m() end end` */
|
|
@@ -1521,9 +1605,9 @@ end
|
|
|
1521
1605
|
const before = [];
|
|
1522
1606
|
let target;
|
|
1523
1607
|
if (node.target.type === "MemberExpression" || node.target.type === "IndexExpression") {
|
|
1524
|
-
const
|
|
1608
|
+
const object2 = this.expression(node.target.object);
|
|
1525
1609
|
const objectName = this.names.fresh("target");
|
|
1526
|
-
before.push(local([objectName], [
|
|
1610
|
+
before.push(local([objectName], [object2]));
|
|
1527
1611
|
if (node.target.type === "MemberExpression") {
|
|
1528
1612
|
target = member(identifier(objectName), node.target.property.name);
|
|
1529
1613
|
} else {
|
|
@@ -1645,8 +1729,9 @@ end
|
|
|
1645
1729
|
/** `[1, ...xs, 2]`. Without a spread it is a Luau sequence; with one, the
|
|
1646
1730
|
* runs of plain elements and the spread arrays are joined by `concat`. */
|
|
1647
1731
|
arrayExpression(node) {
|
|
1648
|
-
|
|
1649
|
-
|
|
1732
|
+
const elements = packs(node.elements).items;
|
|
1733
|
+
if (!elements.some((e) => e.type === "SpreadElement")) {
|
|
1734
|
+
return table(elements.map((e) => ({ type: "TableFieldPositional", value: this.expression(e) })));
|
|
1650
1735
|
}
|
|
1651
1736
|
const parts = [];
|
|
1652
1737
|
let current = [];
|
|
@@ -1658,7 +1743,7 @@ end
|
|
|
1658
1743
|
})));
|
|
1659
1744
|
current = [];
|
|
1660
1745
|
};
|
|
1661
|
-
for (const element of
|
|
1746
|
+
for (const element of elements) {
|
|
1662
1747
|
if (element.type === "SpreadElement") {
|
|
1663
1748
|
flush(false);
|
|
1664
1749
|
parts.push(this.expression(element.argument));
|
|
@@ -1670,6 +1755,29 @@ end
|
|
|
1670
1755
|
return call(this.helper("concat"), parts);
|
|
1671
1756
|
}
|
|
1672
1757
|
};
|
|
1758
|
+
function packs(list) {
|
|
1759
|
+
const items = [];
|
|
1760
|
+
const many = /* @__PURE__ */ new Set();
|
|
1761
|
+
const add = (elements) => {
|
|
1762
|
+
for (const element of elements) {
|
|
1763
|
+
if (element.type === "SpreadElement" && element.argument.type === "ArrayExpression") {
|
|
1764
|
+
const inner = element.argument.elements;
|
|
1765
|
+
add(inner);
|
|
1766
|
+
const last = inner[inner.length - 1];
|
|
1767
|
+
if (last && (last.type === "CallExpression" || last.type === "MethodCallExpression")) many.add(last);
|
|
1768
|
+
} else {
|
|
1769
|
+
items.push(element);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
add(list);
|
|
1774
|
+
items.forEach((item, i) => {
|
|
1775
|
+
if (!many.has(item) || i === items.length - 1) return;
|
|
1776
|
+
many.delete(item);
|
|
1777
|
+
items[i] = { type: "SpreadElement", argument: { type: "ArrayExpression", elements: [item], ...spanOf(item) }, ...spanOf(item) };
|
|
1778
|
+
});
|
|
1779
|
+
return { items, many };
|
|
1780
|
+
}
|
|
1673
1781
|
function isLink(node) {
|
|
1674
1782
|
return node.type === "MemberExpression" || node.type === "IndexExpression" || node.type === "CallExpression" || node.type === "MethodCallExpression";
|
|
1675
1783
|
}
|
|
@@ -1718,10 +1826,19 @@ function memberChain(e) {
|
|
|
1718
1826
|
}
|
|
1719
1827
|
return void 0;
|
|
1720
1828
|
}
|
|
1829
|
+
function declared(target) {
|
|
1830
|
+
if (target.type === "MemberExpression" || target.type === "IndexExpression") {
|
|
1831
|
+
throw new Error("a declaration binds names, not a member or an index");
|
|
1832
|
+
}
|
|
1833
|
+
return target;
|
|
1834
|
+
}
|
|
1721
1835
|
function identifierPatterns(target) {
|
|
1722
1836
|
switch (target.type) {
|
|
1723
1837
|
case "IdentifierPattern":
|
|
1724
1838
|
return [target];
|
|
1839
|
+
case "MemberExpression":
|
|
1840
|
+
case "IndexExpression":
|
|
1841
|
+
return [];
|
|
1725
1842
|
case "ObjectPattern":
|
|
1726
1843
|
return [...target.properties.flatMap((p) => identifierPatterns(p.value)), ...target.rest ? identifierPatterns(target.rest) : []];
|
|
1727
1844
|
case "ArrayPattern":
|
|
@@ -1871,15 +1988,15 @@ async function loadLowerings(modules) {
|
|
|
1871
1988
|
for (const module of modules) {
|
|
1872
1989
|
try {
|
|
1873
1990
|
const loaded = await import(pathToFileURL(module.file).href);
|
|
1874
|
-
const
|
|
1875
|
-
if (!
|
|
1991
|
+
const plugin2 = loaded.default;
|
|
1992
|
+
if (!plugin2 || typeof plugin2 !== "object") {
|
|
1876
1993
|
problems.push({
|
|
1877
1994
|
file: module.file,
|
|
1878
1995
|
message: `'${module.from}' lowering module has no default export`
|
|
1879
1996
|
});
|
|
1880
1997
|
continue;
|
|
1881
1998
|
}
|
|
1882
|
-
lowerings.push({ plugin, from: module.from });
|
|
1999
|
+
lowerings.push({ plugin: plugin2, from: module.from, library: module.library });
|
|
1883
2000
|
} catch (error) {
|
|
1884
2001
|
problems.push({
|
|
1885
2002
|
file: module.file,
|
|
@@ -1891,7 +2008,7 @@ async function loadLowerings(modules) {
|
|
|
1891
2008
|
}
|
|
1892
2009
|
|
|
1893
2010
|
// src/bundle.ts
|
|
1894
|
-
import { readFileSync, statSync } from "fs";
|
|
2011
|
+
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
1895
2012
|
import { dirname, relative, resolve as resolve2 } from "path";
|
|
1896
2013
|
import {
|
|
1897
2014
|
parse,
|
|
@@ -2202,7 +2319,7 @@ function parseFile(file, diagnostics, directives) {
|
|
|
2202
2319
|
}
|
|
2203
2320
|
let text;
|
|
2204
2321
|
try {
|
|
2205
|
-
text =
|
|
2322
|
+
text = readFileSync2(file, "utf8");
|
|
2206
2323
|
} catch {
|
|
2207
2324
|
diagnostics.push({ file, message: "Cannot read file", line: 1, column: 1, category: "module" });
|
|
2208
2325
|
return void 0;
|
|
@@ -2236,7 +2353,7 @@ function parsedLibrary(file) {
|
|
|
2236
2353
|
}
|
|
2237
2354
|
const cached = libraryCache.get(file);
|
|
2238
2355
|
if (cached && cached.stamp === stamp) return cached.program;
|
|
2239
|
-
const program2 = parse(
|
|
2356
|
+
const program2 = parse(readFileSync2(file, "utf8"));
|
|
2240
2357
|
libraryCache.set(file, { stamp, program: program2 });
|
|
2241
2358
|
return program2;
|
|
2242
2359
|
}
|
|
@@ -2259,7 +2376,7 @@ function analyzeModules(modules, config) {
|
|
|
2259
2376
|
const done = analyzed.get(file);
|
|
2260
2377
|
if (done) return done;
|
|
2261
2378
|
const remembered = moduleAnalyses.get(file);
|
|
2262
|
-
if (remembered && remembered.setting === settingFor && libs.length === remembered.libs.length && remembered.libs.every((lib, i) => lib === libs[i]) && remembered.program === program2 && [...remembered.read].every(([
|
|
2379
|
+
if (remembered && remembered.setting === settingFor && libs.length === remembered.libs.length && remembered.libs.every((lib, i) => lib === libs[i]) && remembered.program === program2 && [...remembered.read].every(([read2, stamp]) => stampOf(read2) === stamp)) {
|
|
2263
2380
|
analyzed.set(file, remembered.result);
|
|
2264
2381
|
readWhile.set(file, remembered.read);
|
|
2265
2382
|
return remembered.result;
|
|
@@ -2283,12 +2400,12 @@ function analyzeModules(modules, config) {
|
|
|
2283
2400
|
const result = { types, diagnostics: said };
|
|
2284
2401
|
if (partials === before) {
|
|
2285
2402
|
analyzed.set(file, result);
|
|
2286
|
-
const
|
|
2403
|
+
const read2 = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2287
2404
|
const own = stampOf(file);
|
|
2288
|
-
if (own !== void 0)
|
|
2289
|
-
readWhile.set(file,
|
|
2290
|
-
if ([...
|
|
2291
|
-
moduleAnalyses.set(file, { setting: settingFor, libs: [...libs], program: program2, read, result });
|
|
2405
|
+
if (own !== void 0) read2.set(file, own);
|
|
2406
|
+
readWhile.set(file, read2);
|
|
2407
|
+
if ([...read2.values()].every((stamp) => stamp !== void 0)) {
|
|
2408
|
+
moduleAnalyses.set(file, { setting: settingFor, libs: [...libs], program: program2, read: read2, result });
|
|
2292
2409
|
}
|
|
2293
2410
|
}
|
|
2294
2411
|
return result;
|
|
@@ -2297,11 +2414,11 @@ function analyzeModules(modules, config) {
|
|
|
2297
2414
|
const target = resolveModulePath(file, specifier, config);
|
|
2298
2415
|
if (!target) return void 0;
|
|
2299
2416
|
const noteRead = () => {
|
|
2300
|
-
const
|
|
2301
|
-
readWhile.set(file,
|
|
2417
|
+
const read2 = readWhile.get(file) ?? /* @__PURE__ */ new Map();
|
|
2418
|
+
readWhile.set(file, read2);
|
|
2302
2419
|
const stamp = stampOf(target);
|
|
2303
|
-
if (stamp !== void 0)
|
|
2304
|
-
for (const [below, belowStamp] of readWhile.get(target) ?? [])
|
|
2420
|
+
if (stamp !== void 0) read2.set(target, stamp);
|
|
2421
|
+
for (const [below, belowStamp] of readWhile.get(target) ?? []) read2.set(below, belowStamp);
|
|
2305
2422
|
};
|
|
2306
2423
|
if (inProgress.has(target)) {
|
|
2307
2424
|
partials++;
|
|
@@ -2315,7 +2432,7 @@ function analyzeModules(modules, config) {
|
|
|
2315
2432
|
let program2 = byFile.get(target)?.program;
|
|
2316
2433
|
if (!program2) {
|
|
2317
2434
|
try {
|
|
2318
|
-
program2 = parse(
|
|
2435
|
+
program2 = parse(readFileSync2(target, "utf8"));
|
|
2319
2436
|
} catch {
|
|
2320
2437
|
return void 0;
|
|
2321
2438
|
}
|