@suss/adapter-typescript 0.37.0 → 0.38.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/index.cjs +2281 -1723
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1232 -660
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import path15 from "path";
|
|
3
3
|
import {
|
|
4
4
|
Node as Node82,
|
|
5
|
-
Project as Project2
|
|
5
|
+
Project as Project2,
|
|
6
|
+
SyntaxKind as SyntaxKind31
|
|
6
7
|
} from "ts-morph";
|
|
7
8
|
import {
|
|
8
9
|
BOUNDARY_ROLE,
|
|
@@ -37,21 +38,412 @@ import { force as force8, hostOf as hostOf2, literalOf as literalOf6, pathOf as
|
|
|
37
38
|
|
|
38
39
|
// src/assembly.ts
|
|
39
40
|
import {
|
|
40
|
-
Node as Node67
|
|
41
|
+
Node as Node67,
|
|
42
|
+
SyntaxKind as SyntaxKind27
|
|
41
43
|
} from "ts-morph";
|
|
42
44
|
import { firesOn, runsBefore, splitAtHandOffs } from "@suss/extractor";
|
|
43
45
|
|
|
46
|
+
// src/depTracking.ts
|
|
47
|
+
function createDependencySink() {
|
|
48
|
+
return { files: /* @__PURE__ */ new Set(), mountPrefixes: /* @__PURE__ */ new Map(), claims: [] };
|
|
49
|
+
}
|
|
50
|
+
var activeSink = null;
|
|
51
|
+
function withDependencySink(sink, fn) {
|
|
52
|
+
const previous = activeSink;
|
|
53
|
+
activeSink = sink;
|
|
54
|
+
try {
|
|
55
|
+
return fn();
|
|
56
|
+
} finally {
|
|
57
|
+
activeSink = previous;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function withFilesNoted(fn) {
|
|
61
|
+
const outer = activeSink;
|
|
62
|
+
const noted = createDependencySink();
|
|
63
|
+
activeSink = noted;
|
|
64
|
+
let value;
|
|
65
|
+
try {
|
|
66
|
+
value = fn();
|
|
67
|
+
} finally {
|
|
68
|
+
activeSink = outer;
|
|
69
|
+
}
|
|
70
|
+
if (outer !== null) {
|
|
71
|
+
for (const filePath of noted.files) {
|
|
72
|
+
outer.files.add(filePath);
|
|
73
|
+
}
|
|
74
|
+
for (const [childId, prefix] of noted.mountPrefixes) {
|
|
75
|
+
outer.mountPrefixes.set(childId, prefix);
|
|
76
|
+
}
|
|
77
|
+
outer.claims.push(...noted.claims);
|
|
78
|
+
}
|
|
79
|
+
return { value, files: [...noted.files] };
|
|
80
|
+
}
|
|
81
|
+
function recordFileDependency(filePath) {
|
|
82
|
+
activeSink?.files.add(filePath);
|
|
83
|
+
}
|
|
84
|
+
function recordMountPrefix(childId, prefix) {
|
|
85
|
+
activeSink?.mountPrefixes.set(childId, prefix);
|
|
86
|
+
}
|
|
87
|
+
function recordUnitClaim(key, pack) {
|
|
88
|
+
activeSink?.claims.push({ key, pack });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/shapes/typeText.ts
|
|
92
|
+
import { ts } from "ts-morph";
|
|
93
|
+
var PRINTER = ts.createPrinter({
|
|
94
|
+
removeComments: true,
|
|
95
|
+
newLine: ts.NewLineKind.LineFeed
|
|
96
|
+
});
|
|
97
|
+
var NO_FILE = ts.createSourceFile("", "", ts.ScriptTarget.Latest);
|
|
98
|
+
function defaultFlags(enclosing) {
|
|
99
|
+
const flags = ts.TypeFormatFlags.UseTypeOfFunction | ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType | ts.TypeFormatFlags.WriteTypeArgumentsOfSignature;
|
|
100
|
+
if (enclosing?.getKind() === ts.SyntaxKind.TypeAliasDeclaration) {
|
|
101
|
+
return flags | ts.TypeFormatFlags.InTypeAlias;
|
|
102
|
+
}
|
|
103
|
+
return flags;
|
|
104
|
+
}
|
|
105
|
+
function stableTypeText(type, reader, enclosing, flags) {
|
|
106
|
+
const format = flags ?? defaultFlags(enclosing);
|
|
107
|
+
const place = enclosing?.compilerNode ?? NOWHERE;
|
|
108
|
+
const atPlace = printedAt.get(place) ?? /* @__PURE__ */ new WeakMap();
|
|
109
|
+
printedAt.set(place, atPlace);
|
|
110
|
+
const byFormat = atPlace.get(type.compilerType) ?? /* @__PURE__ */ new Map();
|
|
111
|
+
atPlace.set(type.compilerType, byFormat);
|
|
112
|
+
const kept = byFormat.get(format);
|
|
113
|
+
if (kept !== void 0) {
|
|
114
|
+
return kept;
|
|
115
|
+
}
|
|
116
|
+
const text3 = printedType(type, reader, enclosing, format);
|
|
117
|
+
byFormat.set(format, text3);
|
|
118
|
+
return text3;
|
|
119
|
+
}
|
|
120
|
+
var NOWHERE = {};
|
|
121
|
+
var printedAt = /* @__PURE__ */ new WeakMap();
|
|
122
|
+
function printedType(type, reader, enclosing, format) {
|
|
123
|
+
const checker = reader.getProject().getTypeChecker().compilerObject;
|
|
124
|
+
const enclosingNode = enclosing?.compilerNode;
|
|
125
|
+
const typeNode = checker.typeToTypeNode(
|
|
126
|
+
type.compilerType,
|
|
127
|
+
enclosingNode,
|
|
128
|
+
format & ts.TypeFormatFlags.NodeBuilderFlagsMask | ts.NodeBuilderFlags.IgnoreErrors
|
|
129
|
+
);
|
|
130
|
+
if (typeNode === void 0) {
|
|
131
|
+
return withoutImportQualifiers(
|
|
132
|
+
checker.typeToString(type.compilerType, enclosingNode, format)
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
const file = enclosing?.getSourceFile().compilerNode ?? NO_FILE;
|
|
136
|
+
const ordered = containsUnion(typeNode) ? withUnionMembersOrdered(typeNode, file) : typeNode;
|
|
137
|
+
return withoutImportQualifiers(printed(ordered, file));
|
|
138
|
+
}
|
|
139
|
+
var IMPORT_QUALIFIER = /import\("[^"]*"\)\./g;
|
|
140
|
+
var withoutImportQualifiers = (text3) => text3.replace(IMPORT_QUALIFIER, "");
|
|
141
|
+
function printed(node, file) {
|
|
142
|
+
return PRINTER.printNode(ts.EmitHint.Unspecified, node, file).replace(
|
|
143
|
+
/\n/g,
|
|
144
|
+
""
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
function containsUnion(node) {
|
|
148
|
+
if (ts.isUnionTypeNode(node)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
return ts.forEachChild(node, (child) => containsUnion(child) || void 0) === true;
|
|
152
|
+
}
|
|
153
|
+
function withUnionMembersOrdered(root, file) {
|
|
154
|
+
const result = ts.transform(root, [
|
|
155
|
+
(context) => {
|
|
156
|
+
const visit = (node) => {
|
|
157
|
+
const visited = ts.visitEachChild(node, visit, context);
|
|
158
|
+
if (!ts.isUnionTypeNode(visited)) {
|
|
159
|
+
return visited;
|
|
160
|
+
}
|
|
161
|
+
return context.factory.updateUnionTypeNode(
|
|
162
|
+
visited,
|
|
163
|
+
context.factory.createNodeArray(inStableOrder(visited.types, file))
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
return (node) => visit(node);
|
|
167
|
+
}
|
|
168
|
+
]);
|
|
169
|
+
const [ordered] = result.transformed;
|
|
170
|
+
result.dispose();
|
|
171
|
+
return ordered;
|
|
172
|
+
}
|
|
173
|
+
function inStableOrder(members, file) {
|
|
174
|
+
return members.map((member) => ({
|
|
175
|
+
member,
|
|
176
|
+
text: withoutImportQualifiers(printed(member, file))
|
|
177
|
+
})).sort((a, b) => compareMembers(a.text, b.text)).map(({ member }) => member);
|
|
178
|
+
}
|
|
179
|
+
function compareMembers(a, b) {
|
|
180
|
+
return nullishRank(a) - nullishRank(b) || compareText(a, b);
|
|
181
|
+
}
|
|
182
|
+
function nullishRank(text3) {
|
|
183
|
+
if (text3 === "null") {
|
|
184
|
+
return 1;
|
|
185
|
+
}
|
|
186
|
+
if (text3 === "undefined") {
|
|
187
|
+
return 2;
|
|
188
|
+
}
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
function compareText(a, b) {
|
|
192
|
+
if (a < b) {
|
|
193
|
+
return -1;
|
|
194
|
+
}
|
|
195
|
+
if (a > b) {
|
|
196
|
+
return 1;
|
|
197
|
+
}
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
function stablePropertyName(symbol, reader) {
|
|
201
|
+
const name = symbol.getName();
|
|
202
|
+
if (!name.startsWith("__@")) {
|
|
203
|
+
return name;
|
|
204
|
+
}
|
|
205
|
+
const checker = reader.getProject().getTypeChecker().compilerObject;
|
|
206
|
+
return checker.symbolToString(symbol.compilerSymbol);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/shapes/definitions.ts
|
|
210
|
+
var current = null;
|
|
211
|
+
var definitionsInProgress = () => current;
|
|
212
|
+
function createDefinitionTable() {
|
|
213
|
+
const shapes = /* @__PURE__ */ new Map();
|
|
214
|
+
const deferred = [];
|
|
215
|
+
let settling = false;
|
|
216
|
+
return {
|
|
217
|
+
has: (key) => shapes.has(key),
|
|
218
|
+
reserve: (key) => {
|
|
219
|
+
shapes.set(key, null);
|
|
220
|
+
},
|
|
221
|
+
define: (key, shape) => {
|
|
222
|
+
shapes.set(key, shape);
|
|
223
|
+
},
|
|
224
|
+
defer: (key, expand) => {
|
|
225
|
+
deferred.push({ key, expand });
|
|
226
|
+
},
|
|
227
|
+
settle: () => {
|
|
228
|
+
if (settling) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
settling = true;
|
|
232
|
+
try {
|
|
233
|
+
for (let next = deferred.shift(); next; next = deferred.shift()) {
|
|
234
|
+
shapes.set(next.key, next.expand());
|
|
235
|
+
}
|
|
236
|
+
} finally {
|
|
237
|
+
settling = false;
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
// Sorted because the walk meets types in the checker's union order,
|
|
241
|
+
// which changes between runs.
|
|
242
|
+
collected: () => {
|
|
243
|
+
const out = {};
|
|
244
|
+
let any = false;
|
|
245
|
+
const keys = [...shapes.keys()].sort(compareText);
|
|
246
|
+
for (const key of keys) {
|
|
247
|
+
const shape = shapes.get(key) ?? null;
|
|
248
|
+
if (shape !== null) {
|
|
249
|
+
out[key] = shape;
|
|
250
|
+
any = true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return any ? out : null;
|
|
254
|
+
},
|
|
255
|
+
shapeOf: (key) => shapes.get(key)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function withDefinitionsNoted(read2) {
|
|
259
|
+
const table = current;
|
|
260
|
+
if (table === null) {
|
|
261
|
+
return { value: read2(), noted: [] };
|
|
262
|
+
}
|
|
263
|
+
const keys = /* @__PURE__ */ new Set();
|
|
264
|
+
current = {
|
|
265
|
+
has: (key) => {
|
|
266
|
+
keys.add(key);
|
|
267
|
+
return table.has(key);
|
|
268
|
+
},
|
|
269
|
+
reserve: (key) => {
|
|
270
|
+
keys.add(key);
|
|
271
|
+
table.reserve(key);
|
|
272
|
+
},
|
|
273
|
+
define: (key, shape) => {
|
|
274
|
+
keys.add(key);
|
|
275
|
+
table.define(key, shape);
|
|
276
|
+
},
|
|
277
|
+
defer: (key, expand) => {
|
|
278
|
+
keys.add(key);
|
|
279
|
+
table.defer(key, expand);
|
|
280
|
+
},
|
|
281
|
+
settle: () => table.settle(),
|
|
282
|
+
collected: () => table.collected(),
|
|
283
|
+
shapeOf: (key) => table.shapeOf(key)
|
|
284
|
+
};
|
|
285
|
+
let value;
|
|
286
|
+
try {
|
|
287
|
+
value = read2();
|
|
288
|
+
} finally {
|
|
289
|
+
current = table;
|
|
290
|
+
}
|
|
291
|
+
const noted = [];
|
|
292
|
+
for (const key of keys) {
|
|
293
|
+
const shape = table.shapeOf(key);
|
|
294
|
+
if (shape === null || shape === void 0) {
|
|
295
|
+
return { value, noted: null };
|
|
296
|
+
}
|
|
297
|
+
noted.push([key, shape]);
|
|
298
|
+
}
|
|
299
|
+
return { value, noted };
|
|
300
|
+
}
|
|
301
|
+
function writeNotedDefinitions(noted) {
|
|
302
|
+
const table = current;
|
|
303
|
+
if (table === null) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
for (const [key, shape] of noted) {
|
|
307
|
+
if (!table.has(key)) {
|
|
308
|
+
table.define(key, structuredClone(shape));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function withDefinitions(read2) {
|
|
313
|
+
const table = createDefinitionTable();
|
|
314
|
+
const outer = current;
|
|
315
|
+
current = table;
|
|
316
|
+
try {
|
|
317
|
+
return { value: read2(), definitions: table.collected() };
|
|
318
|
+
} finally {
|
|
319
|
+
current = outer;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/bodyWalks.ts
|
|
324
|
+
var keptByBody = /* @__PURE__ */ new WeakMap();
|
|
325
|
+
var talliesByRecognizer = /* @__PURE__ */ new WeakMap();
|
|
326
|
+
var ids = /* @__PURE__ */ new WeakMap();
|
|
327
|
+
var nextId = 1;
|
|
328
|
+
function noteRecognizerTally(recognizer, tally) {
|
|
329
|
+
talliesByRecognizer.set(recognizer, tally);
|
|
330
|
+
}
|
|
331
|
+
function walkBodyOnce(body, inputs, walk) {
|
|
332
|
+
const key = keyOf(inputs);
|
|
333
|
+
const facts = inputs.resolution?.sourceFactCount() ?? -1;
|
|
334
|
+
const kept = keptByBody.get(body)?.find((one) => one.key === key && one.facts === facts);
|
|
335
|
+
if (kept !== void 0) {
|
|
336
|
+
return replay(kept);
|
|
337
|
+
}
|
|
338
|
+
const before = new Map(
|
|
339
|
+
[...talliesOf(inputs)].map((tally) => [tally, tally.effectsRecognized])
|
|
340
|
+
);
|
|
341
|
+
const read2 = withFilesNoted(() => withDefinitionsNoted(walk));
|
|
342
|
+
const { value, noted } = read2.value;
|
|
343
|
+
const factsAfter = inputs.resolution?.sourceFactCount() ?? -1;
|
|
344
|
+
if (noted === null || factsAfter !== facts) {
|
|
345
|
+
return value;
|
|
346
|
+
}
|
|
347
|
+
const effectsByTally = /* @__PURE__ */ new Map();
|
|
348
|
+
for (const [tally, count] of before) {
|
|
349
|
+
effectsByTally.set(tally, tally.effectsRecognized - count);
|
|
350
|
+
}
|
|
351
|
+
const entry = {
|
|
352
|
+
key,
|
|
353
|
+
facts,
|
|
354
|
+
walk: copyWalk(value),
|
|
355
|
+
definitions: noted.map(([name, shape]) => [name, structuredClone(shape)]),
|
|
356
|
+
files: read2.files,
|
|
357
|
+
effectsByTally
|
|
358
|
+
};
|
|
359
|
+
const forBody = keptByBody.get(body);
|
|
360
|
+
if (forBody === void 0) {
|
|
361
|
+
keptByBody.set(body, [entry]);
|
|
362
|
+
} else {
|
|
363
|
+
forBody.push(entry);
|
|
364
|
+
}
|
|
365
|
+
return value;
|
|
366
|
+
}
|
|
367
|
+
function replay(kept) {
|
|
368
|
+
writeNotedDefinitions(kept.definitions);
|
|
369
|
+
for (const filePath of kept.files) {
|
|
370
|
+
recordFileDependency(filePath);
|
|
371
|
+
}
|
|
372
|
+
for (const [tally, count] of kept.effectsByTally) {
|
|
373
|
+
tally.effectsRecognized += count;
|
|
374
|
+
}
|
|
375
|
+
return copyWalk(kept.walk);
|
|
376
|
+
}
|
|
377
|
+
function keyOf(inputs) {
|
|
378
|
+
const barrierIds = [...inputs.barriers].map(idOf).sort((a, b) => a - b);
|
|
379
|
+
return [
|
|
380
|
+
inputs.terminalPatterns.map(idOf).join(","),
|
|
381
|
+
idOf(inputs.invocationRecognizers),
|
|
382
|
+
idOf(inputs.accessRecognizers),
|
|
383
|
+
barrierIds.join(","),
|
|
384
|
+
inputs.resolution === void 0 ? 0 : idOf(inputs.resolution),
|
|
385
|
+
inputs.callbacks.map((present) => present ? 1 : 0).join(""),
|
|
386
|
+
// A walk with no table to write named types into notes none, so it
|
|
387
|
+
// cannot stand in for one that has a table.
|
|
388
|
+
definitionsInProgress() === null ? 0 : 1
|
|
389
|
+
].join("|");
|
|
390
|
+
}
|
|
391
|
+
function idOf(value) {
|
|
392
|
+
const known = ids.get(value);
|
|
393
|
+
if (known !== void 0) {
|
|
394
|
+
return known;
|
|
395
|
+
}
|
|
396
|
+
const id = nextId++;
|
|
397
|
+
ids.set(value, id);
|
|
398
|
+
return id;
|
|
399
|
+
}
|
|
400
|
+
function talliesOf(inputs) {
|
|
401
|
+
const tallies = /* @__PURE__ */ new Set();
|
|
402
|
+
for (const recognizer of [
|
|
403
|
+
...inputs.invocationRecognizers,
|
|
404
|
+
...inputs.accessRecognizers
|
|
405
|
+
]) {
|
|
406
|
+
const tally = talliesByRecognizer.get(recognizer);
|
|
407
|
+
if (tally !== void 0) {
|
|
408
|
+
tallies.add(tally);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return tallies;
|
|
412
|
+
}
|
|
413
|
+
function copyWalk(walk) {
|
|
414
|
+
return {
|
|
415
|
+
terminals: walk.terminals.map((found) => ({
|
|
416
|
+
...found,
|
|
417
|
+
terminal: structuredClone(found.terminal),
|
|
418
|
+
...found.whenAlso === void 0 ? {} : { whenAlso: copyCondition(found.whenAlso) }
|
|
419
|
+
})),
|
|
420
|
+
invocations: walk.invocations.map((site) => ({
|
|
421
|
+
...site,
|
|
422
|
+
effect: structuredClone(site.effect)
|
|
423
|
+
})),
|
|
424
|
+
recognized: walk.recognized.map((site) => ({
|
|
425
|
+
...site,
|
|
426
|
+
effect: structuredClone(site.effect),
|
|
427
|
+
preconditions: site.preconditions.map(copyCondition),
|
|
428
|
+
...site.slots === void 0 ? {} : { slots: site.slots.map((slot) => ({ ...slot })) }
|
|
429
|
+
}))
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
function copyCondition(condition) {
|
|
433
|
+
return structuredClone(condition);
|
|
434
|
+
}
|
|
435
|
+
|
|
44
436
|
// src/conditions.ts
|
|
45
437
|
import {
|
|
46
438
|
Node as Node46
|
|
47
439
|
} from "ts-morph";
|
|
48
440
|
|
|
49
441
|
// src/predicates.ts
|
|
50
|
-
import { Node as Node45, SyntaxKind as
|
|
442
|
+
import { Node as Node45, SyntaxKind as SyntaxKind19 } from "ts-morph";
|
|
51
443
|
import { replacePredicateRefs } from "@suss/behavioral-ir";
|
|
52
444
|
|
|
53
445
|
// src/resolve/astResolve.ts
|
|
54
|
-
import { Node as Node42, SyntaxKind as
|
|
446
|
+
import { Node as Node42, SyntaxKind as SyntaxKind18 } from "ts-morph";
|
|
55
447
|
|
|
56
448
|
// src/walk/nodeKeys.ts
|
|
57
449
|
import { declarationKey } from "@suss/behavioral-ir";
|
|
@@ -138,12 +530,11 @@ function passesValueThrough(node) {
|
|
|
138
530
|
}
|
|
139
531
|
|
|
140
532
|
// src/resolve/functionBehind.ts
|
|
141
|
-
import { Node as Node41, SyntaxKind as
|
|
533
|
+
import { Node as Node41, SyntaxKind as SyntaxKind17 } from "ts-morph";
|
|
142
534
|
import { normalizeCalleeText } from "@suss/behavioral-ir";
|
|
143
535
|
|
|
144
536
|
// src/facts/store.ts
|
|
145
537
|
import { Node as Node9 } from "ts-morph";
|
|
146
|
-
import { isTestFile } from "@suss/behavioral-ir";
|
|
147
538
|
import {
|
|
148
539
|
clearRelations,
|
|
149
540
|
Database as Database2,
|
|
@@ -179,7 +570,8 @@ import path from "path";
|
|
|
179
570
|
|
|
180
571
|
// src/discovery/shared.ts
|
|
181
572
|
import {
|
|
182
|
-
Node as Node2
|
|
573
|
+
Node as Node2,
|
|
574
|
+
SyntaxKind
|
|
183
575
|
} from "ts-morph";
|
|
184
576
|
function unitNode(unit) {
|
|
185
577
|
return unit.func ?? unit.announcedAt ?? null;
|
|
@@ -218,8 +610,15 @@ function exportIdentityOf(unit) {
|
|
|
218
610
|
return "";
|
|
219
611
|
}
|
|
220
612
|
function isFunctionRoot(node) {
|
|
221
|
-
return
|
|
222
|
-
}
|
|
613
|
+
return FUNCTION_ROOT_KINDS.has(node.getKind());
|
|
614
|
+
}
|
|
615
|
+
var FUNCTION_ROOT_KINDS = /* @__PURE__ */ new Set([
|
|
616
|
+
SyntaxKind.FunctionDeclaration,
|
|
617
|
+
SyntaxKind.FunctionExpression,
|
|
618
|
+
SyntaxKind.ArrowFunction,
|
|
619
|
+
SyntaxKind.MethodDeclaration,
|
|
620
|
+
SyntaxKind.Constructor
|
|
621
|
+
]);
|
|
223
622
|
function declarationCarryingTheBody(declaration) {
|
|
224
623
|
if (!Node2.isFunctionDeclaration(declaration) && !Node2.isMethodDeclaration(declaration) && !Node2.isConstructorDeclaration(declaration)) {
|
|
225
624
|
return declaration;
|
|
@@ -300,6 +699,61 @@ function createPerFileCache() {
|
|
|
300
699
|
};
|
|
301
700
|
}
|
|
302
701
|
|
|
702
|
+
// src/walk/rawDescent.ts
|
|
703
|
+
import {
|
|
704
|
+
ts as ts2
|
|
705
|
+
} from "ts-morph";
|
|
706
|
+
function statementsOfKind(file, kind) {
|
|
707
|
+
const found = [];
|
|
708
|
+
for (const raw of file.compilerNode.statements) {
|
|
709
|
+
if (raw.kind === kind) {
|
|
710
|
+
found.push(wrapperOf(file, raw));
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return found;
|
|
714
|
+
}
|
|
715
|
+
function forEachDescendantOfKinds(root, kinds, visit, skips = runsNothing) {
|
|
716
|
+
forEachDescendantWhere(root, (raw) => kinds.has(raw.kind), visit, skips);
|
|
717
|
+
}
|
|
718
|
+
function forEachDescendantWhere(root, accepts, visit, skips = runsNothing) {
|
|
719
|
+
const walk = (raw) => {
|
|
720
|
+
if (skips(raw)) {
|
|
721
|
+
return void 0;
|
|
722
|
+
}
|
|
723
|
+
if (accepts(raw) && visit(wrapperOf(root, raw)) === true) {
|
|
724
|
+
return void 0;
|
|
725
|
+
}
|
|
726
|
+
ts2.forEachChild(raw, walk);
|
|
727
|
+
return void 0;
|
|
728
|
+
};
|
|
729
|
+
ts2.forEachChild(root.compilerNode, walk);
|
|
730
|
+
}
|
|
731
|
+
function runsNothing(raw) {
|
|
732
|
+
return isTypeOnlySyntax(raw) || isAmbient(raw);
|
|
733
|
+
}
|
|
734
|
+
function skipsNothing() {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
function isTypeOnlySyntax(raw) {
|
|
738
|
+
return raw.kind >= ts2.SyntaxKind.FirstTypeNode && raw.kind <= ts2.SyntaxKind.LastTypeNode || TYPE_DECLARATIONS.has(raw.kind);
|
|
739
|
+
}
|
|
740
|
+
var TYPE_DECLARATIONS = /* @__PURE__ */ new Set([
|
|
741
|
+
ts2.SyntaxKind.TypeAliasDeclaration,
|
|
742
|
+
ts2.SyntaxKind.InterfaceDeclaration,
|
|
743
|
+
ts2.SyntaxKind.TypeParameter
|
|
744
|
+
]);
|
|
745
|
+
function isAmbient(raw) {
|
|
746
|
+
if (!ts2.canHaveModifiers(raw)) {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
return ts2.getModifiers(raw)?.some((modifier) => modifier.kind === ts2.SyntaxKind.DeclareKeyword) ?? false;
|
|
750
|
+
}
|
|
751
|
+
function wrapperOf(anchor, raw) {
|
|
752
|
+
return anchor._getNodeFromCompilerNode(
|
|
753
|
+
raw
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
|
|
303
757
|
// src/bootstrap/sourceFileLookup.ts
|
|
304
758
|
function sourceFileFor(project, moduleKey) {
|
|
305
759
|
if (!isPathKey(moduleKey)) {
|
|
@@ -403,54 +857,43 @@ function spanKey(span) {
|
|
|
403
857
|
var functionIndexes = createPerFileCache();
|
|
404
858
|
function indexFunctions(sf) {
|
|
405
859
|
const index = /* @__PURE__ */ new Map();
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
index.
|
|
415
|
-
|
|
416
|
-
|
|
860
|
+
forEachDescendantOfKinds(
|
|
861
|
+
sf,
|
|
862
|
+
FUNCTION_ROOT_KINDS,
|
|
863
|
+
(found) => {
|
|
864
|
+
const node = found;
|
|
865
|
+
const bySpan = spanKey({ start: node.getStart(), end: node.getEnd() });
|
|
866
|
+
index.set(bySpan, node);
|
|
867
|
+
const key = rangeKey({ start: startLineOf(node), end: endLineOf(node) });
|
|
868
|
+
if (!index.has(key)) {
|
|
869
|
+
index.set(key, node);
|
|
870
|
+
}
|
|
871
|
+
return false;
|
|
872
|
+
},
|
|
873
|
+
isTypeOnlySyntax
|
|
874
|
+
);
|
|
417
875
|
return index;
|
|
418
876
|
}
|
|
419
877
|
|
|
420
|
-
// src/
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
var activeSink = null;
|
|
425
|
-
function withDependencySink(sink, fn) {
|
|
426
|
-
const previous = activeSink;
|
|
427
|
-
activeSink = sink;
|
|
428
|
-
try {
|
|
429
|
-
return fn();
|
|
430
|
-
} finally {
|
|
431
|
-
activeSink = previous;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
function recordFileDependency(filePath) {
|
|
435
|
-
activeSink?.files.add(filePath);
|
|
436
|
-
}
|
|
437
|
-
function recordMountPrefix(childId, prefix) {
|
|
438
|
-
activeSink?.mountPrefixes.set(childId, prefix);
|
|
878
|
+
// src/testCode.ts
|
|
879
|
+
import { isTestFile } from "@suss/behavioral-ir";
|
|
880
|
+
function inTestFile(node) {
|
|
881
|
+
return isTestFile(node.getSourceFile().getFilePath());
|
|
439
882
|
}
|
|
440
|
-
function
|
|
441
|
-
|
|
883
|
+
function testCallingProduction(call, callee) {
|
|
884
|
+
return inTestFile(call) && !inTestFile(callee);
|
|
442
885
|
}
|
|
443
886
|
|
|
444
887
|
// src/facts/containerWrites.ts
|
|
445
|
-
import { Node as Node8, SyntaxKind as
|
|
888
|
+
import { Node as Node8, SyntaxKind as SyntaxKind8 } from "ts-morph";
|
|
446
889
|
|
|
447
890
|
// src/facts/extract.ts
|
|
448
891
|
import { posix } from "path";
|
|
449
892
|
import {
|
|
450
893
|
ModuleDeclarationKind,
|
|
451
894
|
Node as Node6,
|
|
452
|
-
SyntaxKind as
|
|
453
|
-
ts as
|
|
895
|
+
SyntaxKind as SyntaxKind6,
|
|
896
|
+
ts as ts5
|
|
454
897
|
} from "ts-morph";
|
|
455
898
|
import {
|
|
456
899
|
addEntryRows,
|
|
@@ -467,12 +910,12 @@ import {
|
|
|
467
910
|
} from "@suss/resolution";
|
|
468
911
|
|
|
469
912
|
// src/moduleExports.ts
|
|
470
|
-
import { Node as Node3 } from "ts-morph";
|
|
913
|
+
import { Node as Node3, SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
471
914
|
|
|
472
915
|
// src/bootstrap/lazyProjectInit.ts
|
|
473
916
|
import fs2 from "fs/promises";
|
|
474
917
|
import path3 from "path";
|
|
475
|
-
import { ts } from "ts-morph";
|
|
918
|
+
import { ts as ts3 } from "ts-morph";
|
|
476
919
|
|
|
477
920
|
// src/facts/generatedModules.ts
|
|
478
921
|
import fs from "fs";
|
|
@@ -558,6 +1001,7 @@ function generatedModulesOf(packs) {
|
|
|
558
1001
|
}
|
|
559
1002
|
|
|
560
1003
|
// src/facts/moduleGraph.ts
|
|
1004
|
+
import { SyntaxKind as SyntaxKind2 } from "ts-morph";
|
|
561
1005
|
import { Database, evaluate, lit, rule, variable as v } from "@suss/datalog";
|
|
562
1006
|
var NO_GENERATOR = new GeneratedModules([]);
|
|
563
1007
|
var REACH_RULES = [
|
|
@@ -762,10 +1206,16 @@ var ModuleGraph = class {
|
|
|
762
1206
|
};
|
|
763
1207
|
function readModuleSpecifiers(sourceFile) {
|
|
764
1208
|
const specifiers = [];
|
|
765
|
-
for (const importDecl of
|
|
1209
|
+
for (const importDecl of statementsOfKind(
|
|
1210
|
+
sourceFile,
|
|
1211
|
+
SyntaxKind2.ImportDeclaration
|
|
1212
|
+
)) {
|
|
766
1213
|
specifiers.push(importDecl.getModuleSpecifierValue());
|
|
767
1214
|
}
|
|
768
|
-
for (const exportDecl of
|
|
1215
|
+
for (const exportDecl of statementsOfKind(
|
|
1216
|
+
sourceFile,
|
|
1217
|
+
SyntaxKind2.ExportDeclaration
|
|
1218
|
+
)) {
|
|
769
1219
|
const specifier = exportDecl.getModuleSpecifierValue();
|
|
770
1220
|
if (specifier !== void 0) {
|
|
771
1221
|
specifiers.push(specifier);
|
|
@@ -785,13 +1235,19 @@ function resolveModuleSpecifiers(sourceFile) {
|
|
|
785
1235
|
}
|
|
786
1236
|
function resolveModuleSpecifiersOf(sourceFile) {
|
|
787
1237
|
const resolved = [];
|
|
788
|
-
for (const importDecl of
|
|
1238
|
+
for (const importDecl of statementsOfKind(
|
|
1239
|
+
sourceFile,
|
|
1240
|
+
SyntaxKind2.ImportDeclaration
|
|
1241
|
+
)) {
|
|
789
1242
|
const target = importDecl.getModuleSpecifierSourceFile();
|
|
790
1243
|
if (target !== void 0) {
|
|
791
1244
|
resolved.push(target);
|
|
792
1245
|
}
|
|
793
1246
|
}
|
|
794
|
-
for (const exportDecl of
|
|
1247
|
+
for (const exportDecl of statementsOfKind(
|
|
1248
|
+
sourceFile,
|
|
1249
|
+
SyntaxKind2.ExportDeclaration
|
|
1250
|
+
)) {
|
|
795
1251
|
const target = exportDecl.getModuleSpecifierSourceFile();
|
|
796
1252
|
if (target !== void 0) {
|
|
797
1253
|
resolved.push(target);
|
|
@@ -809,6 +1265,7 @@ function namesAnyPackage(specifiers, names) {
|
|
|
809
1265
|
}
|
|
810
1266
|
|
|
811
1267
|
// src/bootstrap/preFilter.ts
|
|
1268
|
+
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
812
1269
|
function computePackApplicability(sourceFiles, packs, resolution) {
|
|
813
1270
|
const ungatedPacks = [];
|
|
814
1271
|
const gatedPacks = [];
|
|
@@ -828,7 +1285,9 @@ function computePackApplicability(sourceFiles, packs, resolution) {
|
|
|
828
1285
|
for (const sf of sourceFiles) {
|
|
829
1286
|
importsByFile.set(
|
|
830
1287
|
sf,
|
|
831
|
-
sf.
|
|
1288
|
+
statementsOfKind(sf, SyntaxKind3.ImportDeclaration).map(
|
|
1289
|
+
(d) => d.getModuleSpecifierValue()
|
|
1290
|
+
)
|
|
832
1291
|
);
|
|
833
1292
|
}
|
|
834
1293
|
}
|
|
@@ -1088,7 +1547,7 @@ function resolutionCacheFor(project, options) {
|
|
|
1088
1547
|
if (existing !== void 0) {
|
|
1089
1548
|
return existing;
|
|
1090
1549
|
}
|
|
1091
|
-
const fresh =
|
|
1550
|
+
const fresh = ts3.createModuleResolutionCache(
|
|
1092
1551
|
project.getFileSystem().getCurrentDirectory(),
|
|
1093
1552
|
(name) => name,
|
|
1094
1553
|
options
|
|
@@ -1122,11 +1581,11 @@ function readSpecifierPaths(project, filePath, options, host) {
|
|
|
1122
1581
|
if (text3 === null) {
|
|
1123
1582
|
return [];
|
|
1124
1583
|
}
|
|
1125
|
-
const scanned =
|
|
1584
|
+
const scanned = ts3.preProcessFile(text3, true, true);
|
|
1126
1585
|
const cache = resolutionCacheFor(project, options);
|
|
1127
1586
|
const paths = [];
|
|
1128
1587
|
for (const imported of scanned.importedFiles) {
|
|
1129
|
-
const resolved =
|
|
1588
|
+
const resolved = ts3.resolveModuleName(
|
|
1130
1589
|
imported.fileName,
|
|
1131
1590
|
filePath,
|
|
1132
1591
|
options,
|
|
@@ -1152,13 +1611,13 @@ function readFileText(project, filePath) {
|
|
|
1152
1611
|
}
|
|
1153
1612
|
function parseTsconfig(tsConfigFilePath, seen = /* @__PURE__ */ new Set()) {
|
|
1154
1613
|
seen.add(tsConfigFilePath);
|
|
1155
|
-
const configFile =
|
|
1614
|
+
const configFile = ts3.readConfigFile(tsConfigFilePath, ts3.sys.readFile);
|
|
1156
1615
|
if (configFile.error !== void 0) {
|
|
1157
1616
|
return { fileNames: [], options: {} };
|
|
1158
1617
|
}
|
|
1159
|
-
const parsed =
|
|
1618
|
+
const parsed = ts3.parseJsonConfigFileContent(
|
|
1160
1619
|
configFile.config,
|
|
1161
|
-
|
|
1620
|
+
ts3.sys,
|
|
1162
1621
|
path3.dirname(tsConfigFilePath),
|
|
1163
1622
|
/*existingOptions*/
|
|
1164
1623
|
void 0,
|
|
@@ -1167,7 +1626,7 @@ function parseTsconfig(tsConfigFilePath, seen = /* @__PURE__ */ new Set()) {
|
|
|
1167
1626
|
if (parsed.fileNames.length > 0) {
|
|
1168
1627
|
return { fileNames: parsed.fileNames, options: parsed.options };
|
|
1169
1628
|
}
|
|
1170
|
-
const referenced = (parsed.projectReferences ?? []).map((reference) =>
|
|
1629
|
+
const referenced = (parsed.projectReferences ?? []).map((reference) => ts3.resolveProjectReferencePath(reference)).filter((referencePath) => !seen.has(referencePath)).map((referencePath) => parseTsconfig(referencePath, seen));
|
|
1171
1630
|
const fileNames = [
|
|
1172
1631
|
...new Set(referenced.flatMap((reference) => reference.fileNames))
|
|
1173
1632
|
];
|
|
@@ -1241,17 +1700,17 @@ function addImportersOfMatches(fileImports, matched, options) {
|
|
|
1241
1700
|
}
|
|
1242
1701
|
function internalSpecifierResolver(files, options) {
|
|
1243
1702
|
const fileSet = new Set(files);
|
|
1244
|
-
const cache =
|
|
1245
|
-
|
|
1703
|
+
const cache = ts3.createModuleResolutionCache(
|
|
1704
|
+
ts3.sys.getCurrentDirectory(),
|
|
1246
1705
|
(name) => name,
|
|
1247
1706
|
options
|
|
1248
1707
|
);
|
|
1249
1708
|
return (fromFile, spec) => {
|
|
1250
|
-
const resolved =
|
|
1709
|
+
const resolved = ts3.resolveModuleName(
|
|
1251
1710
|
spec,
|
|
1252
1711
|
fromFile,
|
|
1253
1712
|
options,
|
|
1254
|
-
|
|
1713
|
+
ts3.sys,
|
|
1255
1714
|
cache
|
|
1256
1715
|
).resolvedModule?.resolvedFileName;
|
|
1257
1716
|
if (resolved === void 0) {
|
|
@@ -1260,7 +1719,7 @@ function internalSpecifierResolver(files, options) {
|
|
|
1260
1719
|
if (fileSet.has(resolved)) {
|
|
1261
1720
|
return resolved;
|
|
1262
1721
|
}
|
|
1263
|
-
const real =
|
|
1722
|
+
const real = ts3.sys.realpath?.(resolved) ?? resolved;
|
|
1264
1723
|
return fileSet.has(real) ? real : null;
|
|
1265
1724
|
};
|
|
1266
1725
|
}
|
|
@@ -1295,7 +1754,7 @@ async function readImportsConcurrently(paths, marks) {
|
|
|
1295
1754
|
const p = paths[i];
|
|
1296
1755
|
try {
|
|
1297
1756
|
const text3 = await fs2.readFile(p, "utf-8");
|
|
1298
|
-
const pre =
|
|
1757
|
+
const pre = ts3.preProcessFile(text3, true, false);
|
|
1299
1758
|
results[i] = {
|
|
1300
1759
|
path: p,
|
|
1301
1760
|
importedModules: pre.importedFiles.map((f) => f.fileName),
|
|
@@ -1418,7 +1877,7 @@ function reExportShapeOf(file, reach) {
|
|
|
1418
1877
|
const targets = [];
|
|
1419
1878
|
const exportNodes = [];
|
|
1420
1879
|
const localNames = /* @__PURE__ */ new Set();
|
|
1421
|
-
for (const decl of file.
|
|
1880
|
+
for (const decl of statementsOfKind(file, SyntaxKind4.ExportDeclaration)) {
|
|
1422
1881
|
const target = decl.getModuleSpecifierSourceFile();
|
|
1423
1882
|
if (target !== void 0) {
|
|
1424
1883
|
targets.push(target);
|
|
@@ -1430,7 +1889,10 @@ function reExportShapeOf(file, reach) {
|
|
|
1430
1889
|
}
|
|
1431
1890
|
}
|
|
1432
1891
|
}
|
|
1433
|
-
for (const assignment of
|
|
1892
|
+
for (const assignment of statementsOfKind(
|
|
1893
|
+
file,
|
|
1894
|
+
SyntaxKind4.ExportAssignment
|
|
1895
|
+
)) {
|
|
1434
1896
|
exportNodes.push(assignment);
|
|
1435
1897
|
const expression = assignment.getExpression();
|
|
1436
1898
|
if (Node3.isIdentifier(expression)) {
|
|
@@ -1438,7 +1900,7 @@ function reExportShapeOf(file, reach) {
|
|
|
1438
1900
|
}
|
|
1439
1901
|
}
|
|
1440
1902
|
const importNodes = [];
|
|
1441
|
-
for (const decl of file.
|
|
1903
|
+
for (const decl of statementsOfKind(file, SyntaxKind4.ImportDeclaration)) {
|
|
1442
1904
|
const all = importBindingsOf(decl);
|
|
1443
1905
|
const bindings = reach === "every import" ? all : all.filter((binding) => localNames.has(binding.name));
|
|
1444
1906
|
if (bindings.length === 0) {
|
|
@@ -1528,7 +1990,7 @@ function keyNameOf(name) {
|
|
|
1528
1990
|
}
|
|
1529
1991
|
|
|
1530
1992
|
// src/facts/assignments.ts
|
|
1531
|
-
import { Node as Node5, SyntaxKind, VariableDeclarationKind } from "ts-morph";
|
|
1993
|
+
import { Node as Node5, SyntaxKind as SyntaxKind5, ts as ts4, VariableDeclarationKind } from "ts-morph";
|
|
1532
1994
|
import { valueLeftByWrites } from "@suss/resolution";
|
|
1533
1995
|
var byFile = createPerFileCache();
|
|
1534
1996
|
var byDeclaration = /* @__PURE__ */ new WeakMap();
|
|
@@ -1576,7 +2038,7 @@ function describeWrites(values) {
|
|
|
1576
2038
|
}));
|
|
1577
2039
|
}
|
|
1578
2040
|
function isNotYetPlaceholder(value) {
|
|
1579
|
-
return value.getKind() ===
|
|
2041
|
+
return value.getKind() === SyntaxKind5.NullKeyword || Node5.isIdentifier(value) && value.getText() === "undefined";
|
|
1580
2042
|
}
|
|
1581
2043
|
function isConstruction(value) {
|
|
1582
2044
|
return Node5.isCallExpression(value) || Node5.isNewExpression(value) || Node5.isObjectLiteralExpression(value) || Node5.isArrayLiteralExpression(value);
|
|
@@ -1711,11 +2173,8 @@ function assignmentsInFile(sourceFile) {
|
|
|
1711
2173
|
}
|
|
1712
2174
|
const found = /* @__PURE__ */ new Map();
|
|
1713
2175
|
byFile.set(sourceFile, found);
|
|
1714
|
-
sourceFile
|
|
2176
|
+
forEachDescendantWhere(sourceFile, mayWrite, (node) => {
|
|
1715
2177
|
const written = writeAt(node);
|
|
1716
|
-
if (written === null) {
|
|
1717
|
-
return;
|
|
1718
|
-
}
|
|
1719
2178
|
for (const declaration of declarationsOf(written.target)) {
|
|
1720
2179
|
const writes = found.get(declaration);
|
|
1721
2180
|
if (writes === void 0) {
|
|
@@ -1724,34 +2183,33 @@ function assignmentsInFile(sourceFile) {
|
|
|
1724
2183
|
writes.push(written.write);
|
|
1725
2184
|
}
|
|
1726
2185
|
}
|
|
2186
|
+
return false;
|
|
1727
2187
|
});
|
|
1728
2188
|
return found;
|
|
1729
2189
|
}
|
|
2190
|
+
function mayWrite(raw) {
|
|
2191
|
+
if (ts4.isBinaryExpression(raw)) {
|
|
2192
|
+
return isAssignmentOperator(raw.operatorToken.kind) && (ts4.isIdentifier(raw.left) || ts4.isPropertyAccessExpression(raw.left));
|
|
2193
|
+
}
|
|
2194
|
+
if (ts4.isPrefixUnaryExpression(raw) || ts4.isPostfixUnaryExpression(raw)) {
|
|
2195
|
+
return (raw.operator === SyntaxKind5.PlusPlusToken || raw.operator === SyntaxKind5.MinusMinusToken) && ts4.isIdentifier(raw.operand);
|
|
2196
|
+
}
|
|
2197
|
+
return false;
|
|
2198
|
+
}
|
|
1730
2199
|
function isAssignmentOperator(kind) {
|
|
1731
|
-
return kind >=
|
|
2200
|
+
return kind >= SyntaxKind5.FirstAssignment && kind <= SyntaxKind5.LastAssignment;
|
|
1732
2201
|
}
|
|
1733
2202
|
function writesItsWholeValue(kind) {
|
|
1734
|
-
return kind ===
|
|
2203
|
+
return kind === SyntaxKind5.EqualsToken || kind === SyntaxKind5.QuestionQuestionEqualsToken || kind === SyntaxKind5.BarBarEqualsToken;
|
|
1735
2204
|
}
|
|
1736
2205
|
function writeAt(node) {
|
|
1737
2206
|
if (Node5.isBinaryExpression(node)) {
|
|
1738
2207
|
const operator = node.getOperatorToken().getKind();
|
|
1739
|
-
const target = node.getLeft();
|
|
1740
|
-
if (!isAssignmentOperator(operator) || !(Node5.isIdentifier(target) || Node5.isPropertyAccessExpression(target))) {
|
|
1741
|
-
return null;
|
|
1742
|
-
}
|
|
1743
2208
|
const value = writesItsWholeValue(operator) ? node.getRight() : null;
|
|
1744
|
-
return { target, write: { value, node } };
|
|
1745
|
-
}
|
|
1746
|
-
if (Node5.isPrefixUnaryExpression(node) || Node5.isPostfixUnaryExpression(node)) {
|
|
1747
|
-
const operator = node.getOperatorToken();
|
|
1748
|
-
if (operator !== SyntaxKind.PlusPlusToken && operator !== SyntaxKind.MinusMinusToken) {
|
|
1749
|
-
return null;
|
|
1750
|
-
}
|
|
1751
|
-
const target = node.getOperand();
|
|
1752
|
-
return Node5.isIdentifier(target) ? { target, write: { value: null, node } } : null;
|
|
2209
|
+
return { target: node.getLeft(), write: { value, node } };
|
|
1753
2210
|
}
|
|
1754
|
-
|
|
2211
|
+
const update = node;
|
|
2212
|
+
return { target: update.getOperand(), write: { value: null, node } };
|
|
1755
2213
|
}
|
|
1756
2214
|
function declarationsOf(name) {
|
|
1757
2215
|
const nameNode = Node5.isPropertyAccessExpression(name) ? name.getNameNode() : name;
|
|
@@ -1793,35 +2251,39 @@ function statementOf(node) {
|
|
|
1793
2251
|
function isReadBefore(declaration, position) {
|
|
1794
2252
|
const name = declaration.getName();
|
|
1795
2253
|
const sourceFile = declaration.getSourceFile();
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
if (
|
|
1799
|
-
|
|
1800
|
-
return;
|
|
1801
|
-
}
|
|
1802
|
-
if (node.getStart() >= position) {
|
|
1803
|
-
traversal.skip();
|
|
1804
|
-
return;
|
|
1805
|
-
}
|
|
1806
|
-
if (startsItsOwnBody(node)) {
|
|
1807
|
-
traversal.skip();
|
|
1808
|
-
return;
|
|
1809
|
-
}
|
|
1810
|
-
if (!Node5.isIdentifier(node) || node.getText() !== name) {
|
|
1811
|
-
return;
|
|
2254
|
+
const file = sourceFile.compilerNode;
|
|
2255
|
+
const readsHere = (raw) => {
|
|
2256
|
+
if (!ts4.isIdentifier(raw) || raw.getText(file) !== name) {
|
|
2257
|
+
return false;
|
|
1812
2258
|
}
|
|
2259
|
+
const node = wrapperOf(sourceFile, raw);
|
|
1813
2260
|
if (node === declaration.getNameNode() || isWriteTarget(node)) {
|
|
1814
|
-
return;
|
|
1815
|
-
}
|
|
1816
|
-
if (declarationsOf(node).includes(declaration)) {
|
|
1817
|
-
read2 = true;
|
|
2261
|
+
return false;
|
|
1818
2262
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
function startsItsOwnBody(node) {
|
|
1823
|
-
return Node5.isFunctionDeclaration(node) || Node5.isFunctionExpression(node) || Node5.isArrowFunction(node) || Node5.isMethodDeclaration(node) || Node5.isClassDeclaration(node);
|
|
2263
|
+
return declarationsOf(node).includes(declaration);
|
|
2264
|
+
};
|
|
2265
|
+
return someBefore(file, position, readsHere);
|
|
1824
2266
|
}
|
|
2267
|
+
function someBefore(root, position, test) {
|
|
2268
|
+
const file = root.getSourceFile();
|
|
2269
|
+
const visit = (raw) => {
|
|
2270
|
+
if (raw.getStart(file) >= position || OWN_BODY_KINDS.has(raw.kind)) {
|
|
2271
|
+
return void 0;
|
|
2272
|
+
}
|
|
2273
|
+
if (test(raw)) {
|
|
2274
|
+
return true;
|
|
2275
|
+
}
|
|
2276
|
+
return ts4.forEachChild(raw, visit);
|
|
2277
|
+
};
|
|
2278
|
+
return ts4.forEachChild(root, visit) === true;
|
|
2279
|
+
}
|
|
2280
|
+
var OWN_BODY_KINDS = /* @__PURE__ */ new Set([
|
|
2281
|
+
SyntaxKind5.FunctionDeclaration,
|
|
2282
|
+
SyntaxKind5.FunctionExpression,
|
|
2283
|
+
SyntaxKind5.ArrowFunction,
|
|
2284
|
+
SyntaxKind5.MethodDeclaration,
|
|
2285
|
+
SyntaxKind5.ClassDeclaration
|
|
2286
|
+
]);
|
|
1825
2287
|
function isWriteTarget(name) {
|
|
1826
2288
|
const parent = name.getParent();
|
|
1827
2289
|
if (parent === void 0) {
|
|
@@ -1911,21 +2373,12 @@ function runsAsItsOwnBody(node) {
|
|
|
1911
2373
|
return Node5.isFunctionDeclaration(node) || Node5.isFunctionExpression(node) || Node5.isArrowFunction(node) || Node5.isMethodDeclaration(node) || Node5.isConstructorDeclaration(node) || Node5.isGetAccessorDeclaration(node) || Node5.isSetAccessorDeclaration(node);
|
|
1912
2374
|
}
|
|
1913
2375
|
function isPropertyReadBefore(statements, name, property, position) {
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
if (node.getStart() >= position || startsItsOwnBody(node)) {
|
|
1921
|
-
traversal.skip();
|
|
1922
|
-
return;
|
|
1923
|
-
}
|
|
1924
|
-
if (Node5.isPropertyAccessExpression(node) && node.getName() === property && node.getExpression().getText() === name && !isWriteTarget(node)) {
|
|
1925
|
-
read2 = true;
|
|
1926
|
-
}
|
|
1927
|
-
});
|
|
1928
|
-
return read2;
|
|
2376
|
+
const file = statements.getSourceFile().compilerNode;
|
|
2377
|
+
return someBefore(
|
|
2378
|
+
statements.compilerNode,
|
|
2379
|
+
position,
|
|
2380
|
+
(raw) => ts4.isPropertyAccessExpression(raw) && raw.name.getText(file) === property && raw.expression.getText(file) === name && !isWriteTarget(wrapperOf(statements, raw))
|
|
2381
|
+
);
|
|
1929
2382
|
}
|
|
1930
2383
|
|
|
1931
2384
|
// src/facts/languageWords.ts
|
|
@@ -1974,8 +2427,15 @@ function createNodeTable(environmentObjects = [], runtime = NO_RUNTIME_SPELLINGS
|
|
|
1974
2427
|
};
|
|
1975
2428
|
}
|
|
1976
2429
|
function nodeId(node) {
|
|
1977
|
-
|
|
2430
|
+
const known = idByNode.get(node.compilerNode);
|
|
2431
|
+
if (known !== void 0) {
|
|
2432
|
+
return known;
|
|
2433
|
+
}
|
|
2434
|
+
const id = `${node.getSourceFile().getFilePath()}:${node.getStart()}-${node.getEnd()}`;
|
|
2435
|
+
idByNode.set(node.compilerNode, id);
|
|
2436
|
+
return id;
|
|
1978
2437
|
}
|
|
2438
|
+
var idByNode = /* @__PURE__ */ new WeakMap();
|
|
1979
2439
|
function moduleKeyOf(declaration) {
|
|
1980
2440
|
const resolved = declaration.getModuleSpecifierSourceFile();
|
|
1981
2441
|
if (resolved !== void 0) {
|
|
@@ -1989,7 +2449,7 @@ function moduleKeyOf(declaration) {
|
|
|
1989
2449
|
}
|
|
1990
2450
|
function compilerResolvedPathOf(declaration, specifier) {
|
|
1991
2451
|
const project = declaration.getProject();
|
|
1992
|
-
const result =
|
|
2452
|
+
const result = ts5.resolveModuleName(
|
|
1993
2453
|
specifier,
|
|
1994
2454
|
declaration.getSourceFile().getFilePath(),
|
|
1995
2455
|
project.getCompilerOptions(),
|
|
@@ -2031,7 +2491,7 @@ function moduleKeysOf(moduleKey, specifier) {
|
|
|
2031
2491
|
}
|
|
2032
2492
|
function dynamicImportKeysOf(expression) {
|
|
2033
2493
|
const call = unwrapExpression(expression);
|
|
2034
|
-
if (!Node6.isCallExpression(call) || call.getExpression().getKind() !==
|
|
2494
|
+
if (!Node6.isCallExpression(call) || call.getExpression().getKind() !== SyntaxKind6.ImportKeyword) {
|
|
2035
2495
|
return null;
|
|
2036
2496
|
}
|
|
2037
2497
|
const [argument] = call.getArguments();
|
|
@@ -2296,7 +2756,33 @@ function spellingsHandedOn(paths, sourceFile) {
|
|
|
2296
2756
|
if (!paths.some((path18) => text3.includes(path18))) {
|
|
2297
2757
|
return [];
|
|
2298
2758
|
}
|
|
2299
|
-
|
|
2759
|
+
const file = sourceFile.compilerNode;
|
|
2760
|
+
const found = [];
|
|
2761
|
+
forEachDescendantWhere(
|
|
2762
|
+
sourceFile,
|
|
2763
|
+
(raw) => ts5.isPropertyAccessExpression(raw) && paths.includes(compilerDottedPathOf(raw, file) ?? ""),
|
|
2764
|
+
(node) => {
|
|
2765
|
+
if (flowsOnward(node)) {
|
|
2766
|
+
found.push(node);
|
|
2767
|
+
}
|
|
2768
|
+
return false;
|
|
2769
|
+
}
|
|
2770
|
+
);
|
|
2771
|
+
return found;
|
|
2772
|
+
}
|
|
2773
|
+
function compilerDottedPathOf(raw, file) {
|
|
2774
|
+
if (ts5.isIdentifier(raw)) {
|
|
2775
|
+
return raw.getText(file);
|
|
2776
|
+
}
|
|
2777
|
+
if (ts5.isMetaProperty(raw)) {
|
|
2778
|
+
const keyword = ts5.tokenToString(raw.keywordToken);
|
|
2779
|
+
return `${keyword}.${raw.name.getText(file)}`;
|
|
2780
|
+
}
|
|
2781
|
+
if (!ts5.isPropertyAccessExpression(raw)) {
|
|
2782
|
+
return null;
|
|
2783
|
+
}
|
|
2784
|
+
const object = compilerDottedPathOf(raw.expression, file);
|
|
2785
|
+
return object === null ? null : `${object}.${raw.name.getText(file)}`;
|
|
2300
2786
|
}
|
|
2301
2787
|
function flowsOnward(node) {
|
|
2302
2788
|
const parent = node.getParent();
|
|
@@ -2313,7 +2799,7 @@ function dottedPathOf(expression) {
|
|
|
2313
2799
|
return expression.getText();
|
|
2314
2800
|
}
|
|
2315
2801
|
if (Node6.isMetaProperty(expression)) {
|
|
2316
|
-
const keyword =
|
|
2802
|
+
const keyword = ts5.tokenToString(expression.getKeywordToken());
|
|
2317
2803
|
return `${keyword}.${expression.getName()}`;
|
|
2318
2804
|
}
|
|
2319
2805
|
if (!Node6.isPropertyAccessExpression(expression)) {
|
|
@@ -2327,7 +2813,7 @@ function asFallbackExpression(expression) {
|
|
|
2327
2813
|
return null;
|
|
2328
2814
|
}
|
|
2329
2815
|
const operator = expression.getOperatorToken().getKind();
|
|
2330
|
-
return operator ===
|
|
2816
|
+
return operator === SyntaxKind6.BarBarToken || operator === SyntaxKind6.QuestionQuestionToken ? expression : null;
|
|
2331
2817
|
}
|
|
2332
2818
|
function unwrapExpression(expression) {
|
|
2333
2819
|
let current2 = expression;
|
|
@@ -2349,7 +2835,7 @@ function unwrapExpression(expression) {
|
|
|
2349
2835
|
}
|
|
2350
2836
|
function emitValue(db, table, value) {
|
|
2351
2837
|
const expression = unwrapExpression(value);
|
|
2352
|
-
if (expression.getKind() ===
|
|
2838
|
+
if (expression.getKind() === SyntaxKind6.ThisKeyword) {
|
|
2353
2839
|
const receiver = receiverKeyOf(db, table, expression);
|
|
2354
2840
|
if (receiver !== null) {
|
|
2355
2841
|
return receiver;
|
|
@@ -2503,7 +2989,7 @@ function memberReadName(read2) {
|
|
|
2503
2989
|
}
|
|
2504
2990
|
function readsOffClassItself(receiver) {
|
|
2505
2991
|
const written = unwrapExpression(receiver);
|
|
2506
|
-
if (written.getKind() ===
|
|
2992
|
+
if (written.getKind() === SyntaxKind6.ThisKeyword) {
|
|
2507
2993
|
return thisIsTheClass(written);
|
|
2508
2994
|
}
|
|
2509
2995
|
return isClassReference(written, /* @__PURE__ */ new Set());
|
|
@@ -2648,7 +3134,7 @@ function emitReferenceFacts(db, table, reference) {
|
|
|
2648
3134
|
}
|
|
2649
3135
|
if (Node6.isImportClause(declaration)) {
|
|
2650
3136
|
const importDecl = declaration.getParentIfKind(
|
|
2651
|
-
|
|
3137
|
+
SyntaxKind6.ImportDeclaration
|
|
2652
3138
|
);
|
|
2653
3139
|
if (importDecl !== void 0) {
|
|
2654
3140
|
emitImportFacts(
|
|
@@ -2664,7 +3150,7 @@ function emitReferenceFacts(db, table, reference) {
|
|
|
2664
3150
|
}
|
|
2665
3151
|
if (Node6.isNamespaceImport(declaration)) {
|
|
2666
3152
|
const importDecl = declaration.getFirstAncestorByKind(
|
|
2667
|
-
|
|
3153
|
+
SyntaxKind6.ImportDeclaration
|
|
2668
3154
|
);
|
|
2669
3155
|
if (importDecl !== void 0) {
|
|
2670
3156
|
emitImportFacts(
|
|
@@ -2978,11 +3464,11 @@ function emitConstructorFacts(db, table, declaration, classId) {
|
|
|
2978
3464
|
return;
|
|
2979
3465
|
}
|
|
2980
3466
|
const writes = propertyWritesOf(implementation, body);
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
3467
|
+
forEachDescendantOfKinds(
|
|
3468
|
+
body,
|
|
3469
|
+
BODY_FACT_KINDS,
|
|
3470
|
+
(descendant) => recordBodyCalls(db, table, classId, descendant, writes)
|
|
3471
|
+
);
|
|
2986
3472
|
emitNamedStores(db, table, writes);
|
|
2987
3473
|
}
|
|
2988
3474
|
function emitParameters(db, table, ownerId, parameters) {
|
|
@@ -3034,11 +3520,11 @@ function emitFunctionFacts(db, table, fn) {
|
|
|
3034
3520
|
returns.stated = true;
|
|
3035
3521
|
recordBodyNode(db, table, fnId, body, returns, writes);
|
|
3036
3522
|
}
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3523
|
+
forEachDescendantOfKinds(
|
|
3524
|
+
body,
|
|
3525
|
+
BODY_FACT_KINDS,
|
|
3526
|
+
(descendant) => recordBodyNode(db, table, fnId, descendant, returns, writes)
|
|
3527
|
+
);
|
|
3042
3528
|
emitNamedStores(db, table, writes);
|
|
3043
3529
|
}
|
|
3044
3530
|
if (!returns.stated) {
|
|
@@ -3096,6 +3582,18 @@ function recordBodyNode(db, table, fnId, node, returns, writes) {
|
|
|
3096
3582
|
}
|
|
3097
3583
|
return recordBodyCalls(db, table, fnId, node, writes);
|
|
3098
3584
|
}
|
|
3585
|
+
var BODY_FACT_KINDS = /* @__PURE__ */ new Set([
|
|
3586
|
+
...FUNCTION_ROOT_KINDS,
|
|
3587
|
+
SyntaxKind6.ReturnStatement,
|
|
3588
|
+
SyntaxKind6.ElementAccessExpression,
|
|
3589
|
+
SyntaxKind6.BinaryExpression,
|
|
3590
|
+
SyntaxKind6.CallExpression,
|
|
3591
|
+
SyntaxKind6.NewExpression,
|
|
3592
|
+
SyntaxKind6.AwaitExpression,
|
|
3593
|
+
SyntaxKind6.ParenthesizedExpression,
|
|
3594
|
+
SyntaxKind6.AsExpression,
|
|
3595
|
+
SyntaxKind6.SatisfiesExpression
|
|
3596
|
+
]);
|
|
3099
3597
|
function recordBodyCalls(db, table, fnId, node, writes) {
|
|
3100
3598
|
if (isFunctionRoot(node)) {
|
|
3101
3599
|
emitValue(db, table, node);
|
|
@@ -3122,7 +3620,7 @@ function recordBodyCalls(db, table, fnId, node, writes) {
|
|
|
3122
3620
|
return false;
|
|
3123
3621
|
}
|
|
3124
3622
|
function emitExitCodeWrite(db, table, node) {
|
|
3125
|
-
if (table.exitCodeWrites.length === 0 || !Node6.isBinaryExpression(node) || node.getOperatorToken().getKind() !==
|
|
3623
|
+
if (table.exitCodeWrites.length === 0 || !Node6.isBinaryExpression(node) || node.getOperatorToken().getKind() !== SyntaxKind6.EqualsToken || !spellsOneOf(table.exitCodeWrites, node.getLeft())) {
|
|
3126
3624
|
return;
|
|
3127
3625
|
}
|
|
3128
3626
|
fact(db, "exitCodeWrite", emitValue(db, table, node.getRight()));
|
|
@@ -3146,12 +3644,12 @@ function emitTopLevelStatements(db, table, sourceFile) {
|
|
|
3146
3644
|
continue;
|
|
3147
3645
|
}
|
|
3148
3646
|
if (TOP_LEVEL_BLOCKS.has(statement.getKind())) {
|
|
3149
|
-
statement
|
|
3647
|
+
forEachDescendantOfKinds(statement, TOP_LEVEL_WRITE_KINDS, (node) => {
|
|
3150
3648
|
if (isFunctionRoot(node) || Node6.isClassDeclaration(node)) {
|
|
3151
|
-
|
|
3152
|
-
return;
|
|
3649
|
+
return true;
|
|
3153
3650
|
}
|
|
3154
3651
|
notePropertyWrite(writes, node);
|
|
3652
|
+
return false;
|
|
3155
3653
|
});
|
|
3156
3654
|
}
|
|
3157
3655
|
}
|
|
@@ -3162,16 +3660,21 @@ function statementExpressionOf(statement) {
|
|
|
3162
3660
|
return Node6.isVoidExpression(expression) ? unwrapExpression(expression.getExpression()) : expression;
|
|
3163
3661
|
}
|
|
3164
3662
|
var TOP_LEVEL_BLOCKS = /* @__PURE__ */ new Set([
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3663
|
+
SyntaxKind6.Block,
|
|
3664
|
+
SyntaxKind6.IfStatement,
|
|
3665
|
+
SyntaxKind6.TryStatement,
|
|
3666
|
+
SyntaxKind6.SwitchStatement,
|
|
3667
|
+
SyntaxKind6.LabeledStatement,
|
|
3668
|
+
SyntaxKind6.ForStatement,
|
|
3669
|
+
SyntaxKind6.ForOfStatement,
|
|
3670
|
+
SyntaxKind6.ForInStatement,
|
|
3671
|
+
SyntaxKind6.WhileStatement,
|
|
3672
|
+
SyntaxKind6.DoStatement
|
|
3673
|
+
]);
|
|
3674
|
+
var TOP_LEVEL_WRITE_KINDS = /* @__PURE__ */ new Set([
|
|
3675
|
+
...FUNCTION_ROOT_KINDS,
|
|
3676
|
+
SyntaxKind6.BinaryExpression,
|
|
3677
|
+
SyntaxKind6.ClassDeclaration
|
|
3175
3678
|
]);
|
|
3176
3679
|
function descendantIsReturned(fn) {
|
|
3177
3680
|
const consumer = climbSyntax(fn).getParent();
|
|
@@ -3180,8 +3683,8 @@ function descendantIsReturned(fn) {
|
|
|
3180
3683
|
function importedModuleKeys(sourceFile) {
|
|
3181
3684
|
const keys = [];
|
|
3182
3685
|
for (const declaration of [
|
|
3183
|
-
...sourceFile.
|
|
3184
|
-
...sourceFile.
|
|
3686
|
+
...statementsOfKind(sourceFile, SyntaxKind6.ImportDeclaration),
|
|
3687
|
+
...statementsOfKind(sourceFile, SyntaxKind6.ExportDeclaration)
|
|
3185
3688
|
]) {
|
|
3186
3689
|
const moduleKey = moduleKeyOf(declaration);
|
|
3187
3690
|
if (moduleKey !== null) {
|
|
@@ -3192,7 +3695,10 @@ function importedModuleKeys(sourceFile) {
|
|
|
3192
3695
|
}
|
|
3193
3696
|
function extractReExportFacts(db, sourceFile) {
|
|
3194
3697
|
const filePath = sourceFile.getFilePath();
|
|
3195
|
-
for (const exportDecl of
|
|
3698
|
+
for (const exportDecl of statementsOfKind(
|
|
3699
|
+
sourceFile,
|
|
3700
|
+
SyntaxKind6.ExportDeclaration
|
|
3701
|
+
)) {
|
|
3196
3702
|
const moduleKey = moduleKeyOf(exportDecl);
|
|
3197
3703
|
if (moduleKey === null) {
|
|
3198
3704
|
continue;
|
|
@@ -3249,7 +3755,7 @@ function collectDirectExports(statements, found) {
|
|
|
3249
3755
|
continue;
|
|
3250
3756
|
}
|
|
3251
3757
|
for (const element of nameNode.getDescendantsOfKind(
|
|
3252
|
-
|
|
3758
|
+
SyntaxKind6.BindingElement
|
|
3253
3759
|
)) {
|
|
3254
3760
|
const bound = element.getNameNode();
|
|
3255
3761
|
if (Node6.isIdentifier(bound)) {
|
|
@@ -3268,7 +3774,10 @@ function collectDirectExports(statements, found) {
|
|
|
3268
3774
|
}
|
|
3269
3775
|
}
|
|
3270
3776
|
function emitLocalExportLists(db, table, sourceFile, filePath) {
|
|
3271
|
-
for (const exportDecl of
|
|
3777
|
+
for (const exportDecl of statementsOfKind(
|
|
3778
|
+
sourceFile,
|
|
3779
|
+
SyntaxKind6.ExportDeclaration
|
|
3780
|
+
)) {
|
|
3272
3781
|
if (exportDecl.getModuleSpecifier() !== void 0) {
|
|
3273
3782
|
continue;
|
|
3274
3783
|
}
|
|
@@ -3279,7 +3788,10 @@ function emitLocalExportLists(db, table, sourceFile, filePath) {
|
|
|
3279
3788
|
}
|
|
3280
3789
|
}
|
|
3281
3790
|
}
|
|
3282
|
-
for (const assignment of
|
|
3791
|
+
for (const assignment of statementsOfKind(
|
|
3792
|
+
sourceFile,
|
|
3793
|
+
SyntaxKind6.ExportAssignment
|
|
3794
|
+
)) {
|
|
3283
3795
|
if (assignment.isExportEquals()) {
|
|
3284
3796
|
continue;
|
|
3285
3797
|
}
|
|
@@ -3303,7 +3815,7 @@ function emitExportedDeclaration(db, table, filePath, alias, declaration) {
|
|
|
3303
3815
|
const specifier = importSpecifierOf(declaration);
|
|
3304
3816
|
if (specifier !== null) {
|
|
3305
3817
|
const importDecl = declaration.getFirstAncestorByKind(
|
|
3306
|
-
|
|
3818
|
+
SyntaxKind6.ImportDeclaration
|
|
3307
3819
|
);
|
|
3308
3820
|
const moduleKey = importDecl === void 0 ? null : moduleKeyOf(importDecl);
|
|
3309
3821
|
if (moduleKey !== null) {
|
|
@@ -3358,7 +3870,7 @@ function emitExportedValue(db, table, filePath, name, spelling) {
|
|
|
3358
3870
|
}
|
|
3359
3871
|
|
|
3360
3872
|
// src/facts/localUses.ts
|
|
3361
|
-
import { Node as Node7, SyntaxKind as
|
|
3873
|
+
import { Node as Node7, SyntaxKind as SyntaxKind7 } from "ts-morph";
|
|
3362
3874
|
import { UNPLACED_STORE_NAME } from "@suss/resolution";
|
|
3363
3875
|
function fact2(db, relation, ...tuple) {
|
|
3364
3876
|
db.add(relation, tuple);
|
|
@@ -3420,25 +3932,25 @@ function emitUse(db, table, operand2) {
|
|
|
3420
3932
|
return key;
|
|
3421
3933
|
}
|
|
3422
3934
|
var CONSUMERS = {
|
|
3423
|
-
[
|
|
3424
|
-
[
|
|
3425
|
-
[
|
|
3426
|
-
[
|
|
3427
|
-
[
|
|
3428
|
-
[
|
|
3429
|
-
[
|
|
3430
|
-
[
|
|
3431
|
-
[
|
|
3432
|
-
[
|
|
3433
|
-
[
|
|
3434
|
-
[
|
|
3435
|
-
[
|
|
3436
|
-
[
|
|
3437
|
-
[
|
|
3438
|
-
[
|
|
3439
|
-
[
|
|
3440
|
-
[
|
|
3441
|
-
[
|
|
3935
|
+
[SyntaxKind7.PropertyAccessExpression]: emitPartRead,
|
|
3936
|
+
[SyntaxKind7.ElementAccessExpression]: emitPartRead,
|
|
3937
|
+
[SyntaxKind7.CallExpression]: emitWhole,
|
|
3938
|
+
[SyntaxKind7.NewExpression]: emitWhole,
|
|
3939
|
+
[SyntaxKind7.ArrayLiteralExpression]: emitWhole,
|
|
3940
|
+
[SyntaxKind7.PropertyAssignment]: emitHolder,
|
|
3941
|
+
[SyntaxKind7.ShorthandPropertyAssignment]: emitHolder,
|
|
3942
|
+
[SyntaxKind7.ReturnStatement]: emitEnclosingFunction,
|
|
3943
|
+
[SyntaxKind7.ArrowFunction]: emitEnclosingFunction,
|
|
3944
|
+
[SyntaxKind7.Parameter]: emitEnclosingFunction,
|
|
3945
|
+
[SyntaxKind7.YieldExpression]: emitYield,
|
|
3946
|
+
[SyntaxKind7.VariableDeclaration]: emitNameWrite,
|
|
3947
|
+
[SyntaxKind7.BinaryExpression]: emitBinary,
|
|
3948
|
+
[SyntaxKind7.ConditionalExpression]: emitConditionalBranch,
|
|
3949
|
+
[SyntaxKind7.SpreadElement]: emitGivenTo,
|
|
3950
|
+
[SyntaxKind7.SpreadAssignment]: emitGivenTo,
|
|
3951
|
+
[SyntaxKind7.JsxSpreadAttribute]: emitGivenToElement,
|
|
3952
|
+
[SyntaxKind7.JsxExpression]: emitGivenToElement,
|
|
3953
|
+
[SyntaxKind7.PropertyDeclaration]: emitFieldInitializer
|
|
3442
3954
|
};
|
|
3443
3955
|
function emitGivenTo(db, _table, _operand, key, parent) {
|
|
3444
3956
|
const container = parent.getParent();
|
|
@@ -3526,16 +4038,16 @@ function emitNameWrite(db, _table, _operand, key, parent) {
|
|
|
3526
4038
|
fact2(db, "mayHold", nodeId(name), key);
|
|
3527
4039
|
}
|
|
3528
4040
|
var WHOLE_VALUE_WRITES = /* @__PURE__ */ new Set([
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
4041
|
+
SyntaxKind7.EqualsToken,
|
|
4042
|
+
SyntaxKind7.BarBarEqualsToken,
|
|
4043
|
+
SyntaxKind7.QuestionQuestionEqualsToken
|
|
3532
4044
|
]);
|
|
3533
4045
|
function emitBinary(db, table, operand2, key, parent) {
|
|
3534
4046
|
if (!Node7.isBinaryExpression(parent)) {
|
|
3535
4047
|
return;
|
|
3536
4048
|
}
|
|
3537
4049
|
const operator = parent.getOperatorToken().getKind();
|
|
3538
|
-
if (operator ===
|
|
4050
|
+
if (operator === SyntaxKind7.AmpersandAmpersandToken && parent.getRight() === operand2) {
|
|
3539
4051
|
fact2(db, "conditionalBranch", nodeId(parent), key);
|
|
3540
4052
|
return;
|
|
3541
4053
|
}
|
|
@@ -3611,7 +4123,7 @@ function valueWrittenThrough(name) {
|
|
|
3611
4123
|
const parent = name.getParent();
|
|
3612
4124
|
if (Node8.isElementAccessExpression(parent) && parent.getExpression() === name) {
|
|
3613
4125
|
const assignment = parent.getParent();
|
|
3614
|
-
return Node8.isBinaryExpression(assignment) && assignment.getLeft() === parent && assignment.getOperatorToken().getKind() ===
|
|
4126
|
+
return Node8.isBinaryExpression(assignment) && assignment.getLeft() === parent && assignment.getOperatorToken().getKind() === SyntaxKind8.EqualsToken ? assignment.getRight() : null;
|
|
3615
4127
|
}
|
|
3616
4128
|
if (Node8.isPropertyAccessExpression(parent) && parent.getExpression() === name && parent.getName() === MAP_ENTRY_WRITE) {
|
|
3617
4129
|
const call = parent.getParent();
|
|
@@ -3629,6 +4141,10 @@ var NOT_BASE_FACTS = /* @__PURE__ */ new Set([
|
|
|
3629
4141
|
...RESOLUTION_PROGRAM.rules.map((r) => r.head.relation),
|
|
3630
4142
|
...ASKING_RELATIONS
|
|
3631
4143
|
]);
|
|
4144
|
+
var DERIVED_RELATIONS = /* @__PURE__ */ new Set([
|
|
4145
|
+
...NOT_BASE_FACTS,
|
|
4146
|
+
...resolutionUnderProgram().rules.map((r) => r.head.relation)
|
|
4147
|
+
]);
|
|
3632
4148
|
var QUERY_FACTS = queryFacts(RESOLUTION_PROGRAM);
|
|
3633
4149
|
var MODULE_DEMANDS = RESOLUTION_PROGRAM.demands.filter(
|
|
3634
4150
|
(one) => (one.relation === "moduleExport" || one.relation === "moduleForwards") && one.bound[0] === true
|
|
@@ -3665,6 +4181,8 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3665
4181
|
constructionSites = /* @__PURE__ */ new Map();
|
|
3666
4182
|
/** What each local's reads do with it, by its declaration. A local's function is walked whole, so an answer stays true. */
|
|
3667
4183
|
localUses = /* @__PURE__ */ new Map();
|
|
4184
|
+
/** See `remembered`. */
|
|
4185
|
+
answers = /* @__PURE__ */ new Map();
|
|
3668
4186
|
/** Files the most recent query read, for the memo to keep. */
|
|
3669
4187
|
lastQueryWalked = [];
|
|
3670
4188
|
/** See `environmentSiteFiles`; null until the first env question. */
|
|
@@ -3716,12 +4234,18 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3716
4234
|
*/
|
|
3717
4235
|
resolveCallableSources(value, alsoFrom) {
|
|
3718
4236
|
const target = factKeyOf(value);
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
4237
|
+
const key = `sources|${nodeId(target)}|${alsoFrom?.getFilePath() ?? ""}`;
|
|
4238
|
+
return [
|
|
4239
|
+
...this.remembered(
|
|
4240
|
+
key,
|
|
4241
|
+
() => this.askAbout(
|
|
4242
|
+
target,
|
|
4243
|
+
"wanted",
|
|
4244
|
+
() => this.lookupSources(target),
|
|
4245
|
+
alsoFrom
|
|
4246
|
+
)
|
|
4247
|
+
)
|
|
4248
|
+
];
|
|
3725
4249
|
}
|
|
3726
4250
|
/**
|
|
3727
4251
|
* `resolveCallable` for several values, asked as one question. A file
|
|
@@ -3783,7 +4307,45 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3783
4307
|
}
|
|
3784
4308
|
resolveObject(value) {
|
|
3785
4309
|
const target = factKeyOf(value);
|
|
3786
|
-
return this.
|
|
4310
|
+
return this.remembered(
|
|
4311
|
+
`object|${nodeId(target)}`,
|
|
4312
|
+
() => this.askAbout(target, "wanted", () => this.lookupObject(target))
|
|
4313
|
+
);
|
|
4314
|
+
}
|
|
4315
|
+
/**
|
|
4316
|
+
* A question asked again over the same facts reads the same files and
|
|
4317
|
+
* derives the same answer, so the store gives back the one it found
|
|
4318
|
+
* before. The files that answer read still count as read.
|
|
4319
|
+
*/
|
|
4320
|
+
remembered(key, ask) {
|
|
4321
|
+
const known = this.answers.get(key);
|
|
4322
|
+
if (known !== void 0 && known.facts === this.sourceFactCount()) {
|
|
4323
|
+
for (const walkedPath of known.walked) {
|
|
4324
|
+
recordFileDependency(walkedPath);
|
|
4325
|
+
}
|
|
4326
|
+
return known.answer;
|
|
4327
|
+
}
|
|
4328
|
+
const answer = ask();
|
|
4329
|
+
this.answers.set(key, {
|
|
4330
|
+
answer,
|
|
4331
|
+
walked: [...this.lastQueryWalked],
|
|
4332
|
+
facts: this.sourceFactCount()
|
|
4333
|
+
});
|
|
4334
|
+
return answer;
|
|
4335
|
+
}
|
|
4336
|
+
/**
|
|
4337
|
+
* How many facts the store has read from source. They are only ever
|
|
4338
|
+
* added, so work that asked the store questions and found this number
|
|
4339
|
+
* unchanged afterwards would get the same answers asking again.
|
|
4340
|
+
*/
|
|
4341
|
+
sourceFactCount() {
|
|
4342
|
+
let count = 0;
|
|
4343
|
+
for (const relation of this.db.relationNames()) {
|
|
4344
|
+
if (!DERIVED_RELATIONS.has(relation)) {
|
|
4345
|
+
count += this.db.size(relation);
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
return count;
|
|
3787
4349
|
}
|
|
3788
4350
|
/**
|
|
3789
4351
|
* The function a call returns: `app.use(requireCaller(config))`
|
|
@@ -3883,7 +4445,7 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3883
4445
|
writtenAnswers(values, wanted) {
|
|
3884
4446
|
const found = /* @__PURE__ */ new Map();
|
|
3885
4447
|
const asked = /* @__PURE__ */ new Map();
|
|
3886
|
-
const
|
|
4448
|
+
const keyOf2 = /* @__PURE__ */ new Map();
|
|
3887
4449
|
for (const value of values) {
|
|
3888
4450
|
const target = factKeyOf(value);
|
|
3889
4451
|
const key = nodeId(this.sharedDeclarationFor(target));
|
|
@@ -3898,7 +4460,7 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3898
4460
|
if (!asked.has(key)) {
|
|
3899
4461
|
asked.set(key, target);
|
|
3900
4462
|
}
|
|
3901
|
-
|
|
4463
|
+
keyOf2.set(value, key);
|
|
3902
4464
|
}
|
|
3903
4465
|
if (asked.size === 0) {
|
|
3904
4466
|
return found;
|
|
@@ -3913,7 +4475,7 @@ var ResolutionStore = class _ResolutionStore {
|
|
|
3913
4475
|
});
|
|
3914
4476
|
}
|
|
3915
4477
|
});
|
|
3916
|
-
for (const [value, key] of
|
|
4478
|
+
for (const [value, key] of keyOf2) {
|
|
3917
4479
|
found.set(value, this.writtenValues.get(key)?.[wanted] ?? null);
|
|
3918
4480
|
}
|
|
3919
4481
|
return found;
|
|
@@ -5196,9 +5758,6 @@ function namesPackage2(moduleKey, packages) {
|
|
|
5196
5758
|
packages
|
|
5197
5759
|
);
|
|
5198
5760
|
}
|
|
5199
|
-
function inTestFile(node) {
|
|
5200
|
-
return isTestFile(node.getSourceFile().getFilePath());
|
|
5201
|
-
}
|
|
5202
5761
|
function declarationOf(value) {
|
|
5203
5762
|
const nameNode = Node9.isPropertyAccessExpression(value) ? value.getNameNode() : value;
|
|
5204
5763
|
return nameNode.getSymbol()?.getDeclarations()[0] ?? value;
|
|
@@ -5246,12 +5805,12 @@ function forgetProgramMemos(project) {
|
|
|
5246
5805
|
}
|
|
5247
5806
|
|
|
5248
5807
|
// src/values/lowering.ts
|
|
5249
|
-
import { Node as Node11, SyntaxKind as
|
|
5808
|
+
import { Node as Node11, SyntaxKind as SyntaxKind10 } from "ts-morph";
|
|
5250
5809
|
|
|
5251
5810
|
// src/resolve/unfollowedCall.ts
|
|
5252
5811
|
import {
|
|
5253
5812
|
Node as Node10,
|
|
5254
|
-
SyntaxKind as
|
|
5813
|
+
SyntaxKind as SyntaxKind9
|
|
5255
5814
|
} from "ts-morph";
|
|
5256
5815
|
import {
|
|
5257
5816
|
unfollowedCallGap,
|
|
@@ -5274,14 +5833,14 @@ function isExternalDeclaration(declaration) {
|
|
|
5274
5833
|
return true;
|
|
5275
5834
|
}
|
|
5276
5835
|
if (Node10.isImportSpecifier(declaration) || Node10.isImportClause(declaration) || Node10.isNamespaceImport(declaration)) {
|
|
5277
|
-
const target = declaration.getFirstAncestorByKind(
|
|
5836
|
+
const target = declaration.getFirstAncestorByKind(SyntaxKind9.ImportDeclaration)?.getModuleSpecifierSourceFile();
|
|
5278
5837
|
return target === void 0 || isInExternalCode(target);
|
|
5279
5838
|
}
|
|
5280
5839
|
return declaresAnotherModule(declaration);
|
|
5281
5840
|
}
|
|
5282
5841
|
function declaresAnotherModule(declaration) {
|
|
5283
5842
|
const module = declaration.getFirstAncestorByKind(
|
|
5284
|
-
|
|
5843
|
+
SyntaxKind9.ModuleDeclaration
|
|
5285
5844
|
);
|
|
5286
5845
|
return module !== void 0 && Node10.isStringLiteral(module.getNameNode());
|
|
5287
5846
|
}
|
|
@@ -5534,7 +6093,7 @@ function expressionOf(node, originOf2) {
|
|
|
5534
6093
|
}
|
|
5535
6094
|
if (Node11.isPrefixUnaryExpression(node)) {
|
|
5536
6095
|
const operator = node.getOperatorToken();
|
|
5537
|
-
return operator ===
|
|
6096
|
+
return operator === SyntaxKind10.ExclamationToken ? { kind: "operator", operator: "!", operands: [node.getOperand()] } : { kind: "opaque" };
|
|
5538
6097
|
}
|
|
5539
6098
|
if (Node11.isConditionalExpression(node)) {
|
|
5540
6099
|
return {
|
|
@@ -6295,7 +6854,7 @@ function settledChannel(argument, resolution) {
|
|
|
6295
6854
|
}
|
|
6296
6855
|
|
|
6297
6856
|
// src/discovery/importedCalls.ts
|
|
6298
|
-
import { Node as Node14 } from "ts-morph";
|
|
6857
|
+
import { Node as Node14, ts as ts6 } from "ts-morph";
|
|
6299
6858
|
function callsResolvingTo(sourceFile, resolution, spec) {
|
|
6300
6859
|
return [
|
|
6301
6860
|
...callsByOriginName(
|
|
@@ -6307,26 +6866,30 @@ function callsResolvingTo(sourceFile, resolution, spec) {
|
|
|
6307
6866
|
];
|
|
6308
6867
|
}
|
|
6309
6868
|
function callsByOriginName(sourceFile, resolution, module, names) {
|
|
6869
|
+
return callsNamed(importedCallOrigins(sourceFile, resolution, module), names);
|
|
6870
|
+
}
|
|
6871
|
+
function importedCallOrigins(sourceFile, resolution, module) {
|
|
6310
6872
|
const candidates = [];
|
|
6311
|
-
sourceFile
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
const callee = node.getExpression();
|
|
6316
|
-
if (Node14.isIdentifier(callee) && !declaredLocally(callee)) {
|
|
6317
|
-
candidates.push(node);
|
|
6873
|
+
forEachDescendantWhere(sourceFile, callsANamedCallee, (node) => {
|
|
6874
|
+
const call = node;
|
|
6875
|
+
if (!declaredLocally(call.getExpression())) {
|
|
6876
|
+
candidates.push(call);
|
|
6318
6877
|
}
|
|
6878
|
+
return false;
|
|
6319
6879
|
});
|
|
6320
|
-
const matched = /* @__PURE__ */ new Map();
|
|
6321
6880
|
if (candidates.length === 0) {
|
|
6322
|
-
return
|
|
6881
|
+
return { candidates, origins: /* @__PURE__ */ new Map() };
|
|
6323
6882
|
}
|
|
6324
6883
|
const origins = resolution.importOriginsOfMany(
|
|
6325
6884
|
candidates.map((call) => call.getExpression()),
|
|
6326
6885
|
[module]
|
|
6327
6886
|
);
|
|
6328
|
-
|
|
6329
|
-
|
|
6887
|
+
return { candidates, origins };
|
|
6888
|
+
}
|
|
6889
|
+
function callsNamed(found, names) {
|
|
6890
|
+
const matched = /* @__PURE__ */ new Map();
|
|
6891
|
+
for (const call of found.candidates) {
|
|
6892
|
+
const origin = (found.origins.get(call.getExpression()) ?? []).find(
|
|
6330
6893
|
(one) => one.path.length === 1 && names.has(one.path[0] ?? "")
|
|
6331
6894
|
);
|
|
6332
6895
|
const name = origin?.path[0];
|
|
@@ -6336,6 +6899,9 @@ function callsByOriginName(sourceFile, resolution, module, names) {
|
|
|
6336
6899
|
}
|
|
6337
6900
|
return matched;
|
|
6338
6901
|
}
|
|
6902
|
+
function callsANamedCallee(raw) {
|
|
6903
|
+
return (ts6.isCallExpression(raw) || ts6.isNewExpression(raw)) && ts6.isIdentifier(raw.expression);
|
|
6904
|
+
}
|
|
6339
6905
|
function declaredLocally(callee) {
|
|
6340
6906
|
const declarations = callee.getSymbol()?.getDeclarations() ?? [];
|
|
6341
6907
|
return declarations.length > 0 && declarations.every(
|
|
@@ -6384,7 +6950,7 @@ function unitFor(call, func, match, kind, store, binding) {
|
|
|
6384
6950
|
}
|
|
6385
6951
|
|
|
6386
6952
|
// src/discovery/clientCall.ts
|
|
6387
|
-
import { Node as Node15, SyntaxKind as
|
|
6953
|
+
import { Node as Node15, SyntaxKind as SyntaxKind12 } from "ts-morph";
|
|
6388
6954
|
import { hasNameHole } from "@suss/behavioral-ir";
|
|
6389
6955
|
|
|
6390
6956
|
// src/resolve/routePath.ts
|
|
@@ -6424,6 +6990,9 @@ function propertyValueAt(arg, property, resolution, site) {
|
|
|
6424
6990
|
|
|
6425
6991
|
// src/discovery/importScan.ts
|
|
6426
6992
|
import path4 from "path";
|
|
6993
|
+
import {
|
|
6994
|
+
SyntaxKind as SyntaxKind11
|
|
6995
|
+
} from "ts-morph";
|
|
6427
6996
|
import { commonDirectoryOf } from "@suss/extractor";
|
|
6428
6997
|
function specifierMatches(specifier, moduleName, subpaths) {
|
|
6429
6998
|
if (specifier === moduleName) {
|
|
@@ -6468,7 +7037,10 @@ function importedRootsOf(sourceFile, modules, options = {}) {
|
|
|
6468
7037
|
return roots;
|
|
6469
7038
|
}
|
|
6470
7039
|
function moduleImportedWholeAs(sourceFile, local) {
|
|
6471
|
-
for (const decl of
|
|
7040
|
+
for (const decl of statementsOfKind(
|
|
7041
|
+
sourceFile,
|
|
7042
|
+
SyntaxKind11.ImportDeclaration
|
|
7043
|
+
)) {
|
|
6472
7044
|
const bound = decl.getNamespaceImport()?.getText() ?? decl.getDefaultImport()?.getText();
|
|
6473
7045
|
if (bound !== local) {
|
|
6474
7046
|
continue;
|
|
@@ -6479,7 +7051,10 @@ function moduleImportedWholeAs(sourceFile, local) {
|
|
|
6479
7051
|
return null;
|
|
6480
7052
|
}
|
|
6481
7053
|
function specifierImportedAs(sourceFile, local) {
|
|
6482
|
-
for (const decl of
|
|
7054
|
+
for (const decl of statementsOfKind(
|
|
7055
|
+
sourceFile,
|
|
7056
|
+
SyntaxKind11.ImportDeclaration
|
|
7057
|
+
)) {
|
|
6483
7058
|
const bound = [
|
|
6484
7059
|
decl.getDefaultImport()?.getText(),
|
|
6485
7060
|
decl.getNamespaceImport()?.getText(),
|
|
@@ -6510,9 +7085,11 @@ function importDeclarationsOf(sourceFile, modules, options = {}) {
|
|
|
6510
7085
|
function matchingImportDeclarations(sourceFile, importModule, resolution, subpaths = false) {
|
|
6511
7086
|
const target = isPathShapedSpecifier(importModule) ? resolvedModuleFile(sourceFile.getProject(), importModule, resolution) : null;
|
|
6512
7087
|
if (target !== null) {
|
|
6513
|
-
return sourceFile.
|
|
7088
|
+
return statementsOfKind(sourceFile, SyntaxKind11.ImportDeclaration).filter(
|
|
7089
|
+
(decl) => decl.getModuleSpecifierSourceFile() === target
|
|
7090
|
+
);
|
|
6514
7091
|
}
|
|
6515
|
-
return sourceFile.
|
|
7092
|
+
return statementsOfKind(sourceFile, SyntaxKind11.ImportDeclaration).filter(
|
|
6516
7093
|
(decl) => specifierMatches(decl.getModuleSpecifierValue(), importModule, subpaths)
|
|
6517
7094
|
);
|
|
6518
7095
|
}
|
|
@@ -6588,14 +7165,18 @@ function importedReferenceSpellings(sourceFile, importModule, importName) {
|
|
|
6588
7165
|
}
|
|
6589
7166
|
|
|
6590
7167
|
// src/discovery/clientCall.ts
|
|
7168
|
+
var CALL_KIND = /* @__PURE__ */ new Set([SyntaxKind12.CallExpression]);
|
|
7169
|
+
var BINDING_KINDS = /* @__PURE__ */ new Set([
|
|
7170
|
+
SyntaxKind12.VariableDeclaration,
|
|
7171
|
+
SyntaxKind12.Parameter
|
|
7172
|
+
]);
|
|
6591
7173
|
var GLOBAL_OBJECTS = /* @__PURE__ */ new Set(["globalThis", "window", "self", "global"]);
|
|
6592
7174
|
function discoverClientCalls(sourceFile, match, kind, resolution, binding) {
|
|
6593
7175
|
const results = [];
|
|
6594
7176
|
const calls = [];
|
|
6595
|
-
sourceFile
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
}
|
|
7177
|
+
forEachDescendantOfKinds(sourceFile, CALL_KIND, (node) => {
|
|
7178
|
+
calls.push(node);
|
|
7179
|
+
return false;
|
|
6599
7180
|
});
|
|
6600
7181
|
const matched = match.importModule === "global" ? globalCallsAmong(calls, match) : clientCallsAmong(calls, match, sourceFile, resolution);
|
|
6601
7182
|
for (const call of calls) {
|
|
@@ -6709,7 +7290,7 @@ function clientsBuiltAtTopLevel(sourceFile, match, resolution) {
|
|
|
6709
7290
|
);
|
|
6710
7291
|
}
|
|
6711
7292
|
function sitesToReadUnder(call, binding, resolution) {
|
|
6712
|
-
const cls = call.getFirstAncestorByKind(
|
|
7293
|
+
const cls = call.getFirstAncestorByKind(SyntaxKind12.ClassDeclaration);
|
|
6713
7294
|
if (binding === void 0 || resolution === void 0 || cls === void 0) {
|
|
6714
7295
|
return [void 0];
|
|
6715
7296
|
}
|
|
@@ -6797,7 +7378,7 @@ function clientReceiverCheckFor(sourceFile, match, resolution) {
|
|
|
6797
7378
|
);
|
|
6798
7379
|
const constructedHere = /* @__PURE__ */ new Set();
|
|
6799
7380
|
const initializedBy = /* @__PURE__ */ new Map();
|
|
6800
|
-
|
|
7381
|
+
const visit = (node) => {
|
|
6801
7382
|
if (Node15.isVariableDeclaration(node)) {
|
|
6802
7383
|
const init = node.getInitializer();
|
|
6803
7384
|
if (init !== void 0 && (Node15.isCallExpression(init) || Node15.isNewExpression(init))) {
|
|
@@ -6806,7 +7387,7 @@ function clientReceiverCheckFor(sourceFile, match, resolution) {
|
|
|
6806
7387
|
if (localName !== null && typedAsClient(node.getTypeNode(), localName)) {
|
|
6807
7388
|
constructedHere.add(node.getName());
|
|
6808
7389
|
}
|
|
6809
|
-
return;
|
|
7390
|
+
return false;
|
|
6810
7391
|
}
|
|
6811
7392
|
if (Node15.isParameterDeclaration(node) && localName !== null && typedAsClient(node.getTypeNode(), localName)) {
|
|
6812
7393
|
const written = node.getNameNode();
|
|
@@ -6814,7 +7395,9 @@ function clientReceiverCheckFor(sourceFile, match, resolution) {
|
|
|
6814
7395
|
constructedHere.add(written.getText());
|
|
6815
7396
|
}
|
|
6816
7397
|
}
|
|
6817
|
-
|
|
7398
|
+
return false;
|
|
7399
|
+
};
|
|
7400
|
+
forEachDescendantOfKinds(sourceFile, BINDING_KINDS, visit, skipsNothing);
|
|
6818
7401
|
const creating = creationCallsAmong(
|
|
6819
7402
|
[...initializedBy.keys()],
|
|
6820
7403
|
match,
|
|
@@ -7011,7 +7594,7 @@ function callableOf(member) {
|
|
|
7011
7594
|
}
|
|
7012
7595
|
|
|
7013
7596
|
// src/discovery/decoratorComposition.ts
|
|
7014
|
-
import { Node as Node17, SyntaxKind as
|
|
7597
|
+
import { Node as Node17, SyntaxKind as SyntaxKind13 } from "ts-morph";
|
|
7015
7598
|
function classDecoratorStandingFor(cls, names, modules, resolution) {
|
|
7016
7599
|
for (const candidate of names) {
|
|
7017
7600
|
const decorator = cls.getDecorator(candidate);
|
|
@@ -7049,7 +7632,7 @@ function frameworkArgs(decorator, standsFor, modules, resolution) {
|
|
|
7049
7632
|
if (wrapper === null) {
|
|
7050
7633
|
return atClass;
|
|
7051
7634
|
}
|
|
7052
|
-
for (const call of wrapper.getDescendantsOfKind(
|
|
7635
|
+
for (const call of wrapper.getDescendantsOfKind(SyntaxKind13.CallExpression)) {
|
|
7053
7636
|
const names = resolution.importedNamesOf(call.getExpression(), modules);
|
|
7054
7637
|
if (!names.includes(standsFor)) {
|
|
7055
7638
|
continue;
|
|
@@ -7060,7 +7643,7 @@ function frameworkArgs(decorator, standsFor, modules, resolution) {
|
|
|
7060
7643
|
return atClass;
|
|
7061
7644
|
}
|
|
7062
7645
|
function statesAValue(arg, wrapper) {
|
|
7063
|
-
const identifiers = Node17.isIdentifier(arg) ? [arg] : arg.getDescendantsOfKind(
|
|
7646
|
+
const identifiers = Node17.isIdentifier(arg) ? [arg] : arg.getDescendantsOfKind(SyntaxKind13.Identifier);
|
|
7064
7647
|
return !identifiers.some(
|
|
7065
7648
|
(identifier) => identifier.getSymbol()?.getDeclarations().some(
|
|
7066
7649
|
(declaration) => Node17.isParameterDeclaration(declaration) && isWithin(declaration, wrapper)
|
|
@@ -7798,7 +8381,8 @@ import picomatch from "picomatch";
|
|
|
7798
8381
|
|
|
7799
8382
|
// src/discovery/namedExport.ts
|
|
7800
8383
|
import {
|
|
7801
|
-
Node as Node27
|
|
8384
|
+
Node as Node27,
|
|
8385
|
+
SyntaxKind as SyntaxKind15
|
|
7802
8386
|
} from "ts-morph";
|
|
7803
8387
|
|
|
7804
8388
|
// src/discovery/wrappedExport.ts
|
|
@@ -7808,7 +8392,7 @@ import { Node as Node26 } from "ts-morph";
|
|
|
7808
8392
|
import { Node as Node23 } from "ts-morph";
|
|
7809
8393
|
|
|
7810
8394
|
// src/walk/descent.ts
|
|
7811
|
-
import { Node as Node22 } from "ts-morph";
|
|
8395
|
+
import { Node as Node22, SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
7812
8396
|
var NO_BARRIERS = /* @__PURE__ */ new Set();
|
|
7813
8397
|
function isDescentStop(node, func, barriers = NO_BARRIERS) {
|
|
7814
8398
|
if (node === func) {
|
|
@@ -7822,24 +8406,16 @@ function isDescentStop(node, func, barriers = NO_BARRIERS) {
|
|
|
7822
8406
|
}
|
|
7823
8407
|
return false;
|
|
7824
8408
|
}
|
|
7825
|
-
function
|
|
7826
|
-
root.
|
|
8409
|
+
function forEachInUnitBodyOfKinds(root, kinds, visit) {
|
|
8410
|
+
forEachInUnitBodyWhere(root, (raw) => kinds.has(raw.kind), visit);
|
|
8411
|
+
}
|
|
8412
|
+
function forEachInUnitBodyWhere(root, accepts, visit) {
|
|
8413
|
+
forEachDescendantWhere(root, accepts, visit);
|
|
7827
8414
|
for (const initializer of fieldInitializersRunBy(root)) {
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
stop: () => {
|
|
7831
|
-
skipped = true;
|
|
7832
|
-
},
|
|
7833
|
-
skip: () => {
|
|
7834
|
-
skipped = true;
|
|
7835
|
-
},
|
|
7836
|
-
up: () => {
|
|
7837
|
-
skipped = true;
|
|
7838
|
-
}
|
|
7839
|
-
});
|
|
7840
|
-
if (!skipped) {
|
|
7841
|
-
initializer.forEachDescendant(visit);
|
|
8415
|
+
if (accepts(initializer.compilerNode) && visit(initializer)) {
|
|
8416
|
+
continue;
|
|
7842
8417
|
}
|
|
8418
|
+
forEachDescendantWhere(initializer, accepts, visit);
|
|
7843
8419
|
}
|
|
7844
8420
|
}
|
|
7845
8421
|
function fieldInitializersRunBy(root) {
|
|
@@ -7868,6 +8444,19 @@ function isInlineCallback(node, func, barriers = NO_BARRIERS) {
|
|
|
7868
8444
|
}
|
|
7869
8445
|
return !barriers.has(node);
|
|
7870
8446
|
}
|
|
8447
|
+
var DESCENT_STOP_KINDS = /* @__PURE__ */ new Set([
|
|
8448
|
+
SyntaxKind14.FunctionDeclaration,
|
|
8449
|
+
SyntaxKind14.MethodDeclaration,
|
|
8450
|
+
SyntaxKind14.Constructor,
|
|
8451
|
+
SyntaxKind14.ArrowFunction,
|
|
8452
|
+
SyntaxKind14.FunctionExpression,
|
|
8453
|
+
SyntaxKind14.ClassDeclaration,
|
|
8454
|
+
SyntaxKind14.ClassExpression,
|
|
8455
|
+
SyntaxKind14.Decorator
|
|
8456
|
+
]);
|
|
8457
|
+
function withDescentStops(...kinds) {
|
|
8458
|
+
return /* @__PURE__ */ new Set([...DESCENT_STOP_KINDS, ...kinds]);
|
|
8459
|
+
}
|
|
7871
8460
|
function isModuleScopeStop(node) {
|
|
7872
8461
|
if (isImmediatelyInvoked(node)) {
|
|
7873
8462
|
return false;
|
|
@@ -7896,11 +8485,17 @@ function crossesNestedFunctionScope(node, func) {
|
|
|
7896
8485
|
return false;
|
|
7897
8486
|
}
|
|
7898
8487
|
function startsItsOwnScope(node) {
|
|
7899
|
-
return
|
|
7900
|
-
}
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
8488
|
+
return OWN_SCOPE_KINDS.has(node.getKind());
|
|
8489
|
+
}
|
|
8490
|
+
var OWN_SCOPE_KINDS = /* @__PURE__ */ new Set([
|
|
8491
|
+
SyntaxKind14.ArrowFunction,
|
|
8492
|
+
SyntaxKind14.FunctionExpression,
|
|
8493
|
+
SyntaxKind14.FunctionDeclaration,
|
|
8494
|
+
SyntaxKind14.MethodDeclaration,
|
|
8495
|
+
SyntaxKind14.GetAccessor,
|
|
8496
|
+
SyntaxKind14.SetAccessor,
|
|
8497
|
+
SyntaxKind14.Constructor
|
|
8498
|
+
]);
|
|
7904
8499
|
|
|
7905
8500
|
// src/parameterReads.ts
|
|
7906
8501
|
function pathAbove(reference) {
|
|
@@ -8710,7 +9305,7 @@ function evaluateObjectLiteralAsJson(node) {
|
|
|
8710
9305
|
return node.getLiteralValue();
|
|
8711
9306
|
}
|
|
8712
9307
|
if (Node25.isNumericLiteral(node)) {
|
|
8713
|
-
return
|
|
9308
|
+
return node.getLiteralValue();
|
|
8714
9309
|
}
|
|
8715
9310
|
const kind = node.getText();
|
|
8716
9311
|
if (kind === "true") {
|
|
@@ -9101,7 +9696,10 @@ function discoverNamedExports(sourceFile, match, kind, resolution, options = {})
|
|
|
9101
9696
|
return results;
|
|
9102
9697
|
}
|
|
9103
9698
|
function defaultExportUnits(sourceFile, kind, resolution, options) {
|
|
9104
|
-
for (const assignment of
|
|
9699
|
+
for (const assignment of statementsOfKind(
|
|
9700
|
+
sourceFile,
|
|
9701
|
+
SyntaxKind15.ExportAssignment
|
|
9702
|
+
)) {
|
|
9105
9703
|
if (assignment.isExportEquals()) {
|
|
9106
9704
|
continue;
|
|
9107
9705
|
}
|
|
@@ -9215,6 +9813,9 @@ function expandParameter(parameter, forwardsResult, depth, expanded, context, ch
|
|
|
9215
9813
|
const units = [];
|
|
9216
9814
|
let unfollowed = 0;
|
|
9217
9815
|
for (const { call, argument } of passed) {
|
|
9816
|
+
if (testCallingProduction(call, parameter)) {
|
|
9817
|
+
continue;
|
|
9818
|
+
}
|
|
9218
9819
|
const caller = enclosingFunctionRoot(call);
|
|
9219
9820
|
if (caller === null || !Node28.isCallExpression(call)) {
|
|
9220
9821
|
unfollowed++;
|
|
@@ -10022,7 +10623,7 @@ function sameDeclaration(a, b) {
|
|
|
10022
10623
|
}
|
|
10023
10624
|
|
|
10024
10625
|
// src/discovery/factorySurface.ts
|
|
10025
|
-
import { Node as Node32, SyntaxKind as
|
|
10626
|
+
import { Node as Node32, SyntaxKind as SyntaxKind16 } from "ts-morph";
|
|
10026
10627
|
var MAX_BUILDER_HOPS = 2;
|
|
10027
10628
|
function surfaceMethods(decl, resolution) {
|
|
10028
10629
|
if (Node32.isClassDeclaration(decl)) {
|
|
@@ -10037,7 +10638,7 @@ function surfaceClassMethods(cls) {
|
|
|
10037
10638
|
const out = [];
|
|
10038
10639
|
const seen = /* @__PURE__ */ new Set();
|
|
10039
10640
|
for (const method of cls.getInstanceMethods()) {
|
|
10040
|
-
if (method.hasModifier(
|
|
10641
|
+
if (method.hasModifier(SyntaxKind16.PrivateKeyword)) {
|
|
10041
10642
|
continue;
|
|
10042
10643
|
}
|
|
10043
10644
|
const name = method.getName();
|
|
@@ -10048,7 +10649,7 @@ function surfaceClassMethods(cls) {
|
|
|
10048
10649
|
out.push({ func: method, name });
|
|
10049
10650
|
}
|
|
10050
10651
|
for (const method of cls.getStaticMethods()) {
|
|
10051
|
-
if (method.hasModifier(
|
|
10652
|
+
if (method.hasModifier(SyntaxKind16.PrivateKeyword)) {
|
|
10052
10653
|
continue;
|
|
10053
10654
|
}
|
|
10054
10655
|
const name = method.getName();
|
|
@@ -10831,7 +11432,7 @@ function creationSiteBehind(parameter, resolution) {
|
|
|
10831
11432
|
}
|
|
10832
11433
|
function registrationSubjectIdsOf(sourceFile, matches, resolution) {
|
|
10833
11434
|
const seenImports = /* @__PURE__ */ new Set();
|
|
10834
|
-
const
|
|
11435
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
10835
11436
|
for (const match of matches) {
|
|
10836
11437
|
const importKey = `${match.importModule}::${match.importName}`;
|
|
10837
11438
|
if (seenImports.has(importKey)) {
|
|
@@ -10844,17 +11445,17 @@ function registrationSubjectIdsOf(sourceFile, matches, resolution) {
|
|
|
10844
11445
|
match.importName,
|
|
10845
11446
|
resolution
|
|
10846
11447
|
).values()) {
|
|
10847
|
-
|
|
11448
|
+
ids2.add(nodeId(node));
|
|
10848
11449
|
}
|
|
10849
11450
|
for (const node of unboundConstructionsOf(
|
|
10850
11451
|
sourceFile,
|
|
10851
11452
|
match.importModule,
|
|
10852
11453
|
match.importName
|
|
10853
11454
|
)) {
|
|
10854
|
-
|
|
11455
|
+
ids2.add(nodeId(node));
|
|
10855
11456
|
}
|
|
10856
11457
|
}
|
|
10857
|
-
return
|
|
11458
|
+
return ids2;
|
|
10858
11459
|
}
|
|
10859
11460
|
function unboundConstructionsOf(sourceFile, importModule, importName) {
|
|
10860
11461
|
const spellings = importedReferenceSpellings(
|
|
@@ -11882,7 +12483,7 @@ function constructorCalledAt(construction) {
|
|
|
11882
12483
|
}
|
|
11883
12484
|
function baseConstructorCalledAt(superKeyword) {
|
|
11884
12485
|
const owner = superKeyword.getFirstAncestorByKind(
|
|
11885
|
-
|
|
12486
|
+
SyntaxKind17.ClassDeclaration
|
|
11886
12487
|
);
|
|
11887
12488
|
const base = owner?.getBaseClass();
|
|
11888
12489
|
return base === void 0 ? null : constructorOf(base);
|
|
@@ -12088,7 +12689,7 @@ function shapeFromDeclaration(decl, extractShape2, ctx) {
|
|
|
12088
12689
|
return enterShape(init, extractShape2, ctx);
|
|
12089
12690
|
}
|
|
12090
12691
|
if (Node42.isBindingElement(decl)) {
|
|
12091
|
-
const varDecl = decl.getFirstAncestorByKind(
|
|
12692
|
+
const varDecl = decl.getFirstAncestorByKind(SyntaxKind18.VariableDeclaration);
|
|
12092
12693
|
if (!varDecl) {
|
|
12093
12694
|
return null;
|
|
12094
12695
|
}
|
|
@@ -12174,7 +12775,7 @@ function isInformativeInitializer(node) {
|
|
|
12174
12775
|
return isInformativeInitializer(unwrapped2.getOperand());
|
|
12175
12776
|
}
|
|
12176
12777
|
const kind = unwrapped2.getKind();
|
|
12177
|
-
return kind ===
|
|
12778
|
+
return kind === SyntaxKind18.TrueKeyword || kind === SyntaxKind18.FalseKeyword || kind === SyntaxKind18.NullKeyword;
|
|
12178
12779
|
}
|
|
12179
12780
|
function resolveCallableBody(callee) {
|
|
12180
12781
|
if (!Node42.isIdentifier(callee)) {
|
|
@@ -12523,7 +13124,7 @@ function parseConditionExpression(expr, depth = 0) {
|
|
|
12523
13124
|
}
|
|
12524
13125
|
}
|
|
12525
13126
|
if (Node45.isPrefixUnaryExpression(expr)) {
|
|
12526
|
-
if (expr.getOperatorToken() !==
|
|
13127
|
+
if (expr.getOperatorToken() !== SyntaxKind19.ExclamationToken) {
|
|
12527
13128
|
return null;
|
|
12528
13129
|
}
|
|
12529
13130
|
const operand2 = expr.getOperand();
|
|
@@ -12551,7 +13152,7 @@ function parseConditionExpression(expr, depth = 0) {
|
|
|
12551
13152
|
const right = expr.getRight();
|
|
12552
13153
|
const opToken = expr.getOperatorToken();
|
|
12553
13154
|
const opText = opToken.getText();
|
|
12554
|
-
if (opToken.getKind() ===
|
|
13155
|
+
if (opToken.getKind() === SyntaxKind19.AmpersandAmpersandToken) {
|
|
12555
13156
|
const leftPred = parseConditionExpression(left, depth);
|
|
12556
13157
|
const rightPred = parseConditionExpression(right, depth);
|
|
12557
13158
|
return {
|
|
@@ -12563,7 +13164,7 @@ function parseConditionExpression(expr, depth = 0) {
|
|
|
12563
13164
|
]
|
|
12564
13165
|
};
|
|
12565
13166
|
}
|
|
12566
|
-
if (opToken.getKind() ===
|
|
13167
|
+
if (opToken.getKind() === SyntaxKind19.BarBarToken) {
|
|
12567
13168
|
const leftPred = parseConditionExpression(left, depth);
|
|
12568
13169
|
const rightPred = parseConditionExpression(right, depth);
|
|
12569
13170
|
return {
|
|
@@ -12575,11 +13176,11 @@ function parseConditionExpression(expr, depth = 0) {
|
|
|
12575
13176
|
]
|
|
12576
13177
|
};
|
|
12577
13178
|
}
|
|
12578
|
-
if (opToken.getKind() ===
|
|
13179
|
+
if (opToken.getKind() === SyntaxKind19.InstanceOfKeyword) {
|
|
12579
13180
|
const subject = resolveSubject(left);
|
|
12580
13181
|
return { type: "typeCheck", subject, expectedType: right.getText() };
|
|
12581
13182
|
}
|
|
12582
|
-
if (opToken.getKind() ===
|
|
13183
|
+
if (opToken.getKind() === SyntaxKind19.InKeyword) {
|
|
12583
13184
|
if (Node45.isStringLiteral(left)) {
|
|
12584
13185
|
const subject = resolveSubject(right);
|
|
12585
13186
|
return {
|
|
@@ -12896,7 +13497,7 @@ function collectFallthroughCaseLabels(caseClause) {
|
|
|
12896
13497
|
}
|
|
12897
13498
|
|
|
12898
13499
|
// src/paths/pathConditions.ts
|
|
12899
|
-
import { Node as Node48 } from "ts-morph";
|
|
13500
|
+
import { Node as Node48, SyntaxKind as SyntaxKind21 } from "ts-morph";
|
|
12900
13501
|
import {
|
|
12901
13502
|
enumerateStructuredPaths,
|
|
12902
13503
|
PathBudgetExceeded,
|
|
@@ -12906,7 +13507,9 @@ import {
|
|
|
12906
13507
|
|
|
12907
13508
|
// src/paths/lowering.ts
|
|
12908
13509
|
import {
|
|
12909
|
-
Node as Node47
|
|
13510
|
+
Node as Node47,
|
|
13511
|
+
SyntaxKind as SyntaxKind20,
|
|
13512
|
+
ts as ts7
|
|
12910
13513
|
} from "ts-morph";
|
|
12911
13514
|
import {
|
|
12912
13515
|
UnmodeledFlow
|
|
@@ -12915,24 +13518,25 @@ var NO_ENDINGS = /* @__PURE__ */ new Set();
|
|
|
12915
13518
|
function exitKindOf(stmt, endings) {
|
|
12916
13519
|
let sawReturn = false;
|
|
12917
13520
|
let sawThrow = false;
|
|
12918
|
-
const
|
|
12919
|
-
|
|
12920
|
-
|
|
13521
|
+
const ending = new Set([...endings].map((node) => node.compilerNode));
|
|
13522
|
+
const root = stmt.compilerNode;
|
|
13523
|
+
const visit = (raw) => {
|
|
13524
|
+
if (raw !== root && OWN_SCOPE_KINDS.has(raw.kind)) {
|
|
13525
|
+
return void 0;
|
|
12921
13526
|
}
|
|
12922
|
-
if (
|
|
12923
|
-
return;
|
|
13527
|
+
if (runsNothing(raw)) {
|
|
13528
|
+
return void 0;
|
|
12924
13529
|
}
|
|
12925
|
-
if (
|
|
13530
|
+
if (raw.kind === SyntaxKind20.ReturnStatement || ending.has(raw)) {
|
|
12926
13531
|
sawReturn = true;
|
|
12927
13532
|
}
|
|
12928
|
-
if (
|
|
13533
|
+
if (raw.kind === SyntaxKind20.ThrowStatement) {
|
|
12929
13534
|
sawThrow = true;
|
|
12930
13535
|
}
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
}
|
|
13536
|
+
ts7.forEachChild(raw, visit);
|
|
13537
|
+
return void 0;
|
|
12934
13538
|
};
|
|
12935
|
-
visit(
|
|
13539
|
+
visit(root);
|
|
12936
13540
|
if (sawThrow) {
|
|
12937
13541
|
return "throw";
|
|
12938
13542
|
}
|
|
@@ -12947,7 +13551,20 @@ var statementsOf = (stmt) => {
|
|
|
12947
13551
|
}
|
|
12948
13552
|
return [stmt];
|
|
12949
13553
|
};
|
|
12950
|
-
var
|
|
13554
|
+
var LOOP_KINDS = /* @__PURE__ */ new Set([
|
|
13555
|
+
SyntaxKind20.ForOfStatement,
|
|
13556
|
+
SyntaxKind20.ForInStatement,
|
|
13557
|
+
SyntaxKind20.ForStatement,
|
|
13558
|
+
SyntaxKind20.WhileStatement,
|
|
13559
|
+
SyntaxKind20.DoStatement
|
|
13560
|
+
]);
|
|
13561
|
+
var isLoop = (stmt) => LOOP_KINDS.has(stmt.getKind());
|
|
13562
|
+
var CLAUSE_BREAK_KINDS = /* @__PURE__ */ new Set([
|
|
13563
|
+
...OWN_SCOPE_KINDS,
|
|
13564
|
+
...LOOP_KINDS,
|
|
13565
|
+
SyntaxKind20.SwitchStatement,
|
|
13566
|
+
SyntaxKind20.BreakStatement
|
|
13567
|
+
]);
|
|
12951
13568
|
function getLoopBody(stmt) {
|
|
12952
13569
|
if (Node47.isForOfStatement(stmt) || Node47.isForInStatement(stmt) || Node47.isForStatement(stmt) || Node47.isWhileStatement(stmt) || Node47.isDoStatement(stmt)) {
|
|
12953
13570
|
return stmt.getStatement();
|
|
@@ -13006,28 +13623,33 @@ function ownExpressionsOf(stmt) {
|
|
|
13006
13623
|
}
|
|
13007
13624
|
function lowerCallbacksIn(parts, ctx) {
|
|
13008
13625
|
const bodies = [];
|
|
13009
|
-
const
|
|
13010
|
-
if (
|
|
13011
|
-
return;
|
|
13012
|
-
}
|
|
13013
|
-
if (node !== root && (Node47.isArrowFunction(node) || Node47.isFunctionExpression(node)) && isInlineCallback(node, ctx.func, ctx.barriers)) {
|
|
13014
|
-
const body = node.getBody();
|
|
13015
|
-
if (body !== void 0 && Node47.isBlock(body)) {
|
|
13016
|
-
bodies.push(lowerList(body.getStatements(), ctx));
|
|
13017
|
-
return;
|
|
13018
|
-
}
|
|
13019
|
-
} else if (node !== root && startsItsOwnScope(node)) {
|
|
13020
|
-
return;
|
|
13626
|
+
const entersScope = (node) => {
|
|
13627
|
+
if (isDescentStop(node, ctx.func, ctx.barriers)) {
|
|
13628
|
+
return false;
|
|
13021
13629
|
}
|
|
13022
|
-
if (
|
|
13023
|
-
return;
|
|
13630
|
+
if (!(Node47.isArrowFunction(node) || Node47.isFunctionExpression(node)) || !isInlineCallback(node, ctx.func, ctx.barriers)) {
|
|
13631
|
+
return !startsItsOwnScope(node);
|
|
13024
13632
|
}
|
|
13025
|
-
|
|
13026
|
-
|
|
13633
|
+
const body = node.getBody();
|
|
13634
|
+
if (body !== void 0 && Node47.isBlock(body)) {
|
|
13635
|
+
bodies.push(lowerList(body.getStatements(), ctx));
|
|
13636
|
+
return false;
|
|
13027
13637
|
}
|
|
13638
|
+
return true;
|
|
13028
13639
|
};
|
|
13029
13640
|
for (const part of parts) {
|
|
13030
|
-
|
|
13641
|
+
const root = part.compilerNode;
|
|
13642
|
+
const visit = (raw) => {
|
|
13643
|
+
if (raw !== root && OWN_SCOPE_KINDS.has(raw.kind) && !entersScope(wrapperOf(part, raw))) {
|
|
13644
|
+
return void 0;
|
|
13645
|
+
}
|
|
13646
|
+
if (runsNothing(raw)) {
|
|
13647
|
+
return void 0;
|
|
13648
|
+
}
|
|
13649
|
+
ts7.forEachChild(raw, visit);
|
|
13650
|
+
return void 0;
|
|
13651
|
+
};
|
|
13652
|
+
visit(root);
|
|
13031
13653
|
}
|
|
13032
13654
|
return bodies;
|
|
13033
13655
|
}
|
|
@@ -13149,14 +13771,11 @@ function validateClauseBreaks(stmts) {
|
|
|
13149
13771
|
if (Node47.isSwitchStatement(stmt) || isLoop(stmt)) {
|
|
13150
13772
|
continue;
|
|
13151
13773
|
}
|
|
13152
|
-
stmt
|
|
13153
|
-
if (startsItsOwnScope(node) || Node47.isSwitchStatement(node) || isLoop(node)) {
|
|
13154
|
-
traversal.skip();
|
|
13155
|
-
return;
|
|
13156
|
-
}
|
|
13774
|
+
forEachDescendantOfKinds(stmt, CLAUSE_BREAK_KINDS, (node) => {
|
|
13157
13775
|
if (Node47.isBreakStatement(node)) {
|
|
13158
13776
|
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
13159
13777
|
}
|
|
13778
|
+
return true;
|
|
13160
13779
|
});
|
|
13161
13780
|
if (Node47.isBreakStatement(stmt)) {
|
|
13162
13781
|
throw new UnmodeledFlow("non-trailing break in switch clause");
|
|
@@ -13211,18 +13830,20 @@ function enclosingLoweredStatement(terminal, body, rawToStructured) {
|
|
|
13211
13830
|
// src/paths/pathConditions.ts
|
|
13212
13831
|
function containsUnmodeledFlow(body, func, barriers) {
|
|
13213
13832
|
let found = false;
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13221
|
-
|
|
13833
|
+
forEachDescendantWhere(
|
|
13834
|
+
body,
|
|
13835
|
+
(raw) => !found && LABELS_AND_STOPS.has(raw.kind),
|
|
13836
|
+
(node) => {
|
|
13837
|
+
if (isDescentStop(node, func, barriers)) {
|
|
13838
|
+
return true;
|
|
13839
|
+
}
|
|
13840
|
+
found = Node48.isLabeledStatement(node);
|
|
13841
|
+
return found;
|
|
13222
13842
|
}
|
|
13223
|
-
|
|
13843
|
+
);
|
|
13224
13844
|
return found;
|
|
13225
13845
|
}
|
|
13846
|
+
var LABELS_AND_STOPS = withDescentStops(SyntaxKind21.LabeledStatement);
|
|
13226
13847
|
function loweredExpressionBody(body, terminalNodes, func, barriers) {
|
|
13227
13848
|
const statement = {
|
|
13228
13849
|
kind: "opaque",
|
|
@@ -13359,151 +13980,49 @@ function refsOf(found, func, resolution) {
|
|
|
13359
13980
|
textAt: (key) => nodes.get(key)?.getText() ?? null
|
|
13360
13981
|
};
|
|
13361
13982
|
return sourceRefsOf(
|
|
13362
|
-
found.map((one) => one.leaf),
|
|
13363
|
-
spelling
|
|
13364
|
-
);
|
|
13365
|
-
}
|
|
13366
|
-
function inputOf(found, func) {
|
|
13367
|
-
const { leaf, node, parameterOf } = found;
|
|
13368
|
-
if (node !== null && Node49.isBindingElement(node)) {
|
|
13369
|
-
return boundByParameterOf(node, func) ? { type: "input", inputRef: node.getName(), path: leaf.path } : null;
|
|
13370
|
-
}
|
|
13371
|
-
if (parameterOf !== func || node === null || !Node49.isParameterDeclaration(node)) {
|
|
13372
|
-
return null;
|
|
13373
|
-
}
|
|
13374
|
-
const name = node.getNameNode();
|
|
13375
|
-
return Node49.isIdentifier(name) ? { type: "input", inputRef: name.getText(), path: leaf.path } : null;
|
|
13376
|
-
}
|
|
13377
|
-
function boundByParameterOf(element, func) {
|
|
13378
|
-
const parameter = element.getParent().getParent();
|
|
13379
|
-
return Node49.isParameterDeclaration(parameter) && parameter.getParent() === func;
|
|
13380
|
-
}
|
|
13381
|
-
function literalAt(node, resolution) {
|
|
13382
|
-
return node === void 0 ? void 0 : constantOf4(evaluatedValue(node, resolution));
|
|
13383
|
-
}
|
|
13384
|
-
|
|
13385
|
-
// src/resolve/invocationEffects.ts
|
|
13386
|
-
import {
|
|
13387
|
-
Node as Node54,
|
|
13388
|
-
VariableDeclarationKind as VariableDeclarationKind2
|
|
13389
|
-
} from "ts-morph";
|
|
13390
|
-
import {
|
|
13391
|
-
numberRepeatedCallSites,
|
|
13392
|
-
rawConditionToPredicate
|
|
13393
|
-
} from "@suss/extractor";
|
|
13394
|
-
|
|
13395
|
-
// src/resolve/callOps.ts
|
|
13396
|
-
import { Node as Node53 } from "ts-morph";
|
|
13397
|
-
|
|
13398
|
-
// src/configuredCall.ts
|
|
13399
|
-
import { Node as Node51 } from "ts-morph";
|
|
13400
|
-
|
|
13401
|
-
// src/values/receiverType.ts
|
|
13402
|
-
import { Node as Node50 } from "ts-morph";
|
|
13403
|
-
|
|
13404
|
-
// src/shapes/typeText.ts
|
|
13405
|
-
import { ts as ts3 } from "ts-morph";
|
|
13406
|
-
var PRINTER = ts3.createPrinter({
|
|
13407
|
-
removeComments: true,
|
|
13408
|
-
newLine: ts3.NewLineKind.LineFeed
|
|
13409
|
-
});
|
|
13410
|
-
var NO_FILE = ts3.createSourceFile("", "", ts3.ScriptTarget.Latest);
|
|
13411
|
-
function defaultFlags(enclosing) {
|
|
13412
|
-
const flags = ts3.TypeFormatFlags.UseTypeOfFunction | ts3.TypeFormatFlags.NoTruncation | ts3.TypeFormatFlags.UseFullyQualifiedType | ts3.TypeFormatFlags.WriteTypeArgumentsOfSignature;
|
|
13413
|
-
if (enclosing?.getKind() === ts3.SyntaxKind.TypeAliasDeclaration) {
|
|
13414
|
-
return flags | ts3.TypeFormatFlags.InTypeAlias;
|
|
13415
|
-
}
|
|
13416
|
-
return flags;
|
|
13417
|
-
}
|
|
13418
|
-
function stableTypeText(type, reader, enclosing, flags) {
|
|
13419
|
-
const checker = reader.getProject().getTypeChecker().compilerObject;
|
|
13420
|
-
const format = flags ?? defaultFlags(enclosing);
|
|
13421
|
-
const enclosingNode = enclosing?.compilerNode;
|
|
13422
|
-
const typeNode = checker.typeToTypeNode(
|
|
13423
|
-
type.compilerType,
|
|
13424
|
-
enclosingNode,
|
|
13425
|
-
format & ts3.TypeFormatFlags.NodeBuilderFlagsMask | ts3.NodeBuilderFlags.IgnoreErrors
|
|
13426
|
-
);
|
|
13427
|
-
if (typeNode === void 0) {
|
|
13428
|
-
return withoutImportQualifiers(
|
|
13429
|
-
checker.typeToString(type.compilerType, enclosingNode, format)
|
|
13430
|
-
);
|
|
13431
|
-
}
|
|
13432
|
-
const file = enclosing?.getSourceFile().compilerNode ?? NO_FILE;
|
|
13433
|
-
const ordered = containsUnion(typeNode) ? withUnionMembersOrdered(typeNode, file) : typeNode;
|
|
13434
|
-
return withoutImportQualifiers(printed(ordered, file));
|
|
13435
|
-
}
|
|
13436
|
-
var IMPORT_QUALIFIER = /import\("[^"]*"\)\./g;
|
|
13437
|
-
var withoutImportQualifiers = (text3) => text3.replace(IMPORT_QUALIFIER, "");
|
|
13438
|
-
function printed(node, file) {
|
|
13439
|
-
return PRINTER.printNode(ts3.EmitHint.Unspecified, node, file).replace(
|
|
13440
|
-
/\n/g,
|
|
13441
|
-
""
|
|
13442
|
-
);
|
|
13443
|
-
}
|
|
13444
|
-
function containsUnion(node) {
|
|
13445
|
-
if (ts3.isUnionTypeNode(node)) {
|
|
13446
|
-
return true;
|
|
13447
|
-
}
|
|
13448
|
-
return ts3.forEachChild(node, (child) => containsUnion(child) || void 0) === true;
|
|
13449
|
-
}
|
|
13450
|
-
function withUnionMembersOrdered(root, file) {
|
|
13451
|
-
const result = ts3.transform(root, [
|
|
13452
|
-
(context) => {
|
|
13453
|
-
const visit = (node) => {
|
|
13454
|
-
const visited = ts3.visitEachChild(node, visit, context);
|
|
13455
|
-
if (!ts3.isUnionTypeNode(visited)) {
|
|
13456
|
-
return visited;
|
|
13457
|
-
}
|
|
13458
|
-
return context.factory.updateUnionTypeNode(
|
|
13459
|
-
visited,
|
|
13460
|
-
context.factory.createNodeArray(inStableOrder(visited.types, file))
|
|
13461
|
-
);
|
|
13462
|
-
};
|
|
13463
|
-
return (node) => visit(node);
|
|
13464
|
-
}
|
|
13465
|
-
]);
|
|
13466
|
-
const [ordered] = result.transformed;
|
|
13467
|
-
result.dispose();
|
|
13468
|
-
return ordered;
|
|
13469
|
-
}
|
|
13470
|
-
function inStableOrder(members, file) {
|
|
13471
|
-
return members.map((member) => ({
|
|
13472
|
-
member,
|
|
13473
|
-
text: withoutImportQualifiers(printed(member, file))
|
|
13474
|
-
})).sort((a, b) => compareMembers(a.text, b.text)).map(({ member }) => member);
|
|
13475
|
-
}
|
|
13476
|
-
function compareMembers(a, b) {
|
|
13477
|
-
return nullishRank(a) - nullishRank(b) || compareText(a, b);
|
|
13983
|
+
found.map((one) => one.leaf),
|
|
13984
|
+
spelling
|
|
13985
|
+
);
|
|
13478
13986
|
}
|
|
13479
|
-
function
|
|
13480
|
-
|
|
13481
|
-
|
|
13987
|
+
function inputOf(found, func) {
|
|
13988
|
+
const { leaf, node, parameterOf } = found;
|
|
13989
|
+
if (node !== null && Node49.isBindingElement(node)) {
|
|
13990
|
+
return boundByParameterOf(node, func) ? { type: "input", inputRef: node.getName(), path: leaf.path } : null;
|
|
13482
13991
|
}
|
|
13483
|
-
if (
|
|
13484
|
-
return
|
|
13992
|
+
if (parameterOf !== func || node === null || !Node49.isParameterDeclaration(node)) {
|
|
13993
|
+
return null;
|
|
13485
13994
|
}
|
|
13486
|
-
|
|
13995
|
+
const name = node.getNameNode();
|
|
13996
|
+
return Node49.isIdentifier(name) ? { type: "input", inputRef: name.getText(), path: leaf.path } : null;
|
|
13487
13997
|
}
|
|
13488
|
-
function
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
}
|
|
13492
|
-
if (a > b) {
|
|
13493
|
-
return 1;
|
|
13494
|
-
}
|
|
13495
|
-
return 0;
|
|
13998
|
+
function boundByParameterOf(element, func) {
|
|
13999
|
+
const parameter = element.getParent().getParent();
|
|
14000
|
+
return Node49.isParameterDeclaration(parameter) && parameter.getParent() === func;
|
|
13496
14001
|
}
|
|
13497
|
-
function
|
|
13498
|
-
|
|
13499
|
-
if (!name.startsWith("__@")) {
|
|
13500
|
-
return name;
|
|
13501
|
-
}
|
|
13502
|
-
const checker = reader.getProject().getTypeChecker().compilerObject;
|
|
13503
|
-
return checker.symbolToString(symbol.compilerSymbol);
|
|
14002
|
+
function literalAt(node, resolution) {
|
|
14003
|
+
return node === void 0 ? void 0 : constantOf4(evaluatedValue(node, resolution));
|
|
13504
14004
|
}
|
|
13505
14005
|
|
|
14006
|
+
// src/resolve/invocationEffects.ts
|
|
14007
|
+
import {
|
|
14008
|
+
Node as Node54,
|
|
14009
|
+
SyntaxKind as SyntaxKind23,
|
|
14010
|
+
ts as ts8,
|
|
14011
|
+
VariableDeclarationKind as VariableDeclarationKind2
|
|
14012
|
+
} from "ts-morph";
|
|
14013
|
+
import {
|
|
14014
|
+
numberRepeatedCallSites,
|
|
14015
|
+
rawConditionToPredicate
|
|
14016
|
+
} from "@suss/extractor";
|
|
14017
|
+
|
|
14018
|
+
// src/resolve/callOps.ts
|
|
14019
|
+
import { Node as Node53 } from "ts-morph";
|
|
14020
|
+
|
|
14021
|
+
// src/configuredCall.ts
|
|
14022
|
+
import { Node as Node51 } from "ts-morph";
|
|
14023
|
+
|
|
13506
14024
|
// src/values/receiverType.ts
|
|
14025
|
+
import { Node as Node50 } from "ts-morph";
|
|
13507
14026
|
function receiverTypesOf(node) {
|
|
13508
14027
|
const type = node.getType();
|
|
13509
14028
|
if (type.isAny()) {
|
|
@@ -13650,7 +14169,7 @@ function rootIdentifier(node) {
|
|
|
13650
14169
|
}
|
|
13651
14170
|
|
|
13652
14171
|
// src/resolve/readName.ts
|
|
13653
|
-
import { Node as Node52, SyntaxKind as
|
|
14172
|
+
import { Node as Node52, SyntaxKind as SyntaxKind22 } from "ts-morph";
|
|
13654
14173
|
import { patternHole, referenceName } from "@suss/behavioral-ir";
|
|
13655
14174
|
var MAX_HELPER_HOPS = 2;
|
|
13656
14175
|
var UNNAMED_HOLE = "param";
|
|
@@ -13748,7 +14267,7 @@ function isFallbackBranch(node) {
|
|
|
13748
14267
|
return false;
|
|
13749
14268
|
}
|
|
13750
14269
|
const operator = step.getOperatorToken().getKind();
|
|
13751
|
-
return operator ===
|
|
14270
|
+
return operator === SyntaxKind22.BarBarToken || operator === SyntaxKind22.QuestionQuestionToken;
|
|
13752
14271
|
}
|
|
13753
14272
|
function fromTemplate(expr, ctx) {
|
|
13754
14273
|
if (!Node52.isTemplateExpression(expr)) {
|
|
@@ -13766,10 +14285,10 @@ function fromBinary(expr, ctx) {
|
|
|
13766
14285
|
return null;
|
|
13767
14286
|
}
|
|
13768
14287
|
const operator = expr.getOperatorToken().getKind();
|
|
13769
|
-
if (operator ===
|
|
14288
|
+
if (operator === SyntaxKind22.BarBarToken || operator === SyntaxKind22.QuestionQuestionToken) {
|
|
13770
14289
|
return ctx.insideHole ? null : read(expr.getRight(), ctx);
|
|
13771
14290
|
}
|
|
13772
|
-
if (operator !==
|
|
14291
|
+
if (operator !== SyntaxKind22.PlusToken) {
|
|
13773
14292
|
return null;
|
|
13774
14293
|
}
|
|
13775
14294
|
const parts = { ...ctx, insideHole: true };
|
|
@@ -14483,16 +15002,32 @@ function extractInvocationEffectsAtModuleScope(sourceFile) {
|
|
|
14483
15002
|
(call) => !invokesFunctionInPlace(call.node)
|
|
14484
15003
|
);
|
|
14485
15004
|
}
|
|
15005
|
+
var CALLS_AND_STOPS = withDescentStops(SyntaxKind23.CallExpression);
|
|
15006
|
+
var ACCESSES_CONSTRUCTIONS_AND_STOPS = withDescentStops(
|
|
15007
|
+
SyntaxKind23.PropertyAccessExpression,
|
|
15008
|
+
SyntaxKind23.CallExpression,
|
|
15009
|
+
SyntaxKind23.TaggedTemplateExpression,
|
|
15010
|
+
SyntaxKind23.NewExpression
|
|
15011
|
+
);
|
|
15012
|
+
var INVOCATIONS_AND_STOPS = withDescentStops(
|
|
15013
|
+
SyntaxKind23.CallExpression,
|
|
15014
|
+
SyntaxKind23.NewExpression
|
|
15015
|
+
);
|
|
15016
|
+
var ACCESSES_AND_STOPS = withDescentStops(
|
|
15017
|
+
SyntaxKind23.PropertyAccessExpression,
|
|
15018
|
+
SyntaxKind23.CallExpression,
|
|
15019
|
+
SyntaxKind23.TaggedTemplateExpression
|
|
15020
|
+
);
|
|
14486
15021
|
function invocationsUnder(root, isStop) {
|
|
14487
15022
|
const calls = [];
|
|
14488
|
-
|
|
15023
|
+
forEachInUnitBodyOfKinds(root, INVOCATIONS_AND_STOPS, (node) => {
|
|
14489
15024
|
if (isStop(node)) {
|
|
14490
|
-
|
|
14491
|
-
return;
|
|
15025
|
+
return true;
|
|
14492
15026
|
}
|
|
14493
15027
|
if (Node54.isCallExpression(node) || runsProjectConstructor(node)) {
|
|
14494
15028
|
calls.push(node);
|
|
14495
15029
|
}
|
|
15030
|
+
return false;
|
|
14496
15031
|
});
|
|
14497
15032
|
calls.sort((a, b) => a.getEnd() - b.getEnd());
|
|
14498
15033
|
return calls.map((call) => invocationAt(call, root));
|
|
@@ -14530,14 +15065,14 @@ function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, res
|
|
|
14530
15065
|
const sites = [];
|
|
14531
15066
|
const sourceFile = func.getSourceFile();
|
|
14532
15067
|
const calls = [];
|
|
14533
|
-
|
|
15068
|
+
forEachInUnitBodyOfKinds(func, CALLS_AND_STOPS, (node) => {
|
|
14534
15069
|
if (isDescentStop(node, func, barriers)) {
|
|
14535
|
-
|
|
14536
|
-
return;
|
|
15070
|
+
return true;
|
|
14537
15071
|
}
|
|
14538
15072
|
if (Node54.isCallExpression(node)) {
|
|
14539
15073
|
calls.push(node);
|
|
14540
15074
|
}
|
|
15075
|
+
return false;
|
|
14541
15076
|
});
|
|
14542
15077
|
const walk = walkArguments(calls, resolution);
|
|
14543
15078
|
for (const node of calls) {
|
|
@@ -14697,10 +15232,11 @@ function dispatchAccessRecognizers(root, recognizers, isStop, resolution, origin
|
|
|
14697
15232
|
function accessedIn(root, isStop) {
|
|
14698
15233
|
const sites = [];
|
|
14699
15234
|
const calls = [];
|
|
14700
|
-
|
|
15235
|
+
const own = root.compilerNode;
|
|
15236
|
+
const accepts = (raw) => ACCESSES_CONSTRUCTIONS_AND_STOPS.has(raw.kind) || ts8.isParameter(raw.parent) && raw.parent.initializer === raw && raw.parent.parent === own;
|
|
15237
|
+
forEachInUnitBodyWhere(root, accepts, (node) => {
|
|
14701
15238
|
if (isStop(node) || isOwnParameterDefault(node, root)) {
|
|
14702
|
-
|
|
14703
|
-
return;
|
|
15239
|
+
return true;
|
|
14704
15240
|
}
|
|
14705
15241
|
if (isAccessed(node)) {
|
|
14706
15242
|
sites.push({ node, at: node });
|
|
@@ -14708,17 +15244,18 @@ function accessedIn(root, isStop) {
|
|
|
14708
15244
|
if (Node54.isCallExpression(node) || Node54.isNewExpression(node)) {
|
|
14709
15245
|
calls.push(node);
|
|
14710
15246
|
}
|
|
15247
|
+
return false;
|
|
14711
15248
|
});
|
|
14712
15249
|
for (const call of calls) {
|
|
14713
15250
|
for (const initializer of defaultsRunBy(call)) {
|
|
14714
|
-
|
|
15251
|
+
forEachInUnitBodyOfKinds(initializer, ACCESSES_AND_STOPS, (node) => {
|
|
14715
15252
|
if (isStop(node)) {
|
|
14716
|
-
|
|
14717
|
-
return;
|
|
15253
|
+
return true;
|
|
14718
15254
|
}
|
|
14719
15255
|
if (isAccessed(node)) {
|
|
14720
15256
|
sites.push({ node, at: call });
|
|
14721
15257
|
}
|
|
15258
|
+
return false;
|
|
14722
15259
|
});
|
|
14723
15260
|
if (isAccessed(initializer)) {
|
|
14724
15261
|
sites.push({ node: initializer, at: call });
|
|
@@ -15455,7 +15992,7 @@ function rootOf(ref) {
|
|
|
15455
15992
|
}
|
|
15456
15993
|
|
|
15457
15994
|
// src/terminals/index.ts
|
|
15458
|
-
import { Node as Node66 } from "ts-morph";
|
|
15995
|
+
import { Node as Node66, SyntaxKind as SyntaxKind26 } from "ts-morph";
|
|
15459
15996
|
|
|
15460
15997
|
// src/terminals/continuation.ts
|
|
15461
15998
|
import { Node as Node57 } from "ts-morph";
|
|
@@ -15493,55 +16030,12 @@ import { constantOf as constantOf5 } from "@suss/values";
|
|
|
15493
16030
|
// src/shapes/shapes.ts
|
|
15494
16031
|
import {
|
|
15495
16032
|
Node as Node59,
|
|
15496
|
-
SyntaxKind as
|
|
16033
|
+
SyntaxKind as SyntaxKind24
|
|
15497
16034
|
} from "ts-morph";
|
|
15498
16035
|
|
|
15499
16036
|
// src/shapes/typeShapes.ts
|
|
15500
16037
|
import { createHash } from "crypto";
|
|
15501
16038
|
import { Node as Node58, TypeFormatFlags } from "ts-morph";
|
|
15502
|
-
|
|
15503
|
-
// src/shapes/definitions.ts
|
|
15504
|
-
var current = null;
|
|
15505
|
-
var definitionsInProgress = () => current;
|
|
15506
|
-
function createDefinitionTable() {
|
|
15507
|
-
const shapes = /* @__PURE__ */ new Map();
|
|
15508
|
-
return {
|
|
15509
|
-
has: (key) => shapes.has(key),
|
|
15510
|
-
reserve: (key) => {
|
|
15511
|
-
shapes.set(key, null);
|
|
15512
|
-
},
|
|
15513
|
-
define: (key, shape) => {
|
|
15514
|
-
shapes.set(key, shape);
|
|
15515
|
-
},
|
|
15516
|
-
// Sorted because the walk meets types in the checker's union order,
|
|
15517
|
-
// which changes between runs.
|
|
15518
|
-
collected: () => {
|
|
15519
|
-
const out = {};
|
|
15520
|
-
let any = false;
|
|
15521
|
-
const keys = [...shapes.keys()].sort(compareText);
|
|
15522
|
-
for (const key of keys) {
|
|
15523
|
-
const shape = shapes.get(key) ?? null;
|
|
15524
|
-
if (shape !== null) {
|
|
15525
|
-
out[key] = shape;
|
|
15526
|
-
any = true;
|
|
15527
|
-
}
|
|
15528
|
-
}
|
|
15529
|
-
return any ? out : null;
|
|
15530
|
-
}
|
|
15531
|
-
};
|
|
15532
|
-
}
|
|
15533
|
-
function withDefinitions(read2) {
|
|
15534
|
-
const table = createDefinitionTable();
|
|
15535
|
-
const outer = current;
|
|
15536
|
-
current = table;
|
|
15537
|
-
try {
|
|
15538
|
-
return { value: read2(), definitions: table.collected() };
|
|
15539
|
-
} finally {
|
|
15540
|
-
current = outer;
|
|
15541
|
-
}
|
|
15542
|
-
}
|
|
15543
|
-
|
|
15544
|
-
// src/shapes/typeShapes.ts
|
|
15545
16039
|
var MAX_DEPTH = 6;
|
|
15546
16040
|
var OPAQUE_NAMED_TYPES = /* @__PURE__ */ new Set([
|
|
15547
16041
|
"Date",
|
|
@@ -15579,16 +16073,17 @@ function overloadIsAGuess(node) {
|
|
|
15579
16073
|
if (signatures.length < 2) {
|
|
15580
16074
|
return false;
|
|
15581
16075
|
}
|
|
15582
|
-
const
|
|
15583
|
-
signatures.map((signature) => signature.getReturnType().getText(node))
|
|
15584
|
-
);
|
|
15585
|
-
if (returns.size < 2) {
|
|
15586
|
-
return false;
|
|
15587
|
-
}
|
|
15588
|
-
return node.getArguments().some((argument) => {
|
|
16076
|
+
const untypedArgument = node.getArguments().some((argument) => {
|
|
15589
16077
|
const type = argument.getType();
|
|
15590
16078
|
return type.isAny() || type.isNever();
|
|
15591
16079
|
});
|
|
16080
|
+
if (!untypedArgument) {
|
|
16081
|
+
return false;
|
|
16082
|
+
}
|
|
16083
|
+
const returns = new Set(
|
|
16084
|
+
signatures.map((signature) => signature.getReturnType().getText(node))
|
|
16085
|
+
);
|
|
16086
|
+
return returns.size >= 2;
|
|
15592
16087
|
}
|
|
15593
16088
|
function typeToShape(type, ctx) {
|
|
15594
16089
|
if (type.isAny()) {
|
|
@@ -15882,16 +16377,16 @@ function namedOnce(type, ctx) {
|
|
|
15882
16377
|
const filed = { ...named2, def: key };
|
|
15883
16378
|
if (!table.has(key)) {
|
|
15884
16379
|
table.reserve(key);
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
table.define(key, expanded);
|
|
16380
|
+
table.defer(
|
|
16381
|
+
key,
|
|
16382
|
+
() => objectToShape(type, {
|
|
16383
|
+
enclosing: ctx.enclosing,
|
|
16384
|
+
depth: 0,
|
|
16385
|
+
seen: /* @__PURE__ */ new Set()
|
|
16386
|
+
})
|
|
16387
|
+
);
|
|
15894
16388
|
}
|
|
16389
|
+
table.settle();
|
|
15895
16390
|
return filed;
|
|
15896
16391
|
}
|
|
15897
16392
|
function definitionKeyFor(type, name, reader) {
|
|
@@ -16055,13 +16550,13 @@ function extractShapeInner(node) {
|
|
|
16055
16550
|
}
|
|
16056
16551
|
if (Node59.isPrefixUnaryExpression(unwrapped2)) {
|
|
16057
16552
|
const op = unwrapped2.getOperatorToken();
|
|
16058
|
-
if (op ===
|
|
16553
|
+
if (op === SyntaxKind24.MinusToken || op === SyntaxKind24.PlusToken) {
|
|
16059
16554
|
const inner = unwrapped2.getOperand();
|
|
16060
16555
|
if (Node59.isNumericLiteral(inner)) {
|
|
16061
16556
|
const v2 = inner.getLiteralValue();
|
|
16062
|
-
const signed = op ===
|
|
16557
|
+
const signed = op === SyntaxKind24.MinusToken ? -v2 : v2;
|
|
16063
16558
|
const rawBody = inner.getText();
|
|
16064
|
-
const raw = op ===
|
|
16559
|
+
const raw = op === SyntaxKind24.MinusToken ? `-${rawBody}` : rawBody;
|
|
16065
16560
|
return numericLiteralShape(signed, raw);
|
|
16066
16561
|
}
|
|
16067
16562
|
}
|
|
@@ -16070,13 +16565,13 @@ function extractShapeInner(node) {
|
|
|
16070
16565
|
return { type: "ref", name: "bigint" };
|
|
16071
16566
|
}
|
|
16072
16567
|
const kind = unwrapped2.getKind();
|
|
16073
|
-
if (kind ===
|
|
16568
|
+
if (kind === SyntaxKind24.TrueKeyword) {
|
|
16074
16569
|
return { type: "literal", value: true };
|
|
16075
16570
|
}
|
|
16076
|
-
if (kind ===
|
|
16571
|
+
if (kind === SyntaxKind24.FalseKeyword) {
|
|
16077
16572
|
return { type: "literal", value: false };
|
|
16078
16573
|
}
|
|
16079
|
-
if (kind ===
|
|
16574
|
+
if (kind === SyntaxKind24.NullKeyword) {
|
|
16080
16575
|
return { type: "null" };
|
|
16081
16576
|
}
|
|
16082
16577
|
if (Node59.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
|
|
@@ -16664,7 +17159,7 @@ import {
|
|
|
16664
17159
|
} from "ts-morph";
|
|
16665
17160
|
|
|
16666
17161
|
// src/terminals/helperResolution.ts
|
|
16667
|
-
import { Node as Node62, SyntaxKind as
|
|
17162
|
+
import { Node as Node62, SyntaxKind as SyntaxKind25 } from "ts-morph";
|
|
16668
17163
|
function resolveHelperReturn(call, resolveCallee2) {
|
|
16669
17164
|
const callee = call.getExpression();
|
|
16670
17165
|
if (!Node62.isIdentifier(callee)) {
|
|
@@ -16767,7 +17262,7 @@ function evaluateComparison(condition, substitutions) {
|
|
|
16767
17262
|
}
|
|
16768
17263
|
function numberFor(node, substitutions) {
|
|
16769
17264
|
const resolved = Node62.isIdentifier(node) && substitutions.has(node.getText()) ? substitutions.get(node.getText()) : node;
|
|
16770
|
-
return Node62.isNumericLiteral(resolved) ?
|
|
17265
|
+
return Node62.isNumericLiteral(resolved) ? resolved.getLiteralValue() : null;
|
|
16771
17266
|
}
|
|
16772
17267
|
var helperBySymbol = createProgramMemo();
|
|
16773
17268
|
function memoizedLocalHelper(callee, resolveCallee2) {
|
|
@@ -16877,7 +17372,7 @@ function returnedObjects(fn) {
|
|
|
16877
17372
|
}
|
|
16878
17373
|
const found = [];
|
|
16879
17374
|
for (const statement of body.getDescendantsOfKind(
|
|
16880
|
-
|
|
17375
|
+
SyntaxKind25.ReturnStatement
|
|
16881
17376
|
)) {
|
|
16882
17377
|
if (enclosingFunctionOf2(statement) !== body) {
|
|
16883
17378
|
continue;
|
|
@@ -17437,12 +17932,23 @@ function classifyThrownExpression(thrown, constructorPattern) {
|
|
|
17437
17932
|
|
|
17438
17933
|
// src/terminals/index.ts
|
|
17439
17934
|
var NESTED_ESCAPING_MATCH_TYPES = /* @__PURE__ */ new Set(["parameterMethodCall"]);
|
|
17935
|
+
var TERMINAL_KINDS = /* @__PURE__ */ new Set([
|
|
17936
|
+
SyntaxKind26.ObjectLiteralExpression,
|
|
17937
|
+
SyntaxKind26.ReturnStatement,
|
|
17938
|
+
SyntaxKind26.ThrowStatement,
|
|
17939
|
+
SyntaxKind26.CallExpression,
|
|
17940
|
+
SyntaxKind26.NewExpression,
|
|
17941
|
+
SyntaxKind26.ArrowFunction,
|
|
17942
|
+
SyntaxKind26.FunctionExpression,
|
|
17943
|
+
SyntaxKind26.FunctionDeclaration,
|
|
17944
|
+
SyntaxKind26.MethodDeclaration,
|
|
17945
|
+
SyntaxKind26.Constructor
|
|
17946
|
+
]);
|
|
17440
17947
|
function findTerminals(func, patterns, barriers = NO_BARRIERS, resolution, originatesFrom, resolveCallee2) {
|
|
17441
17948
|
const results = [];
|
|
17442
|
-
func
|
|
17949
|
+
forEachDescendantOfKinds(func, TERMINAL_KINDS, (node) => {
|
|
17443
17950
|
if (isDescentStop(node, func, barriers)) {
|
|
17444
|
-
|
|
17445
|
-
return;
|
|
17951
|
+
return true;
|
|
17446
17952
|
}
|
|
17447
17953
|
const nested = crossesNestedFunctionScope(node, func);
|
|
17448
17954
|
for (const pattern of patterns) {
|
|
@@ -17510,6 +18016,7 @@ function findTerminals(func, patterns, barriers = NO_BARRIERS, resolution, origi
|
|
|
17510
18016
|
break;
|
|
17511
18017
|
}
|
|
17512
18018
|
}
|
|
18019
|
+
return false;
|
|
17513
18020
|
});
|
|
17514
18021
|
if (results.length === 0 && Node66.isArrowFunction(func)) {
|
|
17515
18022
|
const body = func.getBody();
|
|
@@ -17635,55 +18142,72 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
|
|
|
17635
18142
|
return claimed.has(body) ? 0 : 1;
|
|
17636
18143
|
}
|
|
17637
18144
|
let unmatched = 0;
|
|
17638
|
-
body
|
|
18145
|
+
forEachDescendantOfKinds(body, RETURNS_AND_SCOPES, (node) => {
|
|
17639
18146
|
if (isDescentStop(node, func, barriers)) {
|
|
17640
|
-
|
|
17641
|
-
return;
|
|
18147
|
+
return true;
|
|
17642
18148
|
}
|
|
17643
18149
|
if (startsItsOwnScope(node)) {
|
|
17644
|
-
|
|
17645
|
-
return;
|
|
17646
|
-
}
|
|
17647
|
-
if (!Node67.isReturnStatement(node)) {
|
|
17648
|
-
return;
|
|
18150
|
+
return true;
|
|
17649
18151
|
}
|
|
17650
18152
|
if (node.getExpression() === void 0) {
|
|
17651
|
-
return;
|
|
18153
|
+
return false;
|
|
17652
18154
|
}
|
|
17653
18155
|
if (!claimed.has(node)) {
|
|
17654
18156
|
unmatched++;
|
|
17655
18157
|
}
|
|
18158
|
+
return false;
|
|
17656
18159
|
});
|
|
17657
18160
|
return unmatched;
|
|
17658
18161
|
}
|
|
18162
|
+
var RETURNS_AND_SCOPES = /* @__PURE__ */ new Set([
|
|
18163
|
+
...OWN_SCOPE_KINDS,
|
|
18164
|
+
SyntaxKind27.ReturnStatement
|
|
18165
|
+
]);
|
|
17659
18166
|
function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2, collectCallAccounting = false, keepsArms, handOff) {
|
|
17660
|
-
const terminals =
|
|
18167
|
+
const { terminals, invocations, recognized } = walkBodyOnce(
|
|
17661
18168
|
func,
|
|
17662
|
-
|
|
17663
|
-
|
|
17664
|
-
resolution,
|
|
17665
|
-
originatesFrom,
|
|
17666
|
-
resolveCallee2
|
|
17667
|
-
);
|
|
17668
|
-
const invocations = extractInvocationEffects(func, barriers);
|
|
17669
|
-
const recognized = [
|
|
17670
|
-
...runInvocationRecognizers(
|
|
17671
|
-
func,
|
|
18169
|
+
{
|
|
18170
|
+
terminalPatterns,
|
|
17672
18171
|
invocationRecognizers,
|
|
17673
|
-
barriers,
|
|
17674
|
-
resolution,
|
|
17675
|
-
originatesFrom,
|
|
17676
|
-
anchorCallsOf
|
|
17677
|
-
),
|
|
17678
|
-
...runAccessRecognizers(
|
|
17679
|
-
func,
|
|
17680
18172
|
accessRecognizers,
|
|
17681
18173
|
barriers,
|
|
17682
18174
|
resolution,
|
|
17683
|
-
|
|
17684
|
-
|
|
17685
|
-
|
|
17686
|
-
|
|
18175
|
+
callbacks: [
|
|
18176
|
+
originatesFrom !== void 0,
|
|
18177
|
+
anchorCallsOf !== void 0,
|
|
18178
|
+
resolveCallee2 !== void 0
|
|
18179
|
+
]
|
|
18180
|
+
},
|
|
18181
|
+
() => ({
|
|
18182
|
+
terminals: findTerminals(
|
|
18183
|
+
func,
|
|
18184
|
+
terminalPatterns,
|
|
18185
|
+
barriers,
|
|
18186
|
+
resolution,
|
|
18187
|
+
originatesFrom,
|
|
18188
|
+
resolveCallee2
|
|
18189
|
+
),
|
|
18190
|
+
invocations: extractInvocationEffects(func, barriers),
|
|
18191
|
+
recognized: [
|
|
18192
|
+
...runInvocationRecognizers(
|
|
18193
|
+
func,
|
|
18194
|
+
invocationRecognizers,
|
|
18195
|
+
barriers,
|
|
18196
|
+
resolution,
|
|
18197
|
+
originatesFrom,
|
|
18198
|
+
anchorCallsOf
|
|
18199
|
+
),
|
|
18200
|
+
...runAccessRecognizers(
|
|
18201
|
+
func,
|
|
18202
|
+
accessRecognizers,
|
|
18203
|
+
barriers,
|
|
18204
|
+
resolution,
|
|
18205
|
+
originatesFrom,
|
|
18206
|
+
anchorCallsOf
|
|
18207
|
+
)
|
|
18208
|
+
]
|
|
18209
|
+
})
|
|
18210
|
+
);
|
|
17687
18211
|
const endings = new Set(
|
|
17688
18212
|
terminals.filter(({ terminal }) => terminal.kind === "exit").map(({ node }) => node)
|
|
17689
18213
|
);
|
|
@@ -17847,14 +18371,14 @@ function accountFor(site, terminalNodes, branches) {
|
|
|
17847
18371
|
}
|
|
17848
18372
|
|
|
17849
18373
|
// src/bootstrap/automaticTypes.ts
|
|
17850
|
-
import { ts as
|
|
18374
|
+
import { ts as ts9 } from "ts-morph";
|
|
17851
18375
|
function pinAutomaticTypes(project) {
|
|
17852
18376
|
const options = project.getCompilerOptions();
|
|
17853
18377
|
if (options.types !== void 0) {
|
|
17854
18378
|
return;
|
|
17855
18379
|
}
|
|
17856
18380
|
project.compilerOptions.set({
|
|
17857
|
-
types:
|
|
18381
|
+
types: ts9.getAutomaticTypeDirectiveNames(options, ts9.sys)
|
|
17858
18382
|
});
|
|
17859
18383
|
}
|
|
17860
18384
|
|
|
@@ -18297,7 +18821,7 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
|
|
|
18297
18821
|
|
|
18298
18822
|
// src/diagnostics.ts
|
|
18299
18823
|
import path10 from "path";
|
|
18300
|
-
import { ts as
|
|
18824
|
+
import { ts as ts10 } from "ts-morph";
|
|
18301
18825
|
import {
|
|
18302
18826
|
createPackTallies,
|
|
18303
18827
|
emptyTally,
|
|
@@ -18305,23 +18829,23 @@ import {
|
|
|
18305
18829
|
summaryCountsByPack
|
|
18306
18830
|
} from "@suss/extractor";
|
|
18307
18831
|
var DEFAULT_RESOLUTION = {
|
|
18308
|
-
moduleResolution:
|
|
18309
|
-
target:
|
|
18310
|
-
module:
|
|
18832
|
+
moduleResolution: ts10.ModuleResolutionKind.Bundler,
|
|
18833
|
+
target: ts10.ScriptTarget.ESNext,
|
|
18834
|
+
module: ts10.ModuleKind.ESNext
|
|
18311
18835
|
};
|
|
18312
18836
|
function resolutionContext(args) {
|
|
18313
18837
|
if (args.tsConfigFilePath !== void 0) {
|
|
18314
|
-
const configFile =
|
|
18838
|
+
const configFile = ts10.readConfigFile(
|
|
18315
18839
|
args.tsConfigFilePath,
|
|
18316
|
-
|
|
18840
|
+
ts10.sys.readFile
|
|
18317
18841
|
);
|
|
18318
18842
|
if (configFile.error !== void 0) {
|
|
18319
18843
|
return null;
|
|
18320
18844
|
}
|
|
18321
18845
|
const dir = path10.dirname(args.tsConfigFilePath);
|
|
18322
|
-
const parsed =
|
|
18846
|
+
const parsed = ts10.parseJsonConfigFileContent(
|
|
18323
18847
|
configFile.config,
|
|
18324
|
-
|
|
18848
|
+
ts10.sys,
|
|
18325
18849
|
dir,
|
|
18326
18850
|
/*existingOptions*/
|
|
18327
18851
|
void 0,
|
|
@@ -18350,11 +18874,11 @@ function unresolvedGatesFor(gates, args) {
|
|
|
18350
18874
|
}
|
|
18351
18875
|
const unresolved = [];
|
|
18352
18876
|
for (const gate of gates) {
|
|
18353
|
-
const resolved =
|
|
18877
|
+
const resolved = ts10.resolveModuleName(
|
|
18354
18878
|
gate,
|
|
18355
18879
|
context.containingFile,
|
|
18356
18880
|
context.options,
|
|
18357
|
-
|
|
18881
|
+
ts10.sys
|
|
18358
18882
|
);
|
|
18359
18883
|
if (resolved.resolvedModule === void 0) {
|
|
18360
18884
|
unresolved.push(gate);
|
|
@@ -18706,14 +19230,14 @@ function graphqlClientConstructions(sourceFiles, specs, resolution) {
|
|
|
18706
19230
|
const store = resolution ?? new ResolutionStore();
|
|
18707
19231
|
const found = [];
|
|
18708
19232
|
for (const sourceFile of sourceFiles) {
|
|
19233
|
+
const byModule = /* @__PURE__ */ new Map();
|
|
18709
19234
|
for (const spec of specs) {
|
|
18710
|
-
const
|
|
18711
|
-
|
|
18712
|
-
|
|
18713
|
-
|
|
19235
|
+
const origins = byModule.get(spec.importModule) ?? importedCallOrigins(sourceFile, store, spec.importModule);
|
|
19236
|
+
byModule.set(spec.importModule, origins);
|
|
19237
|
+
for (const node of callsNamed(
|
|
19238
|
+
origins,
|
|
18714
19239
|
/* @__PURE__ */ new Set([spec.importName])
|
|
18715
|
-
)
|
|
18716
|
-
for (const node of constructions.keys()) {
|
|
19240
|
+
).keys()) {
|
|
18717
19241
|
found.push({ node, spec });
|
|
18718
19242
|
}
|
|
18719
19243
|
}
|
|
@@ -19550,6 +20074,9 @@ function callSitesOf(func, store) {
|
|
|
19550
20074
|
if (!Node73.isCallExpression(passed.call)) {
|
|
19551
20075
|
continue;
|
|
19552
20076
|
}
|
|
20077
|
+
if (testCallingProduction(passed.call, func)) {
|
|
20078
|
+
continue;
|
|
20079
|
+
}
|
|
19553
20080
|
const key = siteKey(passed.call);
|
|
19554
20081
|
const site = byCall.get(key) ?? {
|
|
19555
20082
|
call: passed.call,
|
|
@@ -19851,7 +20378,17 @@ function scopeOf(args, wraps, resolution) {
|
|
|
19851
20378
|
}
|
|
19852
20379
|
|
|
19853
20380
|
// src/discoveryContext.ts
|
|
19854
|
-
import { Node as Node75 } from "ts-morph";
|
|
20381
|
+
import { Node as Node75, SyntaxKind as SyntaxKind28 } from "ts-morph";
|
|
20382
|
+
var NESTED_FUNCTION_KINDS = /* @__PURE__ */ new Set([
|
|
20383
|
+
SyntaxKind28.FunctionDeclaration,
|
|
20384
|
+
SyntaxKind28.FunctionExpression,
|
|
20385
|
+
SyntaxKind28.ArrowFunction,
|
|
20386
|
+
SyntaxKind28.MethodDeclaration
|
|
20387
|
+
]);
|
|
20388
|
+
var RETURNS_AND_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
20389
|
+
...NESTED_FUNCTION_KINDS,
|
|
20390
|
+
SyntaxKind28.ReturnStatement
|
|
20391
|
+
]);
|
|
19855
20392
|
function createTsDiscoveryContext(resolution) {
|
|
19856
20393
|
const store = resolution ?? new ResolutionStore();
|
|
19857
20394
|
return {
|
|
@@ -19936,22 +20473,20 @@ function hasJsxReturn(func) {
|
|
|
19936
20473
|
return false;
|
|
19937
20474
|
}
|
|
19938
20475
|
let found = false;
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
19942
|
-
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
traversal.skip();
|
|
19946
|
-
return;
|
|
19947
|
-
}
|
|
19948
|
-
if (Node75.isReturnStatement(node)) {
|
|
19949
|
-
const expr = node.getExpression();
|
|
19950
|
-
if (expr !== void 0 && isJsxOrFragment(expr)) {
|
|
19951
|
-
found = true;
|
|
20476
|
+
forEachDescendantWhere(
|
|
20477
|
+
body,
|
|
20478
|
+
(raw) => !found && RETURNS_AND_FUNCTIONS.has(raw.kind),
|
|
20479
|
+
(node) => {
|
|
20480
|
+
if (node !== func && NESTED_FUNCTION_KINDS.has(node.getKind())) {
|
|
20481
|
+
return true;
|
|
19952
20482
|
}
|
|
20483
|
+
if (Node75.isReturnStatement(node)) {
|
|
20484
|
+
const expr = node.getExpression();
|
|
20485
|
+
found = expr !== void 0 && isJsxOrFragment(expr);
|
|
20486
|
+
}
|
|
20487
|
+
return found;
|
|
19953
20488
|
}
|
|
19954
|
-
|
|
20489
|
+
);
|
|
19955
20490
|
return found;
|
|
19956
20491
|
}
|
|
19957
20492
|
function isJsxOrFragment(node) {
|
|
@@ -20505,7 +21040,8 @@ function placeOfKey(key) {
|
|
|
20505
21040
|
|
|
20506
21041
|
// src/resolve/reachableClosure.ts
|
|
20507
21042
|
import {
|
|
20508
|
-
Node as Node79
|
|
21043
|
+
Node as Node79,
|
|
21044
|
+
SyntaxKind as SyntaxKind29
|
|
20509
21045
|
} from "ts-morph";
|
|
20510
21046
|
import {
|
|
20511
21047
|
functionCallBinding,
|
|
@@ -20912,6 +21448,21 @@ function resolveJsxReference(node, scan) {
|
|
|
20912
21448
|
)
|
|
20913
21449
|
};
|
|
20914
21450
|
}
|
|
21451
|
+
var BODY_SCAN_KINDS = /* @__PURE__ */ new Set([
|
|
21452
|
+
SyntaxKind29.CallExpression,
|
|
21453
|
+
SyntaxKind29.NewExpression,
|
|
21454
|
+
SyntaxKind29.JsxOpeningElement,
|
|
21455
|
+
SyntaxKind29.JsxSelfClosingElement
|
|
21456
|
+
]);
|
|
21457
|
+
var MODULE_SCAN_KINDS = /* @__PURE__ */ new Set([
|
|
21458
|
+
...BODY_SCAN_KINDS,
|
|
21459
|
+
SyntaxKind29.FunctionDeclaration,
|
|
21460
|
+
SyntaxKind29.MethodDeclaration,
|
|
21461
|
+
SyntaxKind29.ArrowFunction,
|
|
21462
|
+
SyntaxKind29.FunctionExpression,
|
|
21463
|
+
SyntaxKind29.ClassDeclaration,
|
|
21464
|
+
SyntaxKind29.ClassExpression
|
|
21465
|
+
]);
|
|
20915
21466
|
function collectReachable(root, scan) {
|
|
20916
21467
|
const atModuleScope = Node79.isSourceFile(root);
|
|
20917
21468
|
const inFunc = atModuleScope ? { ...scan } : { ...scan, scanning: root };
|
|
@@ -20978,31 +21529,32 @@ function collectReachable(root, scan) {
|
|
|
20978
21529
|
});
|
|
20979
21530
|
};
|
|
20980
21531
|
const found = [];
|
|
20981
|
-
|
|
21532
|
+
const kinds = atModuleScope ? MODULE_SCAN_KINDS : BODY_SCAN_KINDS;
|
|
21533
|
+
forEachInUnitBodyOfKinds(root, kinds, (node) => {
|
|
20982
21534
|
if (atModuleScope && isModuleScopeStop(node)) {
|
|
20983
|
-
|
|
20984
|
-
return;
|
|
21535
|
+
return true;
|
|
20985
21536
|
}
|
|
20986
21537
|
const jsx = resolveJsxReference(node, inFunc);
|
|
20987
21538
|
if (jsx !== null) {
|
|
20988
21539
|
found.push({ node, outcome: jsx.outcome });
|
|
20989
|
-
return;
|
|
21540
|
+
return false;
|
|
20990
21541
|
}
|
|
20991
21542
|
if (Node79.isNewExpression(node)) {
|
|
20992
21543
|
const outcome2 = resolveConstruction(node, inFunc);
|
|
20993
21544
|
if (outcome2 !== null) {
|
|
20994
21545
|
found.push({ node, calleeText: constructionCallee(node), outcome: outcome2 });
|
|
20995
21546
|
}
|
|
20996
|
-
return;
|
|
21547
|
+
return false;
|
|
20997
21548
|
}
|
|
20998
21549
|
if (!Node79.isCallExpression(node)) {
|
|
20999
|
-
return;
|
|
21550
|
+
return false;
|
|
21000
21551
|
}
|
|
21001
21552
|
const calleeText = normalizeCalleeText2(node.getExpression().getText());
|
|
21002
21553
|
const outcome = resolveCallee(node, calleeText, inFunc);
|
|
21003
21554
|
if (outcome !== null) {
|
|
21004
21555
|
found.push({ node, calleeText, outcome });
|
|
21005
21556
|
}
|
|
21557
|
+
return false;
|
|
21006
21558
|
});
|
|
21007
21559
|
const settle = settleThroughStore(
|
|
21008
21560
|
found.map((one) => one.outcome),
|
|
@@ -21775,7 +22327,8 @@ function resolveCalleeSummary(call, index) {
|
|
|
21775
22327
|
|
|
21776
22328
|
// src/subUnitContext.ts
|
|
21777
22329
|
import {
|
|
21778
|
-
Node as Node81
|
|
22330
|
+
Node as Node81,
|
|
22331
|
+
SyntaxKind as SyntaxKind30
|
|
21779
22332
|
} from "ts-morph";
|
|
21780
22333
|
function createTsSubUnitContext() {
|
|
21781
22334
|
return {
|
|
@@ -21787,24 +22340,19 @@ function createTsSubUnitContext() {
|
|
|
21787
22340
|
readArrayLiteralText
|
|
21788
22341
|
};
|
|
21789
22342
|
}
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
21794
|
-
|
|
21795
|
-
}
|
|
21796
|
-
return false;
|
|
21797
|
-
};
|
|
21798
|
-
}
|
|
22343
|
+
var JSX_ELEMENTS_AND_STOPS = withDescentStops(
|
|
22344
|
+
SyntaxKind30.JsxOpeningElement,
|
|
22345
|
+
SyntaxKind30.JsxSelfClosingElement
|
|
22346
|
+
);
|
|
22347
|
+
var CALLS_AND_STOPS2 = withDescentStops(SyntaxKind30.CallExpression);
|
|
21799
22348
|
function findJsxAttributes(parent) {
|
|
21800
22349
|
const out = [];
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
return;
|
|
22350
|
+
forEachDescendantOfKinds(parent, JSX_ELEMENTS_AND_STOPS, (node) => {
|
|
22351
|
+
if (isDescentStop(node, parent)) {
|
|
22352
|
+
return true;
|
|
21805
22353
|
}
|
|
21806
22354
|
if (!Node81.isJsxOpeningElement(node) && !Node81.isJsxSelfClosingElement(node)) {
|
|
21807
|
-
return;
|
|
22355
|
+
return false;
|
|
21808
22356
|
}
|
|
21809
22357
|
const tag = node.getTagNameNode().getText();
|
|
21810
22358
|
for (const attr of node.getAttributes()) {
|
|
@@ -21827,23 +22375,24 @@ function findJsxAttributes(parent) {
|
|
|
21827
22375
|
valueExpression
|
|
21828
22376
|
});
|
|
21829
22377
|
}
|
|
22378
|
+
return false;
|
|
21830
22379
|
});
|
|
21831
22380
|
return out;
|
|
21832
22381
|
}
|
|
21833
22382
|
function findCallExpressionsByName(parent, name) {
|
|
21834
22383
|
const out = [];
|
|
21835
|
-
|
|
21836
|
-
|
|
21837
|
-
|
|
21838
|
-
return;
|
|
22384
|
+
forEachDescendantOfKinds(parent, CALLS_AND_STOPS2, (node) => {
|
|
22385
|
+
if (isDescentStop(node, parent)) {
|
|
22386
|
+
return true;
|
|
21839
22387
|
}
|
|
21840
22388
|
if (!Node81.isCallExpression(node)) {
|
|
21841
|
-
return;
|
|
22389
|
+
return false;
|
|
21842
22390
|
}
|
|
21843
22391
|
const callee = node.getExpression();
|
|
21844
22392
|
if (Node81.isIdentifier(callee) && callee.getText() === name) {
|
|
21845
22393
|
out.push(node);
|
|
21846
22394
|
}
|
|
22395
|
+
return false;
|
|
21847
22396
|
});
|
|
21848
22397
|
return out;
|
|
21849
22398
|
}
|
|
@@ -22494,17 +23043,16 @@ function extractParameters(func, inputMapping) {
|
|
|
22494
23043
|
}
|
|
22495
23044
|
function extractDependencyCalls(func, barriers = NO_BARRIERS) {
|
|
22496
23045
|
const results = [];
|
|
22497
|
-
func
|
|
23046
|
+
forEachDescendantOfKinds(func, DECLARATIONS_AND_STOPS, (node) => {
|
|
22498
23047
|
if (isDescentStop(node, func, barriers)) {
|
|
22499
|
-
|
|
22500
|
-
return;
|
|
23048
|
+
return true;
|
|
22501
23049
|
}
|
|
22502
23050
|
if (!Node82.isVariableDeclaration(node)) {
|
|
22503
|
-
return;
|
|
23051
|
+
return false;
|
|
22504
23052
|
}
|
|
22505
23053
|
const init = node.getInitializer();
|
|
22506
23054
|
if (init === void 0) {
|
|
22507
|
-
return;
|
|
23055
|
+
return false;
|
|
22508
23056
|
}
|
|
22509
23057
|
let isAsync = false;
|
|
22510
23058
|
let callExpr = init;
|
|
@@ -22513,7 +23061,7 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
|
|
|
22513
23061
|
callExpr = init.getExpression();
|
|
22514
23062
|
}
|
|
22515
23063
|
if (!Node82.isCallExpression(callExpr)) {
|
|
22516
|
-
return;
|
|
23064
|
+
return false;
|
|
22517
23065
|
}
|
|
22518
23066
|
const calleeName = callExpr.getExpression().getText();
|
|
22519
23067
|
const nameNode = node.getNameNode();
|
|
@@ -22531,9 +23079,11 @@ function extractDependencyCalls(func, barriers = NO_BARRIERS) {
|
|
|
22531
23079
|
end: endLineOf(locationNode)
|
|
22532
23080
|
}
|
|
22533
23081
|
});
|
|
23082
|
+
return false;
|
|
22534
23083
|
});
|
|
22535
23084
|
return results;
|
|
22536
23085
|
}
|
|
23086
|
+
var DECLARATIONS_AND_STOPS = withDescentStops(SyntaxKind31.VariableDeclaration);
|
|
22537
23087
|
function resolveResponseProperties(branches, calleeText, semantics) {
|
|
22538
23088
|
return branches.map((branch) => ({
|
|
22539
23089
|
...branch,
|
|
@@ -22994,13 +23544,15 @@ function resolveContractField(callSite, pack, field, resolution) {
|
|
|
22994
23544
|
return value ?? void 0;
|
|
22995
23545
|
}
|
|
22996
23546
|
function reportingTo(recognize, tally) {
|
|
22997
|
-
|
|
23547
|
+
const reporting = (node, ctx) => {
|
|
22998
23548
|
const effects = recognize(node, ctx);
|
|
22999
23549
|
if (effects !== null) {
|
|
23000
23550
|
tally.effectsRecognized += effects.length;
|
|
23001
23551
|
}
|
|
23002
23552
|
return effects;
|
|
23003
23553
|
};
|
|
23554
|
+
noteRecognizerTally(reporting, tally);
|
|
23555
|
+
return reporting;
|
|
23004
23556
|
}
|
|
23005
23557
|
function collectInvocationRecognizers(frameworks, tallies) {
|
|
23006
23558
|
const out = [];
|
|
@@ -23480,7 +24032,10 @@ function fileImporting(project, modulePrefix) {
|
|
|
23480
24032
|
if (sourceFile.isInNodeModules() || sourceFile.isDeclarationFile()) {
|
|
23481
24033
|
continue;
|
|
23482
24034
|
}
|
|
23483
|
-
for (const imp of
|
|
24035
|
+
for (const imp of statementsOfKind(
|
|
24036
|
+
sourceFile,
|
|
24037
|
+
SyntaxKind31.ImportDeclaration
|
|
24038
|
+
)) {
|
|
23484
24039
|
if (imp.getModuleSpecifierValue().startsWith(modulePrefix)) {
|
|
23485
24040
|
return sourceFile.getFilePath();
|
|
23486
24041
|
}
|
|
@@ -23530,10 +24085,16 @@ function internalImportsOf(project, file) {
|
|
|
23530
24085
|
targets.add(target.getFilePath());
|
|
23531
24086
|
}
|
|
23532
24087
|
};
|
|
23533
|
-
for (const imp of
|
|
24088
|
+
for (const imp of statementsOfKind(
|
|
24089
|
+
sourceFile,
|
|
24090
|
+
SyntaxKind31.ImportDeclaration
|
|
24091
|
+
)) {
|
|
23534
24092
|
record2(imp.getModuleSpecifierSourceFile());
|
|
23535
24093
|
}
|
|
23536
|
-
for (const exp of
|
|
24094
|
+
for (const exp of statementsOfKind(
|
|
24095
|
+
sourceFile,
|
|
24096
|
+
SyntaxKind31.ExportDeclaration
|
|
24097
|
+
)) {
|
|
23537
24098
|
record2(exp.getModuleSpecifierSourceFile());
|
|
23538
24099
|
}
|
|
23539
24100
|
return [...targets].sort();
|
|
@@ -24751,7 +25312,7 @@ function buildSubUnitSummary(subUnit, parent, parentFunc, recognizers, everyUnit
|
|
|
24751
25312
|
|
|
24752
25313
|
// src/facts/why.ts
|
|
24753
25314
|
import path16 from "path";
|
|
24754
|
-
import { Node as Node83, Project as Project3, SyntaxKind as
|
|
25315
|
+
import { Node as Node83, Project as Project3, SyntaxKind as SyntaxKind32 } from "ts-morph";
|
|
24755
25316
|
import { explainResolutionProof, renderExplanation } from "@suss/resolution";
|
|
24756
25317
|
var TypeScriptWhySession = class {
|
|
24757
25318
|
project;
|
|
@@ -24793,7 +25354,7 @@ var TypeScriptWhySession = class {
|
|
|
24793
25354
|
return null;
|
|
24794
25355
|
}
|
|
24795
25356
|
for (const call of sourceFile.getDescendantsOfKind(
|
|
24796
|
-
|
|
25357
|
+
SyntaxKind32.CallExpression
|
|
24797
25358
|
)) {
|
|
24798
25359
|
const line = call.getStartLineNumber();
|
|
24799
25360
|
if (line < startLine || line > endLine) {
|
|
@@ -24929,7 +25490,7 @@ function stubEvidence(options) {
|
|
|
24929
25490
|
}
|
|
24930
25491
|
|
|
24931
25492
|
// src/walk/defaulted.ts
|
|
24932
|
-
import { Node as Node84, SyntaxKind as
|
|
25493
|
+
import { Node as Node84, SyntaxKind as SyntaxKind33, ts as ts11 } from "ts-morph";
|
|
24933
25494
|
function isDefaultedAt(node) {
|
|
24934
25495
|
if (!Node84.isBindingElement(node)) {
|
|
24935
25496
|
const read2 = climbSyntax(node);
|
|
@@ -25219,7 +25780,7 @@ function comparedValue(operand2, other, loose) {
|
|
|
25219
25780
|
return missing ? operand2 : null;
|
|
25220
25781
|
}
|
|
25221
25782
|
function negatedOperand(node) {
|
|
25222
|
-
if (Node84.isPrefixUnaryExpression(node) && node.getOperatorToken() ===
|
|
25783
|
+
if (Node84.isPrefixUnaryExpression(node) && node.getOperatorToken() === SyntaxKind33.ExclamationToken) {
|
|
25223
25784
|
return node.getOperand();
|
|
25224
25785
|
}
|
|
25225
25786
|
return null;
|
|
@@ -25261,9 +25822,20 @@ function declarationInitializedBy(node) {
|
|
|
25261
25822
|
return null;
|
|
25262
25823
|
}
|
|
25263
25824
|
function usesOf(local) {
|
|
25264
|
-
|
|
25265
|
-
|
|
25266
|
-
|
|
25825
|
+
const name = local.name.getText();
|
|
25826
|
+
const file = local.scope.getSourceFile();
|
|
25827
|
+
const uses = [];
|
|
25828
|
+
const visit = (node) => {
|
|
25829
|
+
if (ts11.isIdentifier(node) && node.text === name) {
|
|
25830
|
+
const found = file.getDescendantAtPos(node.getStart(file.compilerNode));
|
|
25831
|
+
if (found !== void 0 && Node84.isIdentifier(found) && found !== local.name && refersTo(found, local)) {
|
|
25832
|
+
uses.push(found);
|
|
25833
|
+
}
|
|
25834
|
+
}
|
|
25835
|
+
ts11.forEachChild(node, visit);
|
|
25836
|
+
};
|
|
25837
|
+
ts11.forEachChild(local.scope.compilerNode, visit);
|
|
25838
|
+
return uses;
|
|
25267
25839
|
}
|
|
25268
25840
|
export {
|
|
25269
25841
|
ADAPTER_VERSION,
|