@tsonic/emitter 0.0.71 → 0.0.73
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/core/semantic/imports.js +9 -0
- package/dist/core/semantic/imports.js.map +1 -1
- package/dist/core/semantic/imports.test.js +43 -0
- package/dist/core/semantic/imports.test.js.map +1 -1
- package/dist/core/semantic/type-resolution.d.ts +1 -0
- package/dist/core/semantic/type-resolution.d.ts.map +1 -1
- package/dist/core/semantic/type-resolution.js +167 -5
- package/dist/core/semantic/type-resolution.js.map +1 -1
- package/dist/core/semantic/type-resolution.test.js +35 -0
- package/dist/core/semantic/type-resolution.test.js.map +1 -1
- package/dist/emitter-types/core.d.ts +5 -0
- package/dist/emitter-types/core.d.ts.map +1 -1
- package/dist/expression-emitter.d.ts.map +1 -1
- package/dist/expression-emitter.js +801 -2
- package/dist/expression-emitter.js.map +1 -1
- package/dist/expressions/access.d.ts.map +1 -1
- package/dist/expressions/access.js +58 -1
- package/dist/expressions/access.js.map +1 -1
- package/dist/expressions/calls/call-analysis.d.ts +1 -0
- package/dist/expressions/calls/call-analysis.d.ts.map +1 -1
- package/dist/expressions/calls/call-analysis.js +57 -0
- package/dist/expressions/calls/call-analysis.js.map +1 -1
- package/dist/expressions/calls/call-emitter.d.ts.map +1 -1
- package/dist/expressions/calls/call-emitter.js +10 -47
- package/dist/expressions/calls/call-emitter.js.map +1 -1
- package/dist/expressions/collections.d.ts.map +1 -1
- package/dist/expressions/collections.js +211 -3
- package/dist/expressions/collections.js.map +1 -1
- package/dist/expressions/identifiers.d.ts.map +1 -1
- package/dist/expressions/identifiers.js +8 -1
- package/dist/expressions/identifiers.js.map +1 -1
- package/dist/expressions/index.test.js +117 -0
- package/dist/expressions/index.test.js.map +1 -1
- package/dist/expressions/operators/binary-emitter.d.ts.map +1 -1
- package/dist/expressions/operators/binary-emitter.js +97 -56
- package/dist/expressions/operators/binary-emitter.js.map +1 -1
- package/dist/expressions/other.d.ts.map +1 -1
- package/dist/expressions/other.js +59 -1
- package/dist/expressions/other.js.map +1 -1
- package/dist/integration.test.js +393 -5
- package/dist/integration.test.js.map +1 -1
- package/dist/specialization/type-aliases.test.js +8 -0
- package/dist/specialization/type-aliases.test.js.map +1 -1
- package/dist/statements/classes/members/methods.d.ts.map +1 -1
- package/dist/statements/classes/members/methods.js +2 -13
- package/dist/statements/classes/members/methods.js.map +1 -1
- package/dist/statements/control/conditionals/guard-analysis.d.ts +42 -0
- package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-analysis.js +284 -121
- package/dist/statements/control/conditionals/guard-analysis.js.map +1 -1
- package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emitter.js +168 -44
- package/dist/statements/control/conditionals/if-emitter.js.map +1 -1
- package/dist/statements/declarations/functions.d.ts.map +1 -1
- package/dist/statements/declarations/functions.js +2 -13
- package/dist/statements/declarations/functions.js.map +1 -1
- package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
- package/dist/statements/declarations/type-aliases.js +2 -1
- package/dist/statements/declarations/type-aliases.js.map +1 -1
- package/dist/statements/declarations/variables.d.ts.map +1 -1
- package/dist/statements/declarations/variables.js +17 -15
- package/dist/statements/declarations/variables.js.map +1 -1
- package/dist/statements/index.test.js +940 -0
- package/dist/statements/index.test.js.map +1 -1
- package/dist/types/references.d.ts.map +1 -1
- package/dist/types/references.js +12 -8
- package/dist/types/references.js.map +1 -1
- package/dist/types/references.test.js +112 -0
- package/dist/types/references.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../../../../src/statements/classes/members/methods.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../../../../src/statements/classes/members/methods.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,9 @@ export type GuardInfo = {
|
|
|
16
16
|
readonly targetType: IrType;
|
|
17
17
|
readonly memberN: number;
|
|
18
18
|
readonly unionArity: number;
|
|
19
|
+
readonly runtimeUnionArity: number;
|
|
20
|
+
readonly candidateMemberNs: readonly number[];
|
|
21
|
+
readonly candidateMembers: readonly IrType[];
|
|
19
22
|
readonly ctxWithId: EmitterContext;
|
|
20
23
|
readonly narrowedName: string;
|
|
21
24
|
readonly escapedOrig: string;
|
|
@@ -55,6 +58,9 @@ export type InGuardInfo = {
|
|
|
55
58
|
readonly propertyName: string;
|
|
56
59
|
readonly memberN: number;
|
|
57
60
|
readonly unionArity: number;
|
|
61
|
+
readonly runtimeUnionArity: number;
|
|
62
|
+
readonly candidateMemberNs: readonly number[];
|
|
63
|
+
readonly candidateMembers: readonly IrType[];
|
|
58
64
|
readonly ctxWithId: EmitterContext;
|
|
59
65
|
readonly narrowedName: string;
|
|
60
66
|
readonly escapedOrig: string;
|
|
@@ -83,12 +89,43 @@ export type DiscriminantEqualityGuardInfo = {
|
|
|
83
89
|
readonly operator: "===" | "!==" | "==" | "!=";
|
|
84
90
|
readonly memberN: number;
|
|
85
91
|
readonly unionArity: number;
|
|
92
|
+
readonly runtimeUnionArity: number;
|
|
93
|
+
readonly candidateMemberNs: readonly number[];
|
|
94
|
+
readonly candidateMembers: readonly IrType[];
|
|
86
95
|
readonly ctxWithId: EmitterContext;
|
|
87
96
|
readonly narrowedName: string;
|
|
88
97
|
readonly escapedOrig: string;
|
|
89
98
|
readonly escapedNarrow: string;
|
|
90
99
|
readonly narrowedMap: Map<string, NarrowedBinding>;
|
|
91
100
|
};
|
|
101
|
+
/**
|
|
102
|
+
* Information extracted from a truthy/falsy property guard:
|
|
103
|
+
* if (result.success) { ... }
|
|
104
|
+
* if (!result.success) { ... }
|
|
105
|
+
*
|
|
106
|
+
* Supports the airplane-grade case where a union member property is definitively
|
|
107
|
+
* truthy or falsy by literal/nullish contract, and exactly one member matches the
|
|
108
|
+
* condition branch.
|
|
109
|
+
*/
|
|
110
|
+
export type PropertyTruthinessGuardInfo = {
|
|
111
|
+
readonly originalName: string;
|
|
112
|
+
readonly propertyName: string;
|
|
113
|
+
readonly memberN: number;
|
|
114
|
+
readonly unionArity: number;
|
|
115
|
+
readonly runtimeUnionArity: number;
|
|
116
|
+
readonly candidateMemberNs: readonly number[];
|
|
117
|
+
readonly candidateMembers: readonly IrType[];
|
|
118
|
+
readonly ctxWithId: EmitterContext;
|
|
119
|
+
readonly narrowedName: string;
|
|
120
|
+
readonly escapedOrig: string;
|
|
121
|
+
readonly escapedNarrow: string;
|
|
122
|
+
readonly narrowedMap: Map<string, NarrowedBinding>;
|
|
123
|
+
};
|
|
124
|
+
export type RuntimeUnionFrame = {
|
|
125
|
+
readonly members: readonly IrType[];
|
|
126
|
+
readonly candidateMemberNs: readonly number[];
|
|
127
|
+
readonly runtimeUnionArity: number;
|
|
128
|
+
};
|
|
92
129
|
/**
|
|
93
130
|
* Information extracted from a nullable guard condition.
|
|
94
131
|
* Used to generate .Value access for narrowed nullable value types.
|
|
@@ -109,6 +146,11 @@ export type NullableGuardInfo = {
|
|
|
109
146
|
* TypeScript flow analysis, by mapping the literal to exactly one union member.
|
|
110
147
|
*/
|
|
111
148
|
export declare const tryResolveDiscriminantEqualityGuard: (condition: IrExpression, context: EmitterContext) => DiscriminantEqualityGuardInfo | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* Try to extract guard info from `x.prop` / `!x.prop` where the property acts as a
|
|
151
|
+
* boolean-style discriminant over a runtime union.
|
|
152
|
+
*/
|
|
153
|
+
export declare const tryResolvePropertyTruthinessGuard: (condition: IrExpression, context: EmitterContext) => PropertyTruthinessGuardInfo | undefined;
|
|
112
154
|
/**
|
|
113
155
|
* Try to extract guard info from an `("prop" in x)` binary expression.
|
|
114
156
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard-analysis.d.ts","sourceRoot":"","sources":["../../../../src/statements/control/conditionals/guard-analysis.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"guard-analysis.d.ts","sourceRoot":"","sources":["../../../../src/statements/control/conditionals/guard-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,71 +13,37 @@ import { extractCalleeNameFromAst } from "../../../core/format/backend-ast/utils
|
|
|
13
13
|
* an identifierExpression. Falls back to extractCalleeNameFromAst for other shapes.
|
|
14
14
|
*/
|
|
15
15
|
const extractIdentifierText = (ast) => extractCalleeNameFromAst(ast);
|
|
16
|
-
import { resolveTypeAlias, stripNullish, findUnionMemberIndex, getPropertyType,
|
|
16
|
+
import { hasDeterministicPropertyMembership, resolveTypeAlias, stripNullish, findUnionMemberIndex, getPropertyType, isDefinitelyValueType, } from "../../../core/semantic/type-resolution.js";
|
|
17
17
|
import { escapeCSharpIdentifier } from "../../../emitter-types/index.js";
|
|
18
18
|
import { emitRemappedLocalName } from "../../../core/format/local-names.js";
|
|
19
19
|
/**
|
|
20
20
|
* Check if a local nominal type (class/interface) has a property with the given TS name.
|
|
21
21
|
*/
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!info)
|
|
27
|
-
return false;
|
|
28
|
-
if (info.kind === "interface") {
|
|
29
|
-
const props = getAllPropertySignatures(type, context);
|
|
30
|
-
return props?.some((p) => p.name === propertyName) ?? false;
|
|
31
|
-
}
|
|
32
|
-
if (info.kind === "class") {
|
|
33
|
-
return info.members.some((m) => m.kind === "propertyDeclaration" && m.name === propertyName);
|
|
22
|
+
const getGuardPropertyType = (type, propertyName, context) => {
|
|
23
|
+
if (type.kind === "objectType") {
|
|
24
|
+
const prop = type.members.find((member) => member.kind === "propertySignature" && member.name === propertyName);
|
|
25
|
+
return prop?.type;
|
|
34
26
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* For same-module types, consult `context.localTypes`.
|
|
41
|
-
* For cross-module types, consult the batch `typeMemberIndex` and resolve the
|
|
42
|
-
* member's fully-qualified name deterministically.
|
|
43
|
-
*/
|
|
44
|
-
const hasProperty = (type, propertyName, context) => {
|
|
45
|
-
if (hasLocalProperty(type, propertyName, context)) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
const index = context.options.typeMemberIndex;
|
|
49
|
-
if (!index)
|
|
50
|
-
return false;
|
|
51
|
-
const stripGlobalPrefix = (name) => name.startsWith("global::") ? name.slice("global::".length) : name;
|
|
52
|
-
const candidates = [];
|
|
53
|
-
if (type.resolvedClrType) {
|
|
54
|
-
candidates.push(stripGlobalPrefix(type.resolvedClrType));
|
|
55
|
-
}
|
|
56
|
-
else if (type.name.includes(".")) {
|
|
57
|
-
candidates.push(type.name);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
// Resolve by suffix match in the type member index.
|
|
61
|
-
const matches = [];
|
|
62
|
-
for (const fqn of index.keys()) {
|
|
63
|
-
if (fqn.endsWith(`.${type.name}`) ||
|
|
64
|
-
fqn.endsWith(`.${type.name}__Alias`)) {
|
|
65
|
-
matches.push(fqn);
|
|
66
|
-
}
|
|
27
|
+
if (type.kind === "referenceType") {
|
|
28
|
+
if (type.structuralMembers?.length) {
|
|
29
|
+
const prop = type.structuralMembers.find((member) => member.kind === "propertySignature" && member.name === propertyName);
|
|
30
|
+
if (prop)
|
|
31
|
+
return prop.type;
|
|
67
32
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
33
|
+
const localTypes = resolveLocalTypesForReference(type, context);
|
|
34
|
+
if (localTypes) {
|
|
35
|
+
const lookupName = type.name.includes(".")
|
|
36
|
+
? (type.name.split(".").pop() ?? type.name)
|
|
37
|
+
: type.name;
|
|
38
|
+
const localPropType = getPropertyType({ ...type, name: lookupName }, propertyName, { ...context, localTypes });
|
|
39
|
+
if (localPropType)
|
|
40
|
+
return localPropType;
|
|
75
41
|
}
|
|
42
|
+
const resolvedPropType = getPropertyType(type, propertyName, context);
|
|
43
|
+
if (resolvedPropType)
|
|
44
|
+
return resolvedPropType;
|
|
76
45
|
}
|
|
77
|
-
return
|
|
78
|
-
const perType = index.get(fqn);
|
|
79
|
-
return perType?.has(propertyName) ?? false;
|
|
80
|
-
});
|
|
46
|
+
return undefined;
|
|
81
47
|
};
|
|
82
48
|
/**
|
|
83
49
|
* Resolve a reference type's LocalTypeInfo map (possibly from a different module).
|
|
@@ -149,6 +115,90 @@ const tryGetLiteralSet = (type, context) => {
|
|
|
149
115
|
}
|
|
150
116
|
return undefined;
|
|
151
117
|
};
|
|
118
|
+
const isClrUnionName = (name) => /^Union_[2-8]$/.test(name) || name === "Union" || name.endsWith(".Union");
|
|
119
|
+
const stripGlobalPrefix = (name) => name.startsWith("global::") ? name.slice("global::".length) : name;
|
|
120
|
+
const extractUnionMembers = (type, context) => {
|
|
121
|
+
const resolvedBase = resolveTypeAlias(stripNullish(type), context);
|
|
122
|
+
const resolved = resolvedBase.kind === "intersectionType"
|
|
123
|
+
? (resolvedBase.types.find((member) => member.kind === "referenceType" && isClrUnionName(member.name)) ?? resolvedBase)
|
|
124
|
+
: resolvedBase;
|
|
125
|
+
if (resolved.kind === "unionType") {
|
|
126
|
+
return resolved.types;
|
|
127
|
+
}
|
|
128
|
+
if (resolved.kind === "referenceType" &&
|
|
129
|
+
isClrUnionName(resolved.name) &&
|
|
130
|
+
resolved.typeArguments &&
|
|
131
|
+
resolved.typeArguments.length >= 2 &&
|
|
132
|
+
resolved.typeArguments.length <= 8) {
|
|
133
|
+
return resolved.typeArguments;
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
};
|
|
137
|
+
const resolveRuntimeUnionFrame = (originalName, unionSourceType, context) => {
|
|
138
|
+
const members = extractUnionMembers(unionSourceType, context);
|
|
139
|
+
if (!members)
|
|
140
|
+
return undefined;
|
|
141
|
+
const narrowed = context.narrowedBindings?.get(originalName);
|
|
142
|
+
if (!narrowed) {
|
|
143
|
+
return {
|
|
144
|
+
members,
|
|
145
|
+
candidateMemberNs: members.map((_, index) => index + 1),
|
|
146
|
+
runtimeUnionArity: members.length,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (narrowed.kind !== "runtimeSubset") {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
if (narrowed.runtimeMemberNs.length !== members.length) {
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
members,
|
|
157
|
+
candidateMemberNs: [...narrowed.runtimeMemberNs],
|
|
158
|
+
runtimeUnionArity: narrowed.runtimeUnionArity,
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
const buildRenameNarrowedMap = (originalName, narrowedName, memberType, ctxWithId) => {
|
|
162
|
+
const narrowedMap = new Map(ctxWithId.narrowedBindings ?? []);
|
|
163
|
+
narrowedMap.set(originalName, {
|
|
164
|
+
kind: "rename",
|
|
165
|
+
name: narrowedName,
|
|
166
|
+
type: memberType,
|
|
167
|
+
});
|
|
168
|
+
return narrowedMap;
|
|
169
|
+
};
|
|
170
|
+
const isDefinitelyTruthyLiteral = (value) => {
|
|
171
|
+
if (typeof value === "string")
|
|
172
|
+
return value.length > 0;
|
|
173
|
+
if (typeof value === "number")
|
|
174
|
+
return value !== 0 && !Number.isNaN(value);
|
|
175
|
+
return value === true;
|
|
176
|
+
};
|
|
177
|
+
const isDefinitelyFalsyType = (type, context) => {
|
|
178
|
+
const resolved = resolveTypeAlias(type, context);
|
|
179
|
+
if (resolved.kind === "literalType") {
|
|
180
|
+
const value = resolved.value;
|
|
181
|
+
return value === false || value === 0 || value === "";
|
|
182
|
+
}
|
|
183
|
+
if (resolved.kind === "primitiveType") {
|
|
184
|
+
return resolved.name === "undefined" || resolved.name === "null";
|
|
185
|
+
}
|
|
186
|
+
if (resolved.kind === "unionType") {
|
|
187
|
+
return resolved.types.every((member) => isDefinitelyFalsyType(member, context));
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
};
|
|
191
|
+
const isDefinitelyTruthyType = (type, context) => {
|
|
192
|
+
const literals = tryGetLiteralSet(type, context);
|
|
193
|
+
if (literals) {
|
|
194
|
+
return Array.from(literals).every(isDefinitelyTruthyLiteral);
|
|
195
|
+
}
|
|
196
|
+
const resolved = resolveTypeAlias(type, context);
|
|
197
|
+
if (resolved.kind === "unionType") {
|
|
198
|
+
return resolved.types.every((member) => isDefinitelyTruthyType(member, context));
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
};
|
|
152
202
|
/**
|
|
153
203
|
* Try to extract guard info from `x.prop === <literal>` or `x.prop !== <literal>`.
|
|
154
204
|
*
|
|
@@ -211,70 +261,52 @@ export const tryResolveDiscriminantEqualityGuard = (condition, context) => {
|
|
|
211
261
|
return undefined;
|
|
212
262
|
const { receiver, propertyName, literal } = match;
|
|
213
263
|
const originalName = receiver.name;
|
|
214
|
-
// If this identifier is already narrowed (union guard emitted earlier), do NOT try to
|
|
215
|
-
// apply another union narrowing rule. This avoids mis-emitting `.IsN()` on a narrowed member type.
|
|
216
|
-
if (context.narrowedBindings?.has(originalName))
|
|
217
|
-
return undefined;
|
|
218
264
|
const unionSourceType = receiver.inferredType;
|
|
219
265
|
if (!unionSourceType)
|
|
220
266
|
return undefined;
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
267
|
+
const frame = resolveRuntimeUnionFrame(originalName, unionSourceType, context);
|
|
268
|
+
if (!frame)
|
|
223
269
|
return undefined;
|
|
224
|
-
const
|
|
270
|
+
const { members, candidateMemberNs, runtimeUnionArity } = frame;
|
|
271
|
+
const unionArity = members.length;
|
|
225
272
|
if (unionArity < 2 || unionArity > 8)
|
|
226
273
|
return undefined;
|
|
227
274
|
// Find which union members have a discriminant property type that includes the literal.
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
275
|
+
const matchingIndices = [];
|
|
276
|
+
const matchingMemberNs = [];
|
|
277
|
+
for (let i = 0; i < members.length; i++) {
|
|
278
|
+
const member = members[i];
|
|
231
279
|
if (!member)
|
|
232
280
|
continue;
|
|
233
|
-
|
|
234
|
-
if (member.kind === "objectType") {
|
|
235
|
-
const prop = member.members.find((m) => m.kind === "propertySignature" && m.name === propertyName);
|
|
236
|
-
propType = prop?.type;
|
|
237
|
-
}
|
|
238
|
-
else if (member.kind === "referenceType") {
|
|
239
|
-
const localTypes = resolveLocalTypesForReference(member, context);
|
|
240
|
-
if (!localTypes)
|
|
241
|
-
continue;
|
|
242
|
-
const lookupName = member.name.includes(".")
|
|
243
|
-
? (member.name.split(".").pop() ?? member.name)
|
|
244
|
-
: member.name;
|
|
245
|
-
// Use the target module's localTypes for property type resolution.
|
|
246
|
-
propType = getPropertyType({ ...member, name: lookupName }, propertyName, { ...context, localTypes });
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
281
|
+
const propType = getGuardPropertyType(member, propertyName, context);
|
|
251
282
|
if (!propType)
|
|
252
283
|
continue;
|
|
253
284
|
const literals = tryGetLiteralSet(propType, context);
|
|
254
285
|
if (!literals)
|
|
255
286
|
continue;
|
|
256
287
|
if (literals.has(literal)) {
|
|
257
|
-
|
|
288
|
+
matchingIndices.push(i);
|
|
289
|
+
matchingMemberNs.push(candidateMemberNs[i] ?? i + 1);
|
|
258
290
|
}
|
|
259
291
|
}
|
|
260
292
|
// Only support the common airplane-grade case: exactly one matching member.
|
|
261
|
-
if (
|
|
293
|
+
if (matchingMemberNs.length !== 1)
|
|
262
294
|
return undefined;
|
|
263
|
-
const memberN =
|
|
295
|
+
const memberN = matchingMemberNs[0];
|
|
264
296
|
if (!memberN)
|
|
265
297
|
return undefined;
|
|
298
|
+
const matchingIndex = matchingIndices[0];
|
|
299
|
+
if (matchingIndex === undefined)
|
|
300
|
+
return undefined;
|
|
266
301
|
const nextId = (context.tempVarId ?? 0) + 1;
|
|
267
302
|
const ctxWithId = { ...context, tempVarId: nextId };
|
|
268
303
|
const narrowedName = `${originalName}__${memberN}_${nextId}`;
|
|
269
304
|
const escapedOrig = emitRemappedLocalName(originalName, context);
|
|
270
305
|
const escapedNarrow = escapeCSharpIdentifier(narrowedName);
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
name: narrowedName,
|
|
276
|
-
type: memberType,
|
|
277
|
-
});
|
|
306
|
+
const memberType = members[matchingIndex];
|
|
307
|
+
if (!memberType)
|
|
308
|
+
return undefined;
|
|
309
|
+
const narrowedMap = buildRenameNarrowedMap(originalName, narrowedName, memberType, ctxWithId);
|
|
278
310
|
return {
|
|
279
311
|
originalName,
|
|
280
312
|
propertyName,
|
|
@@ -282,6 +314,129 @@ export const tryResolveDiscriminantEqualityGuard = (condition, context) => {
|
|
|
282
314
|
operator: condition.operator,
|
|
283
315
|
memberN,
|
|
284
316
|
unionArity,
|
|
317
|
+
runtimeUnionArity,
|
|
318
|
+
candidateMemberNs,
|
|
319
|
+
candidateMembers: members,
|
|
320
|
+
ctxWithId,
|
|
321
|
+
narrowedName,
|
|
322
|
+
escapedOrig,
|
|
323
|
+
escapedNarrow,
|
|
324
|
+
narrowedMap,
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Try to extract guard info from `x.prop` / `!x.prop` where the property acts as a
|
|
329
|
+
* boolean-style discriminant over a runtime union.
|
|
330
|
+
*/
|
|
331
|
+
export const tryResolvePropertyTruthinessGuard = (condition, context) => {
|
|
332
|
+
const extract = (expr) => {
|
|
333
|
+
if (expr.kind === "unary" && expr.operator === "!") {
|
|
334
|
+
const inner = extract(expr.expression);
|
|
335
|
+
return inner ? { ...inner, wantTruthy: !inner.wantTruthy } : undefined;
|
|
336
|
+
}
|
|
337
|
+
if (expr.kind !== "memberAccess")
|
|
338
|
+
return undefined;
|
|
339
|
+
if (expr.isOptional || expr.isComputed)
|
|
340
|
+
return undefined;
|
|
341
|
+
if (expr.object.kind !== "identifier")
|
|
342
|
+
return undefined;
|
|
343
|
+
if (typeof expr.property !== "string")
|
|
344
|
+
return undefined;
|
|
345
|
+
return {
|
|
346
|
+
receiver: expr.object,
|
|
347
|
+
propertyName: expr.property,
|
|
348
|
+
wantTruthy: true,
|
|
349
|
+
bindingType: expr.memberBinding?.type,
|
|
350
|
+
bindingValueTruthiness: expr.inferredType?.kind === "literalType"
|
|
351
|
+
? isDefinitelyTruthyLiteral(expr.inferredType.value)
|
|
352
|
+
: expr.inferredType?.kind === "primitiveType" &&
|
|
353
|
+
(expr.inferredType.name === "undefined" ||
|
|
354
|
+
expr.inferredType.name === "null")
|
|
355
|
+
? false
|
|
356
|
+
: undefined,
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
const match = extract(condition);
|
|
360
|
+
if (!match)
|
|
361
|
+
return undefined;
|
|
362
|
+
const { receiver, propertyName, wantTruthy, bindingType, bindingValueTruthiness } = match;
|
|
363
|
+
const originalName = receiver.name;
|
|
364
|
+
const unionSourceType = receiver.inferredType;
|
|
365
|
+
if (!unionSourceType)
|
|
366
|
+
return undefined;
|
|
367
|
+
const frame = resolveRuntimeUnionFrame(originalName, unionSourceType, context);
|
|
368
|
+
if (!frame)
|
|
369
|
+
return undefined;
|
|
370
|
+
const { members, candidateMemberNs, runtimeUnionArity } = frame;
|
|
371
|
+
const unionArity = members.length;
|
|
372
|
+
if (unionArity < 2 || unionArity > 8)
|
|
373
|
+
return undefined;
|
|
374
|
+
const matchingIndices = [];
|
|
375
|
+
const matchingMemberNs = [];
|
|
376
|
+
if (bindingType && bindingValueTruthiness !== undefined) {
|
|
377
|
+
const bindingTypeName = stripGlobalPrefix(bindingType);
|
|
378
|
+
const boundMemberIndex = members.findIndex((member) => {
|
|
379
|
+
if (member?.kind !== "referenceType")
|
|
380
|
+
return false;
|
|
381
|
+
const candidateClr = member.resolvedClrType
|
|
382
|
+
? stripGlobalPrefix(member.resolvedClrType)
|
|
383
|
+
: undefined;
|
|
384
|
+
return candidateClr === bindingTypeName || member.name === bindingTypeName;
|
|
385
|
+
});
|
|
386
|
+
if (boundMemberIndex >= 0) {
|
|
387
|
+
if (wantTruthy === bindingValueTruthiness) {
|
|
388
|
+
matchingIndices.push(boundMemberIndex);
|
|
389
|
+
matchingMemberNs.push(candidateMemberNs[boundMemberIndex] ?? boundMemberIndex + 1);
|
|
390
|
+
}
|
|
391
|
+
else if (unionArity === 2) {
|
|
392
|
+
const otherIndex = boundMemberIndex === 0 ? 1 : 0;
|
|
393
|
+
matchingIndices.push(otherIndex);
|
|
394
|
+
matchingMemberNs.push(candidateMemberNs[otherIndex] ?? otherIndex + 1);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (matchingMemberNs.length === 0) {
|
|
399
|
+
for (let i = 0; i < members.length; i++) {
|
|
400
|
+
const member = members[i];
|
|
401
|
+
if (!member)
|
|
402
|
+
continue;
|
|
403
|
+
const propType = getGuardPropertyType(member, propertyName, context);
|
|
404
|
+
if (!propType)
|
|
405
|
+
continue;
|
|
406
|
+
const matches = wantTruthy
|
|
407
|
+
? isDefinitelyTruthyType(propType, context)
|
|
408
|
+
: isDefinitelyFalsyType(propType, context);
|
|
409
|
+
if (matches) {
|
|
410
|
+
matchingIndices.push(i);
|
|
411
|
+
matchingMemberNs.push(candidateMemberNs[i] ?? i + 1);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (matchingMemberNs.length !== 1)
|
|
416
|
+
return undefined;
|
|
417
|
+
const memberN = matchingMemberNs[0];
|
|
418
|
+
if (!memberN)
|
|
419
|
+
return undefined;
|
|
420
|
+
const matchingIndex = matchingIndices[0];
|
|
421
|
+
if (matchingIndex === undefined)
|
|
422
|
+
return undefined;
|
|
423
|
+
const nextId = (context.tempVarId ?? 0) + 1;
|
|
424
|
+
const ctxWithId = { ...context, tempVarId: nextId };
|
|
425
|
+
const narrowedName = `${originalName}__${memberN}_${nextId}`;
|
|
426
|
+
const escapedOrig = emitRemappedLocalName(originalName, context);
|
|
427
|
+
const escapedNarrow = escapeCSharpIdentifier(narrowedName);
|
|
428
|
+
const memberType = members[matchingIndex];
|
|
429
|
+
if (!memberType)
|
|
430
|
+
return undefined;
|
|
431
|
+
const narrowedMap = buildRenameNarrowedMap(originalName, narrowedName, memberType, ctxWithId);
|
|
432
|
+
return {
|
|
433
|
+
originalName,
|
|
434
|
+
propertyName,
|
|
435
|
+
memberN,
|
|
436
|
+
unionArity,
|
|
437
|
+
runtimeUnionArity,
|
|
438
|
+
candidateMemberNs,
|
|
439
|
+
candidateMembers: members,
|
|
285
440
|
ctxWithId,
|
|
286
441
|
narrowedName,
|
|
287
442
|
escapedOrig,
|
|
@@ -310,46 +465,52 @@ export const tryResolveInGuard = (condition, context) => {
|
|
|
310
465
|
const unionSourceType = condition.right.inferredType;
|
|
311
466
|
if (!unionSourceType)
|
|
312
467
|
return undefined;
|
|
313
|
-
const
|
|
314
|
-
if (
|
|
468
|
+
const frame = resolveRuntimeUnionFrame(originalName, unionSourceType, context);
|
|
469
|
+
if (!frame)
|
|
315
470
|
return undefined;
|
|
316
|
-
const
|
|
471
|
+
const { members, candidateMemberNs, runtimeUnionArity } = frame;
|
|
472
|
+
const unionArity = members.length;
|
|
317
473
|
if (unionArity < 2 || unionArity > 8)
|
|
318
474
|
return undefined;
|
|
319
475
|
// Find which union members contain the property.
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
476
|
+
const matchingIndices = [];
|
|
477
|
+
const matchingMemberNs = [];
|
|
478
|
+
for (let i = 0; i < members.length; i++) {
|
|
479
|
+
const member = members[i];
|
|
323
480
|
if (!member || member.kind !== "referenceType")
|
|
324
481
|
continue;
|
|
325
|
-
if (
|
|
326
|
-
|
|
482
|
+
if (hasDeterministicPropertyMembership(member, propertyName, context) === true) {
|
|
483
|
+
matchingIndices.push(i);
|
|
484
|
+
matchingMemberNs.push(candidateMemberNs[i] ?? i + 1);
|
|
327
485
|
}
|
|
328
486
|
}
|
|
329
487
|
// Only support the common "exactly one matching member" narrowing case.
|
|
330
|
-
if (
|
|
488
|
+
if (matchingMemberNs.length !== 1)
|
|
331
489
|
return undefined;
|
|
332
|
-
const memberN =
|
|
490
|
+
const memberN = matchingMemberNs[0];
|
|
333
491
|
if (!memberN)
|
|
334
492
|
return undefined;
|
|
493
|
+
const matchingIndex = matchingIndices[0];
|
|
494
|
+
if (matchingIndex === undefined)
|
|
495
|
+
return undefined;
|
|
335
496
|
const nextId = (context.tempVarId ?? 0) + 1;
|
|
336
497
|
const ctxWithId = { ...context, tempVarId: nextId };
|
|
337
498
|
const narrowedName = `${originalName}__${memberN}_${nextId}`;
|
|
338
499
|
const [rhsAst] = emitIdentifier(condition.right, context);
|
|
339
500
|
const escapedOrig = extractIdentifierText(rhsAst);
|
|
340
501
|
const escapedNarrow = escapeCSharpIdentifier(narrowedName);
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
name: narrowedName,
|
|
346
|
-
type: memberType,
|
|
347
|
-
});
|
|
502
|
+
const memberType = members[matchingIndex];
|
|
503
|
+
if (!memberType)
|
|
504
|
+
return undefined;
|
|
505
|
+
const narrowedMap = buildRenameNarrowedMap(originalName, narrowedName, memberType, ctxWithId);
|
|
348
506
|
return {
|
|
349
507
|
originalName,
|
|
350
508
|
propertyName,
|
|
351
509
|
memberN,
|
|
352
510
|
unionArity,
|
|
511
|
+
runtimeUnionArity,
|
|
512
|
+
candidateMemberNs,
|
|
513
|
+
candidateMembers: members,
|
|
353
514
|
ctxWithId,
|
|
354
515
|
narrowedName,
|
|
355
516
|
escapedOrig,
|
|
@@ -395,31 +556,33 @@ export const tryResolvePredicateGuard = (call, context) => {
|
|
|
395
556
|
const unionSourceType = arg.inferredType;
|
|
396
557
|
if (!unionSourceType)
|
|
397
558
|
return undefined;
|
|
398
|
-
const
|
|
399
|
-
if (
|
|
559
|
+
const frame = resolveRuntimeUnionFrame(originalName, unionSourceType, context);
|
|
560
|
+
if (!frame)
|
|
400
561
|
return undefined;
|
|
562
|
+
const resolved = {
|
|
563
|
+
kind: "unionType",
|
|
564
|
+
types: [...frame.members],
|
|
565
|
+
};
|
|
401
566
|
const idx = findUnionMemberIndex(resolved, narrowing.targetType, context);
|
|
402
567
|
if (idx === undefined)
|
|
403
568
|
return undefined;
|
|
404
|
-
const memberN = idx + 1;
|
|
405
|
-
const unionArity =
|
|
569
|
+
const memberN = frame.candidateMemberNs[idx] ?? idx + 1;
|
|
570
|
+
const unionArity = frame.members.length;
|
|
406
571
|
const nextId = (context.tempVarId ?? 0) + 1;
|
|
407
572
|
const ctxWithId = { ...context, tempVarId: nextId };
|
|
408
573
|
const narrowedName = `${originalName}__${memberN}_${nextId}`;
|
|
409
574
|
const [argAst] = emitIdentifier(arg, context);
|
|
410
575
|
const escapedOrig = extractIdentifierText(argAst);
|
|
411
576
|
const escapedNarrow = escapeCSharpIdentifier(narrowedName);
|
|
412
|
-
const narrowedMap =
|
|
413
|
-
narrowedMap.set(originalName, {
|
|
414
|
-
kind: "rename",
|
|
415
|
-
name: narrowedName,
|
|
416
|
-
type: narrowing.targetType,
|
|
417
|
-
});
|
|
577
|
+
const narrowedMap = buildRenameNarrowedMap(originalName, narrowedName, narrowing.targetType, ctxWithId);
|
|
418
578
|
return {
|
|
419
579
|
originalName,
|
|
420
580
|
targetType: narrowing.targetType,
|
|
421
581
|
memberN,
|
|
422
582
|
unionArity,
|
|
583
|
+
runtimeUnionArity: frame.runtimeUnionArity,
|
|
584
|
+
candidateMemberNs: frame.candidateMemberNs,
|
|
585
|
+
candidateMembers: frame.members,
|
|
423
586
|
ctxWithId,
|
|
424
587
|
narrowedName,
|
|
425
588
|
escapedOrig,
|