@suss/adapter-typescript 0.21.1 → 0.22.1
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/README.md +1 -35
- package/dist/index.cjs +934 -1508
- package/dist/index.d.cts +74 -414
- package/dist/index.d.ts +74 -414
- package/dist/index.js +868 -1424
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,209 +1,11 @@
|
|
|
1
1
|
import { SourceFile, Node, FunctionDeclaration, FunctionExpression, ArrowFunction, MethodDeclaration, CallExpression, PropertyAccessExpression, TaggedTemplateExpression, Project, ImportDeclaration, Symbol, Expression, NewExpression, Identifier } from 'ts-morph';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { TransparentWrapper, RawCondition, DiscoveryPattern, TerminalPattern, InputMappingPattern, EffectArg, CallOps, LanguageAdapter, PatternPack, ExtractorOptions, TimingReport, CacheDiagnostic, ExtractionReport, InvocationRecognizer, AccessRecognizer, RawCodeStructure, RawTerminal, RawBranch, configuredCallOption, RawDeclaredContract, ContractPattern, AstCapableOps, ResponsePropertyMapping } from '@suss/extractor';
|
|
3
|
+
export { EmptyStage, ExtractionReport, PackFunnel, Timer, TimingReport, computeContentHash } from '@suss/extractor';
|
|
4
|
+
import { MessageBusSemantics, DeployableUnit, UnfollowedCall, BehavioralSummary, BoundaryBinding, Predicate, TypeShape, ValueRef } from '@suss/behavioral-ir';
|
|
4
5
|
import { z } from 'zod';
|
|
6
|
+
import { ExplainStats, WhyExplained, ValueLocation } from '@suss/resolution';
|
|
7
|
+
export { ExplainStats, ValueLocation, WhyExplained } from '@suss/resolution';
|
|
5
8
|
import { Proof, Atom } from '@suss/datalog';
|
|
6
|
-
import { ResolutionExplanation } from '@suss/resolution';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* cache.ts: the on-disk extraction cache.
|
|
10
|
-
*
|
|
11
|
-
* A run reuses the previous one's summaries whole when nothing
|
|
12
|
-
* changed, and per file when some files did. The entry directory is
|
|
13
|
-
* named after everything that has to agree before any reuse is sound:
|
|
14
|
-
* schema version, adapter version and code hash, pack versions, the
|
|
15
|
-
* extraction config stamp and the tsconfig path. Inside it, the
|
|
16
|
-
* manifest records a stamp and content hash per file, each summary's
|
|
17
|
-
* owning files, and per owning file the other files its walk read, so
|
|
18
|
-
* a change to any of those re-extracts the owner instead of serving a
|
|
19
|
-
* stale answer. The full design, including what per-file reuse can
|
|
20
|
-
* and cannot promise, is in this package's README.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/** Reported by `lookup`: what the cache decided, and why. */
|
|
24
|
-
interface CacheDiagnostic {
|
|
25
|
-
kind: "hit" | "miss" | "partial";
|
|
26
|
-
/**
|
|
27
|
-
* Reason the lookup missed (only set when kind === "miss").
|
|
28
|
-
* `key-changed` means the cache directory contains entries, but none
|
|
29
|
-
* under this run's schema, adapter, packs and tsconfig path.
|
|
30
|
-
* `files-changed` means the include set is not the one the entry
|
|
31
|
-
* was written from.
|
|
32
|
-
*/
|
|
33
|
-
missReason?: "no-manifest" | "key-changed" | "tsconfig-changed" | "files-changed";
|
|
34
|
-
/** Set when kind === "partial". */
|
|
35
|
-
partial?: {
|
|
36
|
-
filesChanged: number;
|
|
37
|
-
filesRemoved: number;
|
|
38
|
-
rootsReused: number;
|
|
39
|
-
rootsReextracted: number;
|
|
40
|
-
rootsDeclined: number;
|
|
41
|
-
summariesReused: number;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Result of a cache lookup. A hit gives back the whole summary set; a miss
|
|
46
|
-
* says why, so a caller can render the reason.
|
|
47
|
-
*/
|
|
48
|
-
type CacheLookup = {
|
|
49
|
-
kind: "hit";
|
|
50
|
-
summaries: BehavioralSummary[];
|
|
51
|
-
diagnostic: CacheDiagnostic;
|
|
52
|
-
} | {
|
|
53
|
-
kind: "miss";
|
|
54
|
-
diagnostic: CacheDiagnostic;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
/** One pack's path through the funnel. */
|
|
58
|
-
interface PackFunnel {
|
|
59
|
-
pack: string;
|
|
60
|
-
/**
|
|
61
|
-
* What the pack calls this build of itself, or null when it declares
|
|
62
|
-
* nothing. The cache keys on it, so a pack that never changes its
|
|
63
|
-
* stamp can serve a later run with an earlier build's results.
|
|
64
|
-
*/
|
|
65
|
-
version: string | null;
|
|
66
|
-
/**
|
|
67
|
-
* Whether the pack looks for units of its own at all. A pack made only
|
|
68
|
-
* of recognisers contributes effects to units other packs found, so it
|
|
69
|
-
* always discovers nothing, and that tells you nothing about whether
|
|
70
|
-
* it is working.
|
|
71
|
-
*/
|
|
72
|
-
discovers: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Whether the pack has any recognisers. Those fire inside units other
|
|
75
|
-
* packs discovered, so a pack made only of them contributes effects
|
|
76
|
-
* and never a summary.
|
|
77
|
-
*/
|
|
78
|
-
recognizes: boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Import specifiers that make a file relevant to this pack. Empty
|
|
81
|
-
* for an ungated pack, which walks every file.
|
|
82
|
-
*/
|
|
83
|
-
gates: string[];
|
|
84
|
-
/**
|
|
85
|
-
* Gate specifiers that do not resolve from the tsconfig. Non-empty
|
|
86
|
-
* here usually means the target project's dependencies are not
|
|
87
|
-
* installed, which stops symbol-resolution packs while leaving
|
|
88
|
-
* textual-gate packs working, so the run half-succeeds in a way
|
|
89
|
-
* nothing else surfaces.
|
|
90
|
-
*/
|
|
91
|
-
unresolvedGates: string[];
|
|
92
|
-
/** Files the pre-filter selected for this pack. */
|
|
93
|
-
candidateFiles: number;
|
|
94
|
-
/** Units discovered across those files. */
|
|
95
|
-
unitsDiscovered: number;
|
|
96
|
-
/**
|
|
97
|
-
* Unit bodies any pack walked in the files this pack's gate selected.
|
|
98
|
-
*
|
|
99
|
-
* This is what a recogniser pack had the chance to fire on. Its own
|
|
100
|
-
* discovery count tells you nothing, since it discovers nothing by
|
|
101
|
-
* design, and neither does its candidate-file count, because a
|
|
102
|
-
* recogniser only runs where some pack found a unit to walk.
|
|
103
|
-
*/
|
|
104
|
-
unitsInGatedFiles: number;
|
|
105
|
-
/** Effects this pack's recognisers returned. */
|
|
106
|
-
effectsRecognized: number;
|
|
107
|
-
/**
|
|
108
|
-
* Units this pack kept. A unit an earlier pack already claimed is
|
|
109
|
-
* dropped here, so a pack can discover plenty and keep none when it
|
|
110
|
-
* comes after a pack that recognises the same code.
|
|
111
|
-
*/
|
|
112
|
-
unitsClaimed: number;
|
|
113
|
-
/**
|
|
114
|
-
* Units this pack discovered twice over. Cross-pack dedup is the
|
|
115
|
-
* point of the claim set, but a pack colliding with itself means its
|
|
116
|
-
* own discovery patterns overlap and one of the two is being thrown
|
|
117
|
-
* away without anybody deciding which.
|
|
118
|
-
*/
|
|
119
|
-
selfCollisions: number;
|
|
120
|
-
/** Summaries built from those units. */
|
|
121
|
-
summariesProduced: number;
|
|
122
|
-
/** Summaries in the finished run that credit this pack for finding them. */
|
|
123
|
-
summariesBound: number;
|
|
124
|
-
/**
|
|
125
|
-
* Bound summaries on the provider side of their boundary.
|
|
126
|
-
*
|
|
127
|
-
* Kept apart from the count below because a provider that produced
|
|
128
|
-
* no transitions is a different problem from a client that produced
|
|
129
|
-
* none.
|
|
130
|
-
*/
|
|
131
|
-
providerSummaries: number;
|
|
132
|
-
/**
|
|
133
|
-
* Summaries with at least one transition, of any role. A provider's
|
|
134
|
-
* transitions say what it does with a request and a client's say what
|
|
135
|
-
* it expects back, so a pack whose summaries have none has bound
|
|
136
|
-
* something and described nothing either way.
|
|
137
|
-
*/
|
|
138
|
-
summariesWithBehavior: number;
|
|
139
|
-
/**
|
|
140
|
-
* Where one of this pack's hooks threw. Every count above is a floor
|
|
141
|
-
* while this is non-empty.
|
|
142
|
-
*/
|
|
143
|
-
failures: PackFailure[];
|
|
144
|
-
/**
|
|
145
|
-
* Registration helpers this pack's config asked for that no call in
|
|
146
|
-
* the run matched. The helper belongs to the project, so a spelling
|
|
147
|
-
* that matches nothing is a config mistake with no other symptom: the
|
|
148
|
-
* routes go missing and every count reads the same as a project
|
|
149
|
-
* without them.
|
|
150
|
-
*/
|
|
151
|
-
helpersUnmatched: string[];
|
|
152
|
-
/**
|
|
153
|
-
* What the pack wrote as data rather than as code, or null for a pack
|
|
154
|
-
* written as a hand-rolled walk. This is the one thing in the funnel
|
|
155
|
-
* that no run produces: it is the pack's own shape, and it is here so
|
|
156
|
-
* the migration onto the declared surface can be measured.
|
|
157
|
-
*/
|
|
158
|
-
declarations: PackDeclarations | null;
|
|
159
|
-
}
|
|
160
|
-
interface ExtractionReport {
|
|
161
|
-
/** Files in the tsconfig include set, or null when the caller supplied a Project. */
|
|
162
|
-
filesInProject: number | null;
|
|
163
|
-
/** Files the bootstrap loaded and the extract walked. */
|
|
164
|
-
filesWalked: number;
|
|
165
|
-
packs: PackFunnel[];
|
|
166
|
-
summaries: number;
|
|
167
|
-
/**
|
|
168
|
-
* Files whose exports the checker could not follow, so the run read
|
|
169
|
-
* them as exporting nothing.
|
|
170
|
-
*
|
|
171
|
-
* Without this the artifact cannot tell the two apart: a module whose
|
|
172
|
-
* barrel chain outran the call stack and a module that really does
|
|
173
|
-
* export nothing both produce no summaries and exit 0.
|
|
174
|
-
* Anything reachable only through these files is missing, and every
|
|
175
|
-
* count below is a floor while this is non-empty.
|
|
176
|
-
*/
|
|
177
|
-
filesWithUnreadableExports: string[];
|
|
178
|
-
/**
|
|
179
|
-
* The first stage whose count was zero, when the run produced
|
|
180
|
-
* nothing. Null when the run produced summaries.
|
|
181
|
-
*/
|
|
182
|
-
emptyStage: EmptyStage | null;
|
|
183
|
-
/**
|
|
184
|
-
* Reassigned names the run stated nothing for, because control flow
|
|
185
|
-
* decides which write a reader sees. Each is a value resolution the
|
|
186
|
-
* facts decline; the count across a large corpus says whether scoped
|
|
187
|
-
* reaching definitions is worth writing.
|
|
188
|
-
*/
|
|
189
|
-
reassignedNamesUnstated: number;
|
|
190
|
-
}
|
|
191
|
-
type EmptyStage = "tsconfig" | "gateResolution" | "candidateFiles" | "discovery" | "assembly";
|
|
192
|
-
/**
|
|
193
|
-
* A pack's hook throwing on one file.
|
|
194
|
-
*
|
|
195
|
-
* The run continues with the other files, so every count for that pack
|
|
196
|
-
* afterwards is a floor rather than a total. Somebody reading those
|
|
197
|
-
* counts has to be told, or a pack that broke looks the same as a pack
|
|
198
|
-
* that looked and found nothing.
|
|
199
|
-
*/
|
|
200
|
-
interface PackFailure {
|
|
201
|
-
/** The hook that threw, called what a pack author would call it. */
|
|
202
|
-
hook: string;
|
|
203
|
-
/** The file the pack was reading. */
|
|
204
|
-
file: string;
|
|
205
|
-
message: string;
|
|
206
|
-
}
|
|
207
9
|
|
|
208
10
|
/** One question: do these files reach any of these packages. */
|
|
209
11
|
interface FileSetQuery {
|
|
@@ -222,8 +24,8 @@ interface FileSetQuery {
|
|
|
222
24
|
* files reach any of a set of packages, which a per-file import check
|
|
223
25
|
* misses whenever a local barrel re-exports the SDK.
|
|
224
26
|
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
27
|
+
* A query extracts the modules the rules ask for while answering it,
|
|
28
|
+
* so the files a question reads do not depend on what was asked before.
|
|
227
29
|
*/
|
|
228
30
|
|
|
229
31
|
interface ExplainCallableOptions {
|
|
@@ -232,14 +34,6 @@ interface ExplainCallableOptions {
|
|
|
232
34
|
/** How many derived nodes deep the proof walk goes; see `proofOf`. */
|
|
233
35
|
maxDepth?: number;
|
|
234
36
|
}
|
|
235
|
-
/** What one witness re-evaluation cost, said rather than hidden. */
|
|
236
|
-
interface ExplainStats {
|
|
237
|
-
/** Facts the demand walk had extracted, which the proof pass reran. */
|
|
238
|
-
baseFacts: number;
|
|
239
|
-
/** Facts the exhaustive pass derived on top of those. */
|
|
240
|
-
derivedFacts: number;
|
|
241
|
-
evaluateMs: number;
|
|
242
|
-
}
|
|
243
37
|
interface ExplainedResolution {
|
|
244
38
|
/** The node the value comes down to. */
|
|
245
39
|
target: Node;
|
|
@@ -263,7 +57,7 @@ declare class ResolutionStore {
|
|
|
263
57
|
* extraction elsewhere cannot change an entry.
|
|
264
58
|
*/
|
|
265
59
|
private readonly exportTables;
|
|
266
|
-
/** Files the most recent
|
|
60
|
+
/** Files the most recent query read, for the memo to keep. */
|
|
267
61
|
private lastQueryWalked;
|
|
268
62
|
private readonly declarations;
|
|
269
63
|
private readonly graph;
|
|
@@ -286,10 +80,10 @@ declare class ResolutionStore {
|
|
|
286
80
|
resolveCallableSources(value: Node, alsoFrom?: SourceFile): Node[];
|
|
287
81
|
/**
|
|
288
82
|
* The witness proof behind `resolveCallable`'s answer. Resolves the
|
|
289
|
-
* value first, which
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
83
|
+
* value first, which extracts the files the question demands, then
|
|
84
|
+
* re-evaluates the rules over those base facts under the witness
|
|
85
|
+
* algebra and rebuilds the proof of the answer. Null when the value
|
|
86
|
+
* does not resolve at all.
|
|
293
87
|
*/
|
|
294
88
|
explainCallable(value: Node, options?: ExplainCallableOptions): ExplainedResolution | null;
|
|
295
89
|
resolveObject(value: Node): Node | null;
|
|
@@ -313,10 +107,8 @@ declare class ResolutionStore {
|
|
|
313
107
|
*/
|
|
314
108
|
subjectCandidateCountOf(value: Node, importModule: string, importName: string): number;
|
|
315
109
|
/**
|
|
316
|
-
* The single-answer policy over the written-value
|
|
317
|
-
* origin check on the one candidate.
|
|
318
|
-
* is settled refusal rather than a reason to widen: its own file's
|
|
319
|
-
* import facts are already in, and more files only add candidates.
|
|
110
|
+
* The single-answer policy over the written-value chain, then the
|
|
111
|
+
* origin check on the one candidate.
|
|
320
112
|
*/
|
|
321
113
|
private lookupSubjectConstruction;
|
|
322
114
|
/**
|
|
@@ -348,8 +140,8 @@ declare class ResolutionStore {
|
|
|
348
140
|
path: string[];
|
|
349
141
|
}>;
|
|
350
142
|
/**
|
|
351
|
-
* The batched form: one demand set, one derivation, one
|
|
352
|
-
*
|
|
143
|
+
* The batched form: one demand set, one derivation, one round of
|
|
144
|
+
* extraction shared by every value. A discovery pass asks about every
|
|
353
145
|
* callee in a file, and per-value queries would re-pay demand
|
|
354
146
|
* clearing and re-derivation once per call site.
|
|
355
147
|
*/
|
|
@@ -365,14 +157,22 @@ declare class ResolutionStore {
|
|
|
365
157
|
*/
|
|
366
158
|
private sharedDeclarationFor;
|
|
367
159
|
private lookupImportOrigins;
|
|
160
|
+
private lookupImportedNames;
|
|
161
|
+
private askAbout;
|
|
368
162
|
/**
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
163
|
+
* Extract the seed files, then every module the rules ask for, until
|
|
164
|
+
* they ask for nothing new. The files a question reads are then fixed
|
|
165
|
+
* by the question alone, so its answer does not depend on what an
|
|
166
|
+
* earlier question left in the store.
|
|
372
167
|
*/
|
|
373
|
-
private
|
|
374
|
-
|
|
375
|
-
|
|
168
|
+
private extractDemanded;
|
|
169
|
+
/**
|
|
170
|
+
* Module keys the rules are waiting on. Demand facts are cleared
|
|
171
|
+
* between queries, so the demand relations contain this query's
|
|
172
|
+
* alone; the unrestricted program has none, and follows the imports
|
|
173
|
+
* of the files read this round instead.
|
|
174
|
+
*/
|
|
175
|
+
private demandedModules;
|
|
376
176
|
/**
|
|
377
177
|
* The question and the chain that settled it are dropped. The files
|
|
378
178
|
* the query extracted stay, since the next query reads the same facts.
|
|
@@ -380,6 +180,13 @@ declare class ResolutionStore {
|
|
|
380
180
|
*/
|
|
381
181
|
private forgetQuery;
|
|
382
182
|
private wantValue;
|
|
183
|
+
private wantExportsOf;
|
|
184
|
+
/**
|
|
185
|
+
* Discovery walks the table in order, and the rounds derive it in
|
|
186
|
+
* the order files arrived. Deriving it again from the demand alone,
|
|
187
|
+
* over the loaded closure, orders it by the file's own statements.
|
|
188
|
+
*/
|
|
189
|
+
private rederiveExportsOf;
|
|
383
190
|
/**
|
|
384
191
|
* File extraction only reaches values hanging off exports, and a query
|
|
385
192
|
* can be rooted anywhere, so the queried value gets its own facts.
|
|
@@ -398,10 +205,10 @@ declare class ResolutionStore {
|
|
|
398
205
|
/**
|
|
399
206
|
* Read these files' facts now, before anything asks a question.
|
|
400
207
|
*
|
|
401
|
-
* A query
|
|
402
|
-
*
|
|
208
|
+
* A query follows the imports of the file it starts in, which is
|
|
209
|
+
* where a value's definition is. What a caller passed is the other
|
|
403
210
|
* direction, so a question about a parameter is answered only by
|
|
404
|
-
* files the
|
|
211
|
+
* files the query never reaches on its own.
|
|
405
212
|
*/
|
|
406
213
|
extractFiles(sourceFiles: Iterable<SourceFile>): void;
|
|
407
214
|
/**
|
|
@@ -411,28 +218,23 @@ declare class ResolutionStore {
|
|
|
411
218
|
*/
|
|
412
219
|
filesImportingTransitively(fileSets: ReadonlyArray<FileSetQuery>): ReadonlyArray<ReadonlySet<SourceFile>>;
|
|
413
220
|
/**
|
|
414
|
-
* The calls behind a receiver that `matches` accepts
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* cannot rank a nearer call above a farther one.
|
|
221
|
+
* The calls behind a receiver that `matches` accepts. The caller
|
|
222
|
+
* applies the single-answer policy to the set; the resolution
|
|
223
|
+
* README's anchor section says why the rules cannot rank a nearer
|
|
224
|
+
* call above a farther one.
|
|
419
225
|
*/
|
|
420
226
|
anchorCallsOf(value: Node, matches: (call: Node) => boolean): Node[];
|
|
421
227
|
/**
|
|
422
228
|
* Every name a module exports and the values behind each, with
|
|
423
|
-
* re-export chains flattened by the rules. The
|
|
229
|
+
* re-export chains flattened by the rules. The demand follows
|
|
424
230
|
* re-export targets only, so a barrel of barrels extracts its own
|
|
425
231
|
* chain and nothing beside it, to any depth.
|
|
426
232
|
*/
|
|
427
233
|
exportsOf(sourceFile: SourceFile): Map<string, Node[]>;
|
|
428
234
|
private collectExports;
|
|
429
|
-
/** Module keys this file re-exports from, read off its own facts. */
|
|
430
|
-
private reExportTargetsOf;
|
|
431
235
|
/**
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
* single-answer policy stays with the callers: picking one of two
|
|
435
|
-
* would make the result depend on the order the facts came in.
|
|
236
|
+
* The single-answer policy stays with the callers: a value with two
|
|
237
|
+
* sources is something to say at the site, not something to pick from.
|
|
436
238
|
*/
|
|
437
239
|
private lookupSources;
|
|
438
240
|
private derive;
|
|
@@ -454,44 +256,6 @@ type FunctionRoot = FunctionDeclaration | FunctionExpression | ArrowFunction | M
|
|
|
454
256
|
*/
|
|
455
257
|
declare function collectAncestorBranches(terminalNode: Node, functionRoot: FunctionRoot): RawCondition[];
|
|
456
258
|
|
|
457
|
-
/**
|
|
458
|
-
* unfollowedCall.ts: naming the calls the reachable closure stops at.
|
|
459
|
-
*
|
|
460
|
-
* The closure follows a call by resolving its callee to a function with a
|
|
461
|
-
* body. When that fails the edge is dropped, and a unit whose body is full
|
|
462
|
-
* of dropped edges produces the same empty summary as a unit that does
|
|
463
|
-
* nothing. This module says which kind of stop a call site is, and which
|
|
464
|
-
* kinds are worth leaving a gap for.
|
|
465
|
-
*
|
|
466
|
-
* The README beside this file explains where that line is drawn, and why
|
|
467
|
-
* a call into a dependency stays on the other side of it.
|
|
468
|
-
*/
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Why the walk stopped.
|
|
472
|
-
*
|
|
473
|
-
* `noBody` states a shape and nothing else: a method on an interface, an
|
|
474
|
-
* abstract method, an ambient declaration. `unsettledValue` is declared
|
|
475
|
-
* as something other than a function, with something in it that could
|
|
476
|
-
* not be read. `multipleSources` reaches two different functions, so no
|
|
477
|
-
* single body can be followed. `outsideRun` is a declaration in a
|
|
478
|
-
* dependency, whose source this run never read. `noDeclaration` is a
|
|
479
|
-
* callee nothing declares, which is what a call on an untyped value
|
|
480
|
-
* comes to. `callerSupplied` is a parameter of the function being
|
|
481
|
-
* scanned, so the call runs whatever its caller handed in.
|
|
482
|
-
* `multipleReceivers` is a registration whose receiver comes down to
|
|
483
|
-
* more than one thing, so nothing says which one it registers on.
|
|
484
|
-
*/
|
|
485
|
-
type UnfollowedReason = "noBody" | "unsettledValue" | "multipleSources" | "outsideRun" | "noDeclaration" | "callerSupplied" | "multipleReceivers";
|
|
486
|
-
/** One call the walk met and could not follow. */
|
|
487
|
-
interface UnfollowedCall {
|
|
488
|
-
/** The callee as the source writes it, `this.dao.getEditions` say. */
|
|
489
|
-
readonly callee: string;
|
|
490
|
-
readonly reason: UnfollowedReason;
|
|
491
|
-
/** How many things the walk reached where it needed one. */
|
|
492
|
-
readonly candidates?: number;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
259
|
interface ClientCallSite {
|
|
496
260
|
callExpression: CallExpression;
|
|
497
261
|
/** Method name on the client object (e.g. "getUser"), null for bare calls like fetch() */
|
|
@@ -717,23 +481,6 @@ interface ExpandedRegistrations {
|
|
|
717
481
|
*/
|
|
718
482
|
declare function discoverUnits(sourceFile: SourceFile, patterns: DiscoveryPattern[], resolution?: ResolutionStore, mountPrefixes?: MountPrefixIndex, expandedElsewhere?: ExpandedRegistrations): DiscoveredUnit[];
|
|
719
483
|
|
|
720
|
-
interface TimingReport {
|
|
721
|
-
totalMs: number;
|
|
722
|
-
phases: Array<{
|
|
723
|
-
label: string;
|
|
724
|
-
durationMs: number;
|
|
725
|
-
calls: number;
|
|
726
|
-
}>;
|
|
727
|
-
}
|
|
728
|
-
interface Timer {
|
|
729
|
-
/** Run `fn`, accumulate wall time under `label`, return its result. */
|
|
730
|
-
time<T>(label: string, fn: () => T): T;
|
|
731
|
-
/** Async variant: same accumulation rule. */
|
|
732
|
-
timeAsync<T>(label: string, fn: () => Promise<T>): Promise<T>;
|
|
733
|
-
/** Snapshot of all accumulated phases, ordered by total time descending. */
|
|
734
|
-
report(): TimingReport;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
484
|
/**
|
|
738
485
|
* Nested function nodes a pack claimed as sub-units. The unit-body
|
|
739
486
|
* walkers stop at these so the sub-unit's behavior isn't double-counted
|
|
@@ -741,6 +488,21 @@ interface Timer {
|
|
|
741
488
|
*/
|
|
742
489
|
type DescentBarriers = ReadonlySet<Node>;
|
|
743
490
|
|
|
491
|
+
/**
|
|
492
|
+
* invocationEffects.ts: capture every call in a unit's body as an
|
|
493
|
+
* `invocation` RawEffect, wherever the call is written: a statement of
|
|
494
|
+
* its own, an argument, an element of a literal, an arm of a ternary,
|
|
495
|
+
* the receiver of a method chain. Which calls a summary keeps is
|
|
496
|
+
* decided in assembly by node identity, so no position needs a rule of
|
|
497
|
+
* its own here.
|
|
498
|
+
*
|
|
499
|
+
* The walk descends into nested arrows and function expressions, since
|
|
500
|
+
* their calls are behavior of the enclosing unit, and stops at named
|
|
501
|
+
* nested declarations, pack-declared sub-unit boundaries and
|
|
502
|
+
* decorators. The README beside this file says how the effects are
|
|
503
|
+
* ordered and what `async` means.
|
|
504
|
+
*/
|
|
505
|
+
|
|
744
506
|
/**
|
|
745
507
|
* Context handed to TypeScript-adapter access recognizers: sister
|
|
746
508
|
* to TsInvocationRecognizerContext but for property-access nodes.
|
|
@@ -1193,23 +955,7 @@ interface WhySessionOptions {
|
|
|
1193
955
|
/** The project root, which paths in every answer come out relative to. */
|
|
1194
956
|
dir: string;
|
|
1195
957
|
}
|
|
1196
|
-
|
|
1197
|
-
interface ValueLocation {
|
|
1198
|
-
name: string;
|
|
1199
|
-
/** Relative to the session root when under it, absolute otherwise. */
|
|
1200
|
-
file: string;
|
|
1201
|
-
line: number;
|
|
1202
|
-
}
|
|
1203
|
-
interface WhyExplained {
|
|
1204
|
-
explanation: ResolutionExplanation;
|
|
1205
|
-
/** The chain's atoms, each said in source terms. */
|
|
1206
|
-
chain: string[];
|
|
1207
|
-
/** The chain and its reasons as printable lines. */
|
|
1208
|
-
lines: string[];
|
|
1209
|
-
target: ValueLocation;
|
|
1210
|
-
stats: ExplainStats;
|
|
1211
|
-
}
|
|
1212
|
-
declare class WhySession {
|
|
958
|
+
declare class TypeScriptWhySession {
|
|
1213
959
|
private readonly project;
|
|
1214
960
|
private readonly store;
|
|
1215
961
|
private readonly root;
|
|
@@ -1254,87 +1000,6 @@ declare function exportedDeclarationsOf(sourceFile: SourceFile, resolution: Reso
|
|
|
1254
1000
|
*/
|
|
1255
1001
|
declare function resolveAliasedSymbol(symbol: Symbol): Symbol | undefined;
|
|
1256
1002
|
|
|
1257
|
-
/**
|
|
1258
|
-
* Checks that tell you a pack is probably not working.
|
|
1259
|
-
*
|
|
1260
|
-
* The funnel shows where a run's counts dropped to zero. These checks
|
|
1261
|
-
* ask something narrower of each pack on its own: did this pack lose
|
|
1262
|
-
* everything at some stage, when the stage before it had something?
|
|
1263
|
-
*
|
|
1264
|
-
* A pack that finds nothing in a codebase that does not use its library
|
|
1265
|
-
* is working correctly, so a count of zero on its own is never the
|
|
1266
|
-
* signal. What makes zero a signal is the count before it. A pack whose
|
|
1267
|
-
* import gate picked forty files and whose discovery then found no unit
|
|
1268
|
-
* in any of them said "look here" and failed to look. Every later stage
|
|
1269
|
-
* works the same way, which is why these checks are one comparison run
|
|
1270
|
-
* over a list of pairs rather than one check written per stage.
|
|
1271
|
-
*/
|
|
1272
|
-
|
|
1273
|
-
/** One thing that looks wrong, reported the way the dogfood invariants are. */
|
|
1274
|
-
interface HealthViolation {
|
|
1275
|
-
label: string;
|
|
1276
|
-
detail: string;
|
|
1277
|
-
}
|
|
1278
|
-
interface HealthCheck {
|
|
1279
|
-
/** The property being checked, as something either true or false. */
|
|
1280
|
-
name: string;
|
|
1281
|
-
/**
|
|
1282
|
-
* The short word this check reports under, kebab-case.
|
|
1283
|
-
*
|
|
1284
|
-
* It is the first column of every line the check prints, so a reader
|
|
1285
|
-
* works out what it means once and recognises it after that. `name`
|
|
1286
|
-
* is written as an assertion and would read backwards over a list of
|
|
1287
|
-
* things failing it.
|
|
1288
|
-
*/
|
|
1289
|
-
code: string;
|
|
1290
|
-
/**
|
|
1291
|
-
* Who the finding is addressed to.
|
|
1292
|
-
*
|
|
1293
|
-
* A `run` check found something about the code in front of it, and
|
|
1294
|
-
* the person who started the run can do something about it: drop a
|
|
1295
|
-
* pack, install a dependency, open an issue with the file that broke.
|
|
1296
|
-
* A `pack` check found something about how a pack was built, which
|
|
1297
|
-
* only whoever ships that pack can fix. Printing the second kind on
|
|
1298
|
-
* every run would teach people to skim past the first.
|
|
1299
|
-
*/
|
|
1300
|
-
audience: "run" | "pack";
|
|
1301
|
-
violations: HealthViolation[];
|
|
1302
|
-
}
|
|
1303
|
-
/**
|
|
1304
|
-
* What one pack paid for what it matches.
|
|
1305
|
-
*
|
|
1306
|
-
* Expressiveness is bought link by link, and #542 asks for the price to
|
|
1307
|
-
* be printed. A pack with every link written as data runs on any
|
|
1308
|
-
* adapter with the executor ops. A link written as a function runs only
|
|
1309
|
-
* where its own language does, and one that reads the syntax tree is
|
|
1310
|
-
* the floor. All three are allowed, and this says which is which.
|
|
1311
|
-
*/
|
|
1312
|
-
interface PackGradient {
|
|
1313
|
-
pack: string;
|
|
1314
|
-
/** Links written as data, across every declaration. */
|
|
1315
|
-
dataLinks: number;
|
|
1316
|
-
/** Links written as a function, as "declaration.question". */
|
|
1317
|
-
functionLinks: string[];
|
|
1318
|
-
/** Links whose function reads the adapter's own syntax tree. */
|
|
1319
|
-
astLinks: string[];
|
|
1320
|
-
/** Declarations shipped without a line of code to run against them. */
|
|
1321
|
-
withoutExample: string[];
|
|
1322
|
-
}
|
|
1323
|
-
/**
|
|
1324
|
-
* Run every health check over one extraction report and return what
|
|
1325
|
-
* fired, grouped by which check caught it.
|
|
1326
|
-
*/
|
|
1327
|
-
declare function evaluatePackHealth(report: ExtractionReport): HealthCheck[];
|
|
1328
|
-
/**
|
|
1329
|
-
* The health checks that fired, as lines for a terminal.
|
|
1330
|
-
*
|
|
1331
|
-
* `audiences` is who the caller is printing for. It is required because
|
|
1332
|
-
* no single choice suits every caller: a CLI run prints what the person
|
|
1333
|
-
* who started it can act on, while a run a pack author is reading wants
|
|
1334
|
-
* both kinds.
|
|
1335
|
-
*/
|
|
1336
|
-
declare function formatPackHealth(checks: ReadonlyArray<HealthCheck>, audiences: ReadonlyArray<HealthCheck["audience"]>): string;
|
|
1337
|
-
|
|
1338
1003
|
/**
|
|
1339
1004
|
* Parse a ts-morph Expression into a structured Predicate.
|
|
1340
1005
|
* Returns null when the expression can't be decomposed cleanly.
|
|
@@ -1580,35 +1245,30 @@ declare function createTsSubUnitContext(): TsSubUnitContext;
|
|
|
1580
1245
|
*/
|
|
1581
1246
|
declare function workspaceRootFor(anchor: string): string;
|
|
1582
1247
|
|
|
1583
|
-
declare const ADAPTER_VERSION = "0.2.1";
|
|
1584
1248
|
/**
|
|
1585
|
-
*
|
|
1586
|
-
* the list is empty or a file cannot be read, so a caller that could not
|
|
1587
|
-
* locate a file gets the same "no stamp" result as a run from source
|
|
1588
|
-
* rather than a hash of a shorter list.
|
|
1249
|
+
* version.ts: this adapter's own half of the cache key.
|
|
1589
1250
|
*
|
|
1590
|
-
*
|
|
1591
|
-
*
|
|
1251
|
+
* `ADAPTER_VERSION` is the hand-bumped semver. Bump it on any change
|
|
1252
|
+
* that affects extraction output: IR shape, discovery semantics,
|
|
1253
|
+
* terminal classification, anything that would invalidate previously
|
|
1254
|
+
* cached summaries. `createAdapterStamp` (from `@suss/extractor`) folds
|
|
1255
|
+
* it together with a hash of this adapter's own loaded code, so a
|
|
1256
|
+
* rebuilt dev build invalidates the cache even when nobody remembered
|
|
1257
|
+
* to bump the constant. See that package's README for the full design.
|
|
1592
1258
|
*/
|
|
1593
|
-
|
|
1259
|
+
|
|
1260
|
+
declare const ADAPTER_VERSION = "0.2.1";
|
|
1594
1261
|
/**
|
|
1595
1262
|
* Compute a cache-friendly identity for an adapter+packs combination.
|
|
1596
|
-
* Stable across processes given the same inputs; bumps when any pack
|
|
1597
|
-
* arrives with a new version stamp, the adapter version changes, or the
|
|
1598
|
-
* loaded adapter dist file changes (dev-mode rebuild auto-invalidation).
|
|
1599
1263
|
*
|
|
1600
1264
|
* A pack's stamp is whatever the caller that loaded the pack put there.
|
|
1601
1265
|
* The adapter takes packs as plain objects and cannot tell where one
|
|
1602
1266
|
* came from, so folding the config and the code into the stamp is the
|
|
1603
1267
|
* loader's job.
|
|
1604
|
-
*
|
|
1605
|
-
* A source run says as much in the digest rather than leaving the
|
|
1606
|
-
* adapter out of it. Nothing writes under that digest today, and a key
|
|
1607
|
-
* that says "source" cannot be mistaken for one built from the code.
|
|
1608
1268
|
*/
|
|
1609
1269
|
declare function computeAdapterPacksDigest(packVersions: ReadonlyArray<{
|
|
1610
1270
|
name: string;
|
|
1611
1271
|
version?: string;
|
|
1612
1272
|
}>): string;
|
|
1613
1273
|
|
|
1614
|
-
export { ADAPTER_VERSION, type Accessed, type
|
|
1274
|
+
export { ADAPTER_VERSION, type Accessed, type ClientCallSite, type ConfiguredCallContext, type ConfiguredCallRead, type ConfiguredCallSpec, type ContractReadResult, type DiscoveredUnit, type ExplainCallableOptions, type ExplainedResolution, type FoundTerminal, type FunctionRoot, type ImportScanOptions, type ObservedStubCall, type ReadNameOptions, ResolutionStore, type StubCallEvidence, type StubEvidenceOptions, type TsDiscoveryContext, type TsInvocationRecognizerContext, type TsJsxAttributeLocation, type TsSubUnitContext, type TypeScriptAdapter, type TypeScriptAdapterConfig, TypeScriptWhySession, type WhySessionOptions, accessContextFor, buildProjectHelperIndex, callOpsFor, collectAncestorBranches, collectClientFieldAccesses, computeAdapterPacksDigest, createProjectWithoutTsconfig, createTsDiscoveryContext, createTsSubUnitContext, createTypeScriptAdapter, discoverUnits, exportedDeclarationsOf, extractCodeStructure, extractRawBranches, findNearestTsconfig, findTerminals, functionTargetOf, importDeclarationsOf, importedNamesOf, importedRootsOf, invocationContextFor, isImportedFrom, methodDeclaredIn, namedImportsOf, parseConditionExpression, readConfiguredCall, readContract, readContractForClientCall, readName, resolveAliasedSymbol, resolveSubject, rootIdentifier, stubEvidence, stubEvidenceIn, workspaceRootFor };
|