@suss/resolution 0.22.1 → 0.22.3

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 CHANGED
@@ -34,9 +34,11 @@ __export(index_exports, {
34
34
  explainResolvedKey: () => explainResolvedKey,
35
35
  joinMountedPath: () => joinMountedPath,
36
36
  mountPathsOf: () => mountPathsOf,
37
+ nodeOfKey: () => nodeOfKey,
37
38
  placeholderValues: () => placeholderValues,
38
39
  renderExplanation: () => renderExplanation,
39
- singleAnswers: () => singleAnswers
40
+ singleAnswers: () => singleAnswers,
41
+ writtenValueOf: () => writtenValueOf
40
42
  });
41
43
  module.exports = __toCommonJS(index_exports);
42
44
 
@@ -519,6 +521,32 @@ function pathsOf(edges, memo, childId, visiting) {
519
521
  return result;
520
522
  }
521
523
 
524
+ // src/nodeKey.ts
525
+ var SPAN_KEY = /^(.*):(\d+)-(\d+)$/;
526
+ function nodeOfKey(rootsByFile, key) {
527
+ const span = key.match(SPAN_KEY);
528
+ if (span === null) {
529
+ return null;
530
+ }
531
+ const root = rootsByFile.get(span[1]);
532
+ const start = Number(span[2]);
533
+ const end = Number(span[3]);
534
+ if (root === void 0 || end <= start) {
535
+ return null;
536
+ }
537
+ let current = root.descendantForIndex(start, end - 1);
538
+ while (current !== null) {
539
+ if (current.startIndex === start && current.endIndex === end) {
540
+ return current;
541
+ }
542
+ if (current.startIndex < start || current.endIndex > end) {
543
+ return null;
544
+ }
545
+ current = current.parent;
546
+ }
547
+ return null;
548
+ }
549
+
522
550
  // src/session.ts
523
551
  var import_datalog2 = require("@suss/datalog");
524
552
  function explainResolvedKey(options) {
@@ -606,6 +634,26 @@ function withoutPlaceholders(answers, placeholders) {
606
634
  return kept;
607
635
  }
608
636
 
637
+ // src/writtenValue.ts
638
+ function writtenValueOf(db, key, ask) {
639
+ const placeholders = placeholderValues(db);
640
+ const direct = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
641
+ key
642
+ );
643
+ if (direct === void 0) {
644
+ return null;
645
+ }
646
+ const isCall = db.facts("call").some((row) => String(row[0]) === direct);
647
+ if (!isCall) {
648
+ return direct;
649
+ }
650
+ ask([direct]);
651
+ const deeper = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
652
+ direct
653
+ );
654
+ return deeper ?? direct;
655
+ }
656
+
609
657
  // src/index.ts
610
658
  var import_datalog3 = require("@suss/datalog");
611
659
  var VALUE_STEP = (0, import_datalog3.constant)("value");
@@ -1361,7 +1409,9 @@ var ANSWER_RELATIONS = [
1361
1409
  explainResolvedKey,
1362
1410
  joinMountedPath,
1363
1411
  mountPathsOf,
1412
+ nodeOfKey,
1364
1413
  placeholderValues,
1365
1414
  renderExplanation,
1366
- singleAnswers
1415
+ singleAnswers,
1416
+ writtenValueOf
1367
1417
  });
package/dist/index.d.cts CHANGED
@@ -148,6 +148,25 @@ declare function mountPathsOf(edges: MountEdges, childId: string): readonly stri
148
148
  */
149
149
  declare function agreedMountPrefix(edges: MountEdges, childId: string): string | null;
150
150
 
151
+ /**
152
+ * The tree-sitter adapters key a node by its file and byte span,
153
+ * `file:start-end`. This finds the node a key refers to again, for an
154
+ * evaluator that gets a key back from the facts and needs the syntax.
155
+ */
156
+ /** What a tree-sitter node offers for finding it by span again. */
157
+ interface SpannedNode<N> {
158
+ readonly startIndex: number;
159
+ readonly endIndex: number;
160
+ readonly parent: N | null;
161
+ descendantForIndex(start: number, end: number): N | null;
162
+ }
163
+ /**
164
+ * The node a key refers to: the smallest node over the span, walked up
165
+ * to the one whose span matches. A key that is not a node, such as a
166
+ * name, has none.
167
+ */
168
+ declare function nodeOfKey<N extends SpannedNode<N>>(rootsByFile: ReadonlyMap<string, N>, key: string): N | null;
169
+
151
170
  /**
152
171
  * The result shape a why session hands back, shared by every language
153
172
  * adapter so the CLI reads one type regardless of which adapter
@@ -224,6 +243,14 @@ declare function singleAnswers(rows: Iterable<Tuple>, placeholders?: ReadonlySet
224
243
  /** The keys an adapter marked `placeholderValue`, for passing to `singleAnswers`. */
225
244
  declare function placeholderValues(db: Database): ReadonlySet<string>;
226
245
 
246
+ /**
247
+ * The single expression a value was written as, once the caller has
248
+ * asked the rules about `key`. A call to a project function is asked
249
+ * about as well, through `ask`, so the answer is what that function
250
+ * returns rather than the call itself.
251
+ */
252
+ declare function writtenValueOf(db: Database, key: string, ask: (keys: readonly string[]) => void): string | null;
253
+
227
254
  /** A step to the value x is written as. */
228
255
  declare const VALUE_STEP: _suss_datalog.Term;
229
256
  /**
@@ -272,4 +299,4 @@ declare const RESOLUTION_QUESTIONS: _suss_datalog.Rule[];
272
299
  /** The relations `RESOLUTION_QUESTIONS` answers into. */
273
300
  declare const ANSWER_RELATIONS: string[];
274
301
 
275
- export { ANSWER_RELATIONS, type CaseFiles, type ContractCase, type ContractOptions, type DescribeAtom, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, type FactsOf, type MountEdge, type MountEdges, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ResolutionExplanation, type ResolutionStep, type StepContext, type StepPhrase, VALUE_STEP, type ValueLocation, type WhyExplained, agreedMountPrefix, checkFactContract, explainResolutionProof, explainResolvedKey, joinMountedPath, mountPathsOf, placeholderValues, renderExplanation, singleAnswers };
302
+ export { ANSWER_RELATIONS, type CaseFiles, type ContractCase, type ContractOptions, type DescribeAtom, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, type FactsOf, type MountEdge, type MountEdges, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ResolutionExplanation, type ResolutionStep, type SpannedNode, type StepContext, type StepPhrase, VALUE_STEP, type ValueLocation, type WhyExplained, agreedMountPrefix, checkFactContract, explainResolutionProof, explainResolvedKey, joinMountedPath, mountPathsOf, nodeOfKey, placeholderValues, renderExplanation, singleAnswers, writtenValueOf };
package/dist/index.d.ts CHANGED
@@ -148,6 +148,25 @@ declare function mountPathsOf(edges: MountEdges, childId: string): readonly stri
148
148
  */
149
149
  declare function agreedMountPrefix(edges: MountEdges, childId: string): string | null;
150
150
 
151
+ /**
152
+ * The tree-sitter adapters key a node by its file and byte span,
153
+ * `file:start-end`. This finds the node a key refers to again, for an
154
+ * evaluator that gets a key back from the facts and needs the syntax.
155
+ */
156
+ /** What a tree-sitter node offers for finding it by span again. */
157
+ interface SpannedNode<N> {
158
+ readonly startIndex: number;
159
+ readonly endIndex: number;
160
+ readonly parent: N | null;
161
+ descendantForIndex(start: number, end: number): N | null;
162
+ }
163
+ /**
164
+ * The node a key refers to: the smallest node over the span, walked up
165
+ * to the one whose span matches. A key that is not a node, such as a
166
+ * name, has none.
167
+ */
168
+ declare function nodeOfKey<N extends SpannedNode<N>>(rootsByFile: ReadonlyMap<string, N>, key: string): N | null;
169
+
151
170
  /**
152
171
  * The result shape a why session hands back, shared by every language
153
172
  * adapter so the CLI reads one type regardless of which adapter
@@ -224,6 +243,14 @@ declare function singleAnswers(rows: Iterable<Tuple>, placeholders?: ReadonlySet
224
243
  /** The keys an adapter marked `placeholderValue`, for passing to `singleAnswers`. */
225
244
  declare function placeholderValues(db: Database): ReadonlySet<string>;
226
245
 
246
+ /**
247
+ * The single expression a value was written as, once the caller has
248
+ * asked the rules about `key`. A call to a project function is asked
249
+ * about as well, through `ask`, so the answer is what that function
250
+ * returns rather than the call itself.
251
+ */
252
+ declare function writtenValueOf(db: Database, key: string, ask: (keys: readonly string[]) => void): string | null;
253
+
227
254
  /** A step to the value x is written as. */
228
255
  declare const VALUE_STEP: _suss_datalog.Term;
229
256
  /**
@@ -272,4 +299,4 @@ declare const RESOLUTION_QUESTIONS: _suss_datalog.Rule[];
272
299
  /** The relations `RESOLUTION_QUESTIONS` answers into. */
273
300
  declare const ANSWER_RELATIONS: string[];
274
301
 
275
- export { ANSWER_RELATIONS, type CaseFiles, type ContractCase, type ContractOptions, type DescribeAtom, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, type FactsOf, type MountEdge, type MountEdges, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ResolutionExplanation, type ResolutionStep, type StepContext, type StepPhrase, VALUE_STEP, type ValueLocation, type WhyExplained, agreedMountPrefix, checkFactContract, explainResolutionProof, explainResolvedKey, joinMountedPath, mountPathsOf, placeholderValues, renderExplanation, singleAnswers };
302
+ export { ANSWER_RELATIONS, type CaseFiles, type ContractCase, type ContractOptions, type DescribeAtom, type ExplainOptions, type ExplainResolvedKeyOptions, type ExplainStats, FACT_CONTRACT_CASES, type FactsOf, type MountEdge, type MountEdges, NAMESPACE_IMPORT, NAMESPACE_IMPORT_NAME, RESOLUTION_QUESTIONS, RESOLUTION_RULES, RESULT_STEP, type ResolutionExplanation, type ResolutionStep, type SpannedNode, type StepContext, type StepPhrase, VALUE_STEP, type ValueLocation, type WhyExplained, agreedMountPrefix, checkFactContract, explainResolutionProof, explainResolvedKey, joinMountedPath, mountPathsOf, nodeOfKey, placeholderValues, renderExplanation, singleAnswers, writtenValueOf };
package/dist/index.js CHANGED
@@ -477,6 +477,32 @@ function pathsOf(edges, memo, childId, visiting) {
477
477
  return result;
478
478
  }
479
479
 
480
+ // src/nodeKey.ts
481
+ var SPAN_KEY = /^(.*):(\d+)-(\d+)$/;
482
+ function nodeOfKey(rootsByFile, key) {
483
+ const span = key.match(SPAN_KEY);
484
+ if (span === null) {
485
+ return null;
486
+ }
487
+ const root = rootsByFile.get(span[1]);
488
+ const start = Number(span[2]);
489
+ const end = Number(span[3]);
490
+ if (root === void 0 || end <= start) {
491
+ return null;
492
+ }
493
+ let current = root.descendantForIndex(start, end - 1);
494
+ while (current !== null) {
495
+ if (current.startIndex === start && current.endIndex === end) {
496
+ return current;
497
+ }
498
+ if (current.startIndex < start || current.endIndex > end) {
499
+ return null;
500
+ }
501
+ current = current.parent;
502
+ }
503
+ return null;
504
+ }
505
+
480
506
  // src/session.ts
481
507
  import { Database, evaluate, proofOf, witnesses } from "@suss/datalog";
482
508
  function explainResolvedKey(options) {
@@ -564,6 +590,26 @@ function withoutPlaceholders(answers, placeholders) {
564
590
  return kept;
565
591
  }
566
592
 
593
+ // src/writtenValue.ts
594
+ function writtenValueOf(db, key, ask) {
595
+ const placeholders = placeholderValues(db);
596
+ const direct = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
597
+ key
598
+ );
599
+ if (direct === void 0) {
600
+ return null;
601
+ }
602
+ const isCall = db.facts("call").some((row) => String(row[0]) === direct);
603
+ if (!isCall) {
604
+ return direct;
605
+ }
606
+ ask([direct]);
607
+ const deeper = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
608
+ direct
609
+ );
610
+ return deeper ?? direct;
611
+ }
612
+
567
613
  // src/index.ts
568
614
  import { constant, lit, rule, variable as v } from "@suss/datalog";
569
615
  var VALUE_STEP = constant("value");
@@ -1318,7 +1364,9 @@ export {
1318
1364
  explainResolvedKey,
1319
1365
  joinMountedPath,
1320
1366
  mountPathsOf,
1367
+ nodeOfKey,
1321
1368
  placeholderValues,
1322
1369
  renderExplanation,
1323
- singleAnswers
1370
+ singleAnswers,
1371
+ writtenValueOf
1324
1372
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/resolution",
3
- "version": "0.22.1",
3
+ "version": "0.22.3",
4
4
  "type": "module",
5
5
  "description": "Language-neutral rules for following a value to the function it comes down to.",
6
6
  "keywords": [
@@ -53,6 +53,6 @@
53
53
  "access": "public"
54
54
  },
55
55
  "dependencies": {
56
- "@suss/datalog": "0.22.1"
56
+ "@suss/datalog": "0.22.3"
57
57
  }
58
58
  }