@suss/adapter-python 0.19.0 → 0.20.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 CHANGED
@@ -69,6 +69,9 @@ function rangeOf(node) {
69
69
  end: node.endPosition.row + 1
70
70
  };
71
71
  }
72
+ function spanOf(node) {
73
+ return { start: node.startIndex, end: node.endIndex };
74
+ }
72
75
  function field(node, name) {
73
76
  return node.childForFieldName(name);
74
77
  }
@@ -1923,8 +1926,8 @@ function assertNever(_x) {
1923
1926
  function assert(_) {
1924
1927
  }
1925
1928
  function getEnumValues(entries) {
1926
- const numericValues = Object.values(entries).filter((v2) => typeof v2 === "number");
1927
- const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v2]) => v2);
1929
+ const numericValues = Object.values(entries).filter((v3) => typeof v3 === "number");
1930
+ const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v3]) => v3);
1928
1931
  return values;
1929
1932
  }
1930
1933
  function joinValues(array2, separator = "|") {
@@ -1978,9 +1981,9 @@ function defineLazy(object2, key, getter) {
1978
1981
  }
1979
1982
  return value;
1980
1983
  },
1981
- set(v2) {
1984
+ set(v3) {
1982
1985
  Object.defineProperty(object2, key, {
1983
- value: v2
1986
+ value: v3
1984
1987
  // configurable: true,
1985
1988
  });
1986
1989
  },
@@ -3667,10 +3670,10 @@ var $ZodUUID = /* @__PURE__ */ $constructor("$ZodUUID", (inst, def) => {
3667
3670
  v7: 7,
3668
3671
  v8: 8
3669
3672
  };
3670
- const v2 = versionMap[def.version];
3671
- if (v2 === void 0)
3673
+ const v3 = versionMap[def.version];
3674
+ if (v3 === void 0)
3672
3675
  throw new Error(`Invalid UUID version: "${def.version}"`);
3673
- def.pattern ?? (def.pattern = uuid(v2));
3676
+ def.pattern ?? (def.pattern = uuid(v3));
3674
3677
  } else
3675
3678
  def.pattern ?? (def.pattern = uuid());
3676
3679
  $ZodStringFormat.init(inst, def);
@@ -4275,8 +4278,8 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
4275
4278
  const field2 = shape[key]._zod;
4276
4279
  if (field2.values) {
4277
4280
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
4278
- for (const v2 of field2.values)
4279
- propValues[key].add(v2);
4281
+ for (const v3 of field2.values)
4282
+ propValues[key].add(v3);
4280
4283
  }
4281
4284
  }
4282
4285
  return propValues;
@@ -4571,10 +4574,10 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4571
4574
  const pv = option._zod.propValues;
4572
4575
  if (!pv || Object.keys(pv).length === 0)
4573
4576
  throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
4574
- for (const [k, v2] of Object.entries(pv)) {
4577
+ for (const [k, v3] of Object.entries(pv)) {
4575
4578
  if (!propValues[k])
4576
4579
  propValues[k] = /* @__PURE__ */ new Set();
4577
- for (const val of v2) {
4580
+ for (const val of v3) {
4578
4581
  propValues[k].add(val);
4579
4582
  }
4580
4583
  }
@@ -4588,11 +4591,11 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4588
4591
  const values = o._zod.propValues?.[def.discriminator];
4589
4592
  if (!values || values.size === 0)
4590
4593
  throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
4591
- for (const v2 of values) {
4592
- if (map2.has(v2)) {
4593
- throw new Error(`Duplicate discriminator value "${String(v2)}"`);
4594
+ for (const v3 of values) {
4595
+ if (map2.has(v3)) {
4596
+ throw new Error(`Duplicate discriminator value "${String(v3)}"`);
4594
4597
  }
4595
- map2.set(v2, o);
4598
+ map2.set(v3, o);
4596
4599
  }
4597
4600
  }
4598
4601
  return map2;
@@ -5231,8 +5234,8 @@ var $ZodPrefault = /* @__PURE__ */ $constructor("$ZodPrefault", (inst, def) => {
5231
5234
  var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def) => {
5232
5235
  $ZodType.init(inst, def);
5233
5236
  defineLazy(inst._zod, "values", () => {
5234
- const v2 = def.innerType._zod.values;
5235
- return v2 ? new Set([...v2].filter((x) => x !== void 0)) : void 0;
5237
+ const v3 = def.innerType._zod.values;
5238
+ return v3 ? new Set([...v3].filter((x) => x !== void 0)) : void 0;
5236
5239
  });
5237
5240
  inst._zod.parse = (payload, ctx) => {
5238
5241
  const result = def.innerType._zod.run(payload, ctx);
@@ -7629,7 +7632,7 @@ var error17 = () => {
7629
7632
  if (issue2.values.length === 1) {
7630
7633
  return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05E2\u05E8\u05DA \u05D7\u05D9\u05D9\u05D1 \u05DC\u05D4\u05D9\u05D5\u05EA ${stringifyPrimitive(issue2.values[0])}`;
7631
7634
  }
7632
- const stringified = issue2.values.map((v2) => stringifyPrimitive(v2));
7635
+ const stringified = issue2.values.map((v3) => stringifyPrimitive(v3));
7633
7636
  if (issue2.values.length === 2) {
7634
7637
  return `\u05E2\u05E8\u05DA \u05DC\u05D0 \u05EA\u05E7\u05D9\u05DF: \u05D4\u05D0\u05E4\u05E9\u05E8\u05D5\u05D9\u05D5\u05EA \u05D4\u05DE\u05EA\u05D0\u05D9\u05DE\u05D5\u05EA \u05D4\u05DF ${stringified[0]} \u05D0\u05D5 ${stringified[1]}`;
7635
7638
  }
@@ -12384,7 +12387,7 @@ function _set(Class2, valueType, params) {
12384
12387
  }
12385
12388
  // @__NO_SIDE_EFFECTS__
12386
12389
  function _enum(Class2, values, params) {
12387
- const entries = Array.isArray(values) ? Object.fromEntries(values.map((v2) => [v2, v2])) : values;
12390
+ const entries = Array.isArray(values) ? Object.fromEntries(values.map((v3) => [v3, v3])) : values;
12388
12391
  return new Class2({
12389
12392
  type: "enum",
12390
12393
  entries,
@@ -12589,8 +12592,8 @@ function _stringbool(Classes, _params) {
12589
12592
  let truthyArray = params.truthy ?? ["true", "1", "yes", "on", "y", "enabled"];
12590
12593
  let falsyArray = params.falsy ?? ["false", "0", "no", "off", "n", "disabled"];
12591
12594
  if (params.case !== "sensitive") {
12592
- truthyArray = truthyArray.map((v2) => typeof v2 === "string" ? v2.toLowerCase() : v2);
12593
- falsyArray = falsyArray.map((v2) => typeof v2 === "string" ? v2.toLowerCase() : v2);
12595
+ truthyArray = truthyArray.map((v3) => typeof v3 === "string" ? v3.toLowerCase() : v3);
12596
+ falsyArray = falsyArray.map((v3) => typeof v3 === "string" ? v3.toLowerCase() : v3);
12594
12597
  }
12595
12598
  const truthySet = new Set(truthyArray);
12596
12599
  const falsySet = new Set(falsyArray);
@@ -13132,9 +13135,9 @@ var dateProcessor = (_schema, ctx, _json, _params) => {
13132
13135
  var enumProcessor = (schema, _ctx, json2, _params) => {
13133
13136
  const def = schema._zod.def;
13134
13137
  const values = getEnumValues(def.entries);
13135
- if (values.every((v2) => typeof v2 === "number"))
13138
+ if (values.every((v3) => typeof v3 === "number"))
13136
13139
  json2.type = "number";
13137
- if (values.every((v2) => typeof v2 === "string"))
13140
+ if (values.every((v3) => typeof v3 === "string"))
13138
13141
  json2.type = "string";
13139
13142
  json2.enum = values;
13140
13143
  };
@@ -13167,13 +13170,13 @@ var literalProcessor = (schema, ctx, json2, _params) => {
13167
13170
  json2.const = val;
13168
13171
  }
13169
13172
  } else {
13170
- if (vals.every((v2) => typeof v2 === "number"))
13173
+ if (vals.every((v3) => typeof v3 === "number"))
13171
13174
  json2.type = "number";
13172
- if (vals.every((v2) => typeof v2 === "string"))
13175
+ if (vals.every((v3) => typeof v3 === "string"))
13173
13176
  json2.type = "string";
13174
- if (vals.every((v2) => typeof v2 === "boolean"))
13177
+ if (vals.every((v3) => typeof v3 === "boolean"))
13175
13178
  json2.type = "boolean";
13176
- if (vals.every((v2) => v2 === null))
13179
+ if (vals.every((v3) => v3 === null))
13177
13180
  json2.type = "null";
13178
13181
  json2.enum = vals;
13179
13182
  }
@@ -13271,11 +13274,11 @@ var objectProcessor = (schema, ctx, _json, params) => {
13271
13274
  }
13272
13275
  const allKeys = new Set(Object.keys(shape));
13273
13276
  const requiredKeys = new Set([...allKeys].filter((key) => {
13274
- const v2 = def.shape[key]._zod;
13277
+ const v3 = def.shape[key]._zod;
13275
13278
  if (ctx.io === "input") {
13276
- return v2.optin === void 0;
13279
+ return v3.optin === void 0;
13277
13280
  } else {
13278
- return v2.optout === void 0;
13281
+ return v3.optout === void 0;
13279
13282
  }
13280
13283
  }));
13281
13284
  if (requiredKeys.size > 0) {
@@ -13395,7 +13398,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
13395
13398
  }
13396
13399
  const keyValues = keyType._zod.values;
13397
13400
  if (keyValues) {
13398
- const validKeyValues = [...keyValues].filter((v2) => typeof v2 === "string" || typeof v2 === "number");
13401
+ const validKeyValues = [...keyValues].filter((v3) => typeof v3 === "string" || typeof v3 === "number");
13399
13402
  if (validKeyValues.length > 0) {
13400
13403
  json2.required = validKeyValues;
13401
13404
  }
@@ -13960,12 +13963,12 @@ function _installLazyMethods(inst, group, methods) {
13960
13963
  });
13961
13964
  return bound;
13962
13965
  },
13963
- set(v2) {
13966
+ set(v3) {
13964
13967
  Object.defineProperty(this, key, {
13965
13968
  configurable: true,
13966
13969
  writable: true,
13967
13970
  enumerable: true,
13968
- value: v2
13971
+ value: v3
13969
13972
  });
13970
13973
  }
13971
13974
  });
@@ -14853,7 +14856,7 @@ var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
14853
14856
  };
14854
14857
  });
14855
14858
  function _enum2(values, params) {
14856
- const entries = Array.isArray(values) ? Object.fromEntries(values.map((v2) => [v2, v2])) : values;
14859
+ const entries = Array.isArray(values) ? Object.fromEntries(values.map((v3) => [v3, v3])) : values;
14857
14860
  return new ZodEnum({
14858
14861
  type: "enum",
14859
14862
  entries,
@@ -15407,10 +15410,10 @@ function convertBaseSchema(schema, ctx) {
15407
15410
  if (enumValues.length === 1) {
15408
15411
  return z.literal(enumValues[0]);
15409
15412
  }
15410
- if (enumValues.every((v2) => typeof v2 === "string")) {
15413
+ if (enumValues.every((v3) => typeof v3 === "string")) {
15411
15414
  return z.enum(enumValues);
15412
15415
  }
15413
- const literalSchemas = enumValues.map((v2) => z.literal(v2));
15416
+ const literalSchemas = enumValues.map((v3) => z.literal(v3));
15414
15417
  if (literalSchemas.length < 2) {
15415
15418
  return literalSchemas[0];
15416
15419
  }
@@ -15757,7 +15760,7 @@ function date4(params) {
15757
15760
  // ../../../node_modules/zod/v4/classic/external.js
15758
15761
  config(en_default());
15759
15762
 
15760
- // ../../ir-core/dist/chunk-HSJYPBJU.js
15763
+ // ../../ir-core/dist/chunk-52CH76PE.js
15761
15764
  function gqlIdentityKey(typeName, fieldName) {
15762
15765
  return `gql:${typeName}.${fieldName}`;
15763
15766
  }
@@ -15821,14 +15824,24 @@ var functionCallSemantics = defineBoundarySemantics({
15821
15824
  */
15822
15825
  canPair: () => true,
15823
15826
  /**
15824
- * `"fn:<package>::<exportPath>"` when both are set. Other in-process
15825
- * function-call units, such as components and bare handlers inside
15826
- * one repo, have no key at all.
15827
+ * `"fn:<package>::<exportPath>"` when both are set, and
15828
+ * `"fn:<module>::<exportName>"` for an in-repo unit that states its
15829
+ * module, the way a server action does. Components and bare
15830
+ * handlers state neither and have no key at all.
15827
15831
  */
15832
+ rewritePaths(semantics, rewrite) {
15833
+ if (semantics.module === void 0) {
15834
+ return semantics;
15835
+ }
15836
+ return { ...semantics, module: rewrite(semantics.module) };
15837
+ },
15828
15838
  identityKey(semantics) {
15829
15839
  if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
15830
15840
  return fnIdentityKey(semantics.package, semantics.exportPath);
15831
15841
  }
15842
+ if (semantics.module !== void 0 && semantics.exportName !== void 0) {
15843
+ return fnIdentityKey(semantics.module, [semantics.exportName]);
15844
+ }
15832
15845
  return null;
15833
15846
  }
15834
15847
  }
@@ -16339,7 +16352,16 @@ var ConfidenceInfoSchema = external_exports.object({
16339
16352
  });
16340
16353
  var SourceLocationSchema = external_exports.object({
16341
16354
  file: external_exports.string(),
16355
+ /** Line numbers, for a person reading the summary or an editor link. */
16342
16356
  range: external_exports.object({ start: external_exports.number(), end: external_exports.number() }),
16357
+ /**
16358
+ * Character offsets of the unit in its file. Identity and joins
16359
+ * measure with these, since two functions can share a line and never
16360
+ * an offset range; the line `range` above is the presentation of the
16361
+ * same place. Absent on summaries no source position backs, a
16362
+ * contract artifact's say.
16363
+ */
16364
+ span: external_exports.object({ start: external_exports.number(), end: external_exports.number() }).optional(),
16343
16365
  exportName: external_exports.string().nullable(),
16344
16366
  /**
16345
16367
  * The project the extract was pointed at, by the name that project
@@ -16547,7 +16569,48 @@ var import_datalog3 = require("@suss/datalog");
16547
16569
  // ../../resolution/dist/index.js
16548
16570
  var import_datalog = require("@suss/datalog");
16549
16571
  var import_datalog2 = require("@suss/datalog");
16572
+ function joinMountedPath(prefix, path4) {
16573
+ const trimmed = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
16574
+ return trimmed === "" ? path4 : trimmed + path4;
16575
+ }
16576
+ function mountPathsOf(edges, childId) {
16577
+ return pathsOf(edges, /* @__PURE__ */ new Map(), childId, /* @__PURE__ */ new Set());
16578
+ }
16579
+ function pathsOf(edges, memo, childId, visiting) {
16580
+ const cached2 = memo.get(childId);
16581
+ if (cached2 !== void 0) {
16582
+ return cached2;
16583
+ }
16584
+ if (visiting.has(childId)) {
16585
+ memo.set(childId, null);
16586
+ return null;
16587
+ }
16588
+ const own = edges.get(childId);
16589
+ if (own === void 0 || own.length === 0) {
16590
+ memo.set(childId, [""]);
16591
+ return [""];
16592
+ }
16593
+ visiting.add(childId);
16594
+ const composed = /* @__PURE__ */ new Set();
16595
+ let unstated = false;
16596
+ for (const edge of own) {
16597
+ const parentPaths = pathsOf(edges, memo, edge.parentId, visiting);
16598
+ if (parentPaths === null) {
16599
+ unstated = true;
16600
+ break;
16601
+ }
16602
+ for (const parentPath of parentPaths) {
16603
+ composed.add(joinMountedPath(parentPath, edge.prefix));
16604
+ }
16605
+ }
16606
+ visiting.delete(childId);
16607
+ const result = unstated ? null : [...composed];
16608
+ memo.set(childId, result);
16609
+ return result;
16610
+ }
16550
16611
  var VALUE_STEP = (0, import_datalog2.constant)("value");
16612
+ var NAMESPACE_IMPORT_NAME = "*";
16613
+ var NAMESPACE_IMPORT = (0, import_datalog2.constant)(NAMESPACE_IMPORT_NAME);
16551
16614
  var RESULT_STEP = (0, import_datalog2.constant)("result");
16552
16615
  var RESOLUTION_RULES = [
16553
16616
  // Aliasing: const x = y, or an identifier referencing a declaration.
@@ -16767,6 +16830,21 @@ var RESOLUTION_RULES = [
16767
16830
  (0, import_datalog2.lit)("callKeywordArg", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("a"))
16768
16831
  ]
16769
16832
  ),
16833
+ // Which module's export a re-exported name forwards to, however
16834
+ // many barrels deep the forwarding runs.
16835
+ (0, import_datalog2.rule)(
16836
+ "moduleForwards",
16837
+ [(0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2")],
16838
+ [(0, import_datalog2.lit)("reExports", (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2"))]
16839
+ ),
16840
+ (0, import_datalog2.rule)(
16841
+ "moduleForwards",
16842
+ [(0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("m3"), (0, import_datalog2.variable)("n3")],
16843
+ [
16844
+ (0, import_datalog2.lit)("reExports", (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2")),
16845
+ (0, import_datalog2.lit)("moduleForwards", (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2"), (0, import_datalog2.variable)("m3"), (0, import_datalog2.variable)("n3"))
16846
+ ]
16847
+ ),
16770
16848
  // What a module exports: directly, or through re-export chains.
16771
16849
  (0, import_datalog2.rule)(
16772
16850
  "moduleExport",
@@ -16946,15 +17024,9 @@ var RESOLUTION_RULES = [
16946
17024
  (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
16947
17025
  ]
16948
17026
  ),
16949
- // Calling f ends up calling the name n that module m exports. One hop
16950
- // is f's own body, including the closures it declares; the other hop
16951
- // is a function f's body calls, so a wrapper of a wrapper answers
16952
- // with what the innermost one reaches.
16953
- //
16954
- // Several answers for one function is the normal case, not an
16955
- // ambiguity: a project decorator that composes two library decorators
16956
- // applies both. A caller asks whether a particular (m, n) is among
16957
- // them.
17027
+ // Calling f ends up calling the name n that module m exports, one
17028
+ // hop through f's own body or deeper through a wrapper of a wrapper.
17029
+ // Several results is normal: a composed decorator applies them all.
16958
17030
  (0, import_datalog2.rule)(
16959
17031
  "callsInto",
16960
17032
  [(0, import_datalog2.variable)("f"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
@@ -17022,6 +17094,155 @@ var RESOLUTION_QUESTIONS = [
17022
17094
  [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
17023
17095
  [(0, import_datalog2.lit)("wantedOrigin", (0, import_datalog2.variable)("x")), (0, import_datalog2.lit)("comesFrom", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))]
17024
17096
  ),
17097
+ // Call-origin questions, for attribution, in their own demand
17098
+ // class. Attribution stops at the import declaration, so nothing
17099
+ // here demands reaches or callsInto. The chains are closures with
17100
+ // no depth bound: an alias run of any length resolves.
17101
+ (0, import_datalog2.rule)("callOriginChain", [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("x")], [(0, import_datalog2.lit)("wantedCallOrigin", (0, import_datalog2.variable)("x"))]),
17102
+ (0, import_datalog2.rule)(
17103
+ "callOriginChain",
17104
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17105
+ [(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17106
+ ),
17107
+ (0, import_datalog2.rule)(
17108
+ "callOriginChain",
17109
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17110
+ [
17111
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17112
+ (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17113
+ ]
17114
+ ),
17115
+ (0, import_datalog2.rule)(
17116
+ "callOriginChain",
17117
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17118
+ [
17119
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17120
+ (0, import_datalog2.lit)("fallbackBranch", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17121
+ ]
17122
+ ),
17123
+ // The chain with at least one hop taken, which is what tells a
17124
+ // destructured binding apart from asking about a node directly.
17125
+ (0, import_datalog2.rule)(
17126
+ "callOriginChainStepped",
17127
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17128
+ [(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17129
+ ),
17130
+ (0, import_datalog2.rule)(
17131
+ "callOriginChainStepped",
17132
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17133
+ [
17134
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17135
+ (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17136
+ ]
17137
+ ),
17138
+ (0, import_datalog2.rule)(
17139
+ "callOriginChainStepped",
17140
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17141
+ [
17142
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17143
+ (0, import_datalog2.lit)("fallbackBranch", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17144
+ ]
17145
+ ),
17146
+ (0, import_datalog2.rule)(
17147
+ "wantedCallOriginPair",
17148
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
17149
+ [
17150
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17151
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
17152
+ ]
17153
+ ),
17154
+ // An import of a project barrel is an import of what the barrel
17155
+ // forwards, so the pair surfaces the module behind the chain.
17156
+ (0, import_datalog2.rule)(
17157
+ "wantedCallOriginPair",
17158
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2")],
17159
+ [
17160
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17161
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")),
17162
+ (0, import_datalog2.lit)("moduleForwards", (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("m2"), (0, import_datalog2.variable)("n2"))
17163
+ ]
17164
+ ),
17165
+ // A namespace member: the module's export of the member's own name.
17166
+ // The imports literal leads, since it is the smallest relation.
17167
+ (0, import_datalog2.rule)(
17168
+ "wantedCallOriginPair",
17169
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("p")],
17170
+ [
17171
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("o"), (0, import_datalog2.variable)("m"), NAMESPACE_IMPORT),
17172
+ (0, import_datalog2.lit)("readsProperty", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("o"), (0, import_datalog2.variable)("p")),
17173
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"))
17174
+ ]
17175
+ ),
17176
+ (0, import_datalog2.rule)(
17177
+ "wantedCallOriginPair",
17178
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("p")],
17179
+ [
17180
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("d"), (0, import_datalog2.variable)("m"), NAMESPACE_IMPORT),
17181
+ (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("o"), (0, import_datalog2.variable)("d")),
17182
+ (0, import_datalog2.lit)("readsProperty", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("o"), (0, import_datalog2.variable)("p")),
17183
+ (0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"))
17184
+ ]
17185
+ ),
17186
+ // What a call made: through the call to its callee, whose own alias
17187
+ // chain leads to the import.
17188
+ (0, import_datalog2.rule)(
17189
+ "callMadeChain",
17190
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("f")],
17191
+ [(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("c")), (0, import_datalog2.lit)("call", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("f"))]
17192
+ ),
17193
+ (0, import_datalog2.rule)(
17194
+ "callMadeChain",
17195
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17196
+ [(0, import_datalog2.lit)("callMadeChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17197
+ ),
17198
+ (0, import_datalog2.rule)(
17199
+ "callMadeChain",
17200
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17201
+ [(0, import_datalog2.lit)("callMadeChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17202
+ ),
17203
+ (0, import_datalog2.rule)(
17204
+ "wantedCallOriginPair",
17205
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
17206
+ [
17207
+ (0, import_datalog2.lit)("callMadeChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17208
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
17209
+ ]
17210
+ ),
17211
+ // A member destructured off what a call made keeps the member name
17212
+ // as one more path segment.
17213
+ (0, import_datalog2.rule)(
17214
+ "callMemberChain",
17215
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("f"), (0, import_datalog2.variable)("p")],
17216
+ [
17217
+ (0, import_datalog2.lit)("callOriginChainStepped", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("e")),
17218
+ (0, import_datalog2.lit)("readsProperty", (0, import_datalog2.variable)("e"), (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("p")),
17219
+ (0, import_datalog2.lit)("call", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("f"))
17220
+ ]
17221
+ ),
17222
+ (0, import_datalog2.rule)(
17223
+ "callMemberChain",
17224
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("p")],
17225
+ [
17226
+ (0, import_datalog2.lit)("callMemberChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("p")),
17227
+ (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17228
+ ]
17229
+ ),
17230
+ (0, import_datalog2.rule)(
17231
+ "callMemberChain",
17232
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("p")],
17233
+ [
17234
+ (0, import_datalog2.lit)("callMemberChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("p")),
17235
+ (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
17236
+ ]
17237
+ ),
17238
+ (0, import_datalog2.rule)(
17239
+ "wantedCallOriginMember",
17240
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("p")],
17241
+ [
17242
+ (0, import_datalog2.lit)("callMemberChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("p")),
17243
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
17244
+ ]
17245
+ ),
17025
17246
  (0, import_datalog2.rule)(
17026
17247
  "wantedCallsInto",
17027
17248
  [(0, import_datalog2.variable)("g"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
@@ -17030,6 +17251,81 @@ var RESOLUTION_QUESTIONS = [
17030
17251
  (0, import_datalog2.lit)("comesTo", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("g")),
17031
17252
  (0, import_datalog2.lit)("callsInto", (0, import_datalog2.variable)("g"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
17032
17253
  ]
17254
+ ),
17255
+ // The export table of one module, keyed by the module asked about.
17256
+ // The moduleExport rules flatten re-export chains of any length, and
17257
+ // the demand cone stays on export facts alone.
17258
+ (0, import_datalog2.rule)(
17259
+ "wantedModuleExport",
17260
+ [(0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("value")],
17261
+ [
17262
+ (0, import_datalog2.lit)("wantedExportsOf", (0, import_datalog2.variable)("m")),
17263
+ (0, import_datalog2.lit)("moduleExport", (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("value"))
17264
+ ]
17265
+ ),
17266
+ // The calls behind a receiver, for a pack that wants the anchor a
17267
+ // chain hangs off; the README's anchor section says which hops and
17268
+ // why the asking side applies the single-answer policy.
17269
+ // A class's ancestry, one hop per extends through the binding that
17270
+ // says which class the written base is; the names on the way out
17271
+ // are what a storage pack matches its library's bases against.
17272
+ (0, import_datalog2.rule)("ancestryChain", [(0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("c")], [(0, import_datalog2.lit)("wantedAncestry", (0, import_datalog2.variable)("c"))]),
17273
+ (0, import_datalog2.rule)(
17274
+ "ancestryChain",
17275
+ [(0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("b2")],
17276
+ [
17277
+ (0, import_datalog2.lit)("ancestryChain", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("b")),
17278
+ (0, import_datalog2.lit)("extends", (0, import_datalog2.variable)("b"), (0, import_datalog2.variable)("x")),
17279
+ (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("b2"))
17280
+ ]
17281
+ ),
17282
+ (0, import_datalog2.rule)(
17283
+ "wantedBaseName",
17284
+ [(0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("n")],
17285
+ [(0, import_datalog2.lit)("ancestryChain", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("b")), (0, import_datalog2.lit)("extendsNamed", (0, import_datalog2.variable)("b"), (0, import_datalog2.variable)("n"))]
17286
+ ),
17287
+ (0, import_datalog2.rule)("anchorChain", [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("x")], [(0, import_datalog2.lit)("wantedAnchor", (0, import_datalog2.variable)("x"))]),
17288
+ (0, import_datalog2.rule)(
17289
+ "anchorChain",
17290
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17291
+ [(0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("binds", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17292
+ ),
17293
+ (0, import_datalog2.rule)(
17294
+ "anchorChain",
17295
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17296
+ [(0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17297
+ ),
17298
+ (0, import_datalog2.rule)(
17299
+ "anchorChain",
17300
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17301
+ [(0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")), (0, import_datalog2.lit)("fallbackBranch", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))]
17302
+ ),
17303
+ (0, import_datalog2.rule)(
17304
+ "anchorChain",
17305
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
17306
+ [
17307
+ (0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17308
+ (0, import_datalog2.lit)("imports", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")),
17309
+ (0, import_datalog2.lit)("moduleExport", (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"), (0, import_datalog2.variable)("z"))
17310
+ ]
17311
+ ),
17312
+ (0, import_datalog2.rule)(
17313
+ "anchorChain",
17314
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("c")],
17315
+ [(0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")), (0, import_datalog2.lit)("call", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("c"))]
17316
+ ),
17317
+ (0, import_datalog2.rule)(
17318
+ "anchorChain",
17319
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("o")],
17320
+ [
17321
+ (0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
17322
+ (0, import_datalog2.lit)("readsProperty", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("o"), (0, import_datalog2.variable)("n"))
17323
+ ]
17324
+ ),
17325
+ (0, import_datalog2.rule)(
17326
+ "wantedAnchorCall",
17327
+ [(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")],
17328
+ [(0, import_datalog2.lit)("anchorChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")), (0, import_datalog2.lit)("call", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("c"))]
17033
17329
  )
17034
17330
  ];
17035
17331
  var ANSWER_RELATIONS = [
@@ -17796,7 +18092,7 @@ function classRouteUnits(pattern, pack, classification, classNode, module2, opti
17796
18092
  if (className === void 0 || bodyNode === null || classScope === void 0) {
17797
18093
  return [];
17798
18094
  }
17799
- const routePath = readRoutePath(
18095
+ const entries = readRoutePaths(
17800
18096
  pattern,
17801
18097
  pathArgument,
17802
18098
  classification,
@@ -17814,32 +18110,35 @@ function classRouteUnits(pattern, pack, classification, classNode, module2, opti
17814
18110
  if (verb === void 0 || methodName2 === void 0) {
17815
18111
  continue;
17816
18112
  }
17817
- units.push(
17818
- ...routeUnitOrAbstention(
17819
- {
17820
- pack,
17821
- name: `${className}.${methodName2}`,
17822
- exportPath: [className, methodName2],
17823
- method: verb,
17824
- routePath,
17825
- requestBodyFromAnnotatedClass: pattern.annotatedClassIsRequestBody === true,
17826
- readsReturnedStatus: pattern.statusFromReturnedTuple === true,
17827
- injectedCallees: new Set(pattern.injectedParameterCallees ?? []),
17828
- definitionNode: maybeMethod,
17829
- enclosingScope: classScope,
17830
- module: module2,
17831
- filePath: options.filePath,
17832
- skipReceiverParam: true,
17833
- responseShape: import_extractor3.absentReading,
17834
- statusCode: defaultedStatus(
17835
- readReturnedStatus(pattern, maybeMethod),
17836
- pattern
17837
- ),
17838
- storage: options.storage
17839
- },
17840
- options
17841
- )
17842
- );
18113
+ for (const entry of entries) {
18114
+ units.push(
18115
+ ...routeUnitOrAbstention(
18116
+ {
18117
+ pack,
18118
+ name: `${className}.${methodName2}`,
18119
+ exportPath: [className, methodName2],
18120
+ method: verb,
18121
+ routePath: entry.routePath,
18122
+ ...entry.mount !== void 0 ? { mount: entry.mount } : {},
18123
+ requestBodyFromAnnotatedClass: pattern.annotatedClassIsRequestBody === true,
18124
+ readsReturnedStatus: pattern.statusFromReturnedTuple === true,
18125
+ injectedCallees: new Set(pattern.injectedParameterCallees ?? []),
18126
+ definitionNode: maybeMethod,
18127
+ enclosingScope: classScope,
18128
+ module: module2,
18129
+ filePath: options.filePath,
18130
+ skipReceiverParam: true,
18131
+ responseShape: import_extractor3.absentReading,
18132
+ statusCode: defaultedStatus(
18133
+ readReturnedStatus(pattern, maybeMethod),
18134
+ pattern
18135
+ ),
18136
+ storage: options.storage
18137
+ },
18138
+ options
18139
+ )
18140
+ );
18141
+ }
17843
18142
  }
17844
18143
  return units;
17845
18144
  }
@@ -17853,6 +18152,47 @@ function readRoutePath(pattern, pathArgument, classification, module2, options)
17853
18152
  (path4, range) => readPathTemplate(pattern, path4, range)
17854
18153
  );
17855
18154
  }
18155
+ function readRoutePaths(pattern, pathArgument, classification, module2, options) {
18156
+ const resolution = routerResolutionOf(
18157
+ pattern,
18158
+ classification,
18159
+ module2,
18160
+ options
18161
+ );
18162
+ if (resolution?.kind !== "composedMany") {
18163
+ return [
18164
+ {
18165
+ routePath: readRoutePath(
18166
+ pattern,
18167
+ pathArgument,
18168
+ classification,
18169
+ module2,
18170
+ options
18171
+ )
18172
+ }
18173
+ ];
18174
+ }
18175
+ return resolution.values.map((prefix) => ({
18176
+ routePath: (0, import_extractor3.andThenReading)(
18177
+ (0, import_extractor3.andThenReading)(
18178
+ pathArgument,
18179
+ (literal2, range) => (0, import_extractor3.writtenReading)(servedSpelling(pattern, prefix + literal2), range)
18180
+ ),
18181
+ (path4, range) => readPathTemplate(pattern, path4, range)
18182
+ ),
18183
+ mount: { siblings: resolution.values.length, prefix }
18184
+ }));
18185
+ }
18186
+ function routerResolutionOf(pattern, classification, module2, options) {
18187
+ if (pattern.routerComposition === void 0 || options.routerIndex === void 0 || classification.objectName === null) {
18188
+ return null;
18189
+ }
18190
+ return options.routerIndex.resolve(
18191
+ pattern,
18192
+ classification.objectModule ?? module2,
18193
+ classification.objectName
18194
+ );
18195
+ }
17856
18196
  function composeRoutePath(pattern, classification, module2, options, literal2, range) {
17857
18197
  const prefix = readRouterPrefix(
17858
18198
  pattern,
@@ -18106,39 +18446,42 @@ function functionRouteUnits(pattern, pack, verb, classification, functionNode, m
18106
18446
  return [];
18107
18447
  }
18108
18448
  const ctx = createAnnotationContext(module2.scopeFor);
18109
- return routeUnitOrAbstention(
18110
- {
18111
- pack,
18112
- name: functionName,
18113
- exportPath: [functionName],
18114
- method: verb,
18115
- routePath: readRoutePath(
18116
- pattern,
18117
- readPathArgument(classification),
18118
- classification,
18119
- module2,
18120
- options
18121
- ),
18122
- requestBodyFromAnnotatedClass: pattern.annotatedClassIsRequestBody === true,
18123
- readsReturnedStatus: pattern.statusFromReturnedTuple === true,
18124
- injectedCallees: new Set(pattern.injectedParameterCallees ?? []),
18125
- definitionNode: functionNode,
18126
- enclosingScope: module2.moduleScope,
18127
- module: module2,
18128
- filePath: options.filePath,
18129
- skipReceiverParam: false,
18130
- responseShape: readResponseModel(pattern, classification, module2, ctx),
18131
- statusCode: defaultedStatus(
18132
- declaredOrReturnedStatus(
18133
- readStatusCode(pattern, classification),
18134
- readReturnedStatus(pattern, functionNode)
18135
- ),
18136
- pattern
18137
- ),
18138
- definitionsCtx: ctx,
18139
- storage: options.storage
18140
- },
18449
+ return readRoutePaths(
18450
+ pattern,
18451
+ readPathArgument(classification),
18452
+ classification,
18453
+ module2,
18141
18454
  options
18455
+ ).flatMap(
18456
+ (entry) => routeUnitOrAbstention(
18457
+ {
18458
+ pack,
18459
+ name: functionName,
18460
+ exportPath: [functionName],
18461
+ method: verb,
18462
+ routePath: entry.routePath,
18463
+ ...entry.mount !== void 0 ? { mount: entry.mount } : {},
18464
+ requestBodyFromAnnotatedClass: pattern.annotatedClassIsRequestBody === true,
18465
+ readsReturnedStatus: pattern.statusFromReturnedTuple === true,
18466
+ injectedCallees: new Set(pattern.injectedParameterCallees ?? []),
18467
+ definitionNode: functionNode,
18468
+ enclosingScope: module2.moduleScope,
18469
+ module: module2,
18470
+ filePath: options.filePath,
18471
+ skipReceiverParam: false,
18472
+ responseShape: readResponseModel(pattern, classification, module2, ctx),
18473
+ statusCode: defaultedStatus(
18474
+ declaredOrReturnedStatus(
18475
+ readStatusCode(pattern, classification),
18476
+ readReturnedStatus(pattern, functionNode)
18477
+ ),
18478
+ pattern
18479
+ ),
18480
+ definitionsCtx: ctx,
18481
+ storage: options.storage
18482
+ },
18483
+ options
18484
+ )
18142
18485
  );
18143
18486
  }
18144
18487
  function readResponseShape(declared, readAnnotation) {
@@ -18281,6 +18624,7 @@ function buildRouteUnit(options) {
18281
18624
  kind: "handler",
18282
18625
  file: filePath,
18283
18626
  range: rangeOf(definitionNode),
18627
+ span: spanOf(definitionNode),
18284
18628
  exportName: exportPath[0] ?? name,
18285
18629
  exportPath
18286
18630
  },
@@ -18300,7 +18644,8 @@ function buildRouteUnit(options) {
18300
18644
  ...unreadRoleReadings(parameters, rangeOf(definitionNode)),
18301
18645
  ...responseShape.passedOver
18302
18646
  ],
18303
- ...collectedDefinitions(ctx) !== null ? { definitions: collectedDefinitions(ctx) } : {}
18647
+ ...collectedDefinitions(ctx) !== null ? { definitions: collectedDefinitions(ctx) } : {},
18648
+ ...options.mount !== void 0 ? { mount: options.mount } : {}
18304
18649
  };
18305
18650
  }
18306
18651
  function unreadRoleReadings(parameters, range) {
@@ -18693,24 +19038,90 @@ function buildRouterIndex(files, packs, resolverOptions) {
18693
19038
  return ownPrefix;
18694
19039
  }
18695
19040
  const routerPath = displayPaths.get(module2);
18696
- const mount = index.mounts.get(construction);
18697
- if (mount === void 0) {
19041
+ const states = index.mounts.get(construction);
19042
+ if (states === void 0 || states.length === 0) {
18698
19043
  return { kind: "abstain", reason: unmountedReason(index, routerPath) };
18699
19044
  }
18700
- if (mount.kind === "abstain") {
18701
- return { kind: "abstain", reason: mount.reason };
19045
+ for (const state of states) {
19046
+ if (state.kind === "abstain") {
19047
+ return { kind: "abstain", reason: state.reason };
19048
+ }
19049
+ const rivalled = rivalRegistration(index, state.site, routerPath);
19050
+ if (rivalled !== null) {
19051
+ return { kind: "abstain", reason: rivalled };
19052
+ }
19053
+ }
19054
+ const composed = composedMountPrefix(index, construction);
19055
+ if (composed.kind === "abstain") {
19056
+ return composed;
18702
19057
  }
18703
- const rivalled = rivalRegistration(index, mount.site, routerPath);
18704
- if (rivalled !== null) {
18705
- return { kind: "abstain", reason: rivalled };
19058
+ if (composed.kind === "composedMany") {
19059
+ return {
19060
+ kind: "composedMany",
19061
+ values: composed.values.map((value) => value + ownPrefix.value)
19062
+ };
18706
19063
  }
18707
19064
  return {
18708
19065
  kind: "composed",
18709
- value: mount.includePrefix + ownPrefix.value
19066
+ value: composed.value + ownPrefix.value
18710
19067
  };
18711
19068
  }
18712
19069
  };
18713
19070
  }
19071
+ function composedMountPrefix(index, construction) {
19072
+ const paths = mountPathsOf(mountEdgesOf(index), construction.valueKey);
19073
+ if (paths === null) {
19074
+ return {
19075
+ kind: "abstain",
19076
+ reason: "is mounted through a chain of routers this reading cannot compose"
19077
+ };
19078
+ }
19079
+ const distinct = [...new Set(paths)];
19080
+ const only = distinct[0];
19081
+ if (only === void 0) {
19082
+ return {
19083
+ kind: "abstain",
19084
+ reason: "is mounted through a chain of routers this reading cannot compose"
19085
+ };
19086
+ }
19087
+ if (distinct.length > 1) {
19088
+ return { kind: "composedMany", values: distinct };
19089
+ }
19090
+ return { kind: "composed", value: only };
19091
+ }
19092
+ function mountEdgesOf(index) {
19093
+ if (index.mountEdges !== void 0) {
19094
+ return index.mountEdges;
19095
+ }
19096
+ const edges = /* @__PURE__ */ new Map();
19097
+ const push = (childKey, edge) => {
19098
+ const list = edges.get(childKey) ?? [];
19099
+ list.push(edge);
19100
+ edges.set(childKey, list);
19101
+ };
19102
+ for (const [target, states] of index.mounts) {
19103
+ for (const state of states) {
19104
+ if (state.kind === "abstain") {
19105
+ push(target.valueKey, { parentId: target.valueKey, prefix: "" });
19106
+ continue;
19107
+ }
19108
+ push(target.valueKey, {
19109
+ parentId: state.parentValueKey ?? rootKeyOf(target),
19110
+ prefix: state.includePrefix
19111
+ });
19112
+ }
19113
+ }
19114
+ for (const [valueKey2, construction] of index.byValueKey) {
19115
+ if (!index.mounts.has(construction)) {
19116
+ push(valueKey2, { parentId: valueKey2, prefix: "" });
19117
+ }
19118
+ }
19119
+ index.mountEdges = edges;
19120
+ return edges;
19121
+ }
19122
+ function rootKeyOf(target) {
19123
+ return `root:${target.valueKey}`;
19124
+ }
18714
19125
  function declaredOnMountObject(index, module2, objectName) {
18715
19126
  const objectPrefix = index.objectPrefixes.get(module2)?.get(objectName);
18716
19127
  if (objectPrefix === void 0) {
@@ -19051,7 +19462,8 @@ var MOUNT_STATE_BY_EFFECT = {
19051
19462
  prefixes: (statedPrefix, site) => ({
19052
19463
  kind: "mounted",
19053
19464
  includePrefix: statedPrefix,
19054
- site
19465
+ site,
19466
+ parentValueKey: null
19055
19467
  }),
19056
19468
  replaces: () => ({
19057
19469
  kind: "abstain",
@@ -19059,14 +19471,9 @@ var MOUNT_STATE_BY_EFFECT = {
19059
19471
  })
19060
19472
  };
19061
19473
  function recordMount(index, target, state) {
19062
- if (index.mounts.has(target)) {
19063
- index.mounts.set(target, {
19064
- kind: "abstain",
19065
- reason: "is mounted more than once"
19066
- });
19067
- return;
19068
- }
19069
- index.mounts.set(target, state);
19474
+ const states = index.mounts.get(target) ?? [];
19475
+ states.push(state);
19476
+ index.mounts.set(target, states);
19070
19477
  }
19071
19478
  function collectMounts(bound, byFile, importModule, composition, resolverOptions, index) {
19072
19479
  const scan = {
@@ -19095,7 +19502,7 @@ var WALK_DESCENTS = {
19095
19502
  decorated_definition: (stmt, position, scan, visit) => {
19096
19503
  walkStatements([stripDecorators(stmt).definition], position, scan, visit);
19097
19504
  },
19098
- function_definition: (stmt, position, scan, visit) => {
19505
+ function_definition: (stmt, _position, scan, visit) => {
19099
19506
  const scope = scan.bound.module.scopeFor.get(stmt.id);
19100
19507
  if (scope === void 0) {
19101
19508
  return;
@@ -19326,8 +19733,10 @@ function recordMountStatement(stmt, position, scan) {
19326
19733
  position.scope,
19327
19734
  scan
19328
19735
  );
19736
+ const includerKey = nodeId(scan.bound.file, mountCall.includerCall);
19329
19737
  const state = mountStateOf(
19330
19738
  mountCall.includerConstructorName,
19739
+ scan.index.byValueKey.get(includerKey) ?? null,
19331
19740
  keywordArgs,
19332
19741
  objectPrefix,
19333
19742
  scan.composition,
@@ -19339,18 +19748,15 @@ function recordMountStatement(stmt, position, scan) {
19339
19748
  recordMount(scan.index, target, state);
19340
19749
  }
19341
19750
  }
19342
- function mountStateOf(includerConstructorName, keywordArgs, objectPrefix, composition, site, scope) {
19343
- if (includerConstructorName === composition.routerConstructorName) {
19344
- return {
19345
- kind: "abstain",
19346
- reason: "is mounted onto another router, one hop past what this reading follows"
19347
- };
19348
- }
19349
- if (objectPrefix.kind === "abstain") {
19350
- return {
19351
- kind: "abstain",
19352
- reason: `is mounted on an object that ${objectPrefix.reason}`
19353
- };
19751
+ function mountStateOf(includerConstructorName, includer, keywordArgs, objectPrefix, composition, site, scope) {
19752
+ const base = mountBaseOf(
19753
+ includerConstructorName,
19754
+ includer,
19755
+ objectPrefix,
19756
+ composition
19757
+ );
19758
+ if (base.kind === "abstain") {
19759
+ return base;
19354
19760
  }
19355
19761
  const mountPrefix = readPrefixKeyword(
19356
19762
  keywordArgs,
@@ -19365,14 +19771,56 @@ function mountStateOf(includerConstructorName, keywordArgs, objectPrefix, compos
19365
19771
  };
19366
19772
  }
19367
19773
  if (mountPrefix.kind === "unstated") {
19368
- return { kind: "mounted", includePrefix: objectPrefix.value, site };
19774
+ return {
19775
+ kind: "mounted",
19776
+ includePrefix: base.value,
19777
+ site,
19778
+ parentValueKey: base.parentValueKey
19779
+ };
19369
19780
  }
19370
19781
  const effect = composition.mountPrefixEffect ?? "prefixes";
19371
19782
  const state = MOUNT_STATE_BY_EFFECT[effect](mountPrefix.value, site);
19372
19783
  if (state.kind === "abstain") {
19373
19784
  return state;
19374
19785
  }
19375
- return { ...state, includePrefix: objectPrefix.value + state.includePrefix };
19786
+ return {
19787
+ ...state,
19788
+ includePrefix: base.value + state.includePrefix,
19789
+ parentValueKey: base.parentValueKey
19790
+ };
19791
+ }
19792
+ function mountBaseOf(includerConstructorName, includer, objectPrefix, composition) {
19793
+ if (includerConstructorName !== composition.routerConstructorName) {
19794
+ if (objectPrefix.kind === "abstain") {
19795
+ return {
19796
+ kind: "abstain",
19797
+ reason: `is mounted on an object that ${objectPrefix.reason}`
19798
+ };
19799
+ }
19800
+ return {
19801
+ kind: "composed",
19802
+ value: objectPrefix.value,
19803
+ parentValueKey: null
19804
+ };
19805
+ }
19806
+ if (includer === null) {
19807
+ return {
19808
+ kind: "abstain",
19809
+ reason: "is mounted onto a router this reading never saw constructed"
19810
+ };
19811
+ }
19812
+ const parentOwn = composedOwnPrefix(includer.prefix, composition);
19813
+ if (parentOwn.kind === "abstain") {
19814
+ return {
19815
+ kind: "abstain",
19816
+ reason: `is mounted onto a router that ${parentOwn.reason}`
19817
+ };
19818
+ }
19819
+ return {
19820
+ kind: "composed",
19821
+ value: parentOwn.value,
19822
+ parentValueKey: includer.valueKey
19823
+ };
19376
19824
  }
19377
19825
  function collectCarrierCalls(carrier, scan) {
19378
19826
  walkStatements(
@@ -19650,7 +20098,11 @@ async function extractPythonProject(options) {
19650
20098
  ...couldMatch,
19651
20099
  ...storagePatterns.flatMap((pattern) => pattern.queryFunctions ?? [])
19652
20100
  ]);
19653
- const leadsToStorage = functionsReachingStorage(definitions, startsAQuery);
20101
+ const leadsToStorage = functionsReachingStorage(
20102
+ db,
20103
+ definitions,
20104
+ startsAQuery
20105
+ );
19654
20106
  const routerIndex = buildRouterIndex(bound, options.packs, {
19655
20107
  roots: options.roots,
19656
20108
  ...mountsRouters ? { facts: db } : {}
@@ -19779,32 +20231,33 @@ function callsUnder(node, found = []) {
19779
20231
  }
19780
20232
  return found;
19781
20233
  }
19782
- function functionsReachingStorage(definitions, couldMatch) {
19783
- const bodies = [];
20234
+ var REACHES_STORAGE_RULES = [
20235
+ (0, import_datalog4.rule)(
20236
+ "reachesStorage",
20237
+ [(0, import_datalog4.variable)("f")],
20238
+ [(0, import_datalog4.lit)("defCallsName", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("m")), (0, import_datalog4.lit)("queryStart", (0, import_datalog4.variable)("m"))]
20239
+ ),
20240
+ (0, import_datalog4.rule)(
20241
+ "reachesStorage",
20242
+ [(0, import_datalog4.variable)("f")],
20243
+ [(0, import_datalog4.lit)("defCallsName", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("m")), (0, import_datalog4.lit)("reachesStorage", (0, import_datalog4.variable)("m"))]
20244
+ )
20245
+ ];
20246
+ function functionsReachingStorage(db, definitions, couldMatch) {
19784
20247
  for (const node of definitions.values()) {
19785
20248
  const name = field(node, "name");
19786
20249
  if (name === null) {
19787
20250
  continue;
19788
20251
  }
19789
- bodies.push({ name: name.text, calls: callsUnder(node).map(calledName) });
19790
- }
19791
- const reaching = /* @__PURE__ */ new Set();
19792
- for (const body of bodies) {
19793
- if (body.calls.some((called) => couldMatch.has(called))) {
19794
- reaching.add(body.name);
20252
+ for (const called of callsUnder(node).map(calledName)) {
20253
+ db.add("defCallsName", [name.text, called]);
19795
20254
  }
19796
20255
  }
19797
- for (let grew = true; grew; ) {
19798
- grew = false;
19799
- for (const body of bodies) {
19800
- if (reaching.has(body.name) || !body.calls.some((c) => reaching.has(c))) {
19801
- continue;
19802
- }
19803
- reaching.add(body.name);
19804
- grew = true;
19805
- }
20256
+ for (const name of couldMatch) {
20257
+ db.add("queryStart", [name]);
19806
20258
  }
19807
- return reaching;
20259
+ (0, import_datalog4.evaluate)(db, REACHES_STORAGE_RULES);
20260
+ return new Set(db.facts("reachesStorage").map((row) => String(row[0])));
19808
20261
  }
19809
20262
  // Annotate the CommonJS export names for ESM import in node:
19810
20263
  0 && (module.exports = {