@suss/resolution 0.33.1 → 0.34.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.d.ts CHANGED
@@ -68,6 +68,23 @@ declare function calleeOutcomeOf(db: Database, key: string, program?: OnDemandRu
68
68
  declare function couldBeSettled(db: Database, key: string): boolean;
69
69
  declare function writtenSourcesOf(db: Database, key: string): string[];
70
70
 
71
+ /**
72
+ * classMember.ts: how an adapter spells a member that only the class
73
+ * itself has, and none of its instances, such as a Ruby class method or a
74
+ * TypeScript static.
75
+ *
76
+ * Ruby and TypeScript let a class and its instances each have a member of
77
+ * the same name. An adapter records the class's own member under this
78
+ * spelling of the name, and spells a read the same way when the read is
79
+ * off the class itself. A read off an instance keeps the plain name, so
80
+ * each read finds its own member and never the other. The spelling is the
81
+ * one YARD and JSDoc give a class member, `Api.create` beside `Api#create`.
82
+ */
83
+ /** The name a class records its own member `name` under. */
84
+ declare function classMemberName(name: string): string;
85
+ /** The member name a class spelling was made from, or null for a plain name. */
86
+ declare function classMemberOf(name: string): string | null;
87
+
71
88
  /** The tuples of one relation, as strings, which is all a case compares. */
72
89
  type FactsOf = (relation: string) => string[][];
73
90
  interface ContractCase {
@@ -103,6 +120,262 @@ declare function checkFactContract(sources: Readonly<Record<string, CaseFiles>>,
103
120
  problem: string;
104
121
  }[]>;
105
122
 
123
+ /**
124
+ * The types a value is declared as, for a caller that wants the class
125
+ * of a name the source gives no type.
126
+ *
127
+ * A parameter nobody annotated still has a type when the callers that
128
+ * pass it do. The rules follow each argument back to a declaration,
129
+ * through as many unannotated helpers as the chain has, and report
130
+ * every type they reach. Whether two of those are one type depends on
131
+ * what each key refers to, which the adapter knows, so the keys come
132
+ * back as found. The DESIGN says which callers are checked.
133
+ */
134
+
135
+ /**
136
+ * Each type key the value is declared as, or none when a caller passes
137
+ * it something no declaration types. A caller passing on a parameter of
138
+ * its own that nothing types makes no claim.
139
+ */
140
+ declare function declaredTypesOf(db: Database, key: string, program?: OnDemandRules): string[];
141
+
142
+ /**
143
+ * What each piece of an adapter's work depended on, so a cache can tell
144
+ * which pieces a later run may reuse.
145
+ *
146
+ * An adapter runs each piece of work, one file's discovery or one
147
+ * function's scan, inside `charging`. Every question the work puts to the
148
+ * rules is charged to it as the values the question demanded, derived or
149
+ * answered. A question asked a second time is answered from the database,
150
+ * so what it touched the first time is kept per key and charged again.
151
+ * Syntax read straight out of another file is charged as that file, and a
152
+ * lookup in an index built over every file is charged with what it gave
153
+ * back. `FactLog` then says whose facts changed between two runs.
154
+ */
155
+
156
+ /** What one piece of work depended on. */
157
+ interface Dependencies {
158
+ /** Files whose syntax the work read directly. */
159
+ readonly files: Set<string>;
160
+ /** Values the rules asked about, derived or answered for the work, and keys it placed on a summary. */
161
+ readonly values: Set<string>;
162
+ /** Lookups in indexes built over every file, by what was looked up, with a hash of what came back. */
163
+ readonly checks: Map<string, number>;
164
+ }
165
+ declare function noDependencies(): Dependencies;
166
+ declare class DependencyLedger {
167
+ private readonly files;
168
+ private readonly fileByValue;
169
+ private readonly valuesByAsked;
170
+ private readonly active;
171
+ constructor(files: Iterable<string>);
172
+ /** The file a key starts with, or is, or null for a value that is neither. */
173
+ fileOf(value: string): string | null;
174
+ private findFile;
175
+ /** Run `work`, charging everything it asks and reads to `into`. */
176
+ charging<T>(into: Dependencies, work: () => T): T;
177
+ /** `charging` for work that awaits. Nothing else may run until it settles. */
178
+ chargingAsync<T>(into: Dependencies, work: () => Promise<T>): Promise<T>;
179
+ private readonly hashByValue;
180
+ /** Dependencies as a cache stores them. The same values come up in many charges, so each is hashed once. */
181
+ store(dependencies: Dependencies): StoredDependencies;
182
+ /** Charge a file whose syntax the work read directly. */
183
+ readFile(file: string): void;
184
+ /** Charge the file of a node the work read the syntax of. */
185
+ readKey(key: string): void;
186
+ /** Charge a key whose facts the work's result depends on without asking about it, such as a callee whose span goes on a summary. */
187
+ touchKey(key: string): void;
188
+ /**
189
+ * Charge a lookup in an index built over every file, such as methods by
190
+ * name. `id` has to be enough for a later run to look again, and `found`
191
+ * describes what came back.
192
+ */
193
+ looked(id: string, found: string): void;
194
+ /**
195
+ * The keys one evaluation asked about for the first time, and every
196
+ * value the rules asked about or derived on the way to the answer.
197
+ */
198
+ evaluated(asking: string, keys: readonly string[], values: ReadonlySet<string>): void;
199
+ /** Keys asked about again, whose answers are already in the database. */
200
+ reasked(asking: string, keys: readonly string[]): void;
201
+ private chargeValues;
202
+ }
203
+ /**
204
+ * A map built over every file whose lookups report what was looked up
205
+ * and what came back, so work that reads it by name is charged for it.
206
+ */
207
+ declare class WatchedMap<K, V> extends Map<K, V> {
208
+ private readonly seen;
209
+ constructor(entries: Iterable<readonly [K, V]>, seen: (key: K, value: V | undefined) => void);
210
+ get(key: K): V | undefined;
211
+ has(key: K): boolean;
212
+ }
213
+ /** A 32-bit FNV-1a hash, for storing many strings compactly where a collision only costs a re-read. */
214
+ declare function hashString(text: string): number;
215
+ /** Hashes as one string of eight hex digits each, which JSON stores in less space than a list of numbers. */
216
+ declare function packHashes(hashes: Iterable<number>): string;
217
+ declare function unpackHashes(packed: string): number[];
218
+ /** Dependencies as a cache stores them: files and values by hash, lookups by id. */
219
+ interface StoredDependencies {
220
+ readonly files: string;
221
+ readonly values: string;
222
+ readonly checks: readonly (readonly [string, number])[];
223
+ }
224
+ /** One stored record for work that was partly reused and partly done again. */
225
+ declare function mergeStoredDependencies(one: StoredDependencies, other: StoredDependencies): StoredDependencies;
226
+ /** What changed between the run that stored some dependencies and this one. */
227
+ interface Changes {
228
+ /** Hashes of the files whose content changed. */
229
+ readonly files: ReadonlySet<number>;
230
+ /** Hashes of the values whose facts changed. */
231
+ readonly values: ReadonlySet<number>;
232
+ /** The lookup stored under `id`, made again in this run, or null when this run cannot make it. */
233
+ lookAgain(id: string): string | null;
234
+ }
235
+ /**
236
+ * Whether stored dependencies still describe this run: none of their
237
+ * files changed, no fact about any of their values changed, and every
238
+ * lookup comes back the same.
239
+ */
240
+ declare function stillValid(stored: StoredDependencies, changes: Changes): boolean;
241
+ /** What one file's facts were, stored so a later run can tell whose facts changed. */
242
+ interface StoredFacts {
243
+ /** For each value in the rows this file emitted on its own, its hash followed by a hash of those rows. */
244
+ readonly own: string;
245
+ /** For each key of this file in a row that joins files, its hash followed by a hash of those rows. */
246
+ readonly joined: string;
247
+ }
248
+ /**
249
+ * The rows a run emitted file by file, and the rows that join files,
250
+ * which an adapter adds once every file is in. A cache stores a digest of
251
+ * the rows each key appears in, and the next run compares. A key whose
252
+ * rows changed is one whose facts changed. That includes a key in a file
253
+ * nobody edited, such as a constant reference that a definition in a new
254
+ * place now binds instead. Names are left out: every way one file reaches
255
+ * into another goes through a key, and a name like `params` is in the
256
+ * rows of nearly every file.
257
+ */
258
+ declare class FactLog {
259
+ private readonly db;
260
+ private readonly ledger;
261
+ private readonly ranges;
262
+ private readonly joinedRanges;
263
+ private opened;
264
+ constructor(db: Database, ledger: DependencyLedger);
265
+ /** Call before a file emits its own rows. */
266
+ startFile(): void;
267
+ /** Call after the file emitted its own rows. */
268
+ endFile(file: string): void;
269
+ /** Call before rows that join files are added. There may be several such stretches. */
270
+ startJoined(): void;
271
+ endJoined(): void;
272
+ private fileOf;
273
+ /** Every row added in a stretch, skipping the answers a question adds, which are not facts. */
274
+ private rowsIn;
275
+ private readonly atomHashes;
276
+ /**
277
+ * An atom's hash as written, and with its node offsets left out, so a
278
+ * row that mentions a key next to another hashes the same after an edit
279
+ * shifts the other. Work that used the other key has it among its own
280
+ * values, and is checked on it.
281
+ */
282
+ private hashesOf;
283
+ /** Each key in a row, with a hash of the row as seen from that key: the key as written, every other key loose. */
284
+ private hashesByKey;
285
+ /** Digests of one file's own rows, by each key in them. */
286
+ private ownDigests;
287
+ /** Digests of the rows that join files, by each key in them, grouped by that key's file. */
288
+ private joinedDigests;
289
+ /**
290
+ * Each file's facts to store. `unchanged` lists the files whose content
291
+ * hashed the same as when `previous` was stored, so their own rows are
292
+ * taken from there instead of being read again.
293
+ */
294
+ stored(files: readonly string[], previous: ReadonlyMap<string, StoredFacts>, unchanged: ReadonlySet<string>): Map<string, StoredFacts>;
295
+ /** The hashes of every value whose facts changed since `previous` was stored. `changed` lists the files whose content changed. */
296
+ changedValues(changed: ReadonlySet<string>, previous: ReadonlyMap<string, StoredFacts>): Set<number>;
297
+ }
298
+
299
+ /**
300
+ * Which records of a stored cache entry a run can replay, for an adapter
301
+ * that stores one record per file: what the file's discovery depended
302
+ * on, and what the walk found for each function written in the file.
303
+ *
304
+ * A function's walk record is valid while nothing it depended on changed.
305
+ * A file's discovery record is valid while nothing its discovery depended
306
+ * on changed and the walk records of the functions its units start from
307
+ * are valid too, since those units' summaries carry what the walk placed
308
+ * on them.
309
+ */
310
+
311
+ /** What the walk found for one function, and what that depended on. */
312
+ interface StoredWalkRecord<Scan, Summary> {
313
+ readonly key: string;
314
+ readonly dependencies: StoredDependencies;
315
+ readonly scan: Scan;
316
+ /** A reached function's summary before parameter gaps were added. Absent for a function a unit starts from. */
317
+ readonly summary?: Summary;
318
+ }
319
+ /** The parts of a file's record every adapter stores. */
320
+ interface StoredFileRecord<Scan, Summary> {
321
+ readonly discovery: StoredDependencies;
322
+ readonly walked: readonly StoredWalkRecord<Scan, Summary>[];
323
+ readonly facts: StoredFacts;
324
+ }
325
+ /** The file a node key is written in. */
326
+ declare function fileOfKey(key: string): string;
327
+ declare class EntryReuse<Scan, Summary, Record extends StoredFileRecord<Scan, Summary>> {
328
+ readonly records: ReadonlyMap<string, Record>;
329
+ readonly changedFiles: ReadonlySet<string>;
330
+ private readonly changes;
331
+ /** The keys of the functions a file's units start from. */
332
+ private readonly seedsOf;
333
+ private readonly walks;
334
+ private readonly walkValid;
335
+ private readonly discoveryValid;
336
+ constructor(records: ReadonlyMap<string, Record>, changedFiles: ReadonlySet<string>, changes: Changes,
337
+ /** The keys of the functions a file's units start from. */
338
+ seedsOf: (record: Record) => Iterable<string>);
339
+ /** The walk record for a function, when nothing it depended on changed. */
340
+ walkOf(key: string): StoredWalkRecord<Scan, Summary> | undefined;
341
+ /** The record of a file whose discovery can be replayed. */
342
+ discoveryOf(file: string): Record | undefined;
343
+ }
344
+ /**
345
+ * The walk records to store, by the file each function is written in.
346
+ * A replayed scan keeps its stored dependencies, with anything the run
347
+ * added for it, such as a summary built again, merged in.
348
+ */
349
+ declare function walkRecordsByFile<Scan, Summary>(args: {
350
+ scans: ReadonlyMap<string, Scan>;
351
+ charges: ReadonlyMap<string, Dependencies>;
352
+ beforeGaps: ReadonlyMap<string, Summary>;
353
+ replayed: (key: string) => StoredWalkRecord<Scan, Summary> | undefined;
354
+ store: (dependencies: Dependencies) => StoredDependencies;
355
+ merge: (one: StoredDependencies, other: StoredDependencies) => StoredDependencies;
356
+ }): Map<string, StoredWalkRecord<Scan, Summary>[]>;
357
+ /**
358
+ * The records an entry's roots carry, when every root has one and no
359
+ * file was added or removed since. An added or removed file can change
360
+ * what a name binds to and which file a path leads to, which no record
361
+ * says, so the run starts over instead.
362
+ */
363
+ declare function recordsToReplay<Record extends {
364
+ readonly discovery: unknown;
365
+ }>(roots: ReadonlyMap<string, {
366
+ readonly meta: unknown;
367
+ }>, changed: ReadonlySet<string>, removed: ReadonlySet<string>): Map<string, Record> | null;
368
+
369
+ /**
370
+ * The functions whose return becomes the process's exit code, for an
371
+ * adapter that found the values ending up as the code itself: the
372
+ * argument an exit call hands over, or what is assigned to the code.
373
+ * DESIGN.md says how the walk gets from a value to a function.
374
+ */
375
+
376
+ /** Each function key a call at or reached from one of these values invokes. */
377
+ declare function exitCodeFunctions(db: Database, sinks: readonly string[], program?: OnDemandRules): Set<string>;
378
+
106
379
  /**
107
380
  * Turn a witness proof over the resolution rules into the chain a
108
381
  * person reads: which value led to which, one reason per hop, with the
@@ -172,6 +445,17 @@ declare function explainResolutionProof(proof: Proof, options: ExplainOptions):
172
445
  */
173
446
  declare function renderExplanation(explanation: ResolutionExplanation, describe: DescribeAtom): string[];
174
447
 
448
+ /**
449
+ * The files each file in a run depends on, read from `importsFile`.
450
+ *
451
+ * No rule reads that relation. An adapter states it, and the run lists
452
+ * each file's dependencies from it, which is what a cache invalidates a
453
+ * summary by and what a checker rebuilds the module graph from.
454
+ */
455
+
456
+ /** Each importing file's imported files, both spelled by `displayPathOf`. */
457
+ declare function importedFilesByFile(db: Database, displayPathOf: (file: string) => string): Map<string, string[]>;
458
+
175
459
  /**
176
460
  * Mount composition, shared between adapters. An adapter states one
177
461
  * fact per mount call, `mounted(child, parent, prefix)`, however its
@@ -322,7 +606,7 @@ declare function nodeOfKey<N extends SpannedNode<N>>(rootsByFile: ReadonlyMap<st
322
606
  * each new word had to be written three times. `addPackWords` is the one
323
607
  * loop; an adapter maps its own pack type onto `PackWords` and calls it.
324
608
  *
325
- * The field names match the fact vocabulary at the top of `index.ts`.
609
+ * Each field has the name of the relation it adds, as DESIGN.md lists it.
326
610
  */
327
611
 
328
612
  /** A method on a class reaching `base` gives back one of that class. */
@@ -345,17 +629,22 @@ interface EntersAsSelf {
345
629
  module: string;
346
630
  name: string;
347
631
  }
348
- /** Calling `callee` out of `module` gives back its argument at `argument`. */
632
+ /** Calling the `name` that `module` exports gives back its argument at `argument`. */
349
633
  interface UnwrapsByName {
350
- callee: string;
351
- argument: number;
352
634
  module: string;
635
+ name: string;
636
+ argument: number;
353
637
  }
354
638
  /** A field given a call of `module`'s `name` declares an association. */
355
639
  interface AssociationConstructor {
356
640
  module: string;
357
641
  name: string;
358
642
  }
643
+ /** A parameter decorated with a call of `module`'s `name` takes its value from that call. */
644
+ interface SuppliesParameter {
645
+ module: string;
646
+ name: string;
647
+ }
359
648
  /** What a run's packs say about their own libraries, in one language-neutral shape. */
360
649
  interface PackWords {
361
650
  givesBackOne?: ReadonlyArray<GivesBackOne>;
@@ -364,10 +653,46 @@ interface PackWords {
364
653
  entersAsSelf?: ReadonlyArray<EntersAsSelf>;
365
654
  unwrapsByName?: ReadonlyArray<UnwrapsByName>;
366
655
  associationConstructor?: ReadonlyArray<AssociationConstructor>;
656
+ /** Methods that hand back the object they are called on, by name. */
657
+ returnsReceiver?: ReadonlyArray<string>;
658
+ suppliesParameter?: ReadonlyArray<SuppliesParameter>;
367
659
  }
368
660
  /** Put a run's pack declarations in the store, so the shared rules can read them. */
369
661
  declare function addPackWords(db: Database, words: PackWords): void;
370
662
 
663
+ /**
664
+ * Whether a value leaves the expressions it is read in: returned, handed
665
+ * to a call, given to another name or object, and so on, each from one
666
+ * fact an adapter states about the read. A router reader asks it about an
667
+ * app its own function builds, since a mount on an app nothing can reach
668
+ * serves nothing. DESIGN.md lists the facts and says why a method call
669
+ * gets a relation of its own.
670
+ *
671
+ * The rules cannot say "no read passes it on", because the demand rewrite
672
+ * refuses negation. So a caller asks the positive question and treats a
673
+ * missing row as the value staying put. A read with no fact behind it
674
+ * looks the same as no read, which is why every spelling needs a fact.
675
+ */
676
+
677
+ /** What a caller asks through, `askResolution(db, keys, USES_QUESTION)`, to learn where the value at each key goes. */
678
+ declare const USES_QUESTION = "wantedUses";
679
+ /** What the reads of one value do with it. */
680
+ interface ValueUses {
681
+ /** Whether some read passes it on, or calls it. */
682
+ passedOn: boolean;
683
+ /** The methods called on it, `use` for `app.use(...)`, each once. */
684
+ methodsCalled: readonly string[];
685
+ }
686
+ /** What the rules derived for one key, read after the question was asked. */
687
+ declare function readUses(db: Database, key: string): ValueUses;
688
+ /**
689
+ * Whether a value stays in the function that built it: nothing passes it
690
+ * on or calls it, and every method called on it is one of `ownMethods`.
691
+ * A router reader passes the methods its pack registers routes and mounts
692
+ * with, since any other method, `listen` say, may serve the app.
693
+ */
694
+ declare function staysInItsFunction(uses: ValueUses, ownMethods: ReadonlySet<string>): boolean;
695
+
371
696
  /**
372
697
  * The rules an adapter evaluates, and how a question is put to them.
373
698
  *
@@ -414,6 +739,18 @@ declare function resolutionUnderProgram(languageRules?: readonly Rule[]): OnDema
414
739
  * since then the answers themselves are what clearing would remove.
415
740
  */
416
741
  declare function queryFacts(program: OnDemandRules): readonly string[];
742
+ /** Tell whoever observes `db` that work read what `key` refers to around the rules. */
743
+ declare function noteKeyRead(db: Database, key: string): void;
744
+ /** Tell whoever observes `db` about a lookup in an index built over every file. */
745
+ declare function noteLookup(db: Database, id: string, found: string): void;
746
+ /** Whether anybody observes `db`, for a lookup whose description costs something to build. */
747
+ declare function isObserved(db: Database): boolean;
748
+ /**
749
+ * Tell `observer` about every question put to `db` until the returned
750
+ * function is called. One observer per database; a second replaces the
751
+ * first.
752
+ */
753
+ declare function observeDemand(db: Database, observer: DependencyLedger): () => void;
417
754
  /**
418
755
  * Ask about these values, derive, and take the question back.
419
756
  *
@@ -519,7 +856,10 @@ interface WhyExplained {
519
856
  stats: ExplainStats;
520
857
  }
521
858
  interface ExplainResolvedKeyOptions {
522
- /** The facts the session extracted. Read, never written to. */
859
+ /**
860
+ * The facts the session extracted. The proof pass derives into them,
861
+ * so nothing else may evaluate rules over this database.
862
+ */
523
863
  db: Database;
524
864
  /** The resolution rules plus whatever the language adds to them. */
525
865
  rules: Rule[];
@@ -532,6 +872,13 @@ interface ExplainResolvedKeyOptions {
532
872
  maxDepth?: number;
533
873
  phrases?: Record<string, StepPhrase>;
534
874
  }
875
+ /**
876
+ * The rules a proof of `resolves` can use. A proof pass runs without
877
+ * demand, over every fact it was given, and the rules under an
878
+ * allocation site join each site against every value when nothing
879
+ * narrows them, so they are left out.
880
+ */
881
+ declare function proofRules(rules: readonly Rule[]): Rule[];
535
882
  /**
536
883
  * Why `key` resolves to what it does: the witness proof, flattened to
537
884
  * the chain and rendered. Null when the key resolves to nothing or to
@@ -540,26 +887,114 @@ interface ExplainResolvedKeyOptions {
540
887
  declare function explainResolvedKey(options: ExplainResolvedKeyOptions): WhyExplained | null;
541
888
 
542
889
  /**
543
- * What counts as an answer to a question shaped `[key, answer]`, such as
544
- * `wantedIsWrittenAs` or `wantedSubjectWritten`. A call is written as
545
- * itself, so a call asked about directly always matches its own key; that
546
- * row is dropped before the count so one other answer settles it instead
547
- * of counting as two.
890
+ * The one reader for an answer the rules derived, such as `wantedResolves`
891
+ * or `wantedIsWrittenAs`. Adapters and the readers in this package read
892
+ * every answer through it, so a policy is applied in one place and a new
893
+ * policy is one edit.
548
894
  *
549
- * A placeholder write, `client = None` before a guard fills it in, is
550
- * set aside the same way when the key has any other answer. A key
551
- * written only as a placeholder keeps it.
895
+ * A placeholder write, `client = None` before a guard fills it in, is set
896
+ * aside when the key has another answer. A member a subclass overrides is
897
+ * set aside when the key reads it through that subclass; the demand
898
+ * rewrite refuses negation, so that happens here rather than in a rule.
899
+ * A written-as question also sets aside a key's match against itself,
900
+ * since a call is written as itself. A function does come to itself, so
901
+ * the other questions keep that row. DESIGN.md has the detail.
902
+ */
903
+
904
+ /** Where the rules list, for a read asked about, the members a nearer declaration overrides. */
905
+ interface OverrideRelations {
906
+ /** `[read, object, member]`: the object contains a member overriding this one. */
907
+ readonly overridden: string;
908
+ /** `[read, object, member]`: every member the read finds on each object. */
909
+ readonly found: string;
910
+ }
911
+ /**
912
+ * Every answer `key` has in a `[key, answer]` relation, in the order the
913
+ * rows arrive, with placeholders and overridden members set aside. The
914
+ * read goes through the relation's index on the key, so a caller asking
915
+ * about one key pays for that key's rows and nothing else.
916
+ */
917
+ declare function answersFor(db: Database, relation: string, key: string, overrides?: OverrideRelations): string[];
918
+ /** `answersFor`, for a written-as question, with the key's match against itself set aside. */
919
+ declare function writtenAnswersFor(db: Database, relation: string, key: string): string[];
920
+ /**
921
+ * Every function that calling this value runs: what the value resolves
922
+ * to, and what a factory returned when the value was assigned from a
923
+ * call. The two are settled together, so an override found through one
924
+ * sets aside the member the other found.
925
+ */
926
+ declare function resolvedFunctions(db: Database, key: string): string[];
927
+ /** The one function calling this value runs, or null when it settles on none or on several. */
928
+ declare function settledFunction(db: Database, key: string): string | null;
929
+
930
+ /**
931
+ * Where a value came from, read from the rows `wantedSource` derives.
552
932
  *
553
- * A caller that can only use one answer takes `singleAnswers`; one with
554
- * something to say about a value written two ways takes `answersByKey`.
933
+ * The rules give the chain as steps. This rebuilds the walk from the
934
+ * value outward and hands back each place it ended, with the properties
935
+ * read off that place on the way to the value. Saying what an ending
936
+ * means (an input, a literal, a call the walk could not follow) is the
937
+ * adapter's job, since each language spells a parameter and a literal
938
+ * its own way. DESIGN.md has the rules and the reasons.
555
939
  */
556
940
 
557
- /** Every answer each key has, in the order the rows arrive, with the two drops above applied. */
558
- declare function answersByKey(rows: Iterable<Tuple>, placeholders?: ReadonlySet<string>): Map<string, string[]>;
559
- /** The one answer each key settles on, for a caller that treats several as none. */
560
- declare function singleAnswers(rows: Iterable<Tuple>, placeholders?: ReadonlySet<string>): Map<string, string>;
561
- /** The keys an adapter marked `placeholderValue`, for passing to `singleAnswers`. */
562
- declare function placeholderValues(db: Database): ReadonlySet<string>;
941
+ /** What the walk ended at. */
942
+ type SourceEnd =
943
+ /** A parameter of the function `of`. The walk never goes on to the callers. */
944
+ {
945
+ is: "parameter";
946
+ of: string;
947
+ }
948
+ /** A name imported from a module no file in the run defines. */
949
+ | {
950
+ is: "import";
951
+ module: string;
952
+ name: string;
953
+ }
954
+ /** A call whose result the walk could not follow. */
955
+ | {
956
+ is: "call";
957
+ }
958
+ /** An expression written out in the source, such as a literal. */
959
+ | {
960
+ is: "written";
961
+ }
962
+ /** Anything else with no step out of it. */
963
+ | {
964
+ is: "other";
965
+ };
966
+ /** One place a value's walk ended. */
967
+ interface SourceLeaf {
968
+ /** The key of the chain member the walk ended at. */
969
+ key: string;
970
+ /** The properties read off it on the way to the value, outermost first. */
971
+ path: string[];
972
+ /**
973
+ * The read nearest the value that takes an entry at a key the source
974
+ * computes, or null when the way there reads none. The path leaves
975
+ * that key out, so a caller that needs the whole path stops here.
976
+ */
977
+ computedAt: string | null;
978
+ /** The language's own conversions on the way to the value, outermost first. */
979
+ conversions: string[];
980
+ end: SourceEnd;
981
+ }
982
+ /**
983
+ * How far the walk goes. `wantedSource` follows a call into what its
984
+ * function returns. `wantedInputRead` follows a name to what it was
985
+ * written as and a read to what it was read off, and stops at a call,
986
+ * which is enough to say which input a guard tests.
987
+ */
988
+ type SourceQuestion = "wantedSource" | "wantedInputRead";
989
+ /** Ask where each value came from, and read where each walk ended. */
990
+ declare function askSources(db: Database, keys: readonly string[], program?: OnDemandRules, question?: SourceQuestion): Map<string, SourceLeaf[]>;
991
+ /**
992
+ * Every place the walk from `key` ended, for a store that has already
993
+ * asked `wantedSource` about it. A parameter always ends the walk, even
994
+ * when a step leads on from it, since the step goes into the caller's
995
+ * code or a declared type rather than to the value.
996
+ */
997
+ declare function sourceLeavesOf(db: Database, key: string): SourceLeaf[];
563
998
 
564
999
  /**
565
1000
  * Reading an answer that was asked for under one allocation site.
@@ -579,12 +1014,16 @@ declare function isWrittenAsUnder(db: Database, key: string, site: string): stri
579
1014
  declare function comesToUnder(db: Database, key: string, site: string): string[];
580
1015
  /** Every object the value refers to under this site, sites included. */
581
1016
  declare function objectOfUnder(db: Database, key: string, site: string): string[];
1017
+ /** Puts each `[key, site]` pair to the rules, the way `askResolutionUnder` does. */
1018
+ type AskUnder = (pairs: ReadonlyArray<readonly [string, string]>) => void;
582
1019
  /**
583
1020
  * The single expression the value was written as under this site, under
584
1021
  * the policy the context-free reader applies: two answers are ambiguity,
585
- * and ambiguity is nothing.
1022
+ * and ambiguity is nothing. A value written as a fallback reads as the
1023
+ * fallback, as `writtenValueOf` reads it, so `a or b` means the same
1024
+ * thing whichever path asked. `ask` puts the fallback's own question.
586
1025
  */
587
- declare function writtenValueUnder(db: Database, key: string, site: string): string | null;
1026
+ declare function writtenValueUnder(db: Database, key: string, site: string, ask: AskUnder): string | null;
588
1027
  /**
589
1028
  * Every site a class was made at, once `askResolution` has asked
590
1029
  * `wantedSites` about it. These are the sites to put a value question
@@ -649,6 +1088,19 @@ type Ask = (keys: readonly string[]) => void;
649
1088
  * returns rather than the call itself.
650
1089
  */
651
1090
  declare function writtenValueOf(db: Database, key: string, ask: Ask, relation?: string): string | null;
1091
+ /**
1092
+ * The fallback, `a or b`, that a value was written as, when the rules
1093
+ * found several expressions and every one of them came through that
1094
+ * fallback. A value reader then reads the fallback whole, and its own
1095
+ * `or` decides: a branch it cannot read makes no claim, and two branches
1096
+ * it can read both count. `writtenValuesOf` still lists the branches, for
1097
+ * a caller that wants each one.
1098
+ *
1099
+ * When one fallback is inside another, the outer one is returned. Null
1100
+ * when no fallback covers all of them, as for a name that two plain
1101
+ * writes leave with two values.
1102
+ */
1103
+ declare function fallbackWrittenAs(db: Database, key: string, ask: Ask): string | null;
652
1104
  /**
653
1105
  * Every expression a value was written as. More than one is a value with
654
1106
  * more than one possible source, which a caller says something about at
@@ -675,6 +1127,14 @@ declare const VALUE_STEP: _suss_datalog.Term;
675
1127
  */
676
1128
  declare const NAMESPACE_IMPORT_NAME = "*";
677
1129
  declare const NAMESPACE_IMPORT: _suss_datalog.Term;
1130
+ /** The name a default import records itself under, `import React from "react"`. */
1131
+ declare const DEFAULT_IMPORT_NAME = "default";
1132
+ /**
1133
+ * The module an adapter records a global under, with the global's full
1134
+ * dotted name: `Object.assign` in JavaScript. A pack word keys on it the
1135
+ * way it keys on any other import.
1136
+ */
1137
+ declare const GLOBAL_MODULE = "global";
678
1138
  /**
679
1139
  * The label on the `comesFrom` rule for a member read off a whole-module
680
1140
  * import. `explain` tells that proof from the two import ones by it.
@@ -685,8 +1145,27 @@ declare const NAMESPACE_MEMBER_RULE = "namespace member";
685
1145
  * `explain` says a name came from a base class when it fired.
686
1146
  */
687
1147
  declare const BASE_CLASS_RULE = "base class";
1148
+ /**
1149
+ * The label on the `hop` rule that takes a name hop. `explain` gives the
1150
+ * name hop's own reason for that step, since this rule adds nothing to it.
1151
+ */
1152
+ declare const NAME_HOP_RULE = "name hop";
688
1153
  /** A step from an instance to the class it is one of. */
689
1154
  declare const INSTANCE_STEP: _suss_datalog.Term;
1155
+ /**
1156
+ * The last column of `storesProperty`: whether the write went through the
1157
+ * receiver, keyed on the method that wrote it, or through a name, keyed on
1158
+ * the name. DESIGN.md says why the two cannot share a key.
1159
+ */
1160
+ declare const RECEIVER_STORE_NAME = "receiver";
1161
+ declare const NAMED_STORE_NAME = "name";
1162
+ /**
1163
+ * The last column for a write the adapter does not place on an object:
1164
+ * one through a parameter or a property read, or one of several writes
1165
+ * that never settle. The rules that put a store on an object match the
1166
+ * other two kinds, so these rows only say where a value went.
1167
+ */
1168
+ declare const UNPLACED_STORE_NAME = "unplaced";
690
1169
  /** A step to what running the call x is handed back. */
691
1170
  declare const RESULT_STEP: _suss_datalog.Term;
692
1171
  /** The context a value read outside every allocation site is read under. */
@@ -704,28 +1183,11 @@ declare const NO_CONTEXT: _suss_datalog.Term;
704
1183
  */
705
1184
  declare function alsoSteps(rules: readonly Rule[]): Rule[];
706
1185
  declare const RESOLUTION_RULES: Rule[];
707
- /**
708
- * The questions a caller asks, written as rules. Two facts say somebody
709
- * is asking: `wanted(x)` for what a value is, and `wantedOrigin(x)` for
710
- * where a name came from. Each answer relation contains the pairs for the
711
- * values somebody asked about, keyed by the value asked about, which is
712
- * the key the caller looks up by anyway.
713
- *
714
- * Written down rather than left to each caller because the engine reads
715
- * them. `deriveOnDemand` follows a chain only as far as one of these
716
- * questions reaches it, and a caller that answered its own questions by
717
- * scanning a relation would give the engine nothing to work from.
718
- *
719
- * The two asking facts are kept apart because they pull on different
720
- * rules. Following a name back to its library goes through every call
721
- * the value's function makes, so a caller that only wants to know what a
722
- * handler resolves to should not pay for that.
723
- */
724
1186
  declare const RESOLUTION_QUESTIONS: Rule[];
725
1187
  /** The relations `RESOLUTION_QUESTIONS` answers into. */
726
1188
  declare const ANSWER_RELATIONS: string[];
727
1189
  /**
728
- * The three of those a caller asks under one allocation site.
1190
+ * The ones of those a caller asks under one allocation site.
729
1191
  *
730
1192
  * They are listed apart because leaving them out of what a program has
731
1193
  * to answer drops the whole second closure from it. A run that never
@@ -734,4 +1196,4 @@ declare const ANSWER_RELATIONS: string[];
734
1196
  */
735
1197
  declare const UNDER_ANSWER_RELATIONS: string[];
736
1198
 
737
- export { ANSWER_RELATIONS, ASKING_RELATIONS, type AssociationConstructor, BASE_CLASS_RULE, type CalleeOutcome, type CaseFiles, type ChainReads, type ContractCase, type ContractOptions, type DescribeAtom, type EntersAsSelf, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, type FactsOf, type GivesBackOne, type GivesBackOneOfArgument, type GivesBackOneOfImport, INSTANCE_STEP, type MountEdge, type MountEdges, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, NAMESPACE_MEMBER_RULE, NO_CONTEXT, NO_CONTEXT_NAME, type NameReads, type NameWrite, type OrderedWrite, type PackWords, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ReadNode, type ResolutionExplanation, type ResolutionStep, type SpannedNode, type StepContext, type StepPhrase, UNDER_ANSWER_RELATIONS, UNDER_QUESTION_ROW_BUDGET, UNDER_RUN_ROW_BUDGET, type UnderOutcome, type UnwrapsByName, VALUE_STEP, type ValueLocation, type WhyExplained, addPackWords, agreedMountPrefix, allocationSitesOf, alsoSteps, answersByKey, askResolution, askResolutionUnder, calleeOutcomeOf, calleeOutcomes, checkFactContract, comesToUnder, couldBeSettled, explainResolutionProof, explainResolvedKey, isWrittenAsUnder, joinMountedPath, mountPathsOf, nodeOfKey, objectOfUnder, placeholderValues, queryFacts, renderExplanation, resolutionProgram, resolutionUnderProgram, singleAnswers, startsAtName, underQuestionSpend, valueLeftByWrites, writesRunInOrder, writtenSourcesOf, writtenValueOf, writtenValueUnder, writtenValuesByKey, writtenValuesOf };
1199
+ export { ANSWER_RELATIONS, ASKING_RELATIONS, type AskUnder, type AssociationConstructor, BASE_CLASS_RULE, type CalleeOutcome, type CaseFiles, type ChainReads, type Changes, type ContractCase, type ContractOptions, DEFAULT_IMPORT_NAME, type Dependencies, DependencyLedger, type DescribeAtom, type EntersAsSelf, EntryReuse, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, FactLog, type FactsOf, GLOBAL_MODULE, type GivesBackOne, type GivesBackOneOfArgument, type GivesBackOneOfImport, INSTANCE_STEP, type MountEdge, type MountEdges, NAMED_STORE_NAME, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, NAMESPACE_MEMBER_RULE, NAME_HOP_RULE, NO_CONTEXT, NO_CONTEXT_NAME, type NameReads, type NameWrite, type OrderedWrite, type PackWords, RECEIVER_STORE_NAME, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ReadNode, type ResolutionExplanation, type ResolutionStep, type SourceEnd, type SourceLeaf, type SourceQuestion, type SpannedNode, type StepContext, type StepPhrase, type StoredDependencies, type StoredFacts, type StoredFileRecord, type StoredWalkRecord, type SuppliesParameter, UNDER_ANSWER_RELATIONS, UNDER_QUESTION_ROW_BUDGET, UNDER_RUN_ROW_BUDGET, UNPLACED_STORE_NAME, USES_QUESTION, type UnderOutcome, type UnwrapsByName, VALUE_STEP, type ValueLocation, type ValueUses, WatchedMap, type WhyExplained, addPackWords, agreedMountPrefix, allocationSitesOf, alsoSteps, answersFor, askResolution, askResolutionUnder, askSources, calleeOutcomeOf, calleeOutcomes, checkFactContract, classMemberName, classMemberOf, comesToUnder, couldBeSettled, declaredTypesOf, exitCodeFunctions, explainResolutionProof, explainResolvedKey, fallbackWrittenAs, fileOfKey, hashString, importedFilesByFile, isObserved, isWrittenAsUnder, joinMountedPath, mergeStoredDependencies, mountPathsOf, noDependencies, nodeOfKey, noteKeyRead, noteLookup, objectOfUnder, observeDemand, packHashes, proofRules, queryFacts, readUses, recordsToReplay, renderExplanation, resolutionProgram, resolutionUnderProgram, resolvedFunctions, settledFunction, sourceLeavesOf, startsAtName, staysInItsFunction, stillValid, underQuestionSpend, unpackHashes, valueLeftByWrites, walkRecordsByFile, writesRunInOrder, writtenAnswersFor, writtenSourcesOf, writtenValueOf, writtenValueUnder, writtenValuesByKey, writtenValuesOf };