@tsonic/frontend 0.0.12 → 0.0.13
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/converters/expressions/access.d.ts.map +1 -1
- package/dist/ir/converters/expressions/access.js +61 -1
- package/dist/ir/converters/expressions/access.js.map +1 -1
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +293 -24
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/helpers.js +4 -4
- package/dist/ir/converters/expressions/helpers.js.map +1 -1
- package/dist/ir/converters/expressions/literals.d.ts +14 -0
- package/dist/ir/converters/expressions/literals.d.ts.map +1 -1
- package/dist/ir/converters/expressions/literals.js +22 -2
- package/dist/ir/converters/expressions/literals.js.map +1 -1
- package/dist/ir/converters/expressions/numeric-recovery.test.js +3 -2
- package/dist/ir/converters/expressions/numeric-recovery.test.js.map +1 -1
- package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
- package/dist/ir/converters/statements/helpers.js +10 -4
- 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 +38 -5
- package/dist/ir/expression-converter.js.map +1 -1
- package/dist/ir/index.d.ts +1 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +1 -1
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/statement-converter.d.ts.map +1 -1
- package/dist/ir/statement-converter.js +12 -0
- package/dist/ir/statement-converter.js.map +1 -1
- package/dist/ir/type-converter/inference.d.ts.map +1 -1
- package/dist/ir/type-converter/inference.js +50 -7
- package/dist/ir/type-converter/inference.js.map +1 -1
- package/dist/ir/type-converter/primitives.d.ts +26 -4
- package/dist/ir/type-converter/primitives.d.ts.map +1 -1
- package/dist/ir/type-converter/primitives.js +36 -2
- package/dist/ir/type-converter/primitives.js.map +1 -1
- package/dist/ir/type-converter/references.d.ts.map +1 -1
- package/dist/ir/type-converter/references.js +324 -11
- package/dist/ir/type-converter/references.js.map +1 -1
- package/dist/ir/type-converter/utility-types.d.ts +93 -0
- package/dist/ir/type-converter/utility-types.d.ts.map +1 -0
- package/dist/ir/type-converter/utility-types.js +528 -0
- package/dist/ir/type-converter/utility-types.js.map +1 -0
- package/dist/ir/type-converter/utility-types.test.d.ts +10 -0
- package/dist/ir/type-converter/utility-types.test.d.ts.map +1 -0
- package/dist/ir/type-converter/utility-types.test.js +1030 -0
- package/dist/ir/type-converter/utility-types.test.js.map +1 -0
- package/dist/ir/types/expressions.d.ts +40 -2
- package/dist/ir/types/expressions.d.ts.map +1 -1
- package/dist/ir/types/helpers.d.ts +3 -1
- package/dist/ir/types/helpers.d.ts.map +1 -1
- package/dist/ir/types/index.d.ts +2 -1
- package/dist/ir/types/index.d.ts.map +1 -1
- package/dist/ir/types/index.js +2 -0
- package/dist/ir/types/index.js.map +1 -1
- package/dist/ir/types/ir-types.d.ts +69 -11
- package/dist/ir/types/ir-types.d.ts.map +1 -1
- package/dist/ir/types/numeric-helpers.d.ts +46 -0
- package/dist/ir/types/numeric-helpers.d.ts.map +1 -0
- package/dist/ir/types/numeric-helpers.js +105 -0
- package/dist/ir/types/numeric-helpers.js.map +1 -0
- package/dist/ir/types/statements.d.ts +11 -1
- package/dist/ir/types/statements.d.ts.map +1 -1
- package/dist/ir/types.d.ts +2 -2
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +3 -1
- package/dist/ir/types.js.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts +32 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.js +854 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts +37 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.js +282 -0
- package/dist/ir/validation/attribute-collection-pass.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.test.d.ts +5 -0
- package/dist/ir/validation/attribute-collection-pass.test.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.test.js +215 -0
- package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -0
- package/dist/ir/validation/index.d.ts +3 -0
- package/dist/ir/validation/index.d.ts.map +1 -1
- package/dist/ir/validation/index.js +3 -0
- package/dist/ir/validation/index.js.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.d.ts +77 -0
- package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -0
- package/dist/ir/validation/numeric-coercion-pass.js +686 -0
- package/dist/ir/validation/numeric-coercion-pass.js.map +1 -0
- package/dist/ir/validation/numeric-invariants.test.js +130 -14
- package/dist/ir/validation/numeric-invariants.test.js.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.d.ts.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.js +68 -108
- 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 +23 -12
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/ir/validation/yield-lowering-pass.test.js +21 -12
- package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
- package/dist/program/bindings.d.ts +20 -9
- package/dist/program/bindings.d.ts.map +1 -1
- package/dist/program/bindings.js +98 -36
- package/dist/program/bindings.js.map +1 -1
- package/dist/program/bindings.test.js +3 -3
- package/dist/program/dependency-graph.d.ts.map +1 -1
- package/dist/program/dependency-graph.js +31 -5
- package/dist/program/dependency-graph.js.map +1 -1
- package/dist/resolver/import-resolution.d.ts +4 -0
- package/dist/resolver/import-resolution.d.ts.map +1 -1
- package/dist/resolver/import-resolution.js +18 -7
- package/dist/resolver/import-resolution.js.map +1 -1
- package/dist/resolver.test.js +2 -2
- package/dist/resolver.test.js.map +1 -1
- package/dist/types/diagnostic.d.ts +1 -1
- package/dist/types/diagnostic.d.ts.map +1 -1
- package/dist/types/diagnostic.js.map +1 -1
- package/dist/validation/generics.d.ts.map +1 -1
- package/dist/validation/generics.js +133 -1
- package/dist/validation/generics.js.map +1 -1
- package/dist/validation/static-safety.js +13 -0
- package/dist/validation/static-safety.js.map +1 -1
- package/dist/validation/unsupported-utility-types.d.ts +10 -8
- package/dist/validation/unsupported-utility-types.d.ts.map +1 -1
- package/dist/validation/unsupported-utility-types.js +12 -19
- package/dist/validation/unsupported-utility-types.js.map +1 -1
- package/dist/validator.test.js +133 -28
- package/dist/validator.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility type expansion - Partial, Required, Readonly, Pick, Omit
|
|
3
|
+
*
|
|
4
|
+
* These utility types are expanded at compile time by resolving the type
|
|
5
|
+
* through TypeScript's type checker and converting the result to IrObjectType.
|
|
6
|
+
*/
|
|
7
|
+
import * as ts from "typescript";
|
|
8
|
+
/**
|
|
9
|
+
* Set of supported mapped utility types that can be expanded
|
|
10
|
+
*/
|
|
11
|
+
export const EXPANDABLE_UTILITY_TYPES = new Set([
|
|
12
|
+
"Partial",
|
|
13
|
+
"Required",
|
|
14
|
+
"Readonly",
|
|
15
|
+
"Pick",
|
|
16
|
+
"Omit",
|
|
17
|
+
]);
|
|
18
|
+
/**
|
|
19
|
+
* Check if a type name is an expandable utility type
|
|
20
|
+
*/
|
|
21
|
+
export const isExpandableUtilityType = (name) => EXPANDABLE_UTILITY_TYPES.has(name);
|
|
22
|
+
/**
|
|
23
|
+
* Set of supported conditional utility types that can be expanded
|
|
24
|
+
* These delegate to TypeScript's type checker for evaluation.
|
|
25
|
+
*/
|
|
26
|
+
export const EXPANDABLE_CONDITIONAL_UTILITY_TYPES = new Set([
|
|
27
|
+
"NonNullable",
|
|
28
|
+
"Exclude",
|
|
29
|
+
"Extract",
|
|
30
|
+
"ReturnType",
|
|
31
|
+
"Parameters",
|
|
32
|
+
"Awaited",
|
|
33
|
+
]);
|
|
34
|
+
/**
|
|
35
|
+
* Check if a type name is an expandable conditional utility type
|
|
36
|
+
*/
|
|
37
|
+
export const isExpandableConditionalUtilityType = (name) => EXPANDABLE_CONDITIONAL_UTILITY_TYPES.has(name);
|
|
38
|
+
/**
|
|
39
|
+
* Check if a type node explicitly contains undefined in a union.
|
|
40
|
+
* Used to detect explicit `x?: T | undefined` vs synthetic `x?: T`.
|
|
41
|
+
*/
|
|
42
|
+
const typeNodeContainsUndefined = (typeNode) => {
|
|
43
|
+
if (!typeNode)
|
|
44
|
+
return false;
|
|
45
|
+
if (ts.isUnionTypeNode(typeNode)) {
|
|
46
|
+
return typeNode.types.some((t) => t.kind === ts.SyntaxKind.UndefinedKeyword);
|
|
47
|
+
}
|
|
48
|
+
return typeNode.kind === ts.SyntaxKind.UndefinedKeyword;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Check if ANY declaration in the list explicitly contains undefined.
|
|
52
|
+
* Handles merged declarations where any declaration might have explicit undefined.
|
|
53
|
+
*/
|
|
54
|
+
const anyDeclarationHasExplicitUndefined = (declarations) => {
|
|
55
|
+
if (!declarations)
|
|
56
|
+
return false;
|
|
57
|
+
return declarations.some((decl) => {
|
|
58
|
+
if (ts.isPropertySignature(decl) || ts.isPropertyDeclaration(decl)) {
|
|
59
|
+
return typeNodeContainsUndefined(decl.type);
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Check if a declaration has a readonly modifier.
|
|
66
|
+
*/
|
|
67
|
+
const declarationHasReadonlyModifier = (decl) => {
|
|
68
|
+
if (ts.isPropertySignature(decl) || ts.isPropertyDeclaration(decl)) {
|
|
69
|
+
return (decl.modifiers?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ??
|
|
70
|
+
false);
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Get readonly status from TypeScript internal checkFlags.
|
|
76
|
+
* WARNING: This uses TypeScript internal API (symbol.links.checkFlags).
|
|
77
|
+
* The value 8 is CheckFlags.Readonly in TypeScript's internal enum.
|
|
78
|
+
* This is necessary for mapped types where readonly is not in declaration modifiers.
|
|
79
|
+
* If TypeScript internals change, this will need updating.
|
|
80
|
+
*/
|
|
81
|
+
const isReadonlyFromCheckFlags = (symbol) => {
|
|
82
|
+
const CHECK_FLAGS_READONLY = 8; // TypeScript internal: CheckFlags.Readonly
|
|
83
|
+
const checkFlags = symbol.links
|
|
84
|
+
?.checkFlags ?? 0;
|
|
85
|
+
return (checkFlags & CHECK_FLAGS_READONLY) !== 0;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Determine if a property is readonly.
|
|
89
|
+
* Combines declaration-based check (stable) with internal checkFlags (for mapped types).
|
|
90
|
+
* Prefers declaration-based when available for stability across TS versions.
|
|
91
|
+
*/
|
|
92
|
+
const isPropertyReadonly = (symbol, declarations) => {
|
|
93
|
+
// First try declaration-based (stable public API)
|
|
94
|
+
const fromDeclaration = declarations?.some(declarationHasReadonlyModifier) ?? false;
|
|
95
|
+
if (fromDeclaration)
|
|
96
|
+
return true;
|
|
97
|
+
// Fall back to internal checkFlags for mapped types (Readonly<T>, etc.)
|
|
98
|
+
// This handles cases where readonly is synthesized, not in declaration
|
|
99
|
+
return isReadonlyFromCheckFlags(symbol);
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Check if a property name is a non-string key (symbol or computed).
|
|
103
|
+
* These cannot be represented as C# property names.
|
|
104
|
+
*/
|
|
105
|
+
const isNonStringKey = (symbol) => {
|
|
106
|
+
const propName = symbol.getName();
|
|
107
|
+
return (propName.startsWith("__@") || // Internal symbol marker
|
|
108
|
+
((symbol.flags & ts.SymbolFlags.Transient) !== 0 &&
|
|
109
|
+
propName.startsWith("[")));
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Strip `undefined` from a union type, but ONLY the synthetic undefined
|
|
113
|
+
* introduced by optionality. If the declaration explicitly included undefined
|
|
114
|
+
* (like `x?: T | undefined`), we preserve it to maintain type semantics.
|
|
115
|
+
*
|
|
116
|
+
* Compiler-grade rule per review:
|
|
117
|
+
* - Only strip the synthetic undefined introduced by optionality
|
|
118
|
+
* - Do NOT strip explicit undefined that was already in the declared type
|
|
119
|
+
* - If we can't reliably distinguish, don't strip (prefer correctness)
|
|
120
|
+
*/
|
|
121
|
+
const stripSyntheticUndefined = (type, checker, enclosingNode, flags, declarations) => {
|
|
122
|
+
// If ANY declaration explicitly contains undefined, don't strip anything
|
|
123
|
+
// This handles merged declarations where any might have explicit undefined
|
|
124
|
+
if (anyDeclarationHasExplicitUndefined(declarations)) {
|
|
125
|
+
return checker.typeToTypeNode(type, enclosingNode, flags);
|
|
126
|
+
}
|
|
127
|
+
// Check if it's a union type
|
|
128
|
+
if (type.isUnion()) {
|
|
129
|
+
// Filter out undefined from the union
|
|
130
|
+
const filteredTypes = type.types.filter((t) => !(t.flags & ts.TypeFlags.Undefined));
|
|
131
|
+
// If only one type remains, return that type's node
|
|
132
|
+
const firstType = filteredTypes[0];
|
|
133
|
+
if (filteredTypes.length === 1 && firstType) {
|
|
134
|
+
return checker.typeToTypeNode(firstType, enclosingNode, flags);
|
|
135
|
+
}
|
|
136
|
+
// If multiple types remain (excluding undefined), keep them as union
|
|
137
|
+
// This happens for things like `string | number | undefined` → `string | number`
|
|
138
|
+
if (filteredTypes.length > 1) {
|
|
139
|
+
// For complex unions, don't strip - let emitter handle it
|
|
140
|
+
// This is safer than potentially changing type semantics
|
|
141
|
+
return checker.typeToTypeNode(type, enclosingNode, flags);
|
|
142
|
+
}
|
|
143
|
+
// All types were undefined (shouldn't happen) - return undefined type
|
|
144
|
+
return checker.typeToTypeNode(type, enclosingNode, flags);
|
|
145
|
+
}
|
|
146
|
+
// Not a union - return as-is
|
|
147
|
+
return checker.typeToTypeNode(type, enclosingNode, flags);
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Expand a mapped utility type to an IrObjectType.
|
|
151
|
+
*
|
|
152
|
+
* This function uses TypeScript's type checker to resolve the utility type
|
|
153
|
+
* and extracts the properties from the resolved type.
|
|
154
|
+
*
|
|
155
|
+
* @param node - The TypeReferenceNode for the utility type
|
|
156
|
+
* @param typeName - The name of the utility type (Partial, Required, etc.)
|
|
157
|
+
* @param checker - The TypeScript type checker
|
|
158
|
+
* @param convertType - Function to convert nested types
|
|
159
|
+
* @returns IrObjectType with the expanded properties, or null if expansion fails
|
|
160
|
+
*/
|
|
161
|
+
export const expandUtilityType = (node, typeName, checker, convertType) => {
|
|
162
|
+
// Get the resolved type from TypeScript's type checker
|
|
163
|
+
const resolvedType = checker.getTypeAtLocation(node);
|
|
164
|
+
// Check if the type has properties (object-like)
|
|
165
|
+
const properties = resolvedType.getProperties();
|
|
166
|
+
if (!properties || properties.length === 0) {
|
|
167
|
+
// Type parameter or empty type - can't expand
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
// Check if ANY type argument is a type parameter (generic)
|
|
171
|
+
// We can only expand when ALL type arguments are concrete.
|
|
172
|
+
// This is important for Pick<T, K> / Omit<T, K> where either T or K
|
|
173
|
+
// could be a type parameter.
|
|
174
|
+
const typeArgs = node.typeArguments;
|
|
175
|
+
if (typeArgs) {
|
|
176
|
+
for (const typeArg of typeArgs) {
|
|
177
|
+
const argType = checker.getTypeAtLocation(typeArg);
|
|
178
|
+
if (argType.flags & ts.TypeFlags.TypeParameter) {
|
|
179
|
+
// At least one type argument is a type parameter - can't expand
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// SAFETY: Check for index signatures - expansion would lose them
|
|
185
|
+
// Never expand if doing so would drop members (compiler-grade rule)
|
|
186
|
+
const stringIndexType = checker.getIndexInfoOfType(resolvedType, ts.IndexKind.String);
|
|
187
|
+
const numberIndexType = checker.getIndexInfoOfType(resolvedType, ts.IndexKind.Number);
|
|
188
|
+
if (stringIndexType || numberIndexType) {
|
|
189
|
+
// Type has index signatures that cannot be represented in expansion
|
|
190
|
+
// Return null to fall back to referenceType behavior
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
// SAFETY: Check for non-string keys before processing
|
|
194
|
+
// Never expand if doing so would drop members (compiler-grade rule)
|
|
195
|
+
for (const prop of properties) {
|
|
196
|
+
if (isNonStringKey(prop)) {
|
|
197
|
+
// Type has symbol/computed keys that cannot be represented as C# properties
|
|
198
|
+
// Return null to fall back to referenceType behavior
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Convert properties to IR members
|
|
203
|
+
const members = [];
|
|
204
|
+
for (const prop of properties) {
|
|
205
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, node);
|
|
206
|
+
// Get declarations for readonly check and explicit undefined detection
|
|
207
|
+
const declarations = prop.getDeclarations();
|
|
208
|
+
// Get optional/readonly status
|
|
209
|
+
// TypeScript correctly sets Optional flag for Partial<T> properties
|
|
210
|
+
const symbolOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
211
|
+
// Readonly: combine declaration-based (stable) with internal checkFlags (mapped types)
|
|
212
|
+
const baseReadonly = isPropertyReadonly(prop, declarations);
|
|
213
|
+
// Apply utility type transformations
|
|
214
|
+
// Readonly<T> makes all properties readonly
|
|
215
|
+
// Required<T> makes all properties required (non-optional)
|
|
216
|
+
// Partial<T> - TypeScript already sets Optional flag, we just use it
|
|
217
|
+
const isReadonly = typeName === "Readonly" ? true : baseReadonly;
|
|
218
|
+
const isOptional = typeName === "Required" ? false : symbolOptional;
|
|
219
|
+
// For optional properties, TypeScript includes `| undefined` in the type.
|
|
220
|
+
// We strip ONLY synthetic undefined (from optionality), not explicit undefined.
|
|
221
|
+
// Pass all declarations so we check ALL for explicit undefined (handles merges).
|
|
222
|
+
// Use NoTruncation to get complete type representation.
|
|
223
|
+
const typeNodeFlags = ts.NodeBuilderFlags.NoTruncation;
|
|
224
|
+
const propTypeNode = isOptional
|
|
225
|
+
? stripSyntheticUndefined(propType, checker, node, typeNodeFlags, declarations)
|
|
226
|
+
: checker.typeToTypeNode(propType, node, typeNodeFlags);
|
|
227
|
+
// Check if it's a method or property
|
|
228
|
+
const isMethod = declarations?.some((decl) => ts.isMethodSignature(decl) || ts.isMethodDeclaration(decl)) ?? false;
|
|
229
|
+
if (isMethod && propTypeNode && ts.isFunctionTypeNode(propTypeNode)) {
|
|
230
|
+
// Method signature
|
|
231
|
+
const methSig = {
|
|
232
|
+
kind: "methodSignature",
|
|
233
|
+
name: prop.name,
|
|
234
|
+
parameters: propTypeNode.parameters.map((param, index) => ({
|
|
235
|
+
kind: "parameter",
|
|
236
|
+
pattern: {
|
|
237
|
+
kind: "identifierPattern",
|
|
238
|
+
// Use identifier text if available, otherwise fallback to arg{index}
|
|
239
|
+
// typeToTypeNode may create synthetic nodes without source file context
|
|
240
|
+
name: ts.isIdentifier(param.name) ? param.name.text : `arg${index}`,
|
|
241
|
+
},
|
|
242
|
+
type: param.type ? convertType(param.type, checker) : undefined,
|
|
243
|
+
isOptional: !!param.questionToken,
|
|
244
|
+
isRest: !!param.dotDotDotToken,
|
|
245
|
+
passing: "value",
|
|
246
|
+
})),
|
|
247
|
+
returnType: propTypeNode.type
|
|
248
|
+
? convertType(propTypeNode.type, checker)
|
|
249
|
+
: undefined,
|
|
250
|
+
};
|
|
251
|
+
members.push(methSig);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// Property signature
|
|
255
|
+
const propSig = {
|
|
256
|
+
kind: "propertySignature",
|
|
257
|
+
name: prop.name,
|
|
258
|
+
type: propTypeNode
|
|
259
|
+
? convertType(propTypeNode, checker)
|
|
260
|
+
: { kind: "anyType" },
|
|
261
|
+
isOptional,
|
|
262
|
+
isReadonly,
|
|
263
|
+
};
|
|
264
|
+
members.push(propSig);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return { kind: "objectType", members };
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* Check if a type contains any type parameters (is generic).
|
|
271
|
+
* Returns true if the type or any nested type is a type parameter.
|
|
272
|
+
*/
|
|
273
|
+
const containsTypeParameter = (type, checker) => {
|
|
274
|
+
// Direct type parameter check
|
|
275
|
+
if (type.flags & ts.TypeFlags.TypeParameter) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
// Check union types recursively
|
|
279
|
+
if (type.isUnion()) {
|
|
280
|
+
return type.types.some((t) => containsTypeParameter(t, checker));
|
|
281
|
+
}
|
|
282
|
+
// Check intersection types recursively
|
|
283
|
+
if (type.isIntersection()) {
|
|
284
|
+
return type.types.some((t) => containsTypeParameter(t, checker));
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Expand a conditional utility type (NonNullable, Exclude, Extract) to IR.
|
|
290
|
+
*
|
|
291
|
+
* This function delegates to TypeScript's type checker to evaluate the
|
|
292
|
+
* conditional type, then converts the resolved result to IR.
|
|
293
|
+
*
|
|
294
|
+
* CONCRETE-ONLY EXPANSION RULE:
|
|
295
|
+
* This function ONLY expands utility types when ALL type arguments are concrete
|
|
296
|
+
* (non-generic). If any type argument contains a type parameter, we return null
|
|
297
|
+
* and let the caller fall through to referenceType. This is intentional because:
|
|
298
|
+
*
|
|
299
|
+
* 1. TypeScript's conditional types are distributive over unions, which requires
|
|
300
|
+
* knowing the actual types at compile time.
|
|
301
|
+
* 2. For generic contexts like `function f<T>(x: NonNullable<T>)`, we cannot
|
|
302
|
+
* evaluate the conditional - it must remain as a type reference.
|
|
303
|
+
* 3. This matches TypeScript semantics: deferred evaluation in generic contexts.
|
|
304
|
+
*
|
|
305
|
+
* Gating conditions:
|
|
306
|
+
* - Returns null if any type argument contains type parameters (generic context)
|
|
307
|
+
* - Returns null if TypeScript cannot resolve the type
|
|
308
|
+
*
|
|
309
|
+
* Special handling:
|
|
310
|
+
* - NonNullable<any> → anyType (preserve)
|
|
311
|
+
* - NonNullable<unknown> → unknownType (preserve)
|
|
312
|
+
* - NonNullable<never> → neverType (preserve)
|
|
313
|
+
* - Result is never → neverType
|
|
314
|
+
*
|
|
315
|
+
* @param node - The TypeReferenceNode for the utility type
|
|
316
|
+
* @param typeName - The name of the utility type (NonNullable, Exclude, Extract)
|
|
317
|
+
* @param checker - The TypeScript type checker
|
|
318
|
+
* @param convertType - Function to convert nested types
|
|
319
|
+
* @returns IR type with the expanded result, or null if expansion fails
|
|
320
|
+
*/
|
|
321
|
+
export const expandConditionalUtilityType = (node, typeName, checker, convertType) => {
|
|
322
|
+
const typeArgs = node.typeArguments;
|
|
323
|
+
if (!typeArgs || typeArgs.length === 0) {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
// Check if ANY type argument contains type parameters (generic)
|
|
327
|
+
// We can only expand when ALL type arguments are concrete.
|
|
328
|
+
for (const typeArg of typeArgs) {
|
|
329
|
+
const argType = checker.getTypeAtLocation(typeArg);
|
|
330
|
+
if (containsTypeParameter(argType, checker)) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Special handling for NonNullable with any/unknown/never
|
|
335
|
+
// These should be preserved rather than transformed
|
|
336
|
+
if (typeName === "NonNullable" && typeArgs.length >= 1) {
|
|
337
|
+
const firstArg = typeArgs[0];
|
|
338
|
+
if (firstArg) {
|
|
339
|
+
const argType = checker.getTypeAtLocation(firstArg);
|
|
340
|
+
if (argType.flags & ts.TypeFlags.Any) {
|
|
341
|
+
return { kind: "anyType" };
|
|
342
|
+
}
|
|
343
|
+
if (argType.flags & ts.TypeFlags.Unknown) {
|
|
344
|
+
return { kind: "unknownType" };
|
|
345
|
+
}
|
|
346
|
+
if (argType.flags & ts.TypeFlags.Never) {
|
|
347
|
+
return { kind: "neverType" };
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Get the resolved type from TypeScript's type checker
|
|
352
|
+
const resolvedType = checker.getTypeAtLocation(node);
|
|
353
|
+
// Check for never result (e.g., Exclude<string, string> → never)
|
|
354
|
+
if (resolvedType.flags & ts.TypeFlags.Never) {
|
|
355
|
+
return { kind: "neverType" };
|
|
356
|
+
}
|
|
357
|
+
// Directly convert the resolved type to IR without using typeToTypeNode
|
|
358
|
+
// This avoids TypeScript substituting back the original type alias name
|
|
359
|
+
const irType = convertTypeDirectly(resolvedType, checker, convertType);
|
|
360
|
+
if (irType) {
|
|
361
|
+
return irType;
|
|
362
|
+
}
|
|
363
|
+
// Fallback: use typeToTypeNode for complex types
|
|
364
|
+
const typeNodeFlags = ts.NodeBuilderFlags.NoTruncation;
|
|
365
|
+
const resolvedTypeNode = checker.typeToTypeNode(resolvedType, node, typeNodeFlags);
|
|
366
|
+
if (!resolvedTypeNode) {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
return convertType(resolvedTypeNode, checker);
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Directly convert a ts.Type to IrType without going through typeToTypeNode.
|
|
373
|
+
* This handles the common cases (primitives, literals, unions) to avoid
|
|
374
|
+
* TypeScript substituting back type alias names.
|
|
375
|
+
*/
|
|
376
|
+
const convertTypeDirectly = (type, checker, convertType) => {
|
|
377
|
+
// Primitive types
|
|
378
|
+
if (type.flags & ts.TypeFlags.String) {
|
|
379
|
+
return { kind: "primitiveType", name: "string" };
|
|
380
|
+
}
|
|
381
|
+
if (type.flags & ts.TypeFlags.Number) {
|
|
382
|
+
return { kind: "primitiveType", name: "number" };
|
|
383
|
+
}
|
|
384
|
+
if (type.flags & ts.TypeFlags.Boolean) {
|
|
385
|
+
return { kind: "primitiveType", name: "boolean" };
|
|
386
|
+
}
|
|
387
|
+
if (type.flags & ts.TypeFlags.Null) {
|
|
388
|
+
return { kind: "primitiveType", name: "null" };
|
|
389
|
+
}
|
|
390
|
+
if (type.flags & ts.TypeFlags.Undefined) {
|
|
391
|
+
return { kind: "primitiveType", name: "undefined" };
|
|
392
|
+
}
|
|
393
|
+
// String literal
|
|
394
|
+
if (type.flags & ts.TypeFlags.StringLiteral) {
|
|
395
|
+
const literal = type;
|
|
396
|
+
return { kind: "literalType", value: literal.value };
|
|
397
|
+
}
|
|
398
|
+
// Number literal
|
|
399
|
+
if (type.flags & ts.TypeFlags.NumberLiteral) {
|
|
400
|
+
const literal = type;
|
|
401
|
+
return { kind: "literalType", value: literal.value };
|
|
402
|
+
}
|
|
403
|
+
// Boolean literal (true/false)
|
|
404
|
+
if (type.flags & ts.TypeFlags.BooleanLiteral) {
|
|
405
|
+
// TypeScript represents true/false via symbol name
|
|
406
|
+
const symbol = type.getSymbol();
|
|
407
|
+
const isTrue = symbol?.getName() === "true";
|
|
408
|
+
return { kind: "literalType", value: isTrue };
|
|
409
|
+
}
|
|
410
|
+
// Union type - recursively convert constituents
|
|
411
|
+
if (type.isUnion()) {
|
|
412
|
+
const irTypes = [];
|
|
413
|
+
for (const constituent of type.types) {
|
|
414
|
+
const irType = convertTypeDirectly(constituent, checker, convertType);
|
|
415
|
+
if (!irType) {
|
|
416
|
+
// Can't convert this constituent directly, fall back
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
irTypes.push(irType);
|
|
420
|
+
}
|
|
421
|
+
return { kind: "unionType", types: irTypes };
|
|
422
|
+
}
|
|
423
|
+
// Can't handle directly - return null to use fallback
|
|
424
|
+
return null;
|
|
425
|
+
};
|
|
426
|
+
/**
|
|
427
|
+
* Extract literal values from a type.
|
|
428
|
+
* Returns an array of string literals (numbers are converted to strings).
|
|
429
|
+
* Returns null if the type contains non-literal constituents or type parameters.
|
|
430
|
+
*/
|
|
431
|
+
const extractLiteralKeys = (type, checker) => {
|
|
432
|
+
// Check for type parameter
|
|
433
|
+
if (containsTypeParameter(type, checker)) {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
// Check for string type (not literal)
|
|
437
|
+
if (type.flags & ts.TypeFlags.String) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
// Check for number type (not literal)
|
|
441
|
+
if (type.flags & ts.TypeFlags.Number) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
// String literal
|
|
445
|
+
if (type.flags & ts.TypeFlags.StringLiteral) {
|
|
446
|
+
const literal = type;
|
|
447
|
+
return [literal.value];
|
|
448
|
+
}
|
|
449
|
+
// Number literal
|
|
450
|
+
if (type.flags & ts.TypeFlags.NumberLiteral) {
|
|
451
|
+
const literal = type;
|
|
452
|
+
return [String(literal.value)];
|
|
453
|
+
}
|
|
454
|
+
// Union type - collect all literals
|
|
455
|
+
if (type.isUnion()) {
|
|
456
|
+
const keys = [];
|
|
457
|
+
for (const t of type.types) {
|
|
458
|
+
const subKeys = extractLiteralKeys(t, checker);
|
|
459
|
+
if (subKeys === null) {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
keys.push(...subKeys);
|
|
463
|
+
}
|
|
464
|
+
return keys;
|
|
465
|
+
}
|
|
466
|
+
// Other types (boolean, object, etc.) - not supported as Record keys
|
|
467
|
+
return null;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Expand Record<K, T> to IrObjectType when K is a finite set of literal keys.
|
|
471
|
+
*
|
|
472
|
+
* Gating conditions:
|
|
473
|
+
* - Returns null if K contains type parameters (generic context)
|
|
474
|
+
* - Returns null if K is string or number (should remain IrDictionaryType)
|
|
475
|
+
* - Returns null if K contains non-literal types
|
|
476
|
+
*
|
|
477
|
+
* Examples:
|
|
478
|
+
* - Record<"a" | "b", number> → IrObjectType with props {a: number, b: number}
|
|
479
|
+
* - Record<1 | 2, string> → IrObjectType with props {"1": string, "2": string}
|
|
480
|
+
* - Record<string, number> → null (use IrDictionaryType)
|
|
481
|
+
* - Record<K, T> → null (type parameter)
|
|
482
|
+
*
|
|
483
|
+
* @param node - The TypeReferenceNode for Record<K, T>
|
|
484
|
+
* @param checker - The TypeScript type checker
|
|
485
|
+
* @param convertType - Function to convert nested types
|
|
486
|
+
* @returns IrObjectType with the expanded properties, or null if should use dictionary
|
|
487
|
+
*/
|
|
488
|
+
export const expandRecordType = (node, checker, convertType) => {
|
|
489
|
+
const typeArgs = node.typeArguments;
|
|
490
|
+
if (!typeArgs || typeArgs.length !== 2) {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
const keyTypeNode = typeArgs[0];
|
|
494
|
+
const valueTypeNode = typeArgs[1];
|
|
495
|
+
if (!keyTypeNode || !valueTypeNode) {
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
// Get the key type
|
|
499
|
+
const keyType = checker.getTypeAtLocation(keyTypeNode);
|
|
500
|
+
// Check for type parameters in key
|
|
501
|
+
if (containsTypeParameter(keyType, checker)) {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
// Check for type parameters in value
|
|
505
|
+
const valueType = checker.getTypeAtLocation(valueTypeNode);
|
|
506
|
+
if (containsTypeParameter(valueType, checker)) {
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
// Try to extract finite literal keys
|
|
510
|
+
const literalKeys = extractLiteralKeys(keyType, checker);
|
|
511
|
+
if (literalKeys === null || literalKeys.length === 0) {
|
|
512
|
+
// Not a finite set of literals - use IrDictionaryType
|
|
513
|
+
return null;
|
|
514
|
+
}
|
|
515
|
+
// Convert the value type
|
|
516
|
+
const irValueType = convertType(valueTypeNode, checker);
|
|
517
|
+
// Build IrObjectType with a property for each key
|
|
518
|
+
// Prefix numeric keys with '_' to make them valid C# identifiers
|
|
519
|
+
const members = literalKeys.map((key) => ({
|
|
520
|
+
kind: "propertySignature",
|
|
521
|
+
name: /^\d/.test(key) ? `_${key}` : key,
|
|
522
|
+
type: irValueType,
|
|
523
|
+
isOptional: false,
|
|
524
|
+
isReadonly: false,
|
|
525
|
+
}));
|
|
526
|
+
return { kind: "objectType", members };
|
|
527
|
+
};
|
|
528
|
+
//# sourceMappingURL=utility-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utility-types.js","sourceRoot":"","sources":["../../../src/ir/type-converter/utility-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for utility type expansion
|
|
3
|
+
*
|
|
4
|
+
* Covers the safety guarantees per Alice's review:
|
|
5
|
+
* 1. Index signatures block expansion (never drop members)
|
|
6
|
+
* 2. Symbol/computed keys block expansion (never drop members)
|
|
7
|
+
* 3. Explicit undefined is preserved (not stripped)
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=utility-types.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utility-types.test.d.ts","sourceRoot":"","sources":["../../../src/ir/type-converter/utility-types.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|