@suss/adapter-ruby 0.20.0 → 0.21.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 +175 -36
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/index.js +176 -37
- 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-QHFMZPEG.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
|
}
|
|
@@ -15724,6 +15744,14 @@ var restSemantics = defineBoundarySemantics({
|
|
|
15724
15744
|
}
|
|
15725
15745
|
return routePathAdmits(semantics.path, path4) ? "match" : "nomatch";
|
|
15726
15746
|
},
|
|
15747
|
+
/**
|
|
15748
|
+
* A route the registration pattern admits is inside it. A route
|
|
15749
|
+
* whose path this source never gave is left outside, because
|
|
15750
|
+
* nothing here can show it is one the pattern covers.
|
|
15751
|
+
*/
|
|
15752
|
+
withinScope(semantics, scope) {
|
|
15753
|
+
return semantics.path !== null && routePathAdmits(scope, semantics.path);
|
|
15754
|
+
},
|
|
15727
15755
|
/**
|
|
15728
15756
|
* A call whose base URL the deployment fills in, resolved to the
|
|
15729
15757
|
* path it reaches.
|
|
@@ -15845,7 +15873,62 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
15845
15873
|
/** A query returns rows or items, not a status and a body. */
|
|
15846
15874
|
exchangesHttpResponses: false,
|
|
15847
15875
|
reportsUnpairedItself: false,
|
|
15848
|
-
identityKey: () => null
|
|
15876
|
+
identityKey: () => null,
|
|
15877
|
+
displayLabel: storageLabel
|
|
15878
|
+
}
|
|
15879
|
+
});
|
|
15880
|
+
function storageLabel(semantics) {
|
|
15881
|
+
return `${semantics.storageSystem}:${storageContainerLabel(semantics)}`;
|
|
15882
|
+
}
|
|
15883
|
+
function storageContainerLabel(semantics) {
|
|
15884
|
+
const container = semantics.container ?? "<unnamed container>";
|
|
15885
|
+
const addressed = semantics.accessPath === null ? container : `${container}#${semantics.accessPath}`;
|
|
15886
|
+
return semantics.scope === "default" ? addressed : `${semantics.scope}/${addressed}`;
|
|
15887
|
+
}
|
|
15888
|
+
var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
|
|
15889
|
+
name: external_exports.literal("unit-invocation"),
|
|
15890
|
+
instanceName: DeployableUnitSchema.shape.instanceName.nullable()
|
|
15891
|
+
});
|
|
15892
|
+
var unitInvocationSemantics = defineBoundarySemantics({
|
|
15893
|
+
name: "unit-invocation",
|
|
15894
|
+
schema: UnitInvocationSemanticsSchema,
|
|
15895
|
+
// faas.name is the deployed function's own name and instanceName is
|
|
15896
|
+
// the deployment template's logical id, which is a different string.
|
|
15897
|
+
// Runtime config leaves the pair off for the same reason.
|
|
15898
|
+
semconv: {},
|
|
15899
|
+
behavior: {
|
|
15900
|
+
/**
|
|
15901
|
+
* A synchronous invoke gives back whatever the handler returned,
|
|
15902
|
+
* which is a value rather than a status and a body. A handler's
|
|
15903
|
+
* return only becomes an HTTP response under a proxy integration,
|
|
15904
|
+
* and that route gets a REST binding instead of this one.
|
|
15905
|
+
*/
|
|
15906
|
+
exchangesHttpResponses: false,
|
|
15907
|
+
/**
|
|
15908
|
+
* A unit nothing in the run invokes is the ordinary case, since
|
|
15909
|
+
* most services are reached from a stack suss never read. So an
|
|
15910
|
+
* uninvoked unit stays in the generic unmatched list rather than
|
|
15911
|
+
* being reported as a problem here.
|
|
15912
|
+
*/
|
|
15913
|
+
reportsUnpairedItself: false,
|
|
15914
|
+
identityKey(semantics) {
|
|
15915
|
+
if (semantics.instanceName === null) {
|
|
15916
|
+
return null;
|
|
15917
|
+
}
|
|
15918
|
+
return unitIdentityKey(
|
|
15919
|
+
semantics.deploymentTarget,
|
|
15920
|
+
semantics.instanceName
|
|
15921
|
+
);
|
|
15922
|
+
},
|
|
15923
|
+
displayLabel(semantics) {
|
|
15924
|
+
if (semantics.instanceName === null) {
|
|
15925
|
+
return `unit:${semantics.deploymentTarget} (named at runtime)`;
|
|
15926
|
+
}
|
|
15927
|
+
return unitIdentityKey(
|
|
15928
|
+
semantics.deploymentTarget,
|
|
15929
|
+
semantics.instanceName
|
|
15930
|
+
);
|
|
15931
|
+
}
|
|
15849
15932
|
}
|
|
15850
15933
|
});
|
|
15851
15934
|
var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
@@ -15856,7 +15939,8 @@ var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
|
15856
15939
|
runtimeConfigSemantics.schema,
|
|
15857
15940
|
storageSemantics.schema,
|
|
15858
15941
|
messageBusSemantics.schema,
|
|
15859
|
-
metricSemantics.schema
|
|
15942
|
+
metricSemantics.schema,
|
|
15943
|
+
unitInvocationSemantics.schema
|
|
15860
15944
|
]);
|
|
15861
15945
|
var DEFINITIONS = [
|
|
15862
15946
|
restSemantics,
|
|
@@ -15866,7 +15950,8 @@ var DEFINITIONS = [
|
|
|
15866
15950
|
runtimeConfigSemantics,
|
|
15867
15951
|
storageSemantics,
|
|
15868
15952
|
messageBusSemantics,
|
|
15869
|
-
metricSemantics
|
|
15953
|
+
metricSemantics,
|
|
15954
|
+
unitInvocationSemantics
|
|
15870
15955
|
];
|
|
15871
15956
|
var BY_NAME = new Map(
|
|
15872
15957
|
DEFINITIONS.map((d) => [d.name, d])
|
|
@@ -15956,6 +16041,13 @@ var TypeShapeSchema = external_exports.lazy(
|
|
|
15956
16041
|
);
|
|
15957
16042
|
|
|
15958
16043
|
// ../../ir-core/dist/index.js
|
|
16044
|
+
var RelationSchema = external_exports.enum([
|
|
16045
|
+
"provides",
|
|
16046
|
+
"reads",
|
|
16047
|
+
"writes",
|
|
16048
|
+
"invokes"
|
|
16049
|
+
]);
|
|
16050
|
+
var EffectRelationSchema = RelationSchema.exclude(["provides"]);
|
|
15959
16051
|
var SuppressionSideSchema = external_exports.object({
|
|
15960
16052
|
summary: external_exports.string().optional(),
|
|
15961
16053
|
transitionId: external_exports.string().optional()
|
|
@@ -16675,6 +16767,23 @@ var RESOLUTION_QUESTIONS = [
|
|
|
16675
16767
|
(0, import_datalog2.lit)("callsInto", (0, import_datalog2.variable)("g"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
|
|
16676
16768
|
]
|
|
16677
16769
|
),
|
|
16770
|
+
// Subject identity, its own demand class; the README's subject
|
|
16771
|
+
// section says why the origin pair rides on the written-value walk.
|
|
16772
|
+
(0, import_datalog2.rule)(
|
|
16773
|
+
"wantedSubjectWritten",
|
|
16774
|
+
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")],
|
|
16775
|
+
[(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"))]
|
|
16776
|
+
),
|
|
16777
|
+
(0, import_datalog2.rule)(
|
|
16778
|
+
"wantedSubjectConstruction",
|
|
16779
|
+
[(0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n")],
|
|
16780
|
+
[
|
|
16781
|
+
(0, import_datalog2.lit)("wantedSubject", (0, import_datalog2.variable)("x")),
|
|
16782
|
+
(0, import_datalog2.lit)("isWrittenAs", (0, import_datalog2.variable)("x"), (0, import_datalog2.variable)("r")),
|
|
16783
|
+
(0, import_datalog2.lit)("call", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("c")),
|
|
16784
|
+
(0, import_datalog2.lit)("comesFrom", (0, import_datalog2.variable)("c"), (0, import_datalog2.variable)("m"), (0, import_datalog2.variable)("n"))
|
|
16785
|
+
]
|
|
16786
|
+
),
|
|
16678
16787
|
// The export table of one module, keyed by the module asked about.
|
|
16679
16788
|
// The moduleExport rules flatten re-export chains of any length, and
|
|
16680
16789
|
// the demand cone stays on export facts alone.
|
|
@@ -17022,7 +17131,10 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
17022
17131
|
const knownClasses = ownBlocks[0]?.knownClasses ?? /* @__PURE__ */ new Set();
|
|
17023
17132
|
const scope = { nesting: info.bodyNesting, knownClasses };
|
|
17024
17133
|
const declsByName = /* @__PURE__ */ new Map();
|
|
17025
|
-
for (const stmt of
|
|
17134
|
+
for (const stmt of runStatements(
|
|
17135
|
+
info.bodyNode,
|
|
17136
|
+
blockConfiguresCall(pattern)
|
|
17137
|
+
)) {
|
|
17026
17138
|
const decl = await readFieldCall(stmt, scope, ctx, ancestry);
|
|
17027
17139
|
if (decl !== null) {
|
|
17028
17140
|
declsByName.set(decl.fieldName, decl);
|
|
@@ -17032,6 +17144,17 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
17032
17144
|
(decl) => buildFieldUnit(pack, typeName, decl, options.filePath)
|
|
17033
17145
|
);
|
|
17034
17146
|
}
|
|
17147
|
+
function blockConfiguresCall(pattern) {
|
|
17148
|
+
const names = /* @__PURE__ */ new Set([
|
|
17149
|
+
pattern.fieldCallName,
|
|
17150
|
+
pattern.typeCallName,
|
|
17151
|
+
pattern.argumentCallName
|
|
17152
|
+
]);
|
|
17153
|
+
return (call) => {
|
|
17154
|
+
const method = field(call, "method")?.text;
|
|
17155
|
+
return field(call, "receiver") === null && method !== void 0 && names.has(method);
|
|
17156
|
+
};
|
|
17157
|
+
}
|
|
17035
17158
|
function branchesFor(body, range) {
|
|
17036
17159
|
if (body.effects === void 0 && body.extraEffects === void 0) {
|
|
17037
17160
|
return [];
|
|
@@ -17107,10 +17230,13 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17107
17230
|
}
|
|
17108
17231
|
const callArgs = readCallArgs(field(stmt, "arguments"));
|
|
17109
17232
|
const nameArg = callArgs.positional[0];
|
|
17110
|
-
|
|
17111
|
-
if (symbol2 === null) {
|
|
17233
|
+
if (nameArg === void 0) {
|
|
17112
17234
|
return null;
|
|
17113
17235
|
}
|
|
17236
|
+
const symbol2 = symbolValue(nameArg);
|
|
17237
|
+
if (symbol2 === null) {
|
|
17238
|
+
return computedNameDeclaration(stmt, nameArg);
|
|
17239
|
+
}
|
|
17114
17240
|
const read = await readFieldShape(
|
|
17115
17241
|
symbol2,
|
|
17116
17242
|
callArgs,
|
|
@@ -17121,11 +17247,29 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17121
17247
|
);
|
|
17122
17248
|
return {
|
|
17123
17249
|
fieldName: resolvedName(symbol2, callArgs, ctx.pattern),
|
|
17250
|
+
namedOnTheWire: true,
|
|
17124
17251
|
node: stmt,
|
|
17125
17252
|
contract: read.contract,
|
|
17126
17253
|
body: read.body
|
|
17127
17254
|
};
|
|
17128
17255
|
}
|
|
17256
|
+
function computedNameDeclaration(stmt, nameArg) {
|
|
17257
|
+
const range = rangeOf(stmt);
|
|
17258
|
+
return {
|
|
17259
|
+
fieldName: nameArg.text,
|
|
17260
|
+
namedOnTheWire: false,
|
|
17261
|
+
node: stmt,
|
|
17262
|
+
contract: null,
|
|
17263
|
+
body: {
|
|
17264
|
+
readings: [
|
|
17265
|
+
(0, import_extractor3.unreadableReading)(
|
|
17266
|
+
`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`,
|
|
17267
|
+
range
|
|
17268
|
+
)
|
|
17269
|
+
]
|
|
17270
|
+
}
|
|
17271
|
+
};
|
|
17272
|
+
}
|
|
17129
17273
|
function wiringReference(callArgs, wiringKeywords) {
|
|
17130
17274
|
for (const keyword of wiringKeywords) {
|
|
17131
17275
|
const ref = callArgs.keyword[keyword];
|
|
@@ -17250,7 +17394,10 @@ function readClassContract(ancestry, pattern) {
|
|
|
17250
17394
|
args: /* @__PURE__ */ new Map()
|
|
17251
17395
|
};
|
|
17252
17396
|
const handlers = classCallHandlers(pattern);
|
|
17253
|
-
for (const { block, statement } of inheritedStatements(
|
|
17397
|
+
for (const { block, statement } of inheritedStatements(
|
|
17398
|
+
ancestry,
|
|
17399
|
+
blockConfiguresCall(pattern)
|
|
17400
|
+
)) {
|
|
17254
17401
|
if (statement.type !== "call" || field(statement, "receiver") !== null) {
|
|
17255
17402
|
continue;
|
|
17256
17403
|
}
|
|
@@ -17341,12 +17488,12 @@ function buildFieldUnit(pack, typeName, decl, filePath) {
|
|
|
17341
17488
|
exportName: null,
|
|
17342
17489
|
exportPath: null
|
|
17343
17490
|
},
|
|
17344
|
-
boundaryBinding: (0, import_behavioral_ir.graphqlResolverBinding)({
|
|
17491
|
+
boundaryBinding: decl.namedOnTheWire ? (0, import_behavioral_ir.graphqlResolverBinding)({
|
|
17345
17492
|
transport: pack.protocol,
|
|
17346
17493
|
recognition: pack.name,
|
|
17347
17494
|
typeName,
|
|
17348
17495
|
fieldName: decl.fieldName
|
|
17349
|
-
}),
|
|
17496
|
+
}) : null,
|
|
17350
17497
|
parameters,
|
|
17351
17498
|
branches: branchesFor(decl.body, rangeOf(decl.node)),
|
|
17352
17499
|
...decl.body.bodyContent !== void 0 ? { bodyContent: decl.body.bodyContent } : {},
|
|
@@ -17417,14 +17564,6 @@ function nodeId(filePath, node) {
|
|
|
17417
17564
|
function nameId(filePath, name) {
|
|
17418
17565
|
return `${filePath}#${name}`;
|
|
17419
17566
|
}
|
|
17420
|
-
var DECLARATION_TYPES2 = /* @__PURE__ */ new Set([
|
|
17421
|
-
"method",
|
|
17422
|
-
"singleton_method",
|
|
17423
|
-
"lambda",
|
|
17424
|
-
"class",
|
|
17425
|
-
"module",
|
|
17426
|
-
"singleton_class"
|
|
17427
|
-
]);
|
|
17428
17567
|
var WRITTEN_VALUE_TYPES = /* @__PURE__ */ new Set([
|
|
17429
17568
|
"string",
|
|
17430
17569
|
"integer",
|
|
@@ -17562,7 +17701,7 @@ function emitHash(emitter, hash2) {
|
|
|
17562
17701
|
}
|
|
17563
17702
|
function walkExpressions(node, visit) {
|
|
17564
17703
|
for (const child of children3(node)) {
|
|
17565
|
-
if (
|
|
17704
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17566
17705
|
continue;
|
|
17567
17706
|
}
|
|
17568
17707
|
visit(child);
|
|
@@ -17620,7 +17759,7 @@ function emitMethodFacts(emitter, method) {
|
|
|
17620
17759
|
}
|
|
17621
17760
|
const recordNested = (node) => {
|
|
17622
17761
|
for (const child of children3(node)) {
|
|
17623
|
-
if (
|
|
17762
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17624
17763
|
add(emitter, "containsFn", funcKey, nodeId(emitter.filePath, child));
|
|
17625
17764
|
continue;
|
|
17626
17765
|
}
|
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
|
}>;
|
package/dist/index.d.ts
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
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/ast.ts
|
|
8
|
-
import { IdMap, IdSet } from "@suss/extractor";
|
|
8
|
+
import { IdMap, IdSet, SKIP_CHILDREN, walkDescendants } from "@suss/extractor";
|
|
9
9
|
function rangeOf(node) {
|
|
10
10
|
return {
|
|
11
11
|
start: node.startPosition.row + 1,
|
|
@@ -21,12 +21,37 @@ function field(node, name) {
|
|
|
21
21
|
function bodyStatements(body) {
|
|
22
22
|
return body.namedChildren.filter((child) => child !== null);
|
|
23
23
|
}
|
|
24
|
+
var OWN_BODY_TYPES = /* @__PURE__ */ new Set([
|
|
25
|
+
"method",
|
|
26
|
+
"singleton_method",
|
|
27
|
+
"lambda",
|
|
28
|
+
"class",
|
|
29
|
+
"module",
|
|
30
|
+
"singleton_class"
|
|
31
|
+
]);
|
|
32
|
+
var ARGUMENT_LIST_TYPE = "argument_list";
|
|
33
|
+
function runStatements(body, blockConfigures = () => false) {
|
|
34
|
+
const found = [];
|
|
35
|
+
const readsItsChildren = (node) => {
|
|
36
|
+
if (OWN_BODY_TYPES.has(node.type) || node.type === ARGUMENT_LIST_TYPE) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return !(node.type === "call" && blockConfigures(node));
|
|
40
|
+
};
|
|
41
|
+
walkDescendants(body, null, {
|
|
42
|
+
at: (node) => {
|
|
43
|
+
found.push(node);
|
|
44
|
+
},
|
|
45
|
+
into: (node) => readsItsChildren(node) ? null : SKIP_CHILDREN
|
|
46
|
+
});
|
|
47
|
+
return found;
|
|
48
|
+
}
|
|
24
49
|
function symbolValue(node) {
|
|
25
50
|
return node.type === "simple_symbol" ? node.text.slice(1) : null;
|
|
26
51
|
}
|
|
27
52
|
function instanceMethodsByName(body) {
|
|
28
53
|
const methods = /* @__PURE__ */ new Map();
|
|
29
|
-
for (const stmt of
|
|
54
|
+
for (const stmt of runStatements(body)) {
|
|
30
55
|
if (stmt.type !== "method") {
|
|
31
56
|
continue;
|
|
32
57
|
}
|
|
@@ -39,7 +64,7 @@ function instanceMethodsByName(body) {
|
|
|
39
64
|
}
|
|
40
65
|
function bareCallArgumentGroups(body, name) {
|
|
41
66
|
const groups = [];
|
|
42
|
-
for (const stmt of
|
|
67
|
+
for (const stmt of runStatements(body)) {
|
|
43
68
|
if (stmt.type !== "call" || field(stmt, "receiver") !== null) {
|
|
44
69
|
continue;
|
|
45
70
|
}
|
|
@@ -142,7 +167,7 @@ function walkClasses(root, visit) {
|
|
|
142
167
|
});
|
|
143
168
|
}
|
|
144
169
|
function walkDefinitions(root, visit) {
|
|
145
|
-
walkBody(
|
|
170
|
+
walkBody(runStatements(root), [], visit);
|
|
146
171
|
}
|
|
147
172
|
function walkBody(statements, nesting, visit) {
|
|
148
173
|
for (const stmt of statements) {
|
|
@@ -181,7 +206,7 @@ function visitClass(node, nesting, visit) {
|
|
|
181
206
|
bodyNesting: identity.bodyNesting
|
|
182
207
|
});
|
|
183
208
|
if (bodyNode !== null) {
|
|
184
|
-
walkBody(
|
|
209
|
+
walkBody(runStatements(bodyNode), identity.bodyNesting, visit);
|
|
185
210
|
}
|
|
186
211
|
}
|
|
187
212
|
function visitModule(node, nesting, visit) {
|
|
@@ -200,7 +225,7 @@ function visitModule(node, nesting, visit) {
|
|
|
200
225
|
bodyNesting: identity.bodyNesting
|
|
201
226
|
});
|
|
202
227
|
if (bodyNode !== null) {
|
|
203
|
-
walkBody(
|
|
228
|
+
walkBody(runStatements(bodyNode), identity.bodyNesting, visit);
|
|
204
229
|
}
|
|
205
230
|
}
|
|
206
231
|
function stripTypeSuffixName(qualifiedName) {
|
|
@@ -356,7 +381,7 @@ function definitionIn(blocks, name) {
|
|
|
356
381
|
}
|
|
357
382
|
return { method, dynamic };
|
|
358
383
|
}
|
|
359
|
-
function inheritedStatements(ancestry) {
|
|
384
|
+
function inheritedStatements(ancestry, blockConfigures) {
|
|
360
385
|
const statements = [];
|
|
361
386
|
for (const entry of [...ancestry].reverse()) {
|
|
362
387
|
if (entry.type !== "bodies") {
|
|
@@ -367,7 +392,7 @@ function inheritedStatements(ancestry) {
|
|
|
367
392
|
if (body === null) {
|
|
368
393
|
continue;
|
|
369
394
|
}
|
|
370
|
-
for (const statement of
|
|
395
|
+
for (const statement of runStatements(body, blockConfigures)) {
|
|
371
396
|
statements.push({ block, statement });
|
|
372
397
|
}
|
|
373
398
|
}
|
|
@@ -593,14 +618,6 @@ function lowerRubyBody(body, terminals) {
|
|
|
593
618
|
}
|
|
594
619
|
|
|
595
620
|
// src/paths/effects.ts
|
|
596
|
-
var DECLARATION_TYPES = /* @__PURE__ */ new Set([
|
|
597
|
-
"method",
|
|
598
|
-
"singleton_method",
|
|
599
|
-
"lambda",
|
|
600
|
-
"class",
|
|
601
|
-
"module",
|
|
602
|
-
"singleton_class"
|
|
603
|
-
]);
|
|
604
621
|
var RAISE_NAMES2 = /* @__PURE__ */ new Set(["raise", "fail"]);
|
|
605
622
|
var BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
606
623
|
"body_statement",
|
|
@@ -648,7 +665,7 @@ function isRaise2(node) {
|
|
|
648
665
|
}
|
|
649
666
|
function bodyCalls(node, found = []) {
|
|
650
667
|
for (const child of children(node)) {
|
|
651
|
-
if (
|
|
668
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
652
669
|
continue;
|
|
653
670
|
}
|
|
654
671
|
if (child.type === "call" && !isPropertyRead(child) && !isRaise2(child)) {
|
|
@@ -15251,7 +15268,7 @@ function date4(params) {
|
|
|
15251
15268
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
15252
15269
|
config(en_default());
|
|
15253
15270
|
|
|
15254
|
-
// ../../ir-core/dist/chunk-
|
|
15271
|
+
// ../../ir-core/dist/chunk-QHFMZPEG.js
|
|
15255
15272
|
function gqlIdentityKey(typeName, fieldName) {
|
|
15256
15273
|
return `gql:${typeName}.${fieldName}`;
|
|
15257
15274
|
}
|
|
@@ -15261,6 +15278,9 @@ function fnIdentityKey(packageName, exportPath) {
|
|
|
15261
15278
|
function busIdentityKey(messageBus, subject) {
|
|
15262
15279
|
return `bus:${messageBus} ${subject}`;
|
|
15263
15280
|
}
|
|
15281
|
+
function unitIdentityKey(deploymentTarget, instanceName) {
|
|
15282
|
+
return `unit:${deploymentTarget} ${instanceName}`;
|
|
15283
|
+
}
|
|
15264
15284
|
function metricIdentityKey(metricSystem, metricType) {
|
|
15265
15285
|
return `metric:${metricSystem} ${metricType}`;
|
|
15266
15286
|
}
|
|
@@ -15673,6 +15693,14 @@ var restSemantics = defineBoundarySemantics({
|
|
|
15673
15693
|
}
|
|
15674
15694
|
return routePathAdmits(semantics.path, path4) ? "match" : "nomatch";
|
|
15675
15695
|
},
|
|
15696
|
+
/**
|
|
15697
|
+
* A route the registration pattern admits is inside it. A route
|
|
15698
|
+
* whose path this source never gave is left outside, because
|
|
15699
|
+
* nothing here can show it is one the pattern covers.
|
|
15700
|
+
*/
|
|
15701
|
+
withinScope(semantics, scope) {
|
|
15702
|
+
return semantics.path !== null && routePathAdmits(scope, semantics.path);
|
|
15703
|
+
},
|
|
15676
15704
|
/**
|
|
15677
15705
|
* A call whose base URL the deployment fills in, resolved to the
|
|
15678
15706
|
* path it reaches.
|
|
@@ -15794,7 +15822,62 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
15794
15822
|
/** A query returns rows or items, not a status and a body. */
|
|
15795
15823
|
exchangesHttpResponses: false,
|
|
15796
15824
|
reportsUnpairedItself: false,
|
|
15797
|
-
identityKey: () => null
|
|
15825
|
+
identityKey: () => null,
|
|
15826
|
+
displayLabel: storageLabel
|
|
15827
|
+
}
|
|
15828
|
+
});
|
|
15829
|
+
function storageLabel(semantics) {
|
|
15830
|
+
return `${semantics.storageSystem}:${storageContainerLabel(semantics)}`;
|
|
15831
|
+
}
|
|
15832
|
+
function storageContainerLabel(semantics) {
|
|
15833
|
+
const container = semantics.container ?? "<unnamed container>";
|
|
15834
|
+
const addressed = semantics.accessPath === null ? container : `${container}#${semantics.accessPath}`;
|
|
15835
|
+
return semantics.scope === "default" ? addressed : `${semantics.scope}/${addressed}`;
|
|
15836
|
+
}
|
|
15837
|
+
var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
|
|
15838
|
+
name: external_exports.literal("unit-invocation"),
|
|
15839
|
+
instanceName: DeployableUnitSchema.shape.instanceName.nullable()
|
|
15840
|
+
});
|
|
15841
|
+
var unitInvocationSemantics = defineBoundarySemantics({
|
|
15842
|
+
name: "unit-invocation",
|
|
15843
|
+
schema: UnitInvocationSemanticsSchema,
|
|
15844
|
+
// faas.name is the deployed function's own name and instanceName is
|
|
15845
|
+
// the deployment template's logical id, which is a different string.
|
|
15846
|
+
// Runtime config leaves the pair off for the same reason.
|
|
15847
|
+
semconv: {},
|
|
15848
|
+
behavior: {
|
|
15849
|
+
/**
|
|
15850
|
+
* A synchronous invoke gives back whatever the handler returned,
|
|
15851
|
+
* which is a value rather than a status and a body. A handler's
|
|
15852
|
+
* return only becomes an HTTP response under a proxy integration,
|
|
15853
|
+
* and that route gets a REST binding instead of this one.
|
|
15854
|
+
*/
|
|
15855
|
+
exchangesHttpResponses: false,
|
|
15856
|
+
/**
|
|
15857
|
+
* A unit nothing in the run invokes is the ordinary case, since
|
|
15858
|
+
* most services are reached from a stack suss never read. So an
|
|
15859
|
+
* uninvoked unit stays in the generic unmatched list rather than
|
|
15860
|
+
* being reported as a problem here.
|
|
15861
|
+
*/
|
|
15862
|
+
reportsUnpairedItself: false,
|
|
15863
|
+
identityKey(semantics) {
|
|
15864
|
+
if (semantics.instanceName === null) {
|
|
15865
|
+
return null;
|
|
15866
|
+
}
|
|
15867
|
+
return unitIdentityKey(
|
|
15868
|
+
semantics.deploymentTarget,
|
|
15869
|
+
semantics.instanceName
|
|
15870
|
+
);
|
|
15871
|
+
},
|
|
15872
|
+
displayLabel(semantics) {
|
|
15873
|
+
if (semantics.instanceName === null) {
|
|
15874
|
+
return `unit:${semantics.deploymentTarget} (named at runtime)`;
|
|
15875
|
+
}
|
|
15876
|
+
return unitIdentityKey(
|
|
15877
|
+
semantics.deploymentTarget,
|
|
15878
|
+
semantics.instanceName
|
|
15879
|
+
);
|
|
15880
|
+
}
|
|
15798
15881
|
}
|
|
15799
15882
|
});
|
|
15800
15883
|
var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
@@ -15805,7 +15888,8 @@ var SemanticsSchema = external_exports.discriminatedUnion("name", [
|
|
|
15805
15888
|
runtimeConfigSemantics.schema,
|
|
15806
15889
|
storageSemantics.schema,
|
|
15807
15890
|
messageBusSemantics.schema,
|
|
15808
|
-
metricSemantics.schema
|
|
15891
|
+
metricSemantics.schema,
|
|
15892
|
+
unitInvocationSemantics.schema
|
|
15809
15893
|
]);
|
|
15810
15894
|
var DEFINITIONS = [
|
|
15811
15895
|
restSemantics,
|
|
@@ -15815,7 +15899,8 @@ var DEFINITIONS = [
|
|
|
15815
15899
|
runtimeConfigSemantics,
|
|
15816
15900
|
storageSemantics,
|
|
15817
15901
|
messageBusSemantics,
|
|
15818
|
-
metricSemantics
|
|
15902
|
+
metricSemantics,
|
|
15903
|
+
unitInvocationSemantics
|
|
15819
15904
|
];
|
|
15820
15905
|
var BY_NAME = new Map(
|
|
15821
15906
|
DEFINITIONS.map((d) => [d.name, d])
|
|
@@ -15905,6 +15990,13 @@ var TypeShapeSchema = external_exports.lazy(
|
|
|
15905
15990
|
);
|
|
15906
15991
|
|
|
15907
15992
|
// ../../ir-core/dist/index.js
|
|
15993
|
+
var RelationSchema = external_exports.enum([
|
|
15994
|
+
"provides",
|
|
15995
|
+
"reads",
|
|
15996
|
+
"writes",
|
|
15997
|
+
"invokes"
|
|
15998
|
+
]);
|
|
15999
|
+
var EffectRelationSchema = RelationSchema.exclude(["provides"]);
|
|
15908
16000
|
var SuppressionSideSchema = external_exports.object({
|
|
15909
16001
|
summary: external_exports.string().optional(),
|
|
15910
16002
|
transitionId: external_exports.string().optional()
|
|
@@ -16624,6 +16716,23 @@ var RESOLUTION_QUESTIONS = [
|
|
|
16624
16716
|
lit("callsInto", v("g"), v("m"), v("n"))
|
|
16625
16717
|
]
|
|
16626
16718
|
),
|
|
16719
|
+
// Subject identity, its own demand class; the README's subject
|
|
16720
|
+
// section says why the origin pair rides on the written-value walk.
|
|
16721
|
+
rule(
|
|
16722
|
+
"wantedSubjectWritten",
|
|
16723
|
+
[v("x"), v("r")],
|
|
16724
|
+
[lit("wantedSubject", v("x")), lit("isWrittenAs", v("x"), v("r"))]
|
|
16725
|
+
),
|
|
16726
|
+
rule(
|
|
16727
|
+
"wantedSubjectConstruction",
|
|
16728
|
+
[v("x"), v("r"), v("m"), v("n")],
|
|
16729
|
+
[
|
|
16730
|
+
lit("wantedSubject", v("x")),
|
|
16731
|
+
lit("isWrittenAs", v("x"), v("r")),
|
|
16732
|
+
lit("call", v("r"), v("c")),
|
|
16733
|
+
lit("comesFrom", v("c"), v("m"), v("n"))
|
|
16734
|
+
]
|
|
16735
|
+
),
|
|
16627
16736
|
// The export table of one module, keyed by the module asked about.
|
|
16628
16737
|
// The moduleExport rules flatten re-export chains of any length, and
|
|
16629
16738
|
// the demand cone stays on export facts alone.
|
|
@@ -16971,7 +17080,10 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
16971
17080
|
const knownClasses = ownBlocks[0]?.knownClasses ?? /* @__PURE__ */ new Set();
|
|
16972
17081
|
const scope = { nesting: info.bodyNesting, knownClasses };
|
|
16973
17082
|
const declsByName = /* @__PURE__ */ new Map();
|
|
16974
|
-
for (const stmt of
|
|
17083
|
+
for (const stmt of runStatements(
|
|
17084
|
+
info.bodyNode,
|
|
17085
|
+
blockConfiguresCall(pattern)
|
|
17086
|
+
)) {
|
|
16975
17087
|
const decl = await readFieldCall(stmt, scope, ctx, ancestry);
|
|
16976
17088
|
if (decl !== null) {
|
|
16977
17089
|
declsByName.set(decl.fieldName, decl);
|
|
@@ -16981,6 +17093,17 @@ async function graphqlObjectFieldUnits(pattern, pack, info, ownBlocks, fileBlock
|
|
|
16981
17093
|
(decl) => buildFieldUnit(pack, typeName, decl, options.filePath)
|
|
16982
17094
|
);
|
|
16983
17095
|
}
|
|
17096
|
+
function blockConfiguresCall(pattern) {
|
|
17097
|
+
const names = /* @__PURE__ */ new Set([
|
|
17098
|
+
pattern.fieldCallName,
|
|
17099
|
+
pattern.typeCallName,
|
|
17100
|
+
pattern.argumentCallName
|
|
17101
|
+
]);
|
|
17102
|
+
return (call) => {
|
|
17103
|
+
const method = field(call, "method")?.text;
|
|
17104
|
+
return field(call, "receiver") === null && method !== void 0 && names.has(method);
|
|
17105
|
+
};
|
|
17106
|
+
}
|
|
16984
17107
|
function branchesFor(body, range) {
|
|
16985
17108
|
if (body.effects === void 0 && body.extraEffects === void 0) {
|
|
16986
17109
|
return [];
|
|
@@ -17056,10 +17179,13 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17056
17179
|
}
|
|
17057
17180
|
const callArgs = readCallArgs(field(stmt, "arguments"));
|
|
17058
17181
|
const nameArg = callArgs.positional[0];
|
|
17059
|
-
|
|
17060
|
-
if (symbol2 === null) {
|
|
17182
|
+
if (nameArg === void 0) {
|
|
17061
17183
|
return null;
|
|
17062
17184
|
}
|
|
17185
|
+
const symbol2 = symbolValue(nameArg);
|
|
17186
|
+
if (symbol2 === null) {
|
|
17187
|
+
return computedNameDeclaration(stmt, nameArg);
|
|
17188
|
+
}
|
|
17063
17189
|
const read = await readFieldShape(
|
|
17064
17190
|
symbol2,
|
|
17065
17191
|
callArgs,
|
|
@@ -17070,11 +17196,29 @@ async function readFieldCall(stmt, scope, ctx, ancestry) {
|
|
|
17070
17196
|
);
|
|
17071
17197
|
return {
|
|
17072
17198
|
fieldName: resolvedName(symbol2, callArgs, ctx.pattern),
|
|
17199
|
+
namedOnTheWire: true,
|
|
17073
17200
|
node: stmt,
|
|
17074
17201
|
contract: read.contract,
|
|
17075
17202
|
body: read.body
|
|
17076
17203
|
};
|
|
17077
17204
|
}
|
|
17205
|
+
function computedNameDeclaration(stmt, nameArg) {
|
|
17206
|
+
const range = rangeOf(stmt);
|
|
17207
|
+
return {
|
|
17208
|
+
fieldName: nameArg.text,
|
|
17209
|
+
namedOnTheWire: false,
|
|
17210
|
+
node: stmt,
|
|
17211
|
+
contract: null,
|
|
17212
|
+
body: {
|
|
17213
|
+
readings: [
|
|
17214
|
+
unreadableReading(
|
|
17215
|
+
`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`,
|
|
17216
|
+
range
|
|
17217
|
+
)
|
|
17218
|
+
]
|
|
17219
|
+
}
|
|
17220
|
+
};
|
|
17221
|
+
}
|
|
17078
17222
|
function wiringReference(callArgs, wiringKeywords) {
|
|
17079
17223
|
for (const keyword of wiringKeywords) {
|
|
17080
17224
|
const ref = callArgs.keyword[keyword];
|
|
@@ -17199,7 +17343,10 @@ function readClassContract(ancestry, pattern) {
|
|
|
17199
17343
|
args: /* @__PURE__ */ new Map()
|
|
17200
17344
|
};
|
|
17201
17345
|
const handlers = classCallHandlers(pattern);
|
|
17202
|
-
for (const { block, statement } of inheritedStatements(
|
|
17346
|
+
for (const { block, statement } of inheritedStatements(
|
|
17347
|
+
ancestry,
|
|
17348
|
+
blockConfiguresCall(pattern)
|
|
17349
|
+
)) {
|
|
17203
17350
|
if (statement.type !== "call" || field(statement, "receiver") !== null) {
|
|
17204
17351
|
continue;
|
|
17205
17352
|
}
|
|
@@ -17290,12 +17437,12 @@ function buildFieldUnit(pack, typeName, decl, filePath) {
|
|
|
17290
17437
|
exportName: null,
|
|
17291
17438
|
exportPath: null
|
|
17292
17439
|
},
|
|
17293
|
-
boundaryBinding: graphqlResolverBinding({
|
|
17440
|
+
boundaryBinding: decl.namedOnTheWire ? graphqlResolverBinding({
|
|
17294
17441
|
transport: pack.protocol,
|
|
17295
17442
|
recognition: pack.name,
|
|
17296
17443
|
typeName,
|
|
17297
17444
|
fieldName: decl.fieldName
|
|
17298
|
-
}),
|
|
17445
|
+
}) : null,
|
|
17299
17446
|
parameters,
|
|
17300
17447
|
branches: branchesFor(decl.body, rangeOf(decl.node)),
|
|
17301
17448
|
...decl.body.bodyContent !== void 0 ? { bodyContent: decl.body.bodyContent } : {},
|
|
@@ -17366,14 +17513,6 @@ function nodeId(filePath, node) {
|
|
|
17366
17513
|
function nameId(filePath, name) {
|
|
17367
17514
|
return `${filePath}#${name}`;
|
|
17368
17515
|
}
|
|
17369
|
-
var DECLARATION_TYPES2 = /* @__PURE__ */ new Set([
|
|
17370
|
-
"method",
|
|
17371
|
-
"singleton_method",
|
|
17372
|
-
"lambda",
|
|
17373
|
-
"class",
|
|
17374
|
-
"module",
|
|
17375
|
-
"singleton_class"
|
|
17376
|
-
]);
|
|
17377
17516
|
var WRITTEN_VALUE_TYPES = /* @__PURE__ */ new Set([
|
|
17378
17517
|
"string",
|
|
17379
17518
|
"integer",
|
|
@@ -17511,7 +17650,7 @@ function emitHash(emitter, hash2) {
|
|
|
17511
17650
|
}
|
|
17512
17651
|
function walkExpressions(node, visit) {
|
|
17513
17652
|
for (const child of children3(node)) {
|
|
17514
|
-
if (
|
|
17653
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17515
17654
|
continue;
|
|
17516
17655
|
}
|
|
17517
17656
|
visit(child);
|
|
@@ -17569,7 +17708,7 @@ function emitMethodFacts(emitter, method) {
|
|
|
17569
17708
|
}
|
|
17570
17709
|
const recordNested = (node) => {
|
|
17571
17710
|
for (const child of children3(node)) {
|
|
17572
|
-
if (
|
|
17711
|
+
if (OWN_BODY_TYPES.has(child.type)) {
|
|
17573
17712
|
add(emitter, "containsFn", funcKey, nodeId(emitter.filePath, child));
|
|
17574
17713
|
continue;
|
|
17575
17714
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-ruby",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruby language adapter for suss, parsing source with tree-sitter (WASM), resolving constant nesting with a lexical binder, and emitting raw extractions for the suss pipeline.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/behavioral-ir": "0.
|
|
51
|
-
"@suss/datalog": "0.
|
|
52
|
-
"@suss/extractor": "0.
|
|
50
|
+
"@suss/behavioral-ir": "0.21.0",
|
|
51
|
+
"@suss/datalog": "0.21.0",
|
|
52
|
+
"@suss/extractor": "0.21.0",
|
|
53
53
|
"web-tree-sitter": "^0.26.11"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|