@suss/adapter-ruby 0.20.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +276 -77
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/index.js +280 -81
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -72,12 +72,37 @@ function field(node, name) {
|
|
|
72
72
|
function bodyStatements(body) {
|
|
73
73
|
return body.namedChildren.filter((child) => child !== null);
|
|
74
74
|
}
|
|
75
|
+
var OWN_BODY_TYPES = /* @__PURE__ */ new Set([
|
|
76
|
+
"method",
|
|
77
|
+
"singleton_method",
|
|
78
|
+
"lambda",
|
|
79
|
+
"class",
|
|
80
|
+
"module",
|
|
81
|
+
"singleton_class"
|
|
82
|
+
]);
|
|
83
|
+
var ARGUMENT_LIST_TYPE = "argument_list";
|
|
84
|
+
function runStatements(body, blockConfigures = () => false) {
|
|
85
|
+
const found = [];
|
|
86
|
+
const readsItsChildren = (node) => {
|
|
87
|
+
if (OWN_BODY_TYPES.has(node.type) || node.type === ARGUMENT_LIST_TYPE) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return !(node.type === "call" && blockConfigures(node));
|
|
91
|
+
};
|
|
92
|
+
(0, import_extractor.walkDescendants)(body, null, {
|
|
93
|
+
at: (node) => {
|
|
94
|
+
found.push(node);
|
|
95
|
+
},
|
|
96
|
+
into: (node) => readsItsChildren(node) ? null : import_extractor.SKIP_CHILDREN
|
|
97
|
+
});
|
|
98
|
+
return found;
|
|
99
|
+
}
|
|
75
100
|
function symbolValue(node) {
|
|
76
101
|
return node.type === "simple_symbol" ? node.text.slice(1) : null;
|
|
77
102
|
}
|
|
78
103
|
function instanceMethodsByName(body) {
|
|
79
104
|
const methods = /* @__PURE__ */ new Map();
|
|
80
|
-
for (const stmt of
|
|
105
|
+
for (const stmt of runStatements(body)) {
|
|
81
106
|
if (stmt.type !== "method") {
|
|
82
107
|
continue;
|
|
83
108
|
}
|
|
@@ -90,7 +115,7 @@ function instanceMethodsByName(body) {
|
|
|
90
115
|
}
|
|
91
116
|
function bareCallArgumentGroups(body, name) {
|
|
92
117
|
const groups = [];
|
|
93
|
-
for (const stmt of
|
|
118
|
+
for (const stmt of runStatements(body)) {
|
|
94
119
|
if (stmt.type !== "call" || field(stmt, "receiver") !== null) {
|
|
95
120
|
continue;
|
|
96
121
|
}
|
|
@@ -193,7 +218,7 @@ function walkClasses(root, visit) {
|
|
|
193
218
|
});
|
|
194
219
|
}
|
|
195
220
|
function walkDefinitions(root, visit) {
|
|
196
|
-
walkBody(
|
|
221
|
+
walkBody(runStatements(root), [], visit);
|
|
197
222
|
}
|
|
198
223
|
function walkBody(statements, nesting, visit) {
|
|
199
224
|
for (const stmt of statements) {
|
|
@@ -232,7 +257,7 @@ function visitClass(node, nesting, visit) {
|
|
|
232
257
|
bodyNesting: identity.bodyNesting
|
|
233
258
|
});
|
|
234
259
|
if (bodyNode !== null) {
|
|
235
|
-
walkBody(
|
|
260
|
+
walkBody(runStatements(bodyNode), identity.bodyNesting, visit);
|
|
236
261
|
}
|
|
237
262
|
}
|
|
238
263
|
function visitModule(node, nesting, visit) {
|
|
@@ -251,7 +276,7 @@ function visitModule(node, nesting, visit) {
|
|
|
251
276
|
bodyNesting: identity.bodyNesting
|
|
252
277
|
});
|
|
253
278
|
if (bodyNode !== null) {
|
|
254
|
-
walkBody(
|
|
279
|
+
walkBody(runStatements(bodyNode), identity.bodyNesting, visit);
|
|
255
280
|
}
|
|
256
281
|
}
|
|
257
282
|
function stripTypeSuffixName(qualifiedName) {
|
|
@@ -407,7 +432,7 @@ function definitionIn(blocks, name) {
|
|
|
407
432
|
}
|
|
408
433
|
return { method, dynamic };
|
|
409
434
|
}
|
|
410
|
-
function inheritedStatements(ancestry) {
|
|
435
|
+
function inheritedStatements(ancestry, blockConfigures) {
|
|
411
436
|
const statements = [];
|
|
412
437
|
for (const entry of [...ancestry].reverse()) {
|
|
413
438
|
if (entry.type !== "bodies") {
|
|
@@ -418,7 +443,7 @@ function inheritedStatements(ancestry) {
|
|
|
418
443
|
if (body === null) {
|
|
419
444
|
continue;
|
|
420
445
|
}
|
|
421
|
-
for (const statement of
|
|
446
|
+
for (const statement of runStatements(body, blockConfigures)) {
|
|
422
447
|
statements.push({ block, statement });
|
|
423
448
|
}
|
|
424
449
|
}
|
|
@@ -644,14 +669,6 @@ function lowerRubyBody(body, terminals) {
|
|
|
644
669
|
}
|
|
645
670
|
|
|
646
671
|
// src/paths/effects.ts
|
|
647
|
-
var DECLARATION_TYPES = /* @__PURE__ */ new Set([
|
|
648
|
-
"method",
|
|
649
|
-
"singleton_method",
|
|
650
|
-
"lambda",
|
|
651
|
-
"class",
|
|
652
|
-
"module",
|
|
653
|
-
"singleton_class"
|
|
654
|
-
]);
|
|
655
672
|
var RAISE_NAMES2 = /* @__PURE__ */ new Set(["raise", "fail"]);
|
|
656
673
|
var BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
657
674
|
"body_statement",
|
|
@@ -699,7 +716,7 @@ function isRaise2(node) {
|
|
|
699
716
|
}
|
|
700
717
|
function bodyCalls(node, found = []) {
|
|
701
718
|
for (const child of children(node)) {
|
|
702
|
-
if (
|
|
719
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
703
720
|
continue;
|
|
704
721
|
}
|
|
705
722
|
if (child.type === "call" && !isPropertyRead(child) && !isRaise2(child)) {
|
|
@@ -15302,7 +15319,7 @@ function date4(params) {
|
|
|
15302
15319
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15303
15320
|
config(en_default());
|
|
15304
15321
|
|
|
15305
|
-
// ../../ir-core/dist/chunk-
|
|
15322
|
+
// ../../ir-core/dist/chunk-PPQWK62O.js
|
|
15306
15323
|
function gqlIdentityKey(typeName, fieldName) {
|
|
15307
15324
|
return `gql:${typeName}.${fieldName}`;
|
|
15308
15325
|
}
|
|
@@ -15312,6 +15329,9 @@ function fnIdentityKey(packageName, exportPath) {
|
|
|
15312
15329
|
function busIdentityKey(messageBus, subject) {
|
|
15313
15330
|
return `bus:${messageBus} ${subject}`;
|
|
15314
15331
|
}
|
|
15332
|
+
function unitIdentityKey(deploymentTarget, instanceName) {
|
|
15333
|
+
return `unit:${deploymentTarget} ${instanceName}`;
|
|
15334
|
+
}
|
|
15315
15335
|
function metricIdentityKey(metricSystem, metricType) {
|
|
15316
15336
|
return `metric:${metricSystem} ${metricType}`;
|
|
15317
15337
|
}
|
|
@@ -15585,6 +15605,42 @@ var metricSemantics = defineBoundarySemantics({
|
|
|
15585
15605
|
}
|
|
15586
15606
|
}
|
|
15587
15607
|
});
|
|
15608
|
+
var HOLE_SPLIT = /(\{[^}]*\})/;
|
|
15609
|
+
function isHole(piece) {
|
|
15610
|
+
return piece.startsWith("{") && piece.endsWith("}");
|
|
15611
|
+
}
|
|
15612
|
+
function parseBoundaryName(name) {
|
|
15613
|
+
const parts = name.split(HOLE_SPLIT).filter((piece) => piece !== "").map(
|
|
15614
|
+
(piece) => isHole(piece) ? { type: "hole", label: piece.slice(1, -1) } : { type: "text", text: piece }
|
|
15615
|
+
);
|
|
15616
|
+
const only = parts.length === 1 ? parts[0] : void 0;
|
|
15617
|
+
if (only !== void 0 && only.type === "hole") {
|
|
15618
|
+
return { type: "reference", path: only.label.split(".") };
|
|
15619
|
+
}
|
|
15620
|
+
if (parts.some((part) => part.type === "hole")) {
|
|
15621
|
+
return { type: "pattern", parts };
|
|
15622
|
+
}
|
|
15623
|
+
return { type: "literal", value: name };
|
|
15624
|
+
}
|
|
15625
|
+
function patternHole(label) {
|
|
15626
|
+
return `{${label}}`;
|
|
15627
|
+
}
|
|
15628
|
+
function namesNothing(name) {
|
|
15629
|
+
return parseBoundaryName(name).type === "reference";
|
|
15630
|
+
}
|
|
15631
|
+
function referenceOf(name) {
|
|
15632
|
+
if (name.type !== "reference") {
|
|
15633
|
+
return null;
|
|
15634
|
+
}
|
|
15635
|
+
const root = name.path[0];
|
|
15636
|
+
if (root === void 0 || name.path.some((part) => part === "")) {
|
|
15637
|
+
return null;
|
|
15638
|
+
}
|
|
15639
|
+
return { root, fields: name.path.slice(1) };
|
|
15640
|
+
}
|
|
15641
|
+
function referenceFromName(name) {
|
|
15642
|
+
return referenceOf(parseBoundaryName(name));
|
|
15643
|
+
}
|
|
15588
15644
|
var SCHEME_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
|
|
15589
15645
|
var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
|
|
15590
15646
|
function pathAfterOrigin(text) {
|
|
@@ -15611,9 +15667,9 @@ var RestSemanticsSchema = external_exports.object({
|
|
|
15611
15667
|
declaredResponses: external_exports.array(external_exports.number()).optional()
|
|
15612
15668
|
});
|
|
15613
15669
|
var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
|
|
15614
|
-
function
|
|
15615
|
-
const
|
|
15616
|
-
return
|
|
15670
|
+
function baseUrlReference(semantics) {
|
|
15671
|
+
const label = OPENING_HOLE.exec(semantics.path ?? "")?.[1];
|
|
15672
|
+
return label === void 0 ? null : referenceFromName(patternHole(label));
|
|
15617
15673
|
}
|
|
15618
15674
|
function normalizePath(path4) {
|
|
15619
15675
|
let normalized = path4.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
|
|
@@ -15724,6 +15780,14 @@ var restSemantics = defineBoundarySemantics({
|
|
|
15724
15780
|
}
|
|
15725
15781
|
return routePathAdmits(semantics.path, path4) ? "match" : "nomatch";
|
|
15726
15782
|
},
|
|
15783
|
+
/**
|
|
15784
|
+
* A route the registration pattern admits is inside it. A route
|
|
15785
|
+
* whose path this source never gave is left outside, because
|
|
15786
|
+
* nothing here can show it is one the pattern covers.
|
|
15787
|
+
*/
|
|
15788
|
+
withinScope(semantics, scope) {
|
|
15789
|
+
return semantics.path !== null && routePathAdmits(scope, semantics.path);
|
|
15790
|
+
},
|
|
15727
15791
|
/**
|
|
15728
15792
|
* A call whose base URL the deployment fills in, resolved to the
|
|
15729
15793
|
* path it reaches.
|
|
@@ -15739,22 +15803,20 @@ var restSemantics = defineBoundarySemantics({
|
|
|
15739
15803
|
* route parameter, and `/orders/{id}` means every id rather than a
|
|
15740
15804
|
* variable somebody set.
|
|
15741
15805
|
*/
|
|
15742
|
-
groundName(semantics,
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
}
|
|
15746
|
-
const opening = OPENING_HOLE.exec(semantics.path);
|
|
15747
|
-
if (opening === null) {
|
|
15806
|
+
groundName(semantics, deployment) {
|
|
15807
|
+
const reference = baseUrlReference(semantics);
|
|
15808
|
+
if (reference === null) {
|
|
15748
15809
|
return null;
|
|
15749
15810
|
}
|
|
15750
|
-
const
|
|
15751
|
-
const base = deployedAs(variableOf(label));
|
|
15811
|
+
const base = deployment.setTo(reference);
|
|
15752
15812
|
if (base === null) {
|
|
15753
15813
|
return null;
|
|
15754
15814
|
}
|
|
15815
|
+
const rest = OPENING_HOLE.exec(semantics.path ?? "")?.[2] ?? "";
|
|
15755
15816
|
const grounded = pathAfterOrigin(`${base}${rest}`);
|
|
15756
15817
|
return { ...semantics, path: grounded === "" ? "/" : grounded };
|
|
15757
15818
|
},
|
|
15819
|
+
nameReference: baseUrlReference,
|
|
15758
15820
|
ruleBoundary: {
|
|
15759
15821
|
// "METHOD /path": one leading token, then an absolute path.
|
|
15760
15822
|
claims(raw) {
|
|
@@ -15830,6 +15892,9 @@ var StorageSemanticsSchema = external_exports.object({
|
|
|
15830
15892
|
*/
|
|
15831
15893
|
accessPath: external_exports.string().nullable()
|
|
15832
15894
|
});
|
|
15895
|
+
function containerReference(semantics) {
|
|
15896
|
+
return semantics.container === null ? null : referenceFromName(semantics.container);
|
|
15897
|
+
}
|
|
15833
15898
|
var storageSemantics = defineBoundarySemantics({
|
|
15834
15899
|
name: "storage",
|
|
15835
15900
|
schema: StorageSemanticsSchema,
|
|
@@ -15845,7 +15910,100 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
15845
15910
|
/** A query returns rows or items, not a status and a body. */
|
|
15846
15911
|
exchangesHttpResponses: false,
|
|
15847
15912
|
reportsUnpairedItself: false,
|
|
15848
|
-
identityKey: () => null
|
|
15913
|
+
identityKey: () => null,
|
|
15914
|
+
displayLabel: storageLabel,
|
|
15915
|
+
/**
|
|
15916
|
+
* A container the source states as a variable is whatever the
|
|
15917
|
+
* deployment sets that variable to. `{SUBSCRIBERS_TABLE}` in the
|
|
15918
|
+
* code and `prod-subscribers-v1` in the manifest are one table.
|
|
15919
|
+
*/
|
|
15920
|
+
groundName(semantics, deployment) {
|
|
15921
|
+
const reference = containerReference(semantics);
|
|
15922
|
+
if (reference === null) {
|
|
15923
|
+
return null;
|
|
15924
|
+
}
|
|
15925
|
+
const name = deployment.setTo(reference);
|
|
15926
|
+
return name === null ? null : { ...semantics, container: name };
|
|
15927
|
+
},
|
|
15928
|
+
nameReference: containerReference
|
|
15929
|
+
}
|
|
15930
|
+
});
|
|
15931
|
+
function storageLabel(semantics) {
|
|
15932
|
+
return `${semantics.storageSystem}:${storageContainerLabel(semantics)}`;
|
|
15933
|
+
}
|
|
15934
|
+
function storageContainerLabel(semantics) {
|
|
15935
|
+
const container = semantics.container ?? "<unnamed container>";
|
|
15936
|
+
const addressed = semantics.accessPath === null ? container : `${container}#${semantics.accessPath}`;
|
|
15937
|
+
return semantics.scope === "default" ? addressed : `${semantics.scope}/${addressed}`;
|
|
15938
|
+
}
|
|
15939
|
+
var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
|
|
15940
|
+
name: external_exports.literal("unit-invocation"),
|
|
15941
|
+
instanceName: DeployableUnitSchema.shape.instanceName.nullable()
|
|
15942
|
+
});
|
|
15943
|
+
function calleeReference(semantics) {
|
|
15944
|
+
return semantics.instanceName === null ? null : referenceFromName(semantics.instanceName);
|
|
15945
|
+
}
|
|
15946
|
+
var unitInvocationSemantics = defineBoundarySemantics({
|
|
15947
|
+
name: "unit-invocation",
|
|
15948
|
+
schema: UnitInvocationSemanticsSchema,
|
|
15949
|
+
// faas.name is the deployed function's own name and instanceName is
|
|
15950
|
+
// the deployment template's logical id, which is a different string.
|
|
15951
|
+
// Runtime config leaves the pair off for the same reason.
|
|
15952
|
+
semconv: {},
|
|
15953
|
+
behavior: {
|
|
15954
|
+
/**
|
|
15955
|
+
* A synchronous invoke gives back whatever the handler returned,
|
|
15956
|
+
* which is a value rather than a status and a body. A handler's
|
|
15957
|
+
* return only becomes an HTTP response under a proxy integration,
|
|
15958
|
+
* and that route gets a REST binding instead of this one.
|
|
15959
|
+
*/
|
|
15960
|
+
exchangesHttpResponses: false,
|
|
15961
|
+
/**
|
|
15962
|
+
* A unit nothing in the run invokes is the ordinary case, since
|
|
15963
|
+
* most services are reached from a stack suss never read. So an
|
|
15964
|
+
* uninvoked unit stays in the generic unmatched list rather than
|
|
15965
|
+
* being reported as a problem here.
|
|
15966
|
+
*/
|
|
15967
|
+
reportsUnpairedItself: false,
|
|
15968
|
+
/**
|
|
15969
|
+
* A callee the source states only as a variable is not a name for
|
|
15970
|
+
* anything until the deployment fills it in, so it keys as nothing
|
|
15971
|
+
* rather than as a bucket that would agree with itself alone.
|
|
15972
|
+
*/
|
|
15973
|
+
identityKey(semantics) {
|
|
15974
|
+
if (semantics.instanceName === null || namesNothing(semantics.instanceName)) {
|
|
15975
|
+
return null;
|
|
15976
|
+
}
|
|
15977
|
+
return unitIdentityKey(
|
|
15978
|
+
semantics.deploymentTarget,
|
|
15979
|
+
semantics.instanceName
|
|
15980
|
+
);
|
|
15981
|
+
},
|
|
15982
|
+
displayLabel(semantics) {
|
|
15983
|
+
if (semantics.instanceName === null) {
|
|
15984
|
+
return `unit:${semantics.deploymentTarget} (named at runtime)`;
|
|
15985
|
+
}
|
|
15986
|
+
return unitIdentityKey(
|
|
15987
|
+
semantics.deploymentTarget,
|
|
15988
|
+
semantics.instanceName
|
|
15989
|
+
);
|
|
15990
|
+
},
|
|
15991
|
+
/**
|
|
15992
|
+
* A call that reads its callee's name out of the environment
|
|
15993
|
+
* reaches whichever resource the template wires that variable to.
|
|
15994
|
+
* The logical id is the answer rather than the deployed name,
|
|
15995
|
+
* because the invoked unit's own summary is keyed by the logical
|
|
15996
|
+
* id and neither side ever writes the other's string.
|
|
15997
|
+
*/
|
|
15998
|
+
groundName(semantics, deployment) {
|
|
15999
|
+
const reference = calleeReference(semantics);
|
|
16000
|
+
if (reference === null) {
|
|
16001
|
+
return null;
|
|
16002
|
+
}
|
|
16003
|
+
const logicalId = deployment.pointsAt(reference);
|
|
16004
|
+
return logicalId === null ? null : { ...semantics, instanceName: logicalId };
|
|
16005
|
+
},
|
|
16006
|
+
nameReference: calleeReference
|
|
15849
16007
|
}
|
|
15850
16008
|
});
|
|
15851
16009
|
var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
@@ -15856,7 +16014,8 @@ var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
|
15856
16014
|
runtimeConfigSemantics.schema,
|
|
15857
16015
|
storageSemantics.schema,
|
|
15858
16016
|
messageBusSemantics.schema,
|
|
15859
|
-
metricSemantics.schema
|
|
16017
|
+
metricSemantics.schema,
|
|
16018
|
+
unitInvocationSemantics.schema
|
|
15860
16019
|
]);
|
|
15861
16020
|
var DEFINITIONS = [
|
|
15862
16021
|
restSemantics,
|
|
@@ -15866,7 +16025,8 @@ var DEFINITIONS = [
|
|
|
15866
16025
|
runtimeConfigSemantics,
|
|
15867
16026
|
storageSemantics,
|
|
15868
16027
|
messageBusSemantics,
|
|
15869
|
-
metricSemantics
|
|
16028
|
+
metricSemantics,
|
|
16029
|
+
unitInvocationSemantics
|
|
15870
16030
|
];
|
|
15871
16031
|
var BY_NAME = new Map(
|
|
15872
16032
|
DEFINITIONS.map((d) => [d.name, d])
|
|
@@ -15956,6 +16116,13 @@ var TypeShapeSchema = external_exports.lazy(
|
|
|
15956
16116
|
);
|
|
15957
16117
|
|
|
15958
16118
|
// ../../ir-core/dist/index.js
|
|
16119
|
+
var RelationSchema = external_exports.enum([
|
|
16120
|
+
"provides",
|
|
16121
|
+
"reads",
|
|
16122
|
+
"writes",
|
|
16123
|
+
"invokes"
|
|
16124
|
+
]);
|
|
16125
|
+
var EffectRelationSchema = RelationSchema.exclude(["provides"]);
|
|
15959
16126
|
var SuppressionSideSchema = external_exports.object({
|
|
15960
16127
|
summary: external_exports.string().optional(),
|
|
15961
16128
|
transitionId: external_exports.string().optional()
|
|
@@ -16144,9 +16311,9 @@ var RESOLUTION_RULES = [
|
|
|
16144
16311
|
[(0, import_datalog2.lit)("invokes", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("f")), (0, import_datalog2.lit)("returnsValue", (0, import_datalog2.variable)("f"), (0, import_datalog2.variable)("ret"))],
|
|
16145
16312
|
"call result"
|
|
16146
16313
|
),
|
|
16147
|
-
// Where a walk gets to, and whether it ran a call on the way.
|
|
16148
|
-
//
|
|
16149
|
-
//
|
|
16314
|
+
// Where a walk gets to, and whether it ran a call on the way. The walk
|
|
16315
|
+
// so far comes first, so demand stays on the value asked about; the
|
|
16316
|
+
// README says what the other order cost.
|
|
16150
16317
|
(0, import_datalog2.rule)(
|
|
16151
16318
|
"reaches",
|
|
16152
16319
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind")],
|
|
@@ -16156,27 +16323,27 @@ var RESOLUTION_RULES = [
|
|
|
16156
16323
|
"reaches",
|
|
16157
16324
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind")],
|
|
16158
16325
|
[
|
|
16159
|
-
(0, import_datalog2.lit)("
|
|
16160
|
-
(0, import_datalog2.lit)("
|
|
16326
|
+
(0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), VALUE_STEP),
|
|
16327
|
+
(0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), (0, import_datalog2.variable)("kind"))
|
|
16161
16328
|
]
|
|
16162
16329
|
),
|
|
16163
|
-
// Two rules rather than one leaving the
|
|
16164
|
-
//
|
|
16330
|
+
// Two rules rather than one leaving the next step's kind free. A free
|
|
16331
|
+
// kind is a second question about the same relation, and a
|
|
16165
16332
|
// demand-driven run then derives both to answer either.
|
|
16166
16333
|
(0, import_datalog2.rule)(
|
|
16167
16334
|
"reaches",
|
|
16168
16335
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), RESULT_STEP],
|
|
16169
16336
|
[
|
|
16170
|
-
(0, import_datalog2.lit)("
|
|
16171
|
-
(0, import_datalog2.lit)("
|
|
16337
|
+
(0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
|
|
16338
|
+
(0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), VALUE_STEP)
|
|
16172
16339
|
]
|
|
16173
16340
|
),
|
|
16174
16341
|
(0, import_datalog2.rule)(
|
|
16175
16342
|
"reaches",
|
|
16176
16343
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"), RESULT_STEP],
|
|
16177
16344
|
[
|
|
16178
|
-
(0, import_datalog2.lit)("
|
|
16179
|
-
(0, import_datalog2.lit)("
|
|
16345
|
+
(0, import_datalog2.lit)("reaches", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y"), RESULT_STEP),
|
|
16346
|
+
(0, import_datalog2.lit)("stepsTo", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"), RESULT_STEP)
|
|
16180
16347
|
]
|
|
16181
16348
|
),
|
|
16182
16349
|
// What a value comes down to: the walk that never ran a call, stopped
|
|
@@ -16522,29 +16689,14 @@ var RESOLUTION_QUESTIONS = [
|
|
|
16522
16689
|
// here demands reaches or callsInto. The chains are closures with
|
|
16523
16690
|
// no depth bound: an alias run of any length resolves.
|
|
16524
16691
|
(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"))]),
|
|
16692
|
+
// The chain with at least one hop taken, which is what tells a
|
|
16693
|
+
// destructured binding apart from asking about a node directly. The
|
|
16694
|
+
// whole chain is the seed plus those hops.
|
|
16525
16695
|
(0, import_datalog2.rule)(
|
|
16526
16696
|
"callOriginChain",
|
|
16527
16697
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
|
|
16528
|
-
[(0, import_datalog2.lit)("
|
|
16529
|
-
),
|
|
16530
|
-
(0, import_datalog2.rule)(
|
|
16531
|
-
"callOriginChain",
|
|
16532
|
-
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
|
|
16533
|
-
[
|
|
16534
|
-
(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
|
|
16535
|
-
(0, import_datalog2.lit)("endsHolding", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
|
|
16536
|
-
]
|
|
16537
|
-
),
|
|
16538
|
-
(0, import_datalog2.rule)(
|
|
16539
|
-
"callOriginChain",
|
|
16540
|
-
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
|
|
16541
|
-
[
|
|
16542
|
-
(0, import_datalog2.lit)("callOriginChain", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("y")),
|
|
16543
|
-
(0, import_datalog2.lit)("fallbackBranch", (0, import_datalog2.variable)("y"), (0, import_datalog2.variable)("z"))
|
|
16544
|
-
]
|
|
16698
|
+
[(0, import_datalog2.lit)("callOriginChainStepped", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z"))]
|
|
16545
16699
|
),
|
|
16546
|
-
// The chain with at least one hop taken, which is what tells a
|
|
16547
|
-
// destructured binding apart from asking about a node directly.
|
|
16548
16700
|
(0, import_datalog2.rule)(
|
|
16549
16701
|
"callOriginChainStepped",
|
|
16550
16702
|
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("z")],
|
|
@@ -16675,6 +16827,23 @@ var RESOLUTION_QUESTIONS = [
|
|
|
16675
16827
|
(0, import_datalog2.lit)("callsInto", (0, import_datalog2.variable)("g"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
|
|
16676
16828
|
]
|
|
16677
16829
|
),
|
|
16830
|
+
// Subject identity, its own demand class; the README's subject
|
|
16831
|
+
// section says why the origin pair rides on the written-value walk.
|
|
16832
|
+
(0, import_datalog2.rule)(
|
|
16833
|
+
"wantedSubjectWritten",
|
|
16834
|
+
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")],
|
|
16835
|
+
[(0, import_datalog2.lit)("wantedSubject", (0, import_datalog2.variable)("x")), (0, import_datalog2.lit)("isWrittenAs", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r"))]
|
|
16836
|
+
),
|
|
16837
|
+
(0, import_datalog2.rule)(
|
|
16838
|
+
"wantedSubjectConstruction",
|
|
16839
|
+
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
|
|
16840
|
+
[
|
|
16841
|
+
(0, import_datalog2.lit)("wantedSubject", (0, import_datalog2.variable)("x")),
|
|
16842
|
+
(0, import_datalog2.lit)("isWrittenAs", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")),
|
|
16843
|
+
(0, import_datalog2.lit)("call", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("c")),
|
|
16844
|
+
(0, import_datalog2.lit)("comesFrom", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
|
|
16845
|
+
]
|
|
16846
|
+
),
|
|
16678
16847
|
// The export table of one module, keyed by the module asked about.
|
|
16679
16848
|
// The moduleExport rules flatten re-export chains of any length, and
|
|
16680
16849
|
// the demand cone stays on export facts alone.
|
|
@@ -17022,7 +17191,10 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
17022
17191
|
const knownClasses = ownBlocks[0]?.knownClasses ?? /* @__PURE__ */ new Set();
|
|
17023
17192
|
const scope = { nesting: info.bodyNesting, knownClasses };
|
|
17024
17193
|
const declsByName = /* @__PURE__ */ new Map();
|
|
17025
|
-
for (const stmt of
|
|
17194
|
+
for (const stmt of runStatements(
|
|
17195
|
+
info.bodyNode,
|
|
17196
|
+
blockConfiguresCall(pattern)
|
|
17197
|
+
)) {
|
|
17026
17198
|
const decl = await readFieldCall(stmt, scope, ctx, ancestry);
|
|
17027
17199
|
if (decl !== null) {
|
|
17028
17200
|
declsByName.set(decl.fieldName, decl);
|
|
@@ -17032,6 +17204,17 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
17032
17204
|
(decl) => buildFieldUnit(pack, typeName, decl, options.filePath)
|
|
17033
17205
|
);
|
|
17034
17206
|
}
|
|
17207
|
+
function blockConfiguresCall(pattern) {
|
|
17208
|
+
const names = /* @__PURE__ */ new Set([
|
|
17209
|
+
pattern.fieldCallName,
|
|
17210
|
+
pattern.typeCallName,
|
|
17211
|
+
pattern.argumentCallName
|
|
17212
|
+
]);
|
|
17213
|
+
return (call) => {
|
|
17214
|
+
const method = field(call, "method")?.text;
|
|
17215
|
+
return field(call, "receiver") === null && method !== void 0 && names.has(method);
|
|
17216
|
+
};
|
|
17217
|
+
}
|
|
17035
17218
|
function branchesFor(body, range) {
|
|
17036
17219
|
if (body.effects === void 0 && body.extraEffects === void 0) {
|
|
17037
17220
|
return [];
|
|
@@ -17107,10 +17290,13 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17107
17290
|
}
|
|
17108
17291
|
const callArgs = readCallArgs(field(stmt, "arguments"));
|
|
17109
17292
|
const nameArg = callArgs.positional[0];
|
|
17110
|
-
|
|
17111
|
-
if (symbol2 === null) {
|
|
17293
|
+
if (nameArg === void 0) {
|
|
17112
17294
|
return null;
|
|
17113
17295
|
}
|
|
17296
|
+
const symbol2 = symbolValue(nameArg);
|
|
17297
|
+
if (symbol2 === null) {
|
|
17298
|
+
return computedNameDeclaration(stmt, nameArg);
|
|
17299
|
+
}
|
|
17114
17300
|
const read = await readFieldShape(
|
|
17115
17301
|
symbol2,
|
|
17116
17302
|
callArgs,
|
|
@@ -17121,11 +17307,29 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17121
17307
|
);
|
|
17122
17308
|
return {
|
|
17123
17309
|
fieldName: resolvedName(symbol2, callArgs, ctx.pattern),
|
|
17310
|
+
namedOnTheWire: true,
|
|
17124
17311
|
node: stmt,
|
|
17125
17312
|
contract: read.contract,
|
|
17126
17313
|
body: read.body
|
|
17127
17314
|
};
|
|
17128
17315
|
}
|
|
17316
|
+
function computedNameDeclaration(stmt, nameArg) {
|
|
17317
|
+
const range = rangeOf(stmt);
|
|
17318
|
+
return {
|
|
17319
|
+
fieldName: nameArg.text,
|
|
17320
|
+
namedOnTheWire: false,
|
|
17321
|
+
node: stmt,
|
|
17322
|
+
contract: null,
|
|
17323
|
+
body: {
|
|
17324
|
+
readings: [
|
|
17325
|
+
(0, import_extractor3.unreadableReading)(
|
|
17326
|
+
`This field is named by ${nameArg.text}, which is worked out when the class body runs, so the name the schema exposes it under was not read here`,
|
|
17327
|
+
range
|
|
17328
|
+
)
|
|
17329
|
+
]
|
|
17330
|
+
}
|
|
17331
|
+
};
|
|
17332
|
+
}
|
|
17129
17333
|
function wiringReference(callArgs, wiringKeywords) {
|
|
17130
17334
|
for (const keyword of wiringKeywords) {
|
|
17131
17335
|
const ref = callArgs.keyword[keyword];
|
|
@@ -17250,7 +17454,10 @@ function readClassContract(ancestry, pattern) {
|
|
|
17250
17454
|
args: /* @__PURE__ */ new Map()
|
|
17251
17455
|
};
|
|
17252
17456
|
const handlers = classCallHandlers(pattern);
|
|
17253
|
-
for (const { block, statement } of inheritedStatements(
|
|
17457
|
+
for (const { block, statement } of inheritedStatements(
|
|
17458
|
+
ancestry,
|
|
17459
|
+
blockConfiguresCall(pattern)
|
|
17460
|
+
)) {
|
|
17254
17461
|
if (statement.type !== "call" || field(statement, "receiver") !== null) {
|
|
17255
17462
|
continue;
|
|
17256
17463
|
}
|
|
@@ -17341,12 +17548,12 @@ function buildFieldUnit(pack, typeName, decl, filePath) {
|
|
|
17341
17548
|
exportName: null,
|
|
17342
17549
|
exportPath: null
|
|
17343
17550
|
},
|
|
17344
|
-
boundaryBinding: (0, import_behavioral_ir.graphqlResolverBinding)({
|
|
17551
|
+
boundaryBinding: decl.namedOnTheWire ? (0, import_behavioral_ir.graphqlResolverBinding)({
|
|
17345
17552
|
transport: pack.protocol,
|
|
17346
17553
|
recognition: pack.name,
|
|
17347
17554
|
typeName,
|
|
17348
17555
|
fieldName: decl.fieldName
|
|
17349
|
-
}),
|
|
17556
|
+
}) : null,
|
|
17350
17557
|
parameters,
|
|
17351
17558
|
branches: branchesFor(decl.body, rangeOf(decl.node)),
|
|
17352
17559
|
...decl.body.bodyContent !== void 0 ? { bodyContent: decl.body.bodyContent } : {},
|
|
@@ -17417,14 +17624,6 @@ function nodeId(filePath, node) {
|
|
|
17417
17624
|
function nameId(filePath, name) {
|
|
17418
17625
|
return `${filePath}#${name}`;
|
|
17419
17626
|
}
|
|
17420
|
-
var DECLARATION_TYPES2 = /* @__PURE__ */ new Set([
|
|
17421
|
-
"method",
|
|
17422
|
-
"singleton_method",
|
|
17423
|
-
"lambda",
|
|
17424
|
-
"class",
|
|
17425
|
-
"module",
|
|
17426
|
-
"singleton_class"
|
|
17427
|
-
]);
|
|
17428
17627
|
var WRITTEN_VALUE_TYPES = /* @__PURE__ */ new Set([
|
|
17429
17628
|
"string",
|
|
17430
17629
|
"integer",
|
|
@@ -17562,7 +17761,7 @@ function emitHash(emitter, hash2) {
|
|
|
17562
17761
|
}
|
|
17563
17762
|
function walkExpressions(node, visit) {
|
|
17564
17763
|
for (const child of children3(node)) {
|
|
17565
|
-
if (
|
|
17764
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17566
17765
|
continue;
|
|
17567
17766
|
}
|
|
17568
17767
|
visit(child);
|
|
@@ -17620,7 +17819,7 @@ function emitMethodFacts(emitter, method) {
|
|
|
17620
17819
|
}
|
|
17621
17820
|
const recordNested = (node) => {
|
|
17622
17821
|
for (const child of children3(node)) {
|
|
17623
|
-
if (
|
|
17822
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17624
17823
|
add(emitter, "containsFn", funcKey, nodeId(emitter.filePath, child));
|
|
17625
17824
|
continue;
|
|
17626
17825
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -4,6 +4,16 @@ import { Database } from '@suss/datalog';
|
|
|
4
4
|
import { TypeShape, BehavioralSummary } from '@suss/behavioral-ir';
|
|
5
5
|
import { RawCodeStructure } from '@suss/extractor';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* A new `Parser` for every call, so that parses running at the same time do
|
|
9
|
+
* not fight over one parser's mutable `language` field. The compiled `Language`
|
|
10
|
+
* is loaded once per process and shared.
|
|
11
|
+
*/
|
|
12
|
+
declare function parseRuby(source: string): Promise<Tree>;
|
|
13
|
+
|
|
14
|
+
/** A call whose block is the thing being configured rather than a place statements run. */
|
|
15
|
+
type BlockConfigures = (call: Node) => boolean;
|
|
16
|
+
|
|
7
17
|
/**
|
|
8
18
|
* Finds the file behind a constant.
|
|
9
19
|
*
|
|
@@ -19,13 +29,6 @@ declare function underscoreConstantPath(qualifiedName: string): string;
|
|
|
19
29
|
/** Null when there is no file at that path. We do not fall back to another root or another spelling. */
|
|
20
30
|
declare function resolveConstantFile(root: string, qualifiedName: string, convention: ConstantPathConvention): string | null;
|
|
21
31
|
|
|
22
|
-
/**
|
|
23
|
-
* A new `Parser` for every call, so that parses running at the same time do
|
|
24
|
-
* not fight over one parser's mutable `language` field. The compiled `Language`
|
|
25
|
-
* is loaded once per process and shared.
|
|
26
|
-
*/
|
|
27
|
-
declare function parseRuby(source: string): Promise<Tree>;
|
|
28
|
-
|
|
29
32
|
/**
|
|
30
33
|
* Resolves Ruby constant paths against lexical nesting.
|
|
31
34
|
*
|
|
@@ -65,7 +68,7 @@ interface ClassInfo {
|
|
|
65
68
|
/** `Module.nesting` in effect inside this class's own body, innermost first. */
|
|
66
69
|
bodyNesting: readonly string[];
|
|
67
70
|
}
|
|
68
|
-
/** Every `class` declaration reachable from `root` through
|
|
71
|
+
/** Every `class` declaration reachable from `root` through module/class nesting, in source order. */
|
|
69
72
|
declare function walkClasses(root: Node, visit: (info: ClassInfo) => void): void;
|
|
70
73
|
/** The same walk including `module` declarations, for a lookup that has to reach a module's own methods. */
|
|
71
74
|
declare function walkDefinitions(root: Node, visit: (info: ClassInfo) => void): void;
|
|
@@ -134,7 +137,7 @@ type MethodLookup = {
|
|
|
134
137
|
*/
|
|
135
138
|
declare function methodInAncestry(ancestry: Ancestry, name: string): MethodLookup;
|
|
136
139
|
/** Every statement of every body reached, most distant ancestor first, so a nearer declaration overwrites what it inherits. */
|
|
137
|
-
declare function inheritedStatements(ancestry: Ancestry): Array<{
|
|
140
|
+
declare function inheritedStatements(ancestry: Ancestry, blockConfigures?: BlockConfigures): Array<{
|
|
138
141
|
block: ReachedBody;
|
|
139
142
|
statement: Node;
|
|
140
143
|
}>;
|