@suss/adapter-ruby 0.18.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 +809 -60
- package/dist/index.js +807 -58
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -12,6 +12,9 @@ function rangeOf(node) {
|
|
|
12
12
|
end: node.endPosition.row + 1
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
+
function spanOf(node) {
|
|
16
|
+
return { start: node.startIndex, end: node.endIndex };
|
|
17
|
+
}
|
|
15
18
|
function field(node, name) {
|
|
16
19
|
return node.childForFieldName(name);
|
|
17
20
|
}
|
|
@@ -731,6 +734,9 @@ function invocationEffects(definitionNode) {
|
|
|
731
734
|
});
|
|
732
735
|
}
|
|
733
736
|
|
|
737
|
+
// src/storage.ts
|
|
738
|
+
import { deriveOnDemand, evaluate } from "@suss/datalog";
|
|
739
|
+
|
|
734
740
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
735
741
|
var external_exports = {};
|
|
736
742
|
__export(external_exports, {
|
|
@@ -1411,8 +1417,8 @@ function assertNever(_x) {
|
|
|
1411
1417
|
function assert(_) {
|
|
1412
1418
|
}
|
|
1413
1419
|
function getEnumValues(entries) {
|
|
1414
|
-
const numericValues = Object.values(entries).filter((
|
|
1415
|
-
const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_,
|
|
1420
|
+
const numericValues = Object.values(entries).filter((v2) => typeof v2 === "number");
|
|
1421
|
+
const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v2]) => v2);
|
|
1416
1422
|
return values;
|
|
1417
1423
|
}
|
|
1418
1424
|
function joinValues(array2, separator = "|") {
|
|
@@ -1466,9 +1472,9 @@ function defineLazy(object2, key, getter) {
|
|
|
1466
1472
|
}
|
|
1467
1473
|
return value;
|
|
1468
1474
|
},
|
|
1469
|
-
set(
|
|
1475
|
+
set(v2) {
|
|
1470
1476
|
Object.defineProperty(object2, key, {
|
|
1471
|
-
value:
|
|
1477
|
+
value: v2
|
|
1472
1478
|
// configurable: true,
|
|
1473
1479
|
});
|
|
1474
1480
|
},
|
|
@@ -3155,10 +3161,10 @@ var $ZodUUID = /* @__PURE__ */ $constructor("$ZodUUID", (inst, def) => {
|
|
|
3155
3161
|
v7: 7,
|
|
3156
3162
|
v8: 8
|
|
3157
3163
|
};
|
|
3158
|
-
const
|
|
3159
|
-
if (
|
|
3164
|
+
const v2 = versionMap[def.version];
|
|
3165
|
+
if (v2 === void 0)
|
|
3160
3166
|
throw new Error(`Invalid UUID version: "${def.version}"`);
|
|
3161
|
-
def.pattern ?? (def.pattern = uuid(
|
|
3167
|
+
def.pattern ?? (def.pattern = uuid(v2));
|
|
3162
3168
|
} else
|
|
3163
3169
|
def.pattern ?? (def.pattern = uuid());
|
|
3164
3170
|
$ZodStringFormat.init(inst, def);
|
|
@@ -3763,8 +3769,8 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
3763
3769
|
const field2 = shape[key]._zod;
|
|
3764
3770
|
if (field2.values) {
|
|
3765
3771
|
propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
|
|
3766
|
-
for (const
|
|
3767
|
-
propValues[key].add(
|
|
3772
|
+
for (const v2 of field2.values)
|
|
3773
|
+
propValues[key].add(v2);
|
|
3768
3774
|
}
|
|
3769
3775
|
}
|
|
3770
3776
|
return propValues;
|
|
@@ -4059,10 +4065,10 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
4059
4065
|
const pv = option._zod.propValues;
|
|
4060
4066
|
if (!pv || Object.keys(pv).length === 0)
|
|
4061
4067
|
throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
|
|
4062
|
-
for (const [k,
|
|
4068
|
+
for (const [k, v2] of Object.entries(pv)) {
|
|
4063
4069
|
if (!propValues[k])
|
|
4064
4070
|
propValues[k] = /* @__PURE__ */ new Set();
|
|
4065
|
-
for (const val of
|
|
4071
|
+
for (const val of v2) {
|
|
4066
4072
|
propValues[k].add(val);
|
|
4067
4073
|
}
|
|
4068
4074
|
}
|
|
@@ -4076,11 +4082,11 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
|
|
|
4076
4082
|
const values = o._zod.propValues?.[def.discriminator];
|
|
4077
4083
|
if (!values || values.size === 0)
|
|
4078
4084
|
throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
|
|
4079
|
-
for (const
|
|
4080
|
-
if (map2.has(
|
|
4081
|
-
throw new Error(`Duplicate discriminator value "${String(
|
|
4085
|
+
for (const v2 of values) {
|
|
4086
|
+
if (map2.has(v2)) {
|
|
4087
|
+
throw new Error(`Duplicate discriminator value "${String(v2)}"`);
|
|
4082
4088
|
}
|
|
4083
|
-
map2.set(
|
|
4089
|
+
map2.set(v2, o);
|
|
4084
4090
|
}
|
|
4085
4091
|
}
|
|
4086
4092
|
return map2;
|
|
@@ -4719,8 +4725,8 @@ var $ZodPrefault = /* @__PURE__ */ $constructor("$ZodPrefault", (inst, def) => {
|
|
|
4719
4725
|
var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def) => {
|
|
4720
4726
|
$ZodType.init(inst, def);
|
|
4721
4727
|
defineLazy(inst._zod, "values", () => {
|
|
4722
|
-
const
|
|
4723
|
-
return
|
|
4728
|
+
const v2 = def.innerType._zod.values;
|
|
4729
|
+
return v2 ? new Set([...v2].filter((x) => x !== void 0)) : void 0;
|
|
4724
4730
|
});
|
|
4725
4731
|
inst._zod.parse = (payload, ctx) => {
|
|
4726
4732
|
const result = def.innerType._zod.run(payload, ctx);
|
|
@@ -7117,7 +7123,7 @@ var error17 = () => {
|
|
|
7117
7123
|
if (issue2.values.length === 1) {
|
|
7118
7124
|
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])}`;
|
|
7119
7125
|
}
|
|
7120
|
-
const stringified = issue2.values.map((
|
|
7126
|
+
const stringified = issue2.values.map((v2) => stringifyPrimitive(v2));
|
|
7121
7127
|
if (issue2.values.length === 2) {
|
|
7122
7128
|
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]}`;
|
|
7123
7129
|
}
|
|
@@ -11872,7 +11878,7 @@ function _set(Class2, valueType, params) {
|
|
|
11872
11878
|
}
|
|
11873
11879
|
// @__NO_SIDE_EFFECTS__
|
|
11874
11880
|
function _enum(Class2, values, params) {
|
|
11875
|
-
const entries = Array.isArray(values) ? Object.fromEntries(values.map((
|
|
11881
|
+
const entries = Array.isArray(values) ? Object.fromEntries(values.map((v2) => [v2, v2])) : values;
|
|
11876
11882
|
return new Class2({
|
|
11877
11883
|
type: "enum",
|
|
11878
11884
|
entries,
|
|
@@ -12077,8 +12083,8 @@ function _stringbool(Classes, _params) {
|
|
|
12077
12083
|
let truthyArray = params.truthy ?? ["true", "1", "yes", "on", "y", "enabled"];
|
|
12078
12084
|
let falsyArray = params.falsy ?? ["false", "0", "no", "off", "n", "disabled"];
|
|
12079
12085
|
if (params.case !== "sensitive") {
|
|
12080
|
-
truthyArray = truthyArray.map((
|
|
12081
|
-
falsyArray = falsyArray.map((
|
|
12086
|
+
truthyArray = truthyArray.map((v2) => typeof v2 === "string" ? v2.toLowerCase() : v2);
|
|
12087
|
+
falsyArray = falsyArray.map((v2) => typeof v2 === "string" ? v2.toLowerCase() : v2);
|
|
12082
12088
|
}
|
|
12083
12089
|
const truthySet = new Set(truthyArray);
|
|
12084
12090
|
const falsySet = new Set(falsyArray);
|
|
@@ -12620,9 +12626,9 @@ var dateProcessor = (_schema, ctx, _json, _params) => {
|
|
|
12620
12626
|
var enumProcessor = (schema, _ctx, json2, _params) => {
|
|
12621
12627
|
const def = schema._zod.def;
|
|
12622
12628
|
const values = getEnumValues(def.entries);
|
|
12623
|
-
if (values.every((
|
|
12629
|
+
if (values.every((v2) => typeof v2 === "number"))
|
|
12624
12630
|
json2.type = "number";
|
|
12625
|
-
if (values.every((
|
|
12631
|
+
if (values.every((v2) => typeof v2 === "string"))
|
|
12626
12632
|
json2.type = "string";
|
|
12627
12633
|
json2.enum = values;
|
|
12628
12634
|
};
|
|
@@ -12655,13 +12661,13 @@ var literalProcessor = (schema, ctx, json2, _params) => {
|
|
|
12655
12661
|
json2.const = val;
|
|
12656
12662
|
}
|
|
12657
12663
|
} else {
|
|
12658
|
-
if (vals.every((
|
|
12664
|
+
if (vals.every((v2) => typeof v2 === "number"))
|
|
12659
12665
|
json2.type = "number";
|
|
12660
|
-
if (vals.every((
|
|
12666
|
+
if (vals.every((v2) => typeof v2 === "string"))
|
|
12661
12667
|
json2.type = "string";
|
|
12662
|
-
if (vals.every((
|
|
12668
|
+
if (vals.every((v2) => typeof v2 === "boolean"))
|
|
12663
12669
|
json2.type = "boolean";
|
|
12664
|
-
if (vals.every((
|
|
12670
|
+
if (vals.every((v2) => v2 === null))
|
|
12665
12671
|
json2.type = "null";
|
|
12666
12672
|
json2.enum = vals;
|
|
12667
12673
|
}
|
|
@@ -12759,11 +12765,11 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
12759
12765
|
}
|
|
12760
12766
|
const allKeys = new Set(Object.keys(shape));
|
|
12761
12767
|
const requiredKeys = new Set([...allKeys].filter((key) => {
|
|
12762
|
-
const
|
|
12768
|
+
const v2 = def.shape[key]._zod;
|
|
12763
12769
|
if (ctx.io === "input") {
|
|
12764
|
-
return
|
|
12770
|
+
return v2.optin === void 0;
|
|
12765
12771
|
} else {
|
|
12766
|
-
return
|
|
12772
|
+
return v2.optout === void 0;
|
|
12767
12773
|
}
|
|
12768
12774
|
}));
|
|
12769
12775
|
if (requiredKeys.size > 0) {
|
|
@@ -12883,7 +12889,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
12883
12889
|
}
|
|
12884
12890
|
const keyValues = keyType._zod.values;
|
|
12885
12891
|
if (keyValues) {
|
|
12886
|
-
const validKeyValues = [...keyValues].filter((
|
|
12892
|
+
const validKeyValues = [...keyValues].filter((v2) => typeof v2 === "string" || typeof v2 === "number");
|
|
12887
12893
|
if (validKeyValues.length > 0) {
|
|
12888
12894
|
json2.required = validKeyValues;
|
|
12889
12895
|
}
|
|
@@ -13448,12 +13454,12 @@ function _installLazyMethods(inst, group, methods) {
|
|
|
13448
13454
|
});
|
|
13449
13455
|
return bound;
|
|
13450
13456
|
},
|
|
13451
|
-
set(
|
|
13457
|
+
set(v2) {
|
|
13452
13458
|
Object.defineProperty(this, key, {
|
|
13453
13459
|
configurable: true,
|
|
13454
13460
|
writable: true,
|
|
13455
13461
|
enumerable: true,
|
|
13456
|
-
value:
|
|
13462
|
+
value: v2
|
|
13457
13463
|
});
|
|
13458
13464
|
}
|
|
13459
13465
|
});
|
|
@@ -14341,7 +14347,7 @@ var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
|
|
|
14341
14347
|
};
|
|
14342
14348
|
});
|
|
14343
14349
|
function _enum2(values, params) {
|
|
14344
|
-
const entries = Array.isArray(values) ? Object.fromEntries(values.map((
|
|
14350
|
+
const entries = Array.isArray(values) ? Object.fromEntries(values.map((v2) => [v2, v2])) : values;
|
|
14345
14351
|
return new ZodEnum({
|
|
14346
14352
|
type: "enum",
|
|
14347
14353
|
entries,
|
|
@@ -14895,10 +14901,10 @@ function convertBaseSchema(schema, ctx) {
|
|
|
14895
14901
|
if (enumValues.length === 1) {
|
|
14896
14902
|
return z.literal(enumValues[0]);
|
|
14897
14903
|
}
|
|
14898
|
-
if (enumValues.every((
|
|
14904
|
+
if (enumValues.every((v2) => typeof v2 === "string")) {
|
|
14899
14905
|
return z.enum(enumValues);
|
|
14900
14906
|
}
|
|
14901
|
-
const literalSchemas = enumValues.map((
|
|
14907
|
+
const literalSchemas = enumValues.map((v2) => z.literal(v2));
|
|
14902
14908
|
if (literalSchemas.length < 2) {
|
|
14903
14909
|
return literalSchemas[0];
|
|
14904
14910
|
}
|
|
@@ -15245,7 +15251,7 @@ function date4(params) {
|
|
|
15245
15251
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15246
15252
|
config(en_default());
|
|
15247
15253
|
|
|
15248
|
-
// ../../ir-core/dist/chunk-
|
|
15254
|
+
// ../../ir-core/dist/chunk-52CH76PE.js
|
|
15249
15255
|
function gqlIdentityKey(typeName, fieldName) {
|
|
15250
15256
|
return `gql:${typeName}.${fieldName}`;
|
|
15251
15257
|
}
|
|
@@ -15309,14 +15315,24 @@ var functionCallSemantics = defineBoundarySemantics({
|
|
|
15309
15315
|
*/
|
|
15310
15316
|
canPair: () => true,
|
|
15311
15317
|
/**
|
|
15312
|
-
* `"fn:<package>::<exportPath>"` when both are set
|
|
15313
|
-
*
|
|
15314
|
-
*
|
|
15318
|
+
* `"fn:<package>::<exportPath>"` when both are set, and
|
|
15319
|
+
* `"fn:<module>::<exportName>"` for an in-repo unit that states its
|
|
15320
|
+
* module, the way a server action does. Components and bare
|
|
15321
|
+
* handlers state neither and have no key at all.
|
|
15315
15322
|
*/
|
|
15323
|
+
rewritePaths(semantics, rewrite) {
|
|
15324
|
+
if (semantics.module === void 0) {
|
|
15325
|
+
return semantics;
|
|
15326
|
+
}
|
|
15327
|
+
return { ...semantics, module: rewrite(semantics.module) };
|
|
15328
|
+
},
|
|
15316
15329
|
identityKey(semantics) {
|
|
15317
15330
|
if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
|
|
15318
15331
|
return fnIdentityKey(semantics.package, semantics.exportPath);
|
|
15319
15332
|
}
|
|
15333
|
+
if (semantics.module !== void 0 && semantics.exportName !== void 0) {
|
|
15334
|
+
return fnIdentityKey(semantics.module, [semantics.exportName]);
|
|
15335
|
+
}
|
|
15320
15336
|
return null;
|
|
15321
15337
|
}
|
|
15322
15338
|
}
|
|
@@ -15827,7 +15843,16 @@ var ConfidenceInfoSchema = external_exports.object({
|
|
|
15827
15843
|
});
|
|
15828
15844
|
var SourceLocationSchema = external_exports.object({
|
|
15829
15845
|
file: external_exports.string(),
|
|
15846
|
+
/** Line numbers, for a person reading the summary or an editor link. */
|
|
15830
15847
|
range: external_exports.object({ start: external_exports.number(), end: external_exports.number() }),
|
|
15848
|
+
/**
|
|
15849
|
+
* Character offsets of the unit in its file. Identity and joins
|
|
15850
|
+
* measure with these, since two functions can share a line and never
|
|
15851
|
+
* an offset range; the line `range` above is the presentation of the
|
|
15852
|
+
* same place. Absent on summaries no source position backs, a
|
|
15853
|
+
* contract artifact's say.
|
|
15854
|
+
*/
|
|
15855
|
+
span: external_exports.object({ start: external_exports.number(), end: external_exports.number() }).optional(),
|
|
15831
15856
|
exportName: external_exports.string().nullable(),
|
|
15832
15857
|
/**
|
|
15833
15858
|
* The project the extract was pointed at, by the name that project
|
|
@@ -15952,6 +15977,733 @@ function storageBinding(opts) {
|
|
|
15952
15977
|
};
|
|
15953
15978
|
}
|
|
15954
15979
|
|
|
15980
|
+
// ../../resolution/dist/index.js
|
|
15981
|
+
import { ruleLabel } from "@suss/datalog";
|
|
15982
|
+
import { constant, lit, rule, variable as v } from "@suss/datalog";
|
|
15983
|
+
var VALUE_STEP = constant("value");
|
|
15984
|
+
var NAMESPACE_IMPORT_NAME = "*";
|
|
15985
|
+
var NAMESPACE_IMPORT = constant(NAMESPACE_IMPORT_NAME);
|
|
15986
|
+
var RESULT_STEP = constant("result");
|
|
15987
|
+
var RESOLUTION_RULES = [
|
|
15988
|
+
// Aliasing: const x = y, or an identifier referencing a declaration.
|
|
15989
|
+
// A language with a hop of its own, like JavaScript's `.bind`, states
|
|
15990
|
+
// it as a step too, or every question but `comesTo` misses it.
|
|
15991
|
+
rule(
|
|
15992
|
+
"stepsTo",
|
|
15993
|
+
[v("x"), v("y"), VALUE_STEP],
|
|
15994
|
+
[lit("binds", v("x"), v("y"))],
|
|
15995
|
+
"alias"
|
|
15996
|
+
),
|
|
15997
|
+
// A name written more than once has the value the last write left
|
|
15998
|
+
// there. The adapter works out which write that is and stays quiet
|
|
15999
|
+
// when control flow decides, so such a name steps nowhere at all.
|
|
16000
|
+
rule(
|
|
16001
|
+
"stepsTo",
|
|
16002
|
+
[v("x"), v("y"), VALUE_STEP],
|
|
16003
|
+
[lit("endsHolding", v("x"), v("y"))],
|
|
16004
|
+
"last write"
|
|
16005
|
+
),
|
|
16006
|
+
// A fallback says the value is one of its branches, so each branch is
|
|
16007
|
+
// a step. A branch that resolves to nothing makes no claim, and two
|
|
16008
|
+
// branches resolving to different things fail the single-answer policy.
|
|
16009
|
+
rule(
|
|
16010
|
+
"stepsTo",
|
|
16011
|
+
[v("x"), v("b"), VALUE_STEP],
|
|
16012
|
+
[lit("fallbackBranch", v("x"), v("b"))],
|
|
16013
|
+
"fallback"
|
|
16014
|
+
),
|
|
16015
|
+
// An import steps to what the module exports under that name.
|
|
16016
|
+
rule(
|
|
16017
|
+
"stepsTo",
|
|
16018
|
+
[v("x"), v("value"), VALUE_STEP],
|
|
16019
|
+
[
|
|
16020
|
+
lit("imports", v("x"), v("m"), v("n")),
|
|
16021
|
+
lit("moduleExport", v("m"), v("n"), v("value"))
|
|
16022
|
+
],
|
|
16023
|
+
"import"
|
|
16024
|
+
),
|
|
16025
|
+
// A parameter steps to what a call passes it. A function called from
|
|
16026
|
+
// several places leaves its parameter with more than one value, and a
|
|
16027
|
+
// caller that needs those apart asks `paramAt`.
|
|
16028
|
+
rule(
|
|
16029
|
+
"stepsTo",
|
|
16030
|
+
[v("p"), v("a"), VALUE_STEP],
|
|
16031
|
+
[lit("passesArgument", v("r"), v("p"), v("a"))],
|
|
16032
|
+
"argument"
|
|
16033
|
+
),
|
|
16034
|
+
// Reading a property steps to what the object contains under that
|
|
16035
|
+
// name, whichever way the object arrived: `routes.list` off a name,
|
|
16036
|
+
// or `make(body).handle` off a call.
|
|
16037
|
+
rule(
|
|
16038
|
+
"stepsTo",
|
|
16039
|
+
[v("x"), v("held"), VALUE_STEP],
|
|
16040
|
+
[
|
|
16041
|
+
lit("readsProperty", v("x"), v("o"), v("n")),
|
|
16042
|
+
lit("objectOf", v("o"), v("obj")),
|
|
16043
|
+
lit("contains", v("obj"), v("n"), v("held"))
|
|
16044
|
+
],
|
|
16045
|
+
"property read"
|
|
16046
|
+
),
|
|
16047
|
+
// Calling a class makes one of it, so the call steps to the class and
|
|
16048
|
+
// a method read off the result is the one the class declares. The
|
|
16049
|
+
// caveat below is about a factory function, and a class is not one.
|
|
16050
|
+
rule(
|
|
16051
|
+
"stepsTo",
|
|
16052
|
+
[v("r"), v("cls"), VALUE_STEP],
|
|
16053
|
+
[
|
|
16054
|
+
lit("call", v("r"), v("c")),
|
|
16055
|
+
lit("comesTo", v("c"), v("cls")),
|
|
16056
|
+
lit("objectValue", v("cls"))
|
|
16057
|
+
],
|
|
16058
|
+
"class instance"
|
|
16059
|
+
),
|
|
16060
|
+
// Wrapper transparency, derived: calling a factory that returns a
|
|
16061
|
+
// function which calls its parameter k steps to argument k.
|
|
16062
|
+
rule(
|
|
16063
|
+
"stepsTo",
|
|
16064
|
+
[v("r"), v("a"), VALUE_STEP],
|
|
16065
|
+
[
|
|
16066
|
+
lit("call", v("r"), v("c")),
|
|
16067
|
+
lit("comesTo", v("c"), v("f")),
|
|
16068
|
+
lit("unwraps", v("f"), v("k")),
|
|
16069
|
+
lit("callArg", v("r"), v("k"), v("a"))
|
|
16070
|
+
],
|
|
16071
|
+
"factory unwrap"
|
|
16072
|
+
),
|
|
16073
|
+
// Wrapper transparency, declared: a pack says this callee wraps
|
|
16074
|
+
// argument k. The callee has to come from the library the pack said,
|
|
16075
|
+
// so a local object spelled the same way is not mistaken for it.
|
|
16076
|
+
rule(
|
|
16077
|
+
"stepsTo",
|
|
16078
|
+
[v("r"), v("a"), VALUE_STEP],
|
|
16079
|
+
[
|
|
16080
|
+
lit("calleeName", v("r"), v("n")),
|
|
16081
|
+
lit("unwrapsByName", v("n"), v("k")),
|
|
16082
|
+
lit("wrapperModule", v("n"), v("m")),
|
|
16083
|
+
lit("calleeOrigin", v("r"), v("m")),
|
|
16084
|
+
lit("callArg", v("r"), v("k"), v("a"))
|
|
16085
|
+
],
|
|
16086
|
+
"declared wrapper"
|
|
16087
|
+
),
|
|
16088
|
+
// The one step that runs a function forwards: a call steps to what
|
|
16089
|
+
// the function it invokes returns.
|
|
16090
|
+
rule(
|
|
16091
|
+
"stepsTo",
|
|
16092
|
+
[v("r"), v("ret"), RESULT_STEP],
|
|
16093
|
+
[lit("invokes", v("r"), v("f")), lit("returnsValue", v("f"), v("ret"))],
|
|
16094
|
+
"call result"
|
|
16095
|
+
),
|
|
16096
|
+
// Where a walk gets to, and whether it ran a call on the way. A value
|
|
16097
|
+
// step keeps whatever the rest of the walk was, and a result step
|
|
16098
|
+
// makes the whole walk one that ran a call.
|
|
16099
|
+
rule(
|
|
16100
|
+
"reaches",
|
|
16101
|
+
[v("x"), v("z"), v("kind")],
|
|
16102
|
+
[lit("stepsTo", v("x"), v("z"), v("kind"))]
|
|
16103
|
+
),
|
|
16104
|
+
rule(
|
|
16105
|
+
"reaches",
|
|
16106
|
+
[v("x"), v("z"), v("kind")],
|
|
16107
|
+
[
|
|
16108
|
+
lit("stepsTo", v("x"), v("y"), VALUE_STEP),
|
|
16109
|
+
lit("reaches", v("y"), v("z"), v("kind"))
|
|
16110
|
+
]
|
|
16111
|
+
),
|
|
16112
|
+
// Two rules rather than one leaving the rest of the walk's kind free.
|
|
16113
|
+
// A free kind is a second question about the same relation, and a
|
|
16114
|
+
// demand-driven run then derives both to answer either.
|
|
16115
|
+
rule(
|
|
16116
|
+
"reaches",
|
|
16117
|
+
[v("x"), v("z"), RESULT_STEP],
|
|
16118
|
+
[
|
|
16119
|
+
lit("stepsTo", v("x"), v("y"), RESULT_STEP),
|
|
16120
|
+
lit("reaches", v("y"), v("z"), VALUE_STEP)
|
|
16121
|
+
]
|
|
16122
|
+
),
|
|
16123
|
+
rule(
|
|
16124
|
+
"reaches",
|
|
16125
|
+
[v("x"), v("z"), RESULT_STEP],
|
|
16126
|
+
[
|
|
16127
|
+
lit("stepsTo", v("x"), v("y"), RESULT_STEP),
|
|
16128
|
+
lit("reaches", v("y"), v("z"), RESULT_STEP)
|
|
16129
|
+
]
|
|
16130
|
+
),
|
|
16131
|
+
// What a value comes down to: the walk that never ran a call, stopped
|
|
16132
|
+
// at a function or an object. Something already written out comes to
|
|
16133
|
+
// itself, and every other walk ends at one of those.
|
|
16134
|
+
rule("comesTo", [v("x"), v("x")], [lit("func", v("x"))]),
|
|
16135
|
+
rule("comesTo", [v("x"), v("x")], [lit("objectValue", v("x"))]),
|
|
16136
|
+
rule(
|
|
16137
|
+
"comesTo",
|
|
16138
|
+
[v("x"), v("z")],
|
|
16139
|
+
[lit("reaches", v("x"), v("z"), VALUE_STEP), lit("func", v("z"))]
|
|
16140
|
+
),
|
|
16141
|
+
rule(
|
|
16142
|
+
"comesTo",
|
|
16143
|
+
[v("x"), v("z")],
|
|
16144
|
+
[lit("reaches", v("x"), v("z"), VALUE_STEP), lit("objectValue", v("z"))]
|
|
16145
|
+
),
|
|
16146
|
+
// The same stopping condition, for the walk that ran a call. A call
|
|
16147
|
+
// gets no `comesTo` answer on purpose: coming back with what a
|
|
16148
|
+
// factory returned would fight the unwrapping answer.
|
|
16149
|
+
rule(
|
|
16150
|
+
"givesBack",
|
|
16151
|
+
[v("x"), v("z")],
|
|
16152
|
+
[lit("reaches", v("x"), v("z"), RESULT_STEP), lit("func", v("z"))]
|
|
16153
|
+
),
|
|
16154
|
+
rule(
|
|
16155
|
+
"givesBack",
|
|
16156
|
+
[v("x"), v("z")],
|
|
16157
|
+
[lit("reaches", v("x"), v("z"), RESULT_STEP), lit("objectValue", v("z"))]
|
|
16158
|
+
),
|
|
16159
|
+
// Following a value to the expression it is written as, whatever kind
|
|
16160
|
+
// that is. A GraphQL document is neither a function nor an object, so
|
|
16161
|
+
// `comesTo` never reaches one.
|
|
16162
|
+
rule("isWrittenAs", [v("x"), v("x")], [lit("writtenValue", v("x"))]),
|
|
16163
|
+
rule("isWrittenAs", [v("x"), v("x")], [lit("objectValue", v("x"))]),
|
|
16164
|
+
rule(
|
|
16165
|
+
"isWrittenAs",
|
|
16166
|
+
[v("x"), v("z")],
|
|
16167
|
+
[lit("reaches", v("x"), v("z"), VALUE_STEP), lit("writtenValue", v("z"))]
|
|
16168
|
+
),
|
|
16169
|
+
rule(
|
|
16170
|
+
"isWrittenAs",
|
|
16171
|
+
[v("x"), v("z")],
|
|
16172
|
+
[lit("reaches", v("x"), v("z"), VALUE_STEP), lit("objectValue", v("z"))]
|
|
16173
|
+
),
|
|
16174
|
+
// What one call site put in a parameter, told apart from what the
|
|
16175
|
+
// other callers passed.
|
|
16176
|
+
rule(
|
|
16177
|
+
"paramAt",
|
|
16178
|
+
[v("r"), v("p"), v("z")],
|
|
16179
|
+
[
|
|
16180
|
+
lit("passesArgument", v("r"), v("p"), v("a")),
|
|
16181
|
+
lit("comesTo", v("a"), v("z"))
|
|
16182
|
+
]
|
|
16183
|
+
),
|
|
16184
|
+
// An argument arriving at the parameter it is passed to, by position
|
|
16185
|
+
// or by the name the caller wrote, keeping the call it went through
|
|
16186
|
+
// so `paramAt` can tell two call sites apart.
|
|
16187
|
+
rule(
|
|
16188
|
+
"passesArgument",
|
|
16189
|
+
[v("r"), v("p"), v("a")],
|
|
16190
|
+
[
|
|
16191
|
+
lit("paramOf", v("f"), v("k"), v("p")),
|
|
16192
|
+
lit("callsFunction", v("r"), v("f")),
|
|
16193
|
+
lit("callArg", v("r"), v("k"), v("a"))
|
|
16194
|
+
]
|
|
16195
|
+
),
|
|
16196
|
+
rule(
|
|
16197
|
+
"passesArgument",
|
|
16198
|
+
[v("r"), v("p"), v("a")],
|
|
16199
|
+
[
|
|
16200
|
+
lit("paramNamed", v("f"), v("n"), v("p")),
|
|
16201
|
+
lit("callsFunction", v("r"), v("f")),
|
|
16202
|
+
lit("callKeywordArg", v("r"), v("n"), v("a"))
|
|
16203
|
+
]
|
|
16204
|
+
),
|
|
16205
|
+
// Which module's export a re-exported name forwards to, however
|
|
16206
|
+
// many barrels deep the forwarding runs.
|
|
16207
|
+
rule(
|
|
16208
|
+
"moduleForwards",
|
|
16209
|
+
[v("m"), v("n"), v("m2"), v("n2")],
|
|
16210
|
+
[lit("reExports", v("m"), v("n"), v("m2"), v("n2"))]
|
|
16211
|
+
),
|
|
16212
|
+
rule(
|
|
16213
|
+
"moduleForwards",
|
|
16214
|
+
[v("m"), v("n"), v("m3"), v("n3")],
|
|
16215
|
+
[
|
|
16216
|
+
lit("reExports", v("m"), v("n"), v("m2"), v("n2")),
|
|
16217
|
+
lit("moduleForwards", v("m2"), v("n2"), v("m3"), v("n3"))
|
|
16218
|
+
]
|
|
16219
|
+
),
|
|
16220
|
+
// What a module exports: directly, or through re-export chains.
|
|
16221
|
+
rule(
|
|
16222
|
+
"moduleExport",
|
|
16223
|
+
[v("m"), v("n"), v("value")],
|
|
16224
|
+
[lit("exportsAs", v("m"), v("n"), v("value"))],
|
|
16225
|
+
"export"
|
|
16226
|
+
),
|
|
16227
|
+
rule(
|
|
16228
|
+
"moduleExport",
|
|
16229
|
+
[v("m"), v("n"), v("value")],
|
|
16230
|
+
[
|
|
16231
|
+
lit("reExports", v("m"), v("n"), v("m2"), v("n2")),
|
|
16232
|
+
lit("moduleExport", v("m2"), v("n2"), v("value"))
|
|
16233
|
+
],
|
|
16234
|
+
"re-export"
|
|
16235
|
+
),
|
|
16236
|
+
rule(
|
|
16237
|
+
"moduleExport",
|
|
16238
|
+
[v("m"), v("n"), v("value")],
|
|
16239
|
+
[
|
|
16240
|
+
lit("reExportsAll", v("m"), v("m2")),
|
|
16241
|
+
lit("moduleExport", v("m2"), v("n"), v("value"))
|
|
16242
|
+
],
|
|
16243
|
+
"re-export all"
|
|
16244
|
+
),
|
|
16245
|
+
// The function a call runs, written from the call's side because a
|
|
16246
|
+
// caller asking what a call gives back has the call in hand.
|
|
16247
|
+
rule(
|
|
16248
|
+
"invokes",
|
|
16249
|
+
[v("r"), v("f")],
|
|
16250
|
+
[lit("call", v("r"), v("c")), lit("comesTo", v("c"), v("f"))]
|
|
16251
|
+
),
|
|
16252
|
+
// The callee is itself a call: `daoBuilder()()`.
|
|
16253
|
+
rule(
|
|
16254
|
+
"invokes",
|
|
16255
|
+
[v("r"), v("f")],
|
|
16256
|
+
[lit("call", v("r"), v("c")), lit("givesBack", v("c"), v("f"))]
|
|
16257
|
+
),
|
|
16258
|
+
// The object an expression refers to: a name through `comesTo`, a
|
|
16259
|
+
// factory call through what it gives back. Naming the step is what
|
|
16260
|
+
// makes `routes.list` and `make(body).handle` one rule.
|
|
16261
|
+
rule(
|
|
16262
|
+
"objectOf",
|
|
16263
|
+
[v("o"), v("obj")],
|
|
16264
|
+
[lit("comesTo", v("o"), v("obj")), lit("objectValue", v("obj"))]
|
|
16265
|
+
),
|
|
16266
|
+
rule(
|
|
16267
|
+
"objectOf",
|
|
16268
|
+
[v("x"), v("obj")],
|
|
16269
|
+
[lit("givesBack", v("x"), v("obj")), lit("objectValue", v("obj"))]
|
|
16270
|
+
),
|
|
16271
|
+
// Which calls a function, found by the name the call is written as
|
|
16272
|
+
// rather than by resolving every callee in the project. A caller knows
|
|
16273
|
+
// the function and wants its call sites, so both of these start from
|
|
16274
|
+
// the function. Starting from `call` instead asks what every call in
|
|
16275
|
+
// the project imports, which was 72% of everything derived.
|
|
16276
|
+
rule(
|
|
16277
|
+
"callsFunction",
|
|
16278
|
+
[v("r"), v("f")],
|
|
16279
|
+
[lit("binds", v("c"), v("f")), lit("call", v("r"), v("c"))]
|
|
16280
|
+
),
|
|
16281
|
+
rule(
|
|
16282
|
+
"callsFunction",
|
|
16283
|
+
[v("r"), v("f")],
|
|
16284
|
+
[
|
|
16285
|
+
lit("moduleExport", v("m"), v("n"), v("f")),
|
|
16286
|
+
lit("imports", v("c"), v("m"), v("n")),
|
|
16287
|
+
lit("call", v("r"), v("c"))
|
|
16288
|
+
]
|
|
16289
|
+
),
|
|
16290
|
+
// The same, for a language whose adapter writes the import down as a
|
|
16291
|
+
// declaration and the call's callee as the name referring to it.
|
|
16292
|
+
rule(
|
|
16293
|
+
"callsFunction",
|
|
16294
|
+
[v("r"), v("f")],
|
|
16295
|
+
[
|
|
16296
|
+
lit("moduleExport", v("m"), v("n"), v("f")),
|
|
16297
|
+
lit("imports", v("d"), v("m"), v("n")),
|
|
16298
|
+
lit("binds", v("c"), v("d")),
|
|
16299
|
+
lit("call", v("r"), v("c"))
|
|
16300
|
+
]
|
|
16301
|
+
),
|
|
16302
|
+
// What an object contains, its base class included, so a method the base
|
|
16303
|
+
// declares is found on a subclass that never overrode it. A method both
|
|
16304
|
+
// declare gives two, and the caller decides. This is its own relation
|
|
16305
|
+
// rather than more `holdsProperty`, which stays something an adapter
|
|
16306
|
+
// states and the rules only read.
|
|
16307
|
+
rule(
|
|
16308
|
+
"contains",
|
|
16309
|
+
[v("o"), v("n"), v("held")],
|
|
16310
|
+
[lit("holdsProperty", v("o"), v("n"), v("held"))]
|
|
16311
|
+
),
|
|
16312
|
+
rule(
|
|
16313
|
+
"contains",
|
|
16314
|
+
[v("cls"), v("n"), v("held")],
|
|
16315
|
+
[
|
|
16316
|
+
lit("extends", v("cls"), v("base")),
|
|
16317
|
+
lit("comesTo", v("base"), v("baseCls")),
|
|
16318
|
+
lit("contains", v("baseCls"), v("n"), v("held"))
|
|
16319
|
+
]
|
|
16320
|
+
),
|
|
16321
|
+
// Which function a factory returns, and which of its parameters that
|
|
16322
|
+
// function calls: together they are what makes it a wrapper.
|
|
16323
|
+
rule(
|
|
16324
|
+
"returnsFunc",
|
|
16325
|
+
[v("f"), v("g")],
|
|
16326
|
+
[
|
|
16327
|
+
lit("returnsValue", v("f"), v("value")),
|
|
16328
|
+
lit("comesTo", v("value"), v("g")),
|
|
16329
|
+
lit("func", v("g"))
|
|
16330
|
+
]
|
|
16331
|
+
),
|
|
16332
|
+
// A call made by a nested closure counts as made by the function
|
|
16333
|
+
// that declares it; the closure runs as part of that function.
|
|
16334
|
+
rule("bodyCallsDeep", [v("f"), v("c")], [lit("bodyCalls", v("f"), v("c"))]),
|
|
16335
|
+
rule(
|
|
16336
|
+
"bodyCallsDeep",
|
|
16337
|
+
[v("f"), v("c")],
|
|
16338
|
+
[lit("containsFn", v("f"), v("g")), lit("bodyCallsDeep", v("g"), v("c"))]
|
|
16339
|
+
),
|
|
16340
|
+
rule(
|
|
16341
|
+
"unwraps",
|
|
16342
|
+
[v("f"), v("k")],
|
|
16343
|
+
[
|
|
16344
|
+
lit("returnsFunc", v("f"), v("g")),
|
|
16345
|
+
lit("bodyCallsDeep", v("g"), v("c")),
|
|
16346
|
+
lit("binds", v("c"), v("p")),
|
|
16347
|
+
lit("paramOf", v("f"), v("k"), v("p"))
|
|
16348
|
+
]
|
|
16349
|
+
),
|
|
16350
|
+
// Argument flow: which parameter a value traces back to. Directly
|
|
16351
|
+
// (an identifier bound to the parameter), or through a call to
|
|
16352
|
+
// another unwrapping factory. This is what lets
|
|
16353
|
+
// `createProtected(h) { return service.withAuth(h); }` unwrap:
|
|
16354
|
+
// the returned call passes h through withAuth, which unwraps.
|
|
16355
|
+
rule(
|
|
16356
|
+
"flowsToParam",
|
|
16357
|
+
[v("x"), v("p")],
|
|
16358
|
+
[
|
|
16359
|
+
lit("binds", v("x"), v("p")),
|
|
16360
|
+
lit("paramOf", v("anyF"), v("anyK"), v("p"))
|
|
16361
|
+
]
|
|
16362
|
+
),
|
|
16363
|
+
rule(
|
|
16364
|
+
"flowsToParam",
|
|
16365
|
+
[v("r"), v("p")],
|
|
16366
|
+
[
|
|
16367
|
+
lit("call", v("r"), v("c")),
|
|
16368
|
+
lit("comesTo", v("c"), v("f")),
|
|
16369
|
+
lit("unwraps", v("f"), v("k")),
|
|
16370
|
+
lit("callArg", v("r"), v("k"), v("a")),
|
|
16371
|
+
lit("flowsToParam", v("a"), v("p"))
|
|
16372
|
+
]
|
|
16373
|
+
),
|
|
16374
|
+
rule(
|
|
16375
|
+
"unwraps",
|
|
16376
|
+
[v("f"), v("k")],
|
|
16377
|
+
[
|
|
16378
|
+
lit("returnsValue", v("f"), v("value")),
|
|
16379
|
+
lit("flowsToParam", v("value"), v("p")),
|
|
16380
|
+
lit("paramOf", v("f"), v("k"), v("p"))
|
|
16381
|
+
]
|
|
16382
|
+
),
|
|
16383
|
+
// Where a name comes from, when what it refers to lives outside the
|
|
16384
|
+
// source being read. A walk ends at something written out in source,
|
|
16385
|
+
// so it never reaches a library's own function.
|
|
16386
|
+
rule(
|
|
16387
|
+
"comesFrom",
|
|
16388
|
+
[v("x"), v("m"), v("n")],
|
|
16389
|
+
[lit("imports", v("x"), v("m"), v("n"))]
|
|
16390
|
+
),
|
|
16391
|
+
rule(
|
|
16392
|
+
"comesFrom",
|
|
16393
|
+
[v("x"), v("m"), v("n")],
|
|
16394
|
+
[
|
|
16395
|
+
lit("reaches", v("x"), v("y"), VALUE_STEP),
|
|
16396
|
+
lit("imports", v("y"), v("m"), v("n"))
|
|
16397
|
+
]
|
|
16398
|
+
),
|
|
16399
|
+
// Calling f ends up calling the name n that module m exports, one
|
|
16400
|
+
// hop through f's own body or deeper through a wrapper of a wrapper.
|
|
16401
|
+
// Several results is normal: a composed decorator applies them all.
|
|
16402
|
+
rule(
|
|
16403
|
+
"callsInto",
|
|
16404
|
+
[v("f"), v("m"), v("n")],
|
|
16405
|
+
[
|
|
16406
|
+
lit("bodyCallsDeep", v("f"), v("c")),
|
|
16407
|
+
lit("comesFrom", v("c"), v("m"), v("n"))
|
|
16408
|
+
]
|
|
16409
|
+
),
|
|
16410
|
+
rule(
|
|
16411
|
+
"callsInto",
|
|
16412
|
+
[v("f"), v("m"), v("n")],
|
|
16413
|
+
[
|
|
16414
|
+
lit("bodyCallsDeep", v("f"), v("c")),
|
|
16415
|
+
lit("comesTo", v("c"), v("g")),
|
|
16416
|
+
lit("callsInto", v("g"), v("m"), v("n"))
|
|
16417
|
+
]
|
|
16418
|
+
),
|
|
16419
|
+
// The question callers ask: what a value comes to, narrowed to the
|
|
16420
|
+
// functions. Objects appear in the middle of chains and never in an
|
|
16421
|
+
// answer.
|
|
16422
|
+
rule(
|
|
16423
|
+
"resolves",
|
|
16424
|
+
[v("x"), v("z")],
|
|
16425
|
+
[lit("comesTo", v("x"), v("z")), lit("func", v("z"))]
|
|
16426
|
+
)
|
|
16427
|
+
];
|
|
16428
|
+
var RESOLUTION_QUESTIONS = [
|
|
16429
|
+
rule(
|
|
16430
|
+
"wantedResolves",
|
|
16431
|
+
[v("x"), v("z")],
|
|
16432
|
+
[lit("wanted", v("x")), lit("resolves", v("x"), v("z"))]
|
|
16433
|
+
),
|
|
16434
|
+
rule(
|
|
16435
|
+
"wantedComesTo",
|
|
16436
|
+
[v("x"), v("z")],
|
|
16437
|
+
[lit("wanted", v("x")), lit("comesTo", v("x"), v("z"))]
|
|
16438
|
+
),
|
|
16439
|
+
rule(
|
|
16440
|
+
"wantedComesTo",
|
|
16441
|
+
[v("x"), v("z")],
|
|
16442
|
+
[lit("wantedOrigin", v("x")), lit("comesTo", v("x"), v("z"))]
|
|
16443
|
+
),
|
|
16444
|
+
rule(
|
|
16445
|
+
"wantedIsWrittenAs",
|
|
16446
|
+
[v("x"), v("z")],
|
|
16447
|
+
[lit("wanted", v("x")), lit("isWrittenAs", v("x"), v("z"))]
|
|
16448
|
+
),
|
|
16449
|
+
// A call is given no `comesTo`, so this is the only way to ask what
|
|
16450
|
+
// object one arrives at, and without it a demand-driven run derives
|
|
16451
|
+
// `objectOf` nowhere.
|
|
16452
|
+
rule(
|
|
16453
|
+
"wantedObjectOf",
|
|
16454
|
+
[v("x"), v("z")],
|
|
16455
|
+
[lit("wanted", v("x")), lit("objectOf", v("x"), v("z"))]
|
|
16456
|
+
),
|
|
16457
|
+
// Keyed by the parameter, since that is what a caller has in hand
|
|
16458
|
+
// when it wants the call sites told apart.
|
|
16459
|
+
rule(
|
|
16460
|
+
"wantedParamAt",
|
|
16461
|
+
[v("p"), v("r"), v("z")],
|
|
16462
|
+
[lit("wanted", v("p")), lit("paramAt", v("r"), v("p"), v("z"))]
|
|
16463
|
+
),
|
|
16464
|
+
rule(
|
|
16465
|
+
"wantedComesFrom",
|
|
16466
|
+
[v("x"), v("m"), v("n")],
|
|
16467
|
+
[lit("wantedOrigin", v("x")), lit("comesFrom", v("x"), v("m"), v("n"))]
|
|
16468
|
+
),
|
|
16469
|
+
// Call-origin questions, for attribution, in their own demand
|
|
16470
|
+
// class. Attribution stops at the import declaration, so nothing
|
|
16471
|
+
// here demands reaches or callsInto. The chains are closures with
|
|
16472
|
+
// no depth bound: an alias run of any length resolves.
|
|
16473
|
+
rule("callOriginChain", [v("x"), v("x")], [lit("wantedCallOrigin", v("x"))]),
|
|
16474
|
+
rule(
|
|
16475
|
+
"callOriginChain",
|
|
16476
|
+
[v("x"), v("z")],
|
|
16477
|
+
[lit("callOriginChain", v("x"), v("y")), lit("binds", v("y"), v("z"))]
|
|
16478
|
+
),
|
|
16479
|
+
rule(
|
|
16480
|
+
"callOriginChain",
|
|
16481
|
+
[v("x"), v("z")],
|
|
16482
|
+
[
|
|
16483
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16484
|
+
lit("endsHolding", v("y"), v("z"))
|
|
16485
|
+
]
|
|
16486
|
+
),
|
|
16487
|
+
rule(
|
|
16488
|
+
"callOriginChain",
|
|
16489
|
+
[v("x"), v("z")],
|
|
16490
|
+
[
|
|
16491
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16492
|
+
lit("fallbackBranch", v("y"), v("z"))
|
|
16493
|
+
]
|
|
16494
|
+
),
|
|
16495
|
+
// The chain with at least one hop taken, which is what tells a
|
|
16496
|
+
// destructured binding apart from asking about a node directly.
|
|
16497
|
+
rule(
|
|
16498
|
+
"callOriginChainStepped",
|
|
16499
|
+
[v("x"), v("z")],
|
|
16500
|
+
[lit("callOriginChain", v("x"), v("y")), lit("binds", v("y"), v("z"))]
|
|
16501
|
+
),
|
|
16502
|
+
rule(
|
|
16503
|
+
"callOriginChainStepped",
|
|
16504
|
+
[v("x"), v("z")],
|
|
16505
|
+
[
|
|
16506
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16507
|
+
lit("endsHolding", v("y"), v("z"))
|
|
16508
|
+
]
|
|
16509
|
+
),
|
|
16510
|
+
rule(
|
|
16511
|
+
"callOriginChainStepped",
|
|
16512
|
+
[v("x"), v("z")],
|
|
16513
|
+
[
|
|
16514
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16515
|
+
lit("fallbackBranch", v("y"), v("z"))
|
|
16516
|
+
]
|
|
16517
|
+
),
|
|
16518
|
+
rule(
|
|
16519
|
+
"wantedCallOriginPair",
|
|
16520
|
+
[v("x"), v("m"), v("n")],
|
|
16521
|
+
[
|
|
16522
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16523
|
+
lit("imports", v("y"), v("m"), v("n"))
|
|
16524
|
+
]
|
|
16525
|
+
),
|
|
16526
|
+
// An import of a project barrel is an import of what the barrel
|
|
16527
|
+
// forwards, so the pair surfaces the module behind the chain.
|
|
16528
|
+
rule(
|
|
16529
|
+
"wantedCallOriginPair",
|
|
16530
|
+
[v("x"), v("m2"), v("n2")],
|
|
16531
|
+
[
|
|
16532
|
+
lit("callOriginChain", v("x"), v("y")),
|
|
16533
|
+
lit("imports", v("y"), v("m"), v("n")),
|
|
16534
|
+
lit("moduleForwards", v("m"), v("n"), v("m2"), v("n2"))
|
|
16535
|
+
]
|
|
16536
|
+
),
|
|
16537
|
+
// A namespace member: the module's export of the member's own name.
|
|
16538
|
+
// The imports literal leads, since it is the smallest relation.
|
|
16539
|
+
rule(
|
|
16540
|
+
"wantedCallOriginPair",
|
|
16541
|
+
[v("x"), v("m"), v("p")],
|
|
16542
|
+
[
|
|
16543
|
+
lit("imports", v("o"), v("m"), NAMESPACE_IMPORT),
|
|
16544
|
+
lit("readsProperty", v("y"), v("o"), v("p")),
|
|
16545
|
+
lit("callOriginChain", v("x"), v("y"))
|
|
16546
|
+
]
|
|
16547
|
+
),
|
|
16548
|
+
rule(
|
|
16549
|
+
"wantedCallOriginPair",
|
|
16550
|
+
[v("x"), v("m"), v("p")],
|
|
16551
|
+
[
|
|
16552
|
+
lit("imports", v("d"), v("m"), NAMESPACE_IMPORT),
|
|
16553
|
+
lit("binds", v("o"), v("d")),
|
|
16554
|
+
lit("readsProperty", v("y"), v("o"), v("p")),
|
|
16555
|
+
lit("callOriginChain", v("x"), v("y"))
|
|
16556
|
+
]
|
|
16557
|
+
),
|
|
16558
|
+
// What a call made: through the call to its callee, whose own alias
|
|
16559
|
+
// chain leads to the import.
|
|
16560
|
+
rule(
|
|
16561
|
+
"callMadeChain",
|
|
16562
|
+
[v("x"), v("f")],
|
|
16563
|
+
[lit("callOriginChain", v("x"), v("c")), lit("call", v("c"), v("f"))]
|
|
16564
|
+
),
|
|
16565
|
+
rule(
|
|
16566
|
+
"callMadeChain",
|
|
16567
|
+
[v("x"), v("z")],
|
|
16568
|
+
[lit("callMadeChain", v("x"), v("y")), lit("binds", v("y"), v("z"))]
|
|
16569
|
+
),
|
|
16570
|
+
rule(
|
|
16571
|
+
"callMadeChain",
|
|
16572
|
+
[v("x"), v("z")],
|
|
16573
|
+
[lit("callMadeChain", v("x"), v("y")), lit("endsHolding", v("y"), v("z"))]
|
|
16574
|
+
),
|
|
16575
|
+
rule(
|
|
16576
|
+
"wantedCallOriginPair",
|
|
16577
|
+
[v("x"), v("m"), v("n")],
|
|
16578
|
+
[
|
|
16579
|
+
lit("callMadeChain", v("x"), v("y")),
|
|
16580
|
+
lit("imports", v("y"), v("m"), v("n"))
|
|
16581
|
+
]
|
|
16582
|
+
),
|
|
16583
|
+
// A member destructured off what a call made keeps the member name
|
|
16584
|
+
// as one more path segment.
|
|
16585
|
+
rule(
|
|
16586
|
+
"callMemberChain",
|
|
16587
|
+
[v("x"), v("f"), v("p")],
|
|
16588
|
+
[
|
|
16589
|
+
lit("callOriginChainStepped", v("x"), v("e")),
|
|
16590
|
+
lit("readsProperty", v("e"), v("c"), v("p")),
|
|
16591
|
+
lit("call", v("c"), v("f"))
|
|
16592
|
+
]
|
|
16593
|
+
),
|
|
16594
|
+
rule(
|
|
16595
|
+
"callMemberChain",
|
|
16596
|
+
[v("x"), v("z"), v("p")],
|
|
16597
|
+
[
|
|
16598
|
+
lit("callMemberChain", v("x"), v("y"), v("p")),
|
|
16599
|
+
lit("binds", v("y"), v("z"))
|
|
16600
|
+
]
|
|
16601
|
+
),
|
|
16602
|
+
rule(
|
|
16603
|
+
"callMemberChain",
|
|
16604
|
+
[v("x"), v("z"), v("p")],
|
|
16605
|
+
[
|
|
16606
|
+
lit("callMemberChain", v("x"), v("y"), v("p")),
|
|
16607
|
+
lit("endsHolding", v("y"), v("z"))
|
|
16608
|
+
]
|
|
16609
|
+
),
|
|
16610
|
+
rule(
|
|
16611
|
+
"wantedCallOriginMember",
|
|
16612
|
+
[v("x"), v("m"), v("n"), v("p")],
|
|
16613
|
+
[
|
|
16614
|
+
lit("callMemberChain", v("x"), v("y"), v("p")),
|
|
16615
|
+
lit("imports", v("y"), v("m"), v("n"))
|
|
16616
|
+
]
|
|
16617
|
+
),
|
|
16618
|
+
rule(
|
|
16619
|
+
"wantedCallsInto",
|
|
16620
|
+
[v("g"), v("m"), v("n")],
|
|
16621
|
+
[
|
|
16622
|
+
lit("wantedOrigin", v("x")),
|
|
16623
|
+
lit("comesTo", v("x"), v("g")),
|
|
16624
|
+
lit("callsInto", v("g"), v("m"), v("n"))
|
|
16625
|
+
]
|
|
16626
|
+
),
|
|
16627
|
+
// The export table of one module, keyed by the module asked about.
|
|
16628
|
+
// The moduleExport rules flatten re-export chains of any length, and
|
|
16629
|
+
// the demand cone stays on export facts alone.
|
|
16630
|
+
rule(
|
|
16631
|
+
"wantedModuleExport",
|
|
16632
|
+
[v("m"), v("n"), v("value")],
|
|
16633
|
+
[
|
|
16634
|
+
lit("wantedExportsOf", v("m")),
|
|
16635
|
+
lit("moduleExport", v("m"), v("n"), v("value"))
|
|
16636
|
+
]
|
|
16637
|
+
),
|
|
16638
|
+
// The calls behind a receiver, for a pack that wants the anchor a
|
|
16639
|
+
// chain hangs off; the README's anchor section says which hops and
|
|
16640
|
+
// why the asking side applies the single-answer policy.
|
|
16641
|
+
// A class's ancestry, one hop per extends through the binding that
|
|
16642
|
+
// says which class the written base is; the names on the way out
|
|
16643
|
+
// are what a storage pack matches its library's bases against.
|
|
16644
|
+
rule("ancestryChain", [v("c"), v("c")], [lit("wantedAncestry", v("c"))]),
|
|
16645
|
+
rule(
|
|
16646
|
+
"ancestryChain",
|
|
16647
|
+
[v("c"), v("b2")],
|
|
16648
|
+
[
|
|
16649
|
+
lit("ancestryChain", v("c"), v("b")),
|
|
16650
|
+
lit("extends", v("b"), v("x")),
|
|
16651
|
+
lit("binds", v("x"), v("b2"))
|
|
16652
|
+
]
|
|
16653
|
+
),
|
|
16654
|
+
rule(
|
|
16655
|
+
"wantedBaseName",
|
|
16656
|
+
[v("c"), v("n")],
|
|
16657
|
+
[lit("ancestryChain", v("c"), v("b")), lit("extendsNamed", v("b"), v("n"))]
|
|
16658
|
+
),
|
|
16659
|
+
rule("anchorChain", [v("x"), v("x")], [lit("wantedAnchor", v("x"))]),
|
|
16660
|
+
rule(
|
|
16661
|
+
"anchorChain",
|
|
16662
|
+
[v("x"), v("z")],
|
|
16663
|
+
[lit("anchorChain", v("x"), v("y")), lit("binds", v("y"), v("z"))]
|
|
16664
|
+
),
|
|
16665
|
+
rule(
|
|
16666
|
+
"anchorChain",
|
|
16667
|
+
[v("x"), v("z")],
|
|
16668
|
+
[lit("anchorChain", v("x"), v("y")), lit("endsHolding", v("y"), v("z"))]
|
|
16669
|
+
),
|
|
16670
|
+
rule(
|
|
16671
|
+
"anchorChain",
|
|
16672
|
+
[v("x"), v("z")],
|
|
16673
|
+
[lit("anchorChain", v("x"), v("y")), lit("fallbackBranch", v("y"), v("z"))]
|
|
16674
|
+
),
|
|
16675
|
+
rule(
|
|
16676
|
+
"anchorChain",
|
|
16677
|
+
[v("x"), v("z")],
|
|
16678
|
+
[
|
|
16679
|
+
lit("anchorChain", v("x"), v("y")),
|
|
16680
|
+
lit("imports", v("y"), v("m"), v("n")),
|
|
16681
|
+
lit("moduleExport", v("m"), v("n"), v("z"))
|
|
16682
|
+
]
|
|
16683
|
+
),
|
|
16684
|
+
rule(
|
|
16685
|
+
"anchorChain",
|
|
16686
|
+
[v("x"), v("c")],
|
|
16687
|
+
[lit("anchorChain", v("x"), v("r")), lit("call", v("r"), v("c"))]
|
|
16688
|
+
),
|
|
16689
|
+
rule(
|
|
16690
|
+
"anchorChain",
|
|
16691
|
+
[v("x"), v("o")],
|
|
16692
|
+
[
|
|
16693
|
+
lit("anchorChain", v("x"), v("y")),
|
|
16694
|
+
lit("readsProperty", v("y"), v("o"), v("n"))
|
|
16695
|
+
]
|
|
16696
|
+
),
|
|
16697
|
+
rule(
|
|
16698
|
+
"wantedAnchorCall",
|
|
16699
|
+
[v("x"), v("r")],
|
|
16700
|
+
[lit("anchorChain", v("x"), v("r")), lit("call", v("r"), v("c"))]
|
|
16701
|
+
)
|
|
16702
|
+
];
|
|
16703
|
+
var ANSWER_RELATIONS = [
|
|
16704
|
+
...new Set(RESOLUTION_QUESTIONS.map((r) => r.head.relation))
|
|
16705
|
+
];
|
|
16706
|
+
|
|
15955
16707
|
// src/storage.ts
|
|
15956
16708
|
function children2(node) {
|
|
15957
16709
|
return node.namedChildren.filter((child) => child !== null);
|
|
@@ -15972,21 +16724,17 @@ function rootConstant(node) {
|
|
|
15972
16724
|
}
|
|
15973
16725
|
return rootConstant(receiver);
|
|
15974
16726
|
}
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
}
|
|
15984
|
-
return facts.facts("extends").filter((row) => String(row[0]) === classKey).flatMap(
|
|
15985
|
-
(row) => facts.facts("binds").filter((bound) => String(bound[0]) === String(row[1])).map((bound) => String(bound[1]))
|
|
15986
|
-
).some((next) => reachesBase(facts, next, bases, seen));
|
|
16727
|
+
var ANCESTRY_PROGRAM = deriveOnDemand(
|
|
16728
|
+
[...RESOLUTION_RULES, ...RESOLUTION_QUESTIONS],
|
|
16729
|
+
ANSWER_RELATIONS
|
|
16730
|
+
);
|
|
16731
|
+
function reachesBase(facts, classKey, bases) {
|
|
16732
|
+
facts.add("wantedAncestry", [classKey]);
|
|
16733
|
+
evaluate(facts, ANCESTRY_PROGRAM.rules);
|
|
16734
|
+
return facts.lookup("wantedBaseName", 0, classKey).some((row) => bases.includes(String(row[1])));
|
|
15987
16735
|
}
|
|
15988
|
-
function classBehind(facts,
|
|
15989
|
-
const wanted = `#${
|
|
16736
|
+
function classBehind(facts, constant2) {
|
|
16737
|
+
const wanted = `#${constant2.text}`;
|
|
15990
16738
|
const bound = new Set(
|
|
15991
16739
|
facts.facts("binds").filter((row) => String(row[0]).endsWith(wanted)).map((row) => String(row[1]))
|
|
15992
16740
|
);
|
|
@@ -16029,11 +16777,11 @@ function storageEffects(calls, options) {
|
|
|
16029
16777
|
if (partOfOne.has(call.id)) {
|
|
16030
16778
|
continue;
|
|
16031
16779
|
}
|
|
16032
|
-
const
|
|
16033
|
-
if (
|
|
16780
|
+
const constant2 = rootConstant(call);
|
|
16781
|
+
if (constant2 === null) {
|
|
16034
16782
|
continue;
|
|
16035
16783
|
}
|
|
16036
|
-
const classKey = classBehind(options.facts,
|
|
16784
|
+
const classKey = classBehind(options.facts, constant2);
|
|
16037
16785
|
if (classKey === void 0) {
|
|
16038
16786
|
continue;
|
|
16039
16787
|
}
|
|
@@ -16051,7 +16799,7 @@ function storageEffects(calls, options) {
|
|
|
16051
16799
|
recognition: "ruby-storage",
|
|
16052
16800
|
storageSystem: pattern.storageSystem,
|
|
16053
16801
|
scope: pattern.baseClasses[0] ?? "",
|
|
16054
|
-
container:
|
|
16802
|
+
container: constant2.text
|
|
16055
16803
|
}),
|
|
16056
16804
|
callee: call.text,
|
|
16057
16805
|
interaction: {
|
|
@@ -16538,6 +17286,7 @@ function buildFieldUnit(pack, typeName, decl, filePath) {
|
|
|
16538
17286
|
kind: "resolver",
|
|
16539
17287
|
file: filePath,
|
|
16540
17288
|
range: rangeOf(decl.node),
|
|
17289
|
+
span: spanOf(decl.node),
|
|
16541
17290
|
exportName: null,
|
|
16542
17291
|
exportPath: null
|
|
16543
17292
|
},
|