@tsonic/frontend 0.0.38 → 0.0.40
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/.tsbuildinfo +1 -1
- package/dist/ir/binding/index.d.ts.map +1 -1
- package/dist/ir/binding/index.js +78 -9
- package/dist/ir/binding/index.js.map +1 -1
- package/dist/ir/binding-resolution.test.js +128 -0
- package/dist/ir/binding-resolution.test.js.map +1 -1
- package/dist/ir/bindings-disambiguation.test.js +9 -0
- package/dist/ir/bindings-disambiguation.test.js.map +1 -1
- package/dist/ir/converters/expressions/access.d.ts.map +1 -1
- package/dist/ir/converters/expressions/access.js +14 -24
- package/dist/ir/converters/expressions/access.js.map +1 -1
- package/dist/ir/converters/expressions/calls.d.ts +2 -2
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +133 -12
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/functions.js +1 -1
- package/dist/ir/converters/expressions/functions.js.map +1 -1
- package/dist/ir/converters/statements/control/exceptions.js +1 -1
- package/dist/ir/converters/statements/control/exceptions.js.map +1 -1
- package/dist/ir/converters/statements/control/loops.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/loops.js +5 -5
- package/dist/ir/converters/statements/control/loops.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js +25 -3
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js.map +1 -1
- package/dist/ir/converters/statements/declarations/interfaces.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/interfaces.js +20 -1
- package/dist/ir/converters/statements/declarations/interfaces.js.map +1 -1
- package/dist/ir/converters/statements/declarations/variables.js +1 -1
- package/dist/ir/converters/statements/declarations/variables.js.map +1 -1
- package/dist/ir/converters/statements/helpers.d.ts +7 -0
- package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
- package/dist/ir/converters/statements/helpers.js +14 -2
- package/dist/ir/converters/statements/helpers.js.map +1 -1
- package/dist/ir/expression-converter.d.ts.map +1 -1
- package/dist/ir/expression-converter.js +4 -3
- package/dist/ir/expression-converter.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/orchestrator.js +15 -16
- package/dist/ir/type-system/internal/type-converter/orchestrator.js.map +1 -1
- package/dist/ir/type-system/type-system.d.ts +12 -1
- package/dist/ir/type-system/type-system.d.ts.map +1 -1
- package/dist/ir/type-system/type-system.js +161 -11
- package/dist/ir/type-system/type-system.js.map +1 -1
- package/dist/ir/types/expressions.d.ts +19 -1
- package/dist/ir/types/expressions.d.ts.map +1 -1
- package/dist/ir/types/index.d.ts +1 -1
- package/dist/ir/types/index.d.ts.map +1 -1
- package/dist/ir/types/index.js.map +1 -1
- package/dist/ir/types.d.ts +1 -1
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.js +6 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.d.ts.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.js +3 -1
- package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
- package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
- package/dist/ir/validation/soundness-gate.js +9 -3
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/types/diagnostic.d.ts +1 -1
- package/dist/types/diagnostic.d.ts.map +1 -1
- package/dist/validation/core-intrinsics.d.ts.map +1 -1
- package/dist/validation/core-intrinsics.js +4 -0
- package/dist/validation/core-intrinsics.js.map +1 -1
- package/package.json +1 -1
|
@@ -230,11 +230,37 @@ export const createTypeSystem = (config) => {
|
|
|
230
230
|
* 1) AliasTable (primitives/globals/System.* canonicalization)
|
|
231
231
|
* 2) UnifiedTypeCatalog by tsName
|
|
232
232
|
* 3) UnifiedTypeCatalog by clrName
|
|
233
|
+
*
|
|
234
|
+
* IMPORTANT (airplane-grade):
|
|
235
|
+
* Resolution must be arity-aware when type arguments are present. Facade
|
|
236
|
+
* types often omit the `_N` generic arity suffix (e.g. `IList<T>` is a
|
|
237
|
+
* facade over `IList_1<T>`). When `arity` is provided and the direct
|
|
238
|
+
* resolution doesn't match, we deterministically try `<name>_<arity>`.
|
|
233
239
|
*/
|
|
234
|
-
const resolveTypeIdByName = (name) => {
|
|
235
|
-
|
|
240
|
+
const resolveTypeIdByName = (name, arity) => {
|
|
241
|
+
const direct = aliasTable.get(name) ??
|
|
236
242
|
unifiedCatalog.resolveTsName(name) ??
|
|
237
|
-
unifiedCatalog.resolveClrName(name)
|
|
243
|
+
unifiedCatalog.resolveClrName(name);
|
|
244
|
+
if (arity === undefined)
|
|
245
|
+
return direct;
|
|
246
|
+
if (direct) {
|
|
247
|
+
const directArity = unifiedCatalog.getTypeParameters(direct).length;
|
|
248
|
+
if (directArity === arity)
|
|
249
|
+
return direct;
|
|
250
|
+
}
|
|
251
|
+
// Facade name without arity suffix → try tsbindgen's structural encoding.
|
|
252
|
+
if (arity > 0) {
|
|
253
|
+
const suffixed = `${name}_${arity}`;
|
|
254
|
+
const candidate = aliasTable.get(suffixed) ??
|
|
255
|
+
unifiedCatalog.resolveTsName(suffixed) ??
|
|
256
|
+
unifiedCatalog.resolveClrName(suffixed);
|
|
257
|
+
if (candidate) {
|
|
258
|
+
const candidateArity = unifiedCatalog.getTypeParameters(candidate).length;
|
|
259
|
+
if (candidateArity === arity)
|
|
260
|
+
return candidate;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return undefined;
|
|
238
264
|
};
|
|
239
265
|
/**
|
|
240
266
|
* Attach canonical TypeIds to IR types where possible.
|
|
@@ -267,7 +293,7 @@ export const createTypeSystem = (config) => {
|
|
|
267
293
|
switch (type.kind) {
|
|
268
294
|
case "referenceType": {
|
|
269
295
|
const typeId = type.typeId ??
|
|
270
|
-
resolveTypeIdByName(type.resolvedClrType ?? type.name);
|
|
296
|
+
resolveTypeIdByName(type.resolvedClrType ?? type.name, type.typeArguments?.length);
|
|
271
297
|
return {
|
|
272
298
|
...type,
|
|
273
299
|
...(type.typeArguments
|
|
@@ -331,22 +357,24 @@ export const createTypeSystem = (config) => {
|
|
|
331
357
|
*/
|
|
332
358
|
const normalizeToNominal = (type) => {
|
|
333
359
|
if (type.kind === "referenceType") {
|
|
360
|
+
const arity = type.typeArguments?.length;
|
|
334
361
|
const typeId = type.typeId ??
|
|
335
362
|
(type.resolvedClrType
|
|
336
|
-
? resolveTypeIdByName(type.resolvedClrType)
|
|
337
|
-
: undefined) ??
|
|
363
|
+
? resolveTypeIdByName(type.resolvedClrType, arity)
|
|
364
|
+
: undefined) ??
|
|
365
|
+
resolveTypeIdByName(type.name, arity);
|
|
338
366
|
if (!typeId)
|
|
339
367
|
return undefined;
|
|
340
368
|
return { typeId, typeArgs: type.typeArguments ?? [] };
|
|
341
369
|
}
|
|
342
370
|
if (type.kind === "primitiveType") {
|
|
343
|
-
const typeId = resolveTypeIdByName(type.name);
|
|
371
|
+
const typeId = resolveTypeIdByName(type.name, 0);
|
|
344
372
|
if (!typeId)
|
|
345
373
|
return undefined;
|
|
346
374
|
return { typeId, typeArgs: [] };
|
|
347
375
|
}
|
|
348
376
|
if (type.kind === "arrayType") {
|
|
349
|
-
const arrayTypeId = resolveTypeIdByName("Array");
|
|
377
|
+
const arrayTypeId = resolveTypeIdByName("Array", 1);
|
|
350
378
|
if (!arrayTypeId)
|
|
351
379
|
return undefined;
|
|
352
380
|
return { typeId: arrayTypeId, typeArgs: [type.elementType] };
|
|
@@ -543,12 +571,31 @@ export const createTypeSystem = (config) => {
|
|
|
543
571
|
return { kind: "unionType", types: filtered };
|
|
544
572
|
};
|
|
545
573
|
const unwrapAwaitedForInference = (type) => {
|
|
574
|
+
if (type.kind === "unionType") {
|
|
575
|
+
return {
|
|
576
|
+
kind: "unionType",
|
|
577
|
+
types: type.types.map((t) => (t ? unwrapAwaitedForInference(t) : t)),
|
|
578
|
+
};
|
|
579
|
+
}
|
|
546
580
|
if (type.kind === "referenceType" &&
|
|
547
581
|
(type.name === "Promise" || type.name === "PromiseLike")) {
|
|
548
582
|
const inner = type.typeArguments?.[0];
|
|
549
583
|
if (inner)
|
|
550
584
|
return unwrapAwaitedForInference(inner);
|
|
551
585
|
}
|
|
586
|
+
if (type.kind === "referenceType") {
|
|
587
|
+
const clrName = type.typeId?.clrName;
|
|
588
|
+
if (clrName === "System.Threading.Tasks.Task" ||
|
|
589
|
+
clrName === "System.Threading.Tasks.ValueTask") {
|
|
590
|
+
return voidType;
|
|
591
|
+
}
|
|
592
|
+
if (clrName?.startsWith("System.Threading.Tasks.Task`") ||
|
|
593
|
+
clrName?.startsWith("System.Threading.Tasks.ValueTask`")) {
|
|
594
|
+
const inner = type.typeArguments?.[0];
|
|
595
|
+
if (inner)
|
|
596
|
+
return unwrapAwaitedForInference(inner);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
552
599
|
return type;
|
|
553
600
|
};
|
|
554
601
|
/**
|
|
@@ -636,6 +683,9 @@ export const createTypeSystem = (config) => {
|
|
|
636
683
|
if (objectType.kind === "primitiveType" && objectType.name === "string") {
|
|
637
684
|
return { kind: "primitiveType", name: "string" };
|
|
638
685
|
}
|
|
686
|
+
if (objectType.kind === "referenceType") {
|
|
687
|
+
return getIndexerInfo(objectType)?.valueType;
|
|
688
|
+
}
|
|
639
689
|
return undefined;
|
|
640
690
|
}
|
|
641
691
|
if (ts.isIdentifier(unwrapped)) {
|
|
@@ -1231,6 +1281,86 @@ export const createTypeSystem = (config) => {
|
|
|
1231
1281
|
emitDiagnostic("TSN5203", `Member '${memberName}' not found`, site);
|
|
1232
1282
|
return unknownType;
|
|
1233
1283
|
};
|
|
1284
|
+
const parseIndexerKeyClrType = (stableId) => {
|
|
1285
|
+
const memberSep = stableId.indexOf("::");
|
|
1286
|
+
if (memberSep < 0)
|
|
1287
|
+
return undefined;
|
|
1288
|
+
const bracketStart = stableId.indexOf("[", memberSep);
|
|
1289
|
+
if (bracketStart < 0)
|
|
1290
|
+
return undefined;
|
|
1291
|
+
let depth = 0;
|
|
1292
|
+
let bracketEnd = -1;
|
|
1293
|
+
for (let i = bracketStart; i < stableId.length; i++) {
|
|
1294
|
+
const ch = stableId[i];
|
|
1295
|
+
if (ch === "[")
|
|
1296
|
+
depth++;
|
|
1297
|
+
if (ch === "]") {
|
|
1298
|
+
depth--;
|
|
1299
|
+
if (depth === 0) {
|
|
1300
|
+
bracketEnd = i;
|
|
1301
|
+
break;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
if (bracketEnd < 0)
|
|
1306
|
+
return undefined;
|
|
1307
|
+
const rawParams = stableId.slice(bracketStart + 1, bracketEnd);
|
|
1308
|
+
// Split on top-level commas to support nested generic types.
|
|
1309
|
+
const splitTopLevel = (value) => {
|
|
1310
|
+
const parts = [];
|
|
1311
|
+
let start = 0;
|
|
1312
|
+
let bracketDepth = 0;
|
|
1313
|
+
for (let i = 0; i < value.length; i++) {
|
|
1314
|
+
const c = value[i];
|
|
1315
|
+
if (c === "[")
|
|
1316
|
+
bracketDepth++;
|
|
1317
|
+
else if (c === "]" && bracketDepth > 0)
|
|
1318
|
+
bracketDepth--;
|
|
1319
|
+
else if (c === "," && bracketDepth === 0) {
|
|
1320
|
+
parts.push(value.slice(start, i).trim());
|
|
1321
|
+
start = i + 1;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
parts.push(value.slice(start).trim());
|
|
1325
|
+
return parts.filter((p) => p.length > 0);
|
|
1326
|
+
};
|
|
1327
|
+
const params = splitTopLevel(rawParams);
|
|
1328
|
+
if (params.length !== 1)
|
|
1329
|
+
return undefined;
|
|
1330
|
+
const first = params[0];
|
|
1331
|
+
if (!first)
|
|
1332
|
+
return undefined;
|
|
1333
|
+
// Strip assembly qualification (", Assembly, Version=..., ...") if present.
|
|
1334
|
+
const withoutAsm = first.includes(",") ? (first.split(",")[0] ?? first) : first;
|
|
1335
|
+
return withoutAsm.trim();
|
|
1336
|
+
};
|
|
1337
|
+
const getIndexerInfo = (receiver, _site) => {
|
|
1338
|
+
const normalized = normalizeToNominal(receiver);
|
|
1339
|
+
if (!normalized)
|
|
1340
|
+
return undefined;
|
|
1341
|
+
// Walk inheritance chain to find the first indexer property.
|
|
1342
|
+
const chain = nominalEnv.getInheritanceChain(normalized.typeId);
|
|
1343
|
+
for (const typeId of chain) {
|
|
1344
|
+
const members = unifiedCatalog.getMembers(typeId);
|
|
1345
|
+
const indexers = Array.from(members.values()).filter((m) => m.memberKind === "property" && m.isIndexer);
|
|
1346
|
+
if (indexers.length === 0)
|
|
1347
|
+
continue;
|
|
1348
|
+
if (indexers.length > 1)
|
|
1349
|
+
return undefined;
|
|
1350
|
+
const indexer = indexers[0];
|
|
1351
|
+
if (!indexer?.type)
|
|
1352
|
+
return undefined;
|
|
1353
|
+
const keyClrType = parseIndexerKeyClrType(indexer.stableId);
|
|
1354
|
+
if (!keyClrType)
|
|
1355
|
+
return undefined;
|
|
1356
|
+
const inst = nominalEnv.getInstantiation(normalized.typeId, normalized.typeArgs, typeId);
|
|
1357
|
+
const valueType = inst && inst.size > 0
|
|
1358
|
+
? irSubstitute(indexer.type, inst)
|
|
1359
|
+
: indexer.type;
|
|
1360
|
+
return { keyClrType, valueType };
|
|
1361
|
+
}
|
|
1362
|
+
return undefined;
|
|
1363
|
+
};
|
|
1234
1364
|
// ─────────────────────────────────────────────────────────────────────────
|
|
1235
1365
|
// resolveCall — THE HEART OF DETERMINISM
|
|
1236
1366
|
// Resolve a call site: returns fully instantiated param/return types + modes
|
|
@@ -1804,7 +1934,7 @@ export const createTypeSystem = (config) => {
|
|
|
1804
1934
|
// - ReturnType/Parameters: F must be function type
|
|
1805
1935
|
// - NonNullable: Works on any type
|
|
1806
1936
|
// - Exclude/Extract: Works on any types
|
|
1807
|
-
// - Awaited: Recursive on Promise<T>
|
|
1937
|
+
// - Awaited: Recursive on Promise<T>, Task<T>, ValueTask<T>
|
|
1808
1938
|
// - Record: K must be finite literal union (string/number infinite → dictionary)
|
|
1809
1939
|
// ─────────────────────────────────────────────────────────────────────────
|
|
1810
1940
|
const expandUtility = (name, args, site) => {
|
|
@@ -2084,9 +2214,12 @@ export const createTypeSystem = (config) => {
|
|
|
2084
2214
|
return { kind: "unionType", types: filtered };
|
|
2085
2215
|
};
|
|
2086
2216
|
/**
|
|
2087
|
-
* Expand Awaited<T>: Unwrap Promise types recursively
|
|
2217
|
+
* Expand Awaited<T>: Unwrap Promise / Task / ValueTask types recursively.
|
|
2088
2218
|
*/
|
|
2089
2219
|
const expandAwaitedUtility = (type) => {
|
|
2220
|
+
if (type.kind === "unionType") {
|
|
2221
|
+
return { kind: "unionType", types: type.types.map((t) => expandAwaitedUtility(t)) };
|
|
2222
|
+
}
|
|
2090
2223
|
// Check for Promise<T>
|
|
2091
2224
|
if (type.kind === "referenceType" &&
|
|
2092
2225
|
(type.name === "Promise" || type.name === "PromiseLike")) {
|
|
@@ -2096,7 +2229,23 @@ export const createTypeSystem = (config) => {
|
|
|
2096
2229
|
return expandAwaitedUtility(innerType);
|
|
2097
2230
|
}
|
|
2098
2231
|
}
|
|
2099
|
-
//
|
|
2232
|
+
// CLR awaitables: Task / ValueTask
|
|
2233
|
+
if (type.kind === "referenceType") {
|
|
2234
|
+
const clrName = type.typeId?.clrName;
|
|
2235
|
+
// Non-generic: await Task / await ValueTask => void
|
|
2236
|
+
if (clrName === "System.Threading.Tasks.Task" ||
|
|
2237
|
+
clrName === "System.Threading.Tasks.ValueTask") {
|
|
2238
|
+
return voidType;
|
|
2239
|
+
}
|
|
2240
|
+
// Generic: await Task<T> / await ValueTask<T> => T (recursively)
|
|
2241
|
+
if (clrName?.startsWith("System.Threading.Tasks.Task`") ||
|
|
2242
|
+
clrName?.startsWith("System.Threading.Tasks.ValueTask`")) {
|
|
2243
|
+
const innerType = type.typeArguments?.[0];
|
|
2244
|
+
if (innerType)
|
|
2245
|
+
return expandAwaitedUtility(innerType);
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
// Not an awaitable - return as-is
|
|
2100
2249
|
return type;
|
|
2101
2250
|
};
|
|
2102
2251
|
/**
|
|
@@ -2559,6 +2708,7 @@ export const createTypeSystem = (config) => {
|
|
|
2559
2708
|
typeFromSyntax,
|
|
2560
2709
|
typeOfDecl,
|
|
2561
2710
|
typeOfMember,
|
|
2711
|
+
getIndexerInfo,
|
|
2562
2712
|
typeOfMemberId,
|
|
2563
2713
|
getFQNameOfDecl,
|
|
2564
2714
|
isTypeDecl,
|