@suss/adapter-typescript 0.22.2 → 0.22.4
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 +587 -329
- package/dist/index.d.cts +65 -3
- package/dist/index.d.ts +65 -3
- package/dist/index.js +579 -325
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -3716,6 +3716,18 @@ var ResolutionStore = class {
|
|
|
3716
3716
|
const target = factKeyOf(value);
|
|
3717
3717
|
return this.askAbout(target, "wanted", () => this.lookupObject(target));
|
|
3718
3718
|
}
|
|
3719
|
+
/**
|
|
3720
|
+
* The function a call returns: `app.use(requireCaller(config))`
|
|
3721
|
+
* registers what the factory gives back. A separate question from
|
|
3722
|
+
* `resolveCallable`, which keeps a call unresolved on purpose so an
|
|
3723
|
+
* unwrapping answer wins; this one is asked only after that has
|
|
3724
|
+
* declined. Two returned functions give null, like every other
|
|
3725
|
+
* single-answer question here.
|
|
3726
|
+
*/
|
|
3727
|
+
resolveReturnedCallable(call) {
|
|
3728
|
+
const target = factKeyOf(call);
|
|
3729
|
+
return this.askAbout(target, "wanted", () => this.lookupReturned(target));
|
|
3730
|
+
}
|
|
3719
3731
|
/**
|
|
3720
3732
|
* For a value that is neither a function nor an object, such as a
|
|
3721
3733
|
* GraphQL document kept in a constant in another file.
|
|
@@ -4159,6 +4171,21 @@ var ResolutionStore = class {
|
|
|
4159
4171
|
}
|
|
4160
4172
|
return [...candidates][0];
|
|
4161
4173
|
}
|
|
4174
|
+
lookupReturned(call) {
|
|
4175
|
+
this.derive();
|
|
4176
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
4177
|
+
for (const target of this.answersFor("wantedGivesBack", nodeId(call))) {
|
|
4178
|
+
const node = this.table.byId.get(target);
|
|
4179
|
+
if (node === void 0 || !isFunctionRoot(node)) {
|
|
4180
|
+
continue;
|
|
4181
|
+
}
|
|
4182
|
+
candidates.add(node);
|
|
4183
|
+
}
|
|
4184
|
+
if (candidates.size !== 1) {
|
|
4185
|
+
return null;
|
|
4186
|
+
}
|
|
4187
|
+
return [...candidates][0];
|
|
4188
|
+
}
|
|
4162
4189
|
/**
|
|
4163
4190
|
* Two candidates give null, since ambiguity is nothing. The value
|
|
4164
4191
|
* itself is never a result either, or an identifier whose chain went
|
|
@@ -4647,6 +4674,26 @@ function resolveImportedLocalName(sourceFile, importModule, importName) {
|
|
|
4647
4674
|
}
|
|
4648
4675
|
return null;
|
|
4649
4676
|
}
|
|
4677
|
+
function importedReferenceSpellings(sourceFile, importModule, importName) {
|
|
4678
|
+
const spellings = [];
|
|
4679
|
+
const localName = resolveImportedLocalName(
|
|
4680
|
+
sourceFile,
|
|
4681
|
+
importModule,
|
|
4682
|
+
importName
|
|
4683
|
+
);
|
|
4684
|
+
if (localName !== null) {
|
|
4685
|
+
spellings.push(localName);
|
|
4686
|
+
}
|
|
4687
|
+
if (!sourceFile.getFullText().includes(`.${importName}`)) {
|
|
4688
|
+
return spellings;
|
|
4689
|
+
}
|
|
4690
|
+
for (const root of importedRootsOf(sourceFile, [importModule])) {
|
|
4691
|
+
if (root !== importName) {
|
|
4692
|
+
spellings.push(`${root}.${importName}`);
|
|
4693
|
+
}
|
|
4694
|
+
}
|
|
4695
|
+
return spellings;
|
|
4696
|
+
}
|
|
4650
4697
|
|
|
4651
4698
|
// src/discovery/resolveValue.ts
|
|
4652
4699
|
import { Node as Node17 } from "ts-morph";
|
|
@@ -5266,7 +5313,27 @@ function functionValueOf(value, resolution) {
|
|
|
5266
5313
|
return null;
|
|
5267
5314
|
}
|
|
5268
5315
|
const resolved = resolution.resolveCallable(written);
|
|
5269
|
-
|
|
5316
|
+
if (resolved !== null) {
|
|
5317
|
+
return toFunctionRoot(resolved);
|
|
5318
|
+
}
|
|
5319
|
+
if (!Node17.isCallExpression(written)) {
|
|
5320
|
+
return null;
|
|
5321
|
+
}
|
|
5322
|
+
const returned = resolution.resolveReturnedCallable(written);
|
|
5323
|
+
return returned === null ? null : toFunctionRoot(returned);
|
|
5324
|
+
}
|
|
5325
|
+
function propertyNameOf(property) {
|
|
5326
|
+
if (Node17.isPropertyAssignment(property) || Node17.isShorthandPropertyAssignment(property) || Node17.isMethodDeclaration(property)) {
|
|
5327
|
+
return property.getName();
|
|
5328
|
+
}
|
|
5329
|
+
return null;
|
|
5330
|
+
}
|
|
5331
|
+
function propertyFunctionOf(property, resolution) {
|
|
5332
|
+
if (Node17.isMethodDeclaration(property)) {
|
|
5333
|
+
return property;
|
|
5334
|
+
}
|
|
5335
|
+
const held = propertyValueOf(property);
|
|
5336
|
+
return held === null ? null : functionValueOf(held, resolution);
|
|
5270
5337
|
}
|
|
5271
5338
|
function objectLiteralOf(value, resolution) {
|
|
5272
5339
|
return literalValueOf(
|
|
@@ -8093,13 +8160,13 @@ function collectMethodsCalledOnCallResults(sourceFile) {
|
|
|
8093
8160
|
return called;
|
|
8094
8161
|
}
|
|
8095
8162
|
function registrationSubjectsOf(sourceFile, importModule, importName, resolution) {
|
|
8096
|
-
const
|
|
8163
|
+
const spellings = importedReferenceSpellings(
|
|
8097
8164
|
sourceFile,
|
|
8098
8165
|
importModule,
|
|
8099
8166
|
importName
|
|
8100
8167
|
);
|
|
8101
8168
|
const subjects = /* @__PURE__ */ new Map();
|
|
8102
|
-
if (
|
|
8169
|
+
if (spellings.length === 0) {
|
|
8103
8170
|
return subjects;
|
|
8104
8171
|
}
|
|
8105
8172
|
sourceFile.forEachDescendant((node) => {
|
|
@@ -8109,7 +8176,7 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
|
|
|
8109
8176
|
return;
|
|
8110
8177
|
}
|
|
8111
8178
|
const calleeText = Node32.isCallExpression(init) || Node32.isNewExpression(init) ? init.getExpression().getText() : null;
|
|
8112
|
-
if (calleeText
|
|
8179
|
+
if (calleeText !== null && spellings.includes(calleeText)) {
|
|
8113
8180
|
subjects.set(node.getName(), init);
|
|
8114
8181
|
}
|
|
8115
8182
|
return;
|
|
@@ -8122,7 +8189,9 @@ function registrationSubjectsOf(sourceFile, importModule, importName, resolution
|
|
|
8122
8189
|
return;
|
|
8123
8190
|
}
|
|
8124
8191
|
const typeText = typeNode.getText();
|
|
8125
|
-
if (
|
|
8192
|
+
if (spellings.some(
|
|
8193
|
+
(spelling) => typeText === spelling || typeText.startsWith(`${spelling}<`)
|
|
8194
|
+
)) {
|
|
8126
8195
|
subjects.set(node.getName(), creationSiteBehind(node, resolution));
|
|
8127
8196
|
}
|
|
8128
8197
|
});
|
|
@@ -8166,17 +8235,17 @@ function registrationSubjectIdsOf(sourceFile, matches, resolution) {
|
|
|
8166
8235
|
return ids;
|
|
8167
8236
|
}
|
|
8168
8237
|
function unboundConstructionsOf(sourceFile, importModule, importName) {
|
|
8169
|
-
const
|
|
8238
|
+
const spellings = importedReferenceSpellings(
|
|
8170
8239
|
sourceFile,
|
|
8171
8240
|
importModule,
|
|
8172
8241
|
importName
|
|
8173
8242
|
);
|
|
8174
|
-
if (
|
|
8243
|
+
if (spellings.length === 0) {
|
|
8175
8244
|
return [];
|
|
8176
8245
|
}
|
|
8177
8246
|
const constructions = [];
|
|
8178
8247
|
sourceFile.forEachDescendant((node) => {
|
|
8179
|
-
if ((Node32.isCallExpression(node) || Node32.isNewExpression(node)) && node.getExpression().getText()
|
|
8248
|
+
if ((Node32.isCallExpression(node) || Node32.isNewExpression(node)) && spellings.includes(node.getExpression().getText()) && !Node32.isVariableDeclaration(node.getParent())) {
|
|
8180
8249
|
constructions.push(node);
|
|
8181
8250
|
}
|
|
8182
8251
|
});
|
|
@@ -8738,7 +8807,7 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
|
|
|
8738
8807
|
}
|
|
8739
8808
|
const schemaSdl = extractTypeDefsSdl(config, store);
|
|
8740
8809
|
for (const typeProp of propertiesOf(resolversObj, store)) {
|
|
8741
|
-
const typeName =
|
|
8810
|
+
const typeName = propertyNameOf(typeProp);
|
|
8742
8811
|
if (typeName === null || excludeTypes.has(typeName)) {
|
|
8743
8812
|
continue;
|
|
8744
8813
|
}
|
|
@@ -8747,11 +8816,11 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
|
|
|
8747
8816
|
continue;
|
|
8748
8817
|
}
|
|
8749
8818
|
for (const fieldProp of propertiesOf(typeObj, store)) {
|
|
8750
|
-
const fieldName =
|
|
8819
|
+
const fieldName = propertyNameOf(fieldProp);
|
|
8751
8820
|
if (fieldName === null) {
|
|
8752
8821
|
continue;
|
|
8753
8822
|
}
|
|
8754
|
-
const fn =
|
|
8823
|
+
const fn = propertyFunctionOf(fieldProp, store);
|
|
8755
8824
|
if (fn === null) {
|
|
8756
8825
|
continue;
|
|
8757
8826
|
}
|
|
@@ -8815,22 +8884,6 @@ function writtenSdl(expr) {
|
|
|
8815
8884
|
}
|
|
8816
8885
|
return null;
|
|
8817
8886
|
}
|
|
8818
|
-
function resolverPropertyName(prop) {
|
|
8819
|
-
if (Node36.isPropertyAssignment(prop) || Node36.isMethodDeclaration(prop)) {
|
|
8820
|
-
return prop.getName();
|
|
8821
|
-
}
|
|
8822
|
-
if (Node36.isShorthandPropertyAssignment(prop)) {
|
|
8823
|
-
return prop.getName();
|
|
8824
|
-
}
|
|
8825
|
-
return null;
|
|
8826
|
-
}
|
|
8827
|
-
function resolverPropertyFunction(prop, resolution) {
|
|
8828
|
-
if (Node36.isMethodDeclaration(prop)) {
|
|
8829
|
-
return prop;
|
|
8830
|
-
}
|
|
8831
|
-
const held = propertyValueOf(prop);
|
|
8832
|
-
return held === null ? null : functionValueOf(held, resolution);
|
|
8833
|
-
}
|
|
8834
8887
|
|
|
8835
8888
|
// src/discovery/index.ts
|
|
8836
8889
|
function runPattern(sourceFile, pattern, resolution, mountPrefixes, expandedElsewhere) {
|
|
@@ -10213,202 +10266,15 @@ function tryMatchParameterCall(node, func, pattern, match) {
|
|
|
10213
10266
|
return { node, terminal };
|
|
10214
10267
|
}
|
|
10215
10268
|
|
|
10216
|
-
// src/terminals/
|
|
10217
|
-
import { Node as Node44 } from "ts-morph";
|
|
10218
|
-
function tryMatchJsxReturn(node, pattern) {
|
|
10219
|
-
let expr;
|
|
10220
|
-
let source;
|
|
10221
|
-
if (Node44.isReturnStatement(node)) {
|
|
10222
|
-
expr = node.getExpression();
|
|
10223
|
-
source = node;
|
|
10224
|
-
} else if (Node44.isArrowFunction(node)) {
|
|
10225
|
-
const body = node.getBody();
|
|
10226
|
-
if (body !== void 0 && !Node44.isBlock(body)) {
|
|
10227
|
-
expr = body;
|
|
10228
|
-
source = body;
|
|
10229
|
-
}
|
|
10230
|
-
}
|
|
10231
|
-
if (expr === void 0 || source === void 0) {
|
|
10232
|
-
return null;
|
|
10233
|
-
}
|
|
10234
|
-
const tree = jsxToRenderNode(expr);
|
|
10235
|
-
if (tree === null) {
|
|
10236
|
-
return null;
|
|
10237
|
-
}
|
|
10238
|
-
const component = tree.type === "element" ? tree.tag : "Fragment";
|
|
10239
|
-
const terminal = {
|
|
10240
|
-
kind: pattern.kind,
|
|
10241
|
-
statusCode: null,
|
|
10242
|
-
body: null,
|
|
10243
|
-
exceptionType: null,
|
|
10244
|
-
message: null,
|
|
10245
|
-
component,
|
|
10246
|
-
delegateTarget: null,
|
|
10247
|
-
emitEvent: null,
|
|
10248
|
-
renderTree: tree,
|
|
10249
|
-
location: {
|
|
10250
|
-
start: startLineOf(node),
|
|
10251
|
-
end: endLineOf(node)
|
|
10252
|
-
}
|
|
10253
|
-
};
|
|
10254
|
-
return { node, source, terminal };
|
|
10255
|
-
}
|
|
10256
|
-
function componentTargetOf(tagNode) {
|
|
10257
|
-
if (!Node44.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
|
|
10258
|
-
return null;
|
|
10259
|
-
}
|
|
10260
|
-
const target = functionTargetOf(tagNode);
|
|
10261
|
-
return target === null ? null : { file: target.file, name: target.name };
|
|
10262
|
-
}
|
|
10263
|
-
function jsxToRenderNode(node) {
|
|
10264
|
-
if (Node44.isJsxElement(node)) {
|
|
10265
|
-
const opening = node.getOpeningElement();
|
|
10266
|
-
const tag = opening.getTagNameNode().getText();
|
|
10267
|
-
const attrs = collectJsxAttributes(opening);
|
|
10268
|
-
const target = componentTargetOf(opening.getTagNameNode());
|
|
10269
|
-
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
10270
|
-
return {
|
|
10271
|
-
type: "element",
|
|
10272
|
-
tag,
|
|
10273
|
-
children,
|
|
10274
|
-
...attrs !== null ? { attrs } : {},
|
|
10275
|
-
...target !== null ? { target } : {}
|
|
10276
|
-
};
|
|
10277
|
-
}
|
|
10278
|
-
if (Node44.isJsxSelfClosingElement(node)) {
|
|
10279
|
-
const tag = node.getTagNameNode().getText();
|
|
10280
|
-
const attrs = collectJsxAttributes(node);
|
|
10281
|
-
const target = componentTargetOf(node.getTagNameNode());
|
|
10282
|
-
return {
|
|
10283
|
-
type: "element",
|
|
10284
|
-
tag,
|
|
10285
|
-
children: [],
|
|
10286
|
-
...attrs !== null ? { attrs } : {},
|
|
10287
|
-
...target !== null ? { target } : {}
|
|
10288
|
-
};
|
|
10289
|
-
}
|
|
10290
|
-
if (Node44.isJsxFragment(node)) {
|
|
10291
|
-
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
10292
|
-
return { type: "element", tag: "Fragment", children };
|
|
10293
|
-
}
|
|
10294
|
-
if (Node44.isParenthesizedExpression(node)) {
|
|
10295
|
-
return jsxToRenderNode(node.getExpression());
|
|
10296
|
-
}
|
|
10297
|
-
return null;
|
|
10298
|
-
}
|
|
10299
|
-
function collectJsxAttributes(opening) {
|
|
10300
|
-
const entries = {};
|
|
10301
|
-
for (const attr of opening.getAttributes()) {
|
|
10302
|
-
if (Node44.isJsxSpreadAttribute(attr)) {
|
|
10303
|
-
const exprText = attr.getExpression().getText();
|
|
10304
|
-
entries[`...${exprText}`] = exprText;
|
|
10305
|
-
continue;
|
|
10306
|
-
}
|
|
10307
|
-
if (!Node44.isJsxAttribute(attr)) {
|
|
10308
|
-
continue;
|
|
10309
|
-
}
|
|
10310
|
-
const name = attr.getNameNode().getText();
|
|
10311
|
-
const initializer = attr.getInitializer();
|
|
10312
|
-
if (initializer === void 0) {
|
|
10313
|
-
entries[name] = "";
|
|
10314
|
-
continue;
|
|
10315
|
-
}
|
|
10316
|
-
if (Node44.isJsxExpression(initializer)) {
|
|
10317
|
-
const inner = initializer.getExpression();
|
|
10318
|
-
entries[name] = inner !== void 0 ? inner.getText() : "";
|
|
10319
|
-
continue;
|
|
10320
|
-
}
|
|
10321
|
-
entries[name] = initializer.getText();
|
|
10322
|
-
}
|
|
10323
|
-
return Object.keys(entries).length > 0 ? entries : null;
|
|
10324
|
-
}
|
|
10325
|
-
function jsxChildToRenderNode(child) {
|
|
10326
|
-
if (Node44.isJsxText(child)) {
|
|
10327
|
-
const text = child.getLiteralText().trim();
|
|
10328
|
-
if (text.length === 0) {
|
|
10329
|
-
return null;
|
|
10330
|
-
}
|
|
10331
|
-
return { type: "text", value: text };
|
|
10332
|
-
}
|
|
10333
|
-
if (Node44.isJsxExpression(child)) {
|
|
10334
|
-
const inner = child.getExpression();
|
|
10335
|
-
if (inner === void 0) {
|
|
10336
|
-
return null;
|
|
10337
|
-
}
|
|
10338
|
-
return jsxExpressionToRenderNode(inner);
|
|
10339
|
-
}
|
|
10340
|
-
if (Node44.isJsxElement(child) || Node44.isJsxSelfClosingElement(child) || Node44.isJsxFragment(child)) {
|
|
10341
|
-
return jsxToRenderNode(child);
|
|
10342
|
-
}
|
|
10343
|
-
return null;
|
|
10344
|
-
}
|
|
10345
|
-
function jsxExpressionToRenderNode(expr) {
|
|
10346
|
-
if (Node44.isParenthesizedExpression(expr)) {
|
|
10347
|
-
return jsxExpressionToRenderNode(expr.getExpression());
|
|
10348
|
-
}
|
|
10349
|
-
if (Node44.isBinaryExpression(expr)) {
|
|
10350
|
-
const op = expr.getOperatorToken().getText();
|
|
10351
|
-
if (op === "&&") {
|
|
10352
|
-
const right = renderAlternative(peelParens(expr.getRight()));
|
|
10353
|
-
if (right.kind === "jsx") {
|
|
10354
|
-
return {
|
|
10355
|
-
type: "conditional",
|
|
10356
|
-
condition: expr.getLeft().getText(),
|
|
10357
|
-
whenTrue: right.node,
|
|
10358
|
-
whenFalse: null
|
|
10359
|
-
};
|
|
10360
|
-
}
|
|
10361
|
-
}
|
|
10362
|
-
}
|
|
10363
|
-
if (Node44.isConditionalExpression(expr)) {
|
|
10364
|
-
const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
|
|
10365
|
-
const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
|
|
10366
|
-
if (truthy.kind === "jsx") {
|
|
10367
|
-
return {
|
|
10368
|
-
type: "conditional",
|
|
10369
|
-
condition: expr.getCondition().getText(),
|
|
10370
|
-
whenTrue: truthy.node,
|
|
10371
|
-
whenFalse: falsy.kind === "jsx" ? falsy.node : null
|
|
10372
|
-
};
|
|
10373
|
-
}
|
|
10374
|
-
if (falsy.kind === "jsx") {
|
|
10375
|
-
return {
|
|
10376
|
-
type: "conditional",
|
|
10377
|
-
condition: `!(${expr.getCondition().getText()})`,
|
|
10378
|
-
whenTrue: falsy.node,
|
|
10379
|
-
whenFalse: null
|
|
10380
|
-
};
|
|
10381
|
-
}
|
|
10382
|
-
}
|
|
10383
|
-
return { type: "expression", sourceText: expr.getText() };
|
|
10384
|
-
}
|
|
10385
|
-
function renderAlternative(node) {
|
|
10386
|
-
if (Node44.isNullLiteral(node)) {
|
|
10387
|
-
return { kind: "noRender" };
|
|
10388
|
-
}
|
|
10389
|
-
if (Node44.isFalseLiteral(node)) {
|
|
10390
|
-
return { kind: "noRender" };
|
|
10391
|
-
}
|
|
10392
|
-
if (Node44.isIdentifier(node) && node.getText() === "undefined") {
|
|
10393
|
-
return { kind: "noRender" };
|
|
10394
|
-
}
|
|
10395
|
-
if (Node44.isJsxElement(node) || Node44.isJsxSelfClosingElement(node) || Node44.isJsxFragment(node)) {
|
|
10396
|
-
const tree = jsxToRenderNode(node);
|
|
10397
|
-
if (tree !== null) {
|
|
10398
|
-
return { kind: "jsx", node: tree };
|
|
10399
|
-
}
|
|
10400
|
-
}
|
|
10401
|
-
return { kind: "notStatic" };
|
|
10402
|
-
}
|
|
10403
|
-
|
|
10404
|
-
// src/terminals/returns.ts
|
|
10269
|
+
// src/terminals/extract.ts
|
|
10405
10270
|
import {
|
|
10406
|
-
Node as
|
|
10271
|
+
Node as Node45
|
|
10407
10272
|
} from "ts-morph";
|
|
10273
|
+
import { constantOf } from "@suss/values";
|
|
10408
10274
|
|
|
10409
10275
|
// src/shapes/shapes.ts
|
|
10410
10276
|
import {
|
|
10411
|
-
Node as
|
|
10277
|
+
Node as Node44,
|
|
10412
10278
|
SyntaxKind as SyntaxKind10
|
|
10413
10279
|
} from "ts-morph";
|
|
10414
10280
|
|
|
@@ -10869,35 +10735,35 @@ function extractShapeWithArguments(node, substitutions) {
|
|
|
10869
10735
|
}
|
|
10870
10736
|
function extractShapeInner(node) {
|
|
10871
10737
|
const unwrapped2 = peelSyntax(node);
|
|
10872
|
-
if (boundArguments !== null &&
|
|
10738
|
+
if (boundArguments !== null && Node44.isIdentifier(unwrapped2)) {
|
|
10873
10739
|
const argument = boundArguments.get(unwrapped2.getText());
|
|
10874
10740
|
if (argument !== void 0 && argument !== unwrapped2) {
|
|
10875
10741
|
return extractShape(argument);
|
|
10876
10742
|
}
|
|
10877
10743
|
}
|
|
10878
|
-
if (
|
|
10744
|
+
if (Node44.isObjectLiteralExpression(unwrapped2)) {
|
|
10879
10745
|
return shapeFromObjectLiteral(unwrapped2);
|
|
10880
10746
|
}
|
|
10881
|
-
if (
|
|
10747
|
+
if (Node44.isArrayLiteralExpression(unwrapped2)) {
|
|
10882
10748
|
return shapeFromArrayLiteral(unwrapped2);
|
|
10883
10749
|
}
|
|
10884
|
-
if (
|
|
10750
|
+
if (Node44.isStringLiteral(unwrapped2) || Node44.isNoSubstitutionTemplateLiteral(unwrapped2)) {
|
|
10885
10751
|
return { type: "literal", value: unwrapped2.getLiteralValue() };
|
|
10886
10752
|
}
|
|
10887
|
-
if (
|
|
10753
|
+
if (Node44.isTemplateExpression(unwrapped2)) {
|
|
10888
10754
|
return { type: "text" };
|
|
10889
10755
|
}
|
|
10890
|
-
if (
|
|
10756
|
+
if (Node44.isNumericLiteral(unwrapped2)) {
|
|
10891
10757
|
return numericLiteralShape(
|
|
10892
10758
|
unwrapped2.getLiteralValue(),
|
|
10893
10759
|
unwrapped2.getText()
|
|
10894
10760
|
);
|
|
10895
10761
|
}
|
|
10896
|
-
if (
|
|
10762
|
+
if (Node44.isPrefixUnaryExpression(unwrapped2)) {
|
|
10897
10763
|
const op = unwrapped2.getOperatorToken();
|
|
10898
10764
|
if (op === SyntaxKind10.MinusToken || op === SyntaxKind10.PlusToken) {
|
|
10899
10765
|
const inner = unwrapped2.getOperand();
|
|
10900
|
-
if (
|
|
10766
|
+
if (Node44.isNumericLiteral(inner)) {
|
|
10901
10767
|
const v3 = inner.getLiteralValue();
|
|
10902
10768
|
const signed = op === SyntaxKind10.MinusToken ? -v3 : v3;
|
|
10903
10769
|
const rawBody = inner.getText();
|
|
@@ -10906,7 +10772,7 @@ function extractShapeInner(node) {
|
|
|
10906
10772
|
}
|
|
10907
10773
|
}
|
|
10908
10774
|
}
|
|
10909
|
-
if (
|
|
10775
|
+
if (Node44.isBigIntLiteral(unwrapped2)) {
|
|
10910
10776
|
return { type: "ref", name: "bigint" };
|
|
10911
10777
|
}
|
|
10912
10778
|
const kind = unwrapped2.getKind();
|
|
@@ -10919,10 +10785,10 @@ function extractShapeInner(node) {
|
|
|
10919
10785
|
if (kind === SyntaxKind10.NullKeyword) {
|
|
10920
10786
|
return { type: "null" };
|
|
10921
10787
|
}
|
|
10922
|
-
if (
|
|
10788
|
+
if (Node44.isIdentifier(unwrapped2) && unwrapped2.getText() === "undefined") {
|
|
10923
10789
|
return { type: "undefined" };
|
|
10924
10790
|
}
|
|
10925
|
-
if (
|
|
10791
|
+
if (Node44.isConditionalExpression(unwrapped2)) {
|
|
10926
10792
|
const whenTrue = extractShape(unwrapped2.getWhenTrue());
|
|
10927
10793
|
const whenFalse = extractShape(unwrapped2.getWhenFalse());
|
|
10928
10794
|
const variants = [];
|
|
@@ -10953,7 +10819,7 @@ function shapeFromArrayLiteral(arr) {
|
|
|
10953
10819
|
}
|
|
10954
10820
|
const shapes = [];
|
|
10955
10821
|
for (const el of elements) {
|
|
10956
|
-
if (
|
|
10822
|
+
if (Node44.isSpreadElement(el)) {
|
|
10957
10823
|
const inner = el.getExpression();
|
|
10958
10824
|
const innerShape = extractShape(inner);
|
|
10959
10825
|
if (innerShape?.type === "array") {
|
|
@@ -10972,7 +10838,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10972
10838
|
const properties = {};
|
|
10973
10839
|
const unresolvedSpreads = [];
|
|
10974
10840
|
for (const prop of obj.getProperties()) {
|
|
10975
|
-
if (
|
|
10841
|
+
if (Node44.isPropertyAssignment(prop)) {
|
|
10976
10842
|
const name = propertyName2(prop);
|
|
10977
10843
|
if (name === null) {
|
|
10978
10844
|
continue;
|
|
@@ -10988,7 +10854,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10988
10854
|
};
|
|
10989
10855
|
continue;
|
|
10990
10856
|
}
|
|
10991
|
-
if (
|
|
10857
|
+
if (Node44.isShorthandPropertyAssignment(prop)) {
|
|
10992
10858
|
const name = prop.getName();
|
|
10993
10859
|
const valueExpr = prop.getNameNode();
|
|
10994
10860
|
properties[name] = extractShape(valueExpr) ?? {
|
|
@@ -10997,7 +10863,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
10997
10863
|
};
|
|
10998
10864
|
continue;
|
|
10999
10865
|
}
|
|
11000
|
-
if (
|
|
10866
|
+
if (Node44.isSpreadAssignment(prop)) {
|
|
11001
10867
|
const expr = prop.getExpression();
|
|
11002
10868
|
const spreadShape = extractShape(expr);
|
|
11003
10869
|
if (spreadShape?.type === "record") {
|
|
@@ -11016,7 +10882,7 @@ function shapeFromObjectLiteral(obj) {
|
|
|
11016
10882
|
}
|
|
11017
10883
|
function propertyName2(prop) {
|
|
11018
10884
|
const nameNode = prop.getNameNode();
|
|
11019
|
-
if (
|
|
10885
|
+
if (Node44.isIdentifier(nameNode) || Node44.isStringLiteral(nameNode) || Node44.isNoSubstitutionTemplateLiteral(nameNode) || Node44.isNumericLiteral(nameNode)) {
|
|
11020
10886
|
return nameNode.getText().replace(/^["']|["']$/g, "");
|
|
11021
10887
|
}
|
|
11022
10888
|
return null;
|
|
@@ -11042,24 +10908,20 @@ function collapseVariants2(shapes) {
|
|
|
11042
10908
|
}
|
|
11043
10909
|
|
|
11044
10910
|
// src/terminals/extract.ts
|
|
11045
|
-
import {
|
|
11046
|
-
Node as Node46
|
|
11047
|
-
} from "ts-morph";
|
|
11048
|
-
import { constantOf } from "@suss/values";
|
|
11049
10911
|
function unwrapAs(node) {
|
|
11050
10912
|
return peelSyntax(node);
|
|
11051
10913
|
}
|
|
11052
10914
|
function unwrapJsonStringify(node) {
|
|
11053
10915
|
const outer = unwrapAs(node);
|
|
11054
|
-
if (!
|
|
10916
|
+
if (!Node45.isCallExpression(outer)) {
|
|
11055
10917
|
return node;
|
|
11056
10918
|
}
|
|
11057
10919
|
const callee = outer.getExpression();
|
|
11058
|
-
if (!
|
|
10920
|
+
if (!Node45.isPropertyAccessExpression(callee) || callee.getName() !== "stringify") {
|
|
11059
10921
|
return node;
|
|
11060
10922
|
}
|
|
11061
10923
|
const receiver = callee.getExpression();
|
|
11062
|
-
if (!
|
|
10924
|
+
if (!Node45.isIdentifier(receiver) || receiver.getText() !== "JSON") {
|
|
11063
10925
|
return node;
|
|
11064
10926
|
}
|
|
11065
10927
|
const args = outer.getArguments();
|
|
@@ -11069,7 +10931,7 @@ function unwrapJsonStringify(node) {
|
|
|
11069
10931
|
return unwrapAs(args[0]);
|
|
11070
10932
|
}
|
|
11071
10933
|
function substituted(value, ctx) {
|
|
11072
|
-
if (ctx.substitutions === void 0 || !
|
|
10934
|
+
if (ctx.substitutions === void 0 || !Node45.isIdentifier(value)) {
|
|
11073
10935
|
return value;
|
|
11074
10936
|
}
|
|
11075
10937
|
return ctx.substitutions.get(value.getText()) ?? value;
|
|
@@ -11082,10 +10944,10 @@ function extractStatusCode(ctx) {
|
|
|
11082
10944
|
if (result !== null) {
|
|
11083
10945
|
return result;
|
|
11084
10946
|
}
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
return null;
|
|
10947
|
+
return declaredStatusCode(ctx.extraction);
|
|
10948
|
+
}
|
|
10949
|
+
function declaredStatusCode(extraction) {
|
|
10950
|
+
return extraction.defaultStatusCode !== void 0 ? { type: "literal", value: extraction.defaultStatusCode } : null;
|
|
11089
10951
|
}
|
|
11090
10952
|
function matchConstructorCode(ctorText, codes) {
|
|
11091
10953
|
const fullMatch = codes[ctorText];
|
|
@@ -11113,10 +10975,10 @@ function statusFromProperty(obj, name, ctx) {
|
|
|
11113
10975
|
if (prop === void 0) {
|
|
11114
10976
|
return null;
|
|
11115
10977
|
}
|
|
11116
|
-
if (
|
|
10978
|
+
if (Node45.isShorthandPropertyAssignment(prop)) {
|
|
11117
10979
|
return { type: "dynamic", sourceText: prop.getName() };
|
|
11118
10980
|
}
|
|
11119
|
-
if (!
|
|
10981
|
+
if (!Node45.isPropertyAssignment(prop)) {
|
|
11120
10982
|
return null;
|
|
11121
10983
|
}
|
|
11122
10984
|
const value = prop.getInitializer();
|
|
@@ -11139,7 +11001,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11139
11001
|
return null;
|
|
11140
11002
|
}
|
|
11141
11003
|
const first = ctx.throwCallArgs?.[0];
|
|
11142
|
-
if (first !== void 0 &&
|
|
11004
|
+
if (first !== void 0 && Node45.isNumericLiteral(first)) {
|
|
11143
11005
|
const value = first.getLiteralValue();
|
|
11144
11006
|
if (value >= 100 && value <= 599) {
|
|
11145
11007
|
return { type: "literal", value };
|
|
@@ -11152,7 +11014,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11152
11014
|
return null;
|
|
11153
11015
|
}
|
|
11154
11016
|
const arg = ctx.throwCallArgs[sc.position];
|
|
11155
|
-
if (arg === void 0 || !
|
|
11017
|
+
if (arg === void 0 || !Node45.isNewExpression(arg)) {
|
|
11156
11018
|
return null;
|
|
11157
11019
|
}
|
|
11158
11020
|
const ctorText = arg.getExpression().getText();
|
|
@@ -11161,7 +11023,7 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11161
11023
|
if (sc.from === "argumentProperty") {
|
|
11162
11024
|
const args = ctx.throwCallArgs ?? ctx.calls?.[0]?.getArguments();
|
|
11163
11025
|
const arg = args?.[sc.position];
|
|
11164
|
-
if (arg === void 0 || !
|
|
11026
|
+
if (arg === void 0 || !Node45.isObjectLiteralExpression(arg)) {
|
|
11165
11027
|
return null;
|
|
11166
11028
|
}
|
|
11167
11029
|
return statusFromProperty(arg, sc.name, ctx);
|
|
@@ -11171,8 +11033,8 @@ function extractStatusCodeFromRule(ctx) {
|
|
|
11171
11033
|
return null;
|
|
11172
11034
|
}
|
|
11173
11035
|
for (const prop of ctx.returnedObj.getProperties()) {
|
|
11174
|
-
if (!
|
|
11175
|
-
if (
|
|
11036
|
+
if (!Node45.isPropertyAssignment(prop)) {
|
|
11037
|
+
if (Node45.isShorthandPropertyAssignment(prop)) {
|
|
11176
11038
|
if (prop.getName() === sc.name) {
|
|
11177
11039
|
const resolved = ctx.substitutions?.get(prop.getName());
|
|
11178
11040
|
if (resolved !== void 0) {
|
|
@@ -11230,8 +11092,8 @@ function extractBody(ctx) {
|
|
|
11230
11092
|
return null;
|
|
11231
11093
|
}
|
|
11232
11094
|
for (const prop of ctx.returnedObj.getProperties()) {
|
|
11233
|
-
if (!
|
|
11234
|
-
if (
|
|
11095
|
+
if (!Node45.isPropertyAssignment(prop)) {
|
|
11096
|
+
if (Node45.isShorthandPropertyAssignment(prop)) {
|
|
11235
11097
|
if (prop.getName() === b.name) {
|
|
11236
11098
|
const resolved = ctx.substitutions?.get(prop.getName());
|
|
11237
11099
|
if (resolved !== void 0) {
|
|
@@ -11285,6 +11147,199 @@ function extractBody(ctx) {
|
|
|
11285
11147
|
return null;
|
|
11286
11148
|
}
|
|
11287
11149
|
|
|
11150
|
+
// src/terminals/jsx.ts
|
|
11151
|
+
import { Node as Node46 } from "ts-morph";
|
|
11152
|
+
function tryMatchJsxReturn(node, pattern) {
|
|
11153
|
+
let expr;
|
|
11154
|
+
let source;
|
|
11155
|
+
if (Node46.isReturnStatement(node)) {
|
|
11156
|
+
expr = node.getExpression();
|
|
11157
|
+
source = node;
|
|
11158
|
+
} else if (Node46.isArrowFunction(node)) {
|
|
11159
|
+
const body = node.getBody();
|
|
11160
|
+
if (body !== void 0 && !Node46.isBlock(body)) {
|
|
11161
|
+
expr = body;
|
|
11162
|
+
source = body;
|
|
11163
|
+
}
|
|
11164
|
+
}
|
|
11165
|
+
if (expr === void 0 || source === void 0) {
|
|
11166
|
+
return null;
|
|
11167
|
+
}
|
|
11168
|
+
const tree = jsxToRenderNode(expr);
|
|
11169
|
+
if (tree === null) {
|
|
11170
|
+
return null;
|
|
11171
|
+
}
|
|
11172
|
+
const component = tree.type === "element" ? tree.tag : "Fragment";
|
|
11173
|
+
const terminal = {
|
|
11174
|
+
kind: pattern.kind,
|
|
11175
|
+
statusCode: null,
|
|
11176
|
+
body: null,
|
|
11177
|
+
exceptionType: null,
|
|
11178
|
+
message: null,
|
|
11179
|
+
component,
|
|
11180
|
+
delegateTarget: null,
|
|
11181
|
+
emitEvent: null,
|
|
11182
|
+
renderTree: tree,
|
|
11183
|
+
location: {
|
|
11184
|
+
start: startLineOf(node),
|
|
11185
|
+
end: endLineOf(node)
|
|
11186
|
+
}
|
|
11187
|
+
};
|
|
11188
|
+
return { node, source, terminal };
|
|
11189
|
+
}
|
|
11190
|
+
function componentTargetOf(tagNode) {
|
|
11191
|
+
if (!Node46.isIdentifier(tagNode) || !/^[A-Z]/.test(tagNode.getText())) {
|
|
11192
|
+
return null;
|
|
11193
|
+
}
|
|
11194
|
+
const target = functionTargetOf(tagNode);
|
|
11195
|
+
return target === null ? null : { file: target.file, name: target.name };
|
|
11196
|
+
}
|
|
11197
|
+
function jsxToRenderNode(node) {
|
|
11198
|
+
if (Node46.isJsxElement(node)) {
|
|
11199
|
+
const opening = node.getOpeningElement();
|
|
11200
|
+
const tag = opening.getTagNameNode().getText();
|
|
11201
|
+
const attrs = collectJsxAttributes(opening);
|
|
11202
|
+
const target = componentTargetOf(opening.getTagNameNode());
|
|
11203
|
+
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
11204
|
+
return {
|
|
11205
|
+
type: "element",
|
|
11206
|
+
tag,
|
|
11207
|
+
children,
|
|
11208
|
+
...attrs !== null ? { attrs } : {},
|
|
11209
|
+
...target !== null ? { target } : {}
|
|
11210
|
+
};
|
|
11211
|
+
}
|
|
11212
|
+
if (Node46.isJsxSelfClosingElement(node)) {
|
|
11213
|
+
const tag = node.getTagNameNode().getText();
|
|
11214
|
+
const attrs = collectJsxAttributes(node);
|
|
11215
|
+
const target = componentTargetOf(node.getTagNameNode());
|
|
11216
|
+
return {
|
|
11217
|
+
type: "element",
|
|
11218
|
+
tag,
|
|
11219
|
+
children: [],
|
|
11220
|
+
...attrs !== null ? { attrs } : {},
|
|
11221
|
+
...target !== null ? { target } : {}
|
|
11222
|
+
};
|
|
11223
|
+
}
|
|
11224
|
+
if (Node46.isJsxFragment(node)) {
|
|
11225
|
+
const children = node.getJsxChildren().map(jsxChildToRenderNode).filter((n) => n !== null);
|
|
11226
|
+
return { type: "element", tag: "Fragment", children };
|
|
11227
|
+
}
|
|
11228
|
+
if (Node46.isParenthesizedExpression(node)) {
|
|
11229
|
+
return jsxToRenderNode(node.getExpression());
|
|
11230
|
+
}
|
|
11231
|
+
return null;
|
|
11232
|
+
}
|
|
11233
|
+
function collectJsxAttributes(opening) {
|
|
11234
|
+
const entries = {};
|
|
11235
|
+
for (const attr of opening.getAttributes()) {
|
|
11236
|
+
if (Node46.isJsxSpreadAttribute(attr)) {
|
|
11237
|
+
const exprText = attr.getExpression().getText();
|
|
11238
|
+
entries[`...${exprText}`] = exprText;
|
|
11239
|
+
continue;
|
|
11240
|
+
}
|
|
11241
|
+
if (!Node46.isJsxAttribute(attr)) {
|
|
11242
|
+
continue;
|
|
11243
|
+
}
|
|
11244
|
+
const name = attr.getNameNode().getText();
|
|
11245
|
+
const initializer = attr.getInitializer();
|
|
11246
|
+
if (initializer === void 0) {
|
|
11247
|
+
entries[name] = "";
|
|
11248
|
+
continue;
|
|
11249
|
+
}
|
|
11250
|
+
if (Node46.isJsxExpression(initializer)) {
|
|
11251
|
+
const inner = initializer.getExpression();
|
|
11252
|
+
entries[name] = inner !== void 0 ? inner.getText() : "";
|
|
11253
|
+
continue;
|
|
11254
|
+
}
|
|
11255
|
+
entries[name] = initializer.getText();
|
|
11256
|
+
}
|
|
11257
|
+
return Object.keys(entries).length > 0 ? entries : null;
|
|
11258
|
+
}
|
|
11259
|
+
function jsxChildToRenderNode(child) {
|
|
11260
|
+
if (Node46.isJsxText(child)) {
|
|
11261
|
+
const text = child.getLiteralText().trim();
|
|
11262
|
+
if (text.length === 0) {
|
|
11263
|
+
return null;
|
|
11264
|
+
}
|
|
11265
|
+
return { type: "text", value: text };
|
|
11266
|
+
}
|
|
11267
|
+
if (Node46.isJsxExpression(child)) {
|
|
11268
|
+
const inner = child.getExpression();
|
|
11269
|
+
if (inner === void 0) {
|
|
11270
|
+
return null;
|
|
11271
|
+
}
|
|
11272
|
+
return jsxExpressionToRenderNode(inner);
|
|
11273
|
+
}
|
|
11274
|
+
if (Node46.isJsxElement(child) || Node46.isJsxSelfClosingElement(child) || Node46.isJsxFragment(child)) {
|
|
11275
|
+
return jsxToRenderNode(child);
|
|
11276
|
+
}
|
|
11277
|
+
return null;
|
|
11278
|
+
}
|
|
11279
|
+
function jsxExpressionToRenderNode(expr) {
|
|
11280
|
+
if (Node46.isParenthesizedExpression(expr)) {
|
|
11281
|
+
return jsxExpressionToRenderNode(expr.getExpression());
|
|
11282
|
+
}
|
|
11283
|
+
if (Node46.isBinaryExpression(expr)) {
|
|
11284
|
+
const op = expr.getOperatorToken().getText();
|
|
11285
|
+
if (op === "&&") {
|
|
11286
|
+
const right = renderAlternative(peelParens(expr.getRight()));
|
|
11287
|
+
if (right.kind === "jsx") {
|
|
11288
|
+
return {
|
|
11289
|
+
type: "conditional",
|
|
11290
|
+
condition: expr.getLeft().getText(),
|
|
11291
|
+
whenTrue: right.node,
|
|
11292
|
+
whenFalse: null
|
|
11293
|
+
};
|
|
11294
|
+
}
|
|
11295
|
+
}
|
|
11296
|
+
}
|
|
11297
|
+
if (Node46.isConditionalExpression(expr)) {
|
|
11298
|
+
const truthy = renderAlternative(peelParens(expr.getWhenTrue()));
|
|
11299
|
+
const falsy = renderAlternative(peelParens(expr.getWhenFalse()));
|
|
11300
|
+
if (truthy.kind === "jsx") {
|
|
11301
|
+
return {
|
|
11302
|
+
type: "conditional",
|
|
11303
|
+
condition: expr.getCondition().getText(),
|
|
11304
|
+
whenTrue: truthy.node,
|
|
11305
|
+
whenFalse: falsy.kind === "jsx" ? falsy.node : null
|
|
11306
|
+
};
|
|
11307
|
+
}
|
|
11308
|
+
if (falsy.kind === "jsx") {
|
|
11309
|
+
return {
|
|
11310
|
+
type: "conditional",
|
|
11311
|
+
condition: `!(${expr.getCondition().getText()})`,
|
|
11312
|
+
whenTrue: falsy.node,
|
|
11313
|
+
whenFalse: null
|
|
11314
|
+
};
|
|
11315
|
+
}
|
|
11316
|
+
}
|
|
11317
|
+
return { type: "expression", sourceText: expr.getText() };
|
|
11318
|
+
}
|
|
11319
|
+
function renderAlternative(node) {
|
|
11320
|
+
if (Node46.isNullLiteral(node)) {
|
|
11321
|
+
return { kind: "noRender" };
|
|
11322
|
+
}
|
|
11323
|
+
if (Node46.isFalseLiteral(node)) {
|
|
11324
|
+
return { kind: "noRender" };
|
|
11325
|
+
}
|
|
11326
|
+
if (Node46.isIdentifier(node) && node.getText() === "undefined") {
|
|
11327
|
+
return { kind: "noRender" };
|
|
11328
|
+
}
|
|
11329
|
+
if (Node46.isJsxElement(node) || Node46.isJsxSelfClosingElement(node) || Node46.isJsxFragment(node)) {
|
|
11330
|
+
const tree = jsxToRenderNode(node);
|
|
11331
|
+
if (tree !== null) {
|
|
11332
|
+
return { kind: "jsx", node: tree };
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
return { kind: "notStatic" };
|
|
11336
|
+
}
|
|
11337
|
+
|
|
11338
|
+
// src/terminals/returns.ts
|
|
11339
|
+
import {
|
|
11340
|
+
Node as Node49
|
|
11341
|
+
} from "ts-morph";
|
|
11342
|
+
|
|
11288
11343
|
// src/terminals/helperResolution.ts
|
|
11289
11344
|
import { Node as Node47, SyntaxKind as SyntaxKind11 } from "ts-morph";
|
|
11290
11345
|
function resolveHelperReturn(call, resolveCallee2) {
|
|
@@ -11856,10 +11911,9 @@ function tryMatchReturnStatement(node, pattern, func, allPatterns) {
|
|
|
11856
11911
|
return null;
|
|
11857
11912
|
}
|
|
11858
11913
|
function buildReturnTerminal(locationNode, pattern, body) {
|
|
11859
|
-
const statusCode = pattern.extraction.defaultStatusCode !== void 0 ? { type: "literal", value: pattern.extraction.defaultStatusCode } : null;
|
|
11860
11914
|
const terminal = {
|
|
11861
11915
|
kind: pattern.kind,
|
|
11862
|
-
statusCode,
|
|
11916
|
+
statusCode: declaredStatusCode(pattern.extraction),
|
|
11863
11917
|
body,
|
|
11864
11918
|
exceptionType: null,
|
|
11865
11919
|
message: null,
|
|
@@ -12148,15 +12202,15 @@ function functionMayFallThrough(func) {
|
|
|
12148
12202
|
}
|
|
12149
12203
|
return true;
|
|
12150
12204
|
}
|
|
12151
|
-
function makeFallthroughTerminal(func) {
|
|
12205
|
+
function makeFallthroughTerminal(func, pattern) {
|
|
12152
12206
|
const body = func.getBody();
|
|
12153
12207
|
const anchor = body ?? func;
|
|
12154
12208
|
const line = endLineOf(anchor);
|
|
12155
12209
|
return {
|
|
12156
12210
|
node: anchor,
|
|
12157
12211
|
terminal: {
|
|
12158
|
-
kind:
|
|
12159
|
-
statusCode:
|
|
12212
|
+
kind: pattern.kind,
|
|
12213
|
+
statusCode: declaredStatusCode(pattern.extraction),
|
|
12160
12214
|
body: null,
|
|
12161
12215
|
exceptionType: null,
|
|
12162
12216
|
message: null,
|
|
@@ -12242,7 +12296,7 @@ function countUnmatchedReturns(func, terminals, barriers = NO_BARRIERS) {
|
|
|
12242
12296
|
});
|
|
12243
12297
|
return unmatched;
|
|
12244
12298
|
}
|
|
12245
|
-
function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2) {
|
|
12299
|
+
function extractRawBranches(func, terminalPatterns, invocationRecognizers = [], accessRecognizers = [], barriers = NO_BARRIERS, resolution, originatesFrom, anchorCallsOf, resolveCallee2, collectCallAccounting = false) {
|
|
12246
12300
|
const terminals = findTerminals(
|
|
12247
12301
|
func,
|
|
12248
12302
|
terminalPatterns,
|
|
@@ -12276,15 +12330,15 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12276
12330
|
terminals.map(({ node }) => node),
|
|
12277
12331
|
barriers
|
|
12278
12332
|
);
|
|
12279
|
-
const
|
|
12333
|
+
const fallthroughPattern = terminalPatterns.find(
|
|
12280
12334
|
(p) => p.match.type === "functionFallthrough"
|
|
12281
12335
|
);
|
|
12282
|
-
if (
|
|
12336
|
+
if (fallthroughPattern !== void 0 && functionMayFallThrough(func)) {
|
|
12283
12337
|
const hasDefaultTerminal = terminals.some(
|
|
12284
12338
|
({ node }) => (byTerminal.get(node) ?? []).some(isDefaultConditionList)
|
|
12285
12339
|
);
|
|
12286
12340
|
if (!hasDefaultTerminal) {
|
|
12287
|
-
const synthetic = makeFallthroughTerminal(func);
|
|
12341
|
+
const synthetic = makeFallthroughTerminal(func, fallthroughPattern);
|
|
12288
12342
|
terminals.push(synthetic);
|
|
12289
12343
|
const pathResult = computePathConditions(
|
|
12290
12344
|
func,
|
|
@@ -12330,8 +12384,8 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12330
12384
|
seenBranches.add(key);
|
|
12331
12385
|
return true;
|
|
12332
12386
|
});
|
|
12387
|
+
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
12333
12388
|
if (invocations.length > 0) {
|
|
12334
|
-
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
12335
12389
|
const sideEffects = invocations.filter(
|
|
12336
12390
|
(i) => !writesTerminal(i.node, terminalNodes)
|
|
12337
12391
|
);
|
|
@@ -12347,7 +12401,39 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
12347
12401
|
branch.extraEffects = [...branch.extraEffects ?? [], ...extra];
|
|
12348
12402
|
}
|
|
12349
12403
|
}
|
|
12350
|
-
return {
|
|
12404
|
+
return {
|
|
12405
|
+
branches: distinctBranches,
|
|
12406
|
+
terminals,
|
|
12407
|
+
...collectCallAccounting ? {
|
|
12408
|
+
callAccounting: invocations.map(
|
|
12409
|
+
(site) => accountFor(site, terminalNodes, distinctBranches)
|
|
12410
|
+
)
|
|
12411
|
+
} : {}
|
|
12412
|
+
};
|
|
12413
|
+
}
|
|
12414
|
+
function accountFor(site, terminalNodes, branches) {
|
|
12415
|
+
const { node, line } = site;
|
|
12416
|
+
const callee = node.getExpression().getText();
|
|
12417
|
+
if (writesTerminal(node, terminalNodes)) {
|
|
12418
|
+
return { node, callee, line, outcome: "terminal" };
|
|
12419
|
+
}
|
|
12420
|
+
const call = {
|
|
12421
|
+
line,
|
|
12422
|
+
alwaysRuns: site.alwaysRuns,
|
|
12423
|
+
preconditions: preconditionsOf(site.effect)
|
|
12424
|
+
};
|
|
12425
|
+
if (branches.some((branch) => firesOn(call, branch))) {
|
|
12426
|
+
return { node, callee, line, outcome: "invocation" };
|
|
12427
|
+
}
|
|
12428
|
+
const reachable = branches.some(
|
|
12429
|
+
(branch) => site.alwaysRuns || runsBefore(line, branch.terminal.location.end)
|
|
12430
|
+
);
|
|
12431
|
+
return {
|
|
12432
|
+
node,
|
|
12433
|
+
callee,
|
|
12434
|
+
line,
|
|
12435
|
+
outcome: reachable ? "unrecorded" : "unreachable"
|
|
12436
|
+
};
|
|
12351
12437
|
}
|
|
12352
12438
|
|
|
12353
12439
|
// src/bootstrap/sourceFileLookup.ts
|
|
@@ -12562,7 +12648,7 @@ function unwrapContractInit(init) {
|
|
|
12562
12648
|
}
|
|
12563
12649
|
return null;
|
|
12564
12650
|
}
|
|
12565
|
-
function extractEndpointContract(endpointNode, pattern, framework) {
|
|
12651
|
+
function extractEndpointContract(endpointNode, pattern, framework, resolution) {
|
|
12566
12652
|
if (!Node54.isObjectLiteralExpression(endpointNode)) {
|
|
12567
12653
|
return null;
|
|
12568
12654
|
}
|
|
@@ -12587,9 +12673,10 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
12587
12673
|
}
|
|
12588
12674
|
}
|
|
12589
12675
|
if (propName === pattern.responseExtraction.property) {
|
|
12590
|
-
const
|
|
12591
|
-
|
|
12592
|
-
|
|
12676
|
+
const written = prop.getInitializer();
|
|
12677
|
+
const val = written === void 0 ? null : objectLiteralOf(written, resolution);
|
|
12678
|
+
if (val !== null) {
|
|
12679
|
+
for (const respProp of propertiesOf(val, resolution)) {
|
|
12593
12680
|
if (!Node54.isPropertyAssignment(respProp)) {
|
|
12594
12681
|
continue;
|
|
12595
12682
|
}
|
|
@@ -12628,7 +12715,12 @@ function readContract(unit, pattern, framework, resolution) {
|
|
|
12628
12715
|
if (endpointNode === null) {
|
|
12629
12716
|
return null;
|
|
12630
12717
|
}
|
|
12631
|
-
return extractEndpointContract(
|
|
12718
|
+
return extractEndpointContract(
|
|
12719
|
+
endpointNode,
|
|
12720
|
+
pattern,
|
|
12721
|
+
framework,
|
|
12722
|
+
resolution
|
|
12723
|
+
);
|
|
12632
12724
|
}
|
|
12633
12725
|
const routerInfo = findRouterCall(unit);
|
|
12634
12726
|
if (routerInfo === null) {
|
|
@@ -12649,7 +12741,12 @@ function readContract(unit, pattern, framework, resolution) {
|
|
|
12649
12741
|
if (endpointInit === void 0) {
|
|
12650
12742
|
continue;
|
|
12651
12743
|
}
|
|
12652
|
-
return extractEndpointContract(
|
|
12744
|
+
return extractEndpointContract(
|
|
12745
|
+
endpointInit,
|
|
12746
|
+
pattern,
|
|
12747
|
+
framework,
|
|
12748
|
+
resolution
|
|
12749
|
+
);
|
|
12653
12750
|
}
|
|
12654
12751
|
return null;
|
|
12655
12752
|
}
|
|
@@ -12726,7 +12823,12 @@ function readContractForClientCall(callExpression, methodName, pattern, framewor
|
|
|
12726
12823
|
if (endpointInit === void 0) {
|
|
12727
12824
|
continue;
|
|
12728
12825
|
}
|
|
12729
|
-
return extractEndpointContract(
|
|
12826
|
+
return extractEndpointContract(
|
|
12827
|
+
endpointInit,
|
|
12828
|
+
pattern,
|
|
12829
|
+
framework,
|
|
12830
|
+
resolution
|
|
12831
|
+
);
|
|
12730
12832
|
}
|
|
12731
12833
|
return null;
|
|
12732
12834
|
}
|
|
@@ -13486,7 +13588,11 @@ function recordEdge(edgesByChild, candidate) {
|
|
|
13486
13588
|
// src/discovery/wrapperIndex.ts
|
|
13487
13589
|
import { Node as Node58 } from "ts-morph";
|
|
13488
13590
|
import { joinMountedPath as joinMountedPath3 } from "@suss/resolution";
|
|
13489
|
-
var NO_WRAPPERS = {
|
|
13591
|
+
var NO_WRAPPERS = {
|
|
13592
|
+
wrappersFor: () => [],
|
|
13593
|
+
unfollowedFor: () => [],
|
|
13594
|
+
unitsIn: () => []
|
|
13595
|
+
};
|
|
13490
13596
|
var ANONYMOUS = "<anon>";
|
|
13491
13597
|
function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
13492
13598
|
const workByPack = /* @__PURE__ */ new Map();
|
|
@@ -13512,21 +13618,32 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
|
13512
13618
|
}
|
|
13513
13619
|
}
|
|
13514
13620
|
const bySubject = /* @__PURE__ */ new Map();
|
|
13621
|
+
const unfollowedBySubject = /* @__PURE__ */ new Map();
|
|
13515
13622
|
const unitsByFile = /* @__PURE__ */ new Map();
|
|
13623
|
+
const stopsSeen = /* @__PURE__ */ new Set();
|
|
13516
13624
|
let found = false;
|
|
13517
13625
|
for (const [packName, work] of workByPack) {
|
|
13518
13626
|
const candidates = [];
|
|
13519
13627
|
for (const { sourceFile, pattern, match, wraps } of work) {
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
|
|
13527
|
-
mountPrefixes
|
|
13528
|
-
)
|
|
13628
|
+
const scan = discoverWrapperRegistrations(
|
|
13629
|
+
sourceFile,
|
|
13630
|
+
pattern,
|
|
13631
|
+
match,
|
|
13632
|
+
wraps,
|
|
13633
|
+
resolution,
|
|
13634
|
+
mountPrefixes
|
|
13529
13635
|
);
|
|
13636
|
+
candidates.push(...scan.candidates);
|
|
13637
|
+
for (const { subjectId, callId, stop } of scan.unresolved) {
|
|
13638
|
+
if (stopsSeen.has(callId)) {
|
|
13639
|
+
continue;
|
|
13640
|
+
}
|
|
13641
|
+
stopsSeen.add(callId);
|
|
13642
|
+
found = true;
|
|
13643
|
+
const stops = unfollowedBySubject.get(subjectId) ?? [];
|
|
13644
|
+
stops.push(stop);
|
|
13645
|
+
unfollowedBySubject.set(subjectId, stops);
|
|
13646
|
+
}
|
|
13530
13647
|
}
|
|
13531
13648
|
for (const candidate of mostSpecific(candidates)) {
|
|
13532
13649
|
found = true;
|
|
@@ -13544,6 +13661,7 @@ function buildWrapperIndex(packsByFile, resolution, mountPrefixes) {
|
|
|
13544
13661
|
}
|
|
13545
13662
|
return {
|
|
13546
13663
|
wrappersFor: (subjectId) => bySubject.get(subjectId) ?? [],
|
|
13664
|
+
unfollowedFor: (subjectId) => unfollowedBySubject.get(subjectId) ?? [],
|
|
13547
13665
|
unitsIn: (file, pack) => unitsByFile.get(unitKey(file, pack)) ?? []
|
|
13548
13666
|
};
|
|
13549
13667
|
}
|
|
@@ -13577,10 +13695,20 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13577
13695
|
match.importName,
|
|
13578
13696
|
resolution
|
|
13579
13697
|
);
|
|
13698
|
+
if ("constructorOption" in wraps) {
|
|
13699
|
+
return discoverConstructorOptions(
|
|
13700
|
+
sourceFile,
|
|
13701
|
+
pattern,
|
|
13702
|
+
wraps,
|
|
13703
|
+
subjects,
|
|
13704
|
+
resolution
|
|
13705
|
+
);
|
|
13706
|
+
}
|
|
13580
13707
|
if (subjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution)) {
|
|
13581
|
-
return [];
|
|
13708
|
+
return { candidates: [], unresolved: [] };
|
|
13582
13709
|
}
|
|
13583
13710
|
const candidates = [];
|
|
13711
|
+
const unresolved = [];
|
|
13584
13712
|
sourceFile.forEachDescendant((node) => {
|
|
13585
13713
|
if (!Node58.isCallExpression(node)) {
|
|
13586
13714
|
return;
|
|
@@ -13603,8 +13731,13 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13603
13731
|
if (targetArg === void 0) {
|
|
13604
13732
|
return;
|
|
13605
13733
|
}
|
|
13734
|
+
const subjectId = nodeId(subjectNode);
|
|
13606
13735
|
const target = functionValueOf(targetArg, resolution);
|
|
13607
13736
|
if (target === null) {
|
|
13737
|
+
const stop = factoryStopOf(targetArg);
|
|
13738
|
+
if (stop !== null) {
|
|
13739
|
+
unresolved.push({ subjectId, callId: nodeId(node), stop });
|
|
13740
|
+
}
|
|
13608
13741
|
return;
|
|
13609
13742
|
}
|
|
13610
13743
|
if (wraps.arity !== void 0 && target.getParameters().length !== wraps.arity) {
|
|
@@ -13614,29 +13747,136 @@ function discoverWrapperRegistrations(sourceFile, pattern, match, wraps, resolut
|
|
|
13614
13747
|
if (scope === null) {
|
|
13615
13748
|
return;
|
|
13616
13749
|
}
|
|
13617
|
-
const subjectId = nodeId(subjectNode);
|
|
13618
13750
|
const mountedScope = scope === void 0 ? void 0 : mountedAt(subjectId, mountPrefixes, scope);
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
...wraps.throwParam === void 0 ? {} : { onThrow: true },
|
|
13635
|
-
...mountedScope === void 0 ? {} : { scope: mountedScope }
|
|
13636
|
-
}
|
|
13637
|
-
});
|
|
13751
|
+
candidates.push(
|
|
13752
|
+
candidateOf(
|
|
13753
|
+
{
|
|
13754
|
+
subjectId,
|
|
13755
|
+
callId: nodeId(node),
|
|
13756
|
+
target,
|
|
13757
|
+
label: labelFor(targetArg, wraps),
|
|
13758
|
+
byArity: wraps.arity !== void 0,
|
|
13759
|
+
onThrow: wraps.throwParam !== void 0,
|
|
13760
|
+
scope: mountedScope
|
|
13761
|
+
},
|
|
13762
|
+
pattern,
|
|
13763
|
+
sourceFile
|
|
13764
|
+
)
|
|
13765
|
+
);
|
|
13638
13766
|
});
|
|
13639
|
-
return candidates;
|
|
13767
|
+
return { candidates, unresolved };
|
|
13768
|
+
}
|
|
13769
|
+
function discoverConstructorOptions(sourceFile, pattern, wraps, subjects, resolution) {
|
|
13770
|
+
const candidates = [];
|
|
13771
|
+
const unresolved = [];
|
|
13772
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13773
|
+
for (const construction of subjects.values()) {
|
|
13774
|
+
const subjectId = nodeId(construction);
|
|
13775
|
+
if (seen.has(subjectId) || construction.getSourceFile() !== sourceFile) {
|
|
13776
|
+
continue;
|
|
13777
|
+
}
|
|
13778
|
+
seen.add(subjectId);
|
|
13779
|
+
const option = constructorOptionOf(construction, wraps, resolution);
|
|
13780
|
+
if (option === void 0) {
|
|
13781
|
+
continue;
|
|
13782
|
+
}
|
|
13783
|
+
const callId = nodeId(option);
|
|
13784
|
+
const written = propertyValueOf(option);
|
|
13785
|
+
const target = propertyFunctionOf(option, resolution);
|
|
13786
|
+
if (target === null) {
|
|
13787
|
+
const stop = written === null ? null : factoryStopOf(written);
|
|
13788
|
+
if (stop !== null) {
|
|
13789
|
+
unresolved.push({ subjectId, callId, stop });
|
|
13790
|
+
}
|
|
13791
|
+
continue;
|
|
13792
|
+
}
|
|
13793
|
+
candidates.push(
|
|
13794
|
+
candidateOf(
|
|
13795
|
+
{
|
|
13796
|
+
subjectId,
|
|
13797
|
+
callId,
|
|
13798
|
+
target,
|
|
13799
|
+
label: (written === null ? void 0 : factoryNameOf(written)) ?? wraps.constructorOption,
|
|
13800
|
+
byArity: false,
|
|
13801
|
+
onThrow: wraps.throwParam !== void 0,
|
|
13802
|
+
scope: void 0
|
|
13803
|
+
},
|
|
13804
|
+
pattern,
|
|
13805
|
+
sourceFile
|
|
13806
|
+
)
|
|
13807
|
+
);
|
|
13808
|
+
}
|
|
13809
|
+
return { candidates, unresolved };
|
|
13810
|
+
}
|
|
13811
|
+
function constructorOptionOf(construction, wraps, resolution) {
|
|
13812
|
+
if (!(Node58.isNewExpression(construction) || Node58.isCallExpression(construction))) {
|
|
13813
|
+
return void 0;
|
|
13814
|
+
}
|
|
13815
|
+
const optionsArg = construction.getArguments()[wraps.targetPosition];
|
|
13816
|
+
if (optionsArg === void 0) {
|
|
13817
|
+
return void 0;
|
|
13818
|
+
}
|
|
13819
|
+
const options = objectLiteralOf(optionsArg, resolution);
|
|
13820
|
+
if (options === null) {
|
|
13821
|
+
return void 0;
|
|
13822
|
+
}
|
|
13823
|
+
return propertiesOf(options, resolution).find(
|
|
13824
|
+
(property) => propertyNameOf(property) === wraps.constructorOption
|
|
13825
|
+
);
|
|
13826
|
+
}
|
|
13827
|
+
function candidateOf(registration, pattern, sourceFile) {
|
|
13828
|
+
const { target, label, onThrow, scope } = registration;
|
|
13829
|
+
const named2 = functionNameOrAnon(target) !== ANONYMOUS;
|
|
13830
|
+
return {
|
|
13831
|
+
subjectId: registration.subjectId,
|
|
13832
|
+
callId: registration.callId,
|
|
13833
|
+
targetId: nodeId(target),
|
|
13834
|
+
byArity: registration.byArity,
|
|
13835
|
+
target,
|
|
13836
|
+
pattern,
|
|
13837
|
+
registeredIn: sourceFile.getFilePath(),
|
|
13838
|
+
named: named2,
|
|
13839
|
+
reference: {
|
|
13840
|
+
file: target.getSourceFile().getFilePath(),
|
|
13841
|
+
name: named2 ? functionNameOrAnon(target) : label,
|
|
13842
|
+
...onThrow ? { onThrow: true } : {},
|
|
13843
|
+
...scope === void 0 ? {} : { scope }
|
|
13844
|
+
}
|
|
13845
|
+
};
|
|
13846
|
+
}
|
|
13847
|
+
function labelFor(targetArg, wraps) {
|
|
13848
|
+
return factoryNameOf(targetArg) ?? wraps.method;
|
|
13849
|
+
}
|
|
13850
|
+
function factoryNameOf(targetArg) {
|
|
13851
|
+
const written = factKeyOf(targetArg);
|
|
13852
|
+
if (!Node58.isCallExpression(written)) {
|
|
13853
|
+
return void 0;
|
|
13854
|
+
}
|
|
13855
|
+
const callee = written.getExpression();
|
|
13856
|
+
if (Node58.isIdentifier(callee)) {
|
|
13857
|
+
return callee.getText();
|
|
13858
|
+
}
|
|
13859
|
+
if (Node58.isPropertyAccessExpression(callee)) {
|
|
13860
|
+
return callee.getName();
|
|
13861
|
+
}
|
|
13862
|
+
return void 0;
|
|
13863
|
+
}
|
|
13864
|
+
function factoryStopOf(targetArg) {
|
|
13865
|
+
const written = factKeyOf(targetArg);
|
|
13866
|
+
if (!Node58.isCallExpression(written)) {
|
|
13867
|
+
return null;
|
|
13868
|
+
}
|
|
13869
|
+
const callee = factoryNameOf(targetArg);
|
|
13870
|
+
if (callee === void 0) {
|
|
13871
|
+
return null;
|
|
13872
|
+
}
|
|
13873
|
+
const reason = classifyStop(
|
|
13874
|
+
declarationsBehind(written.getExpression().getSymbol())
|
|
13875
|
+
);
|
|
13876
|
+
if (!worthRecording(reason)) {
|
|
13877
|
+
return null;
|
|
13878
|
+
}
|
|
13879
|
+
return { callee, reason: "unresolvedWrapper" };
|
|
13640
13880
|
}
|
|
13641
13881
|
function mountedAt(subjectId, mountPrefixes, scope) {
|
|
13642
13882
|
const prefix = mountPrefixes?.prefixForId?.(subjectId) ?? "";
|
|
@@ -14011,22 +14251,23 @@ import { Node as Node60 } from "ts-morph";
|
|
|
14011
14251
|
import { functionCallBinding, TargetPlacements } from "@suss/behavioral-ir";
|
|
14012
14252
|
import { Database as Database3, evaluate as evaluate4, lit as lit4, rule as rule4, variable as variable2 } from "@suss/datalog";
|
|
14013
14253
|
import { assembleSummary as assembleSummary2 } from "@suss/extractor";
|
|
14254
|
+
var GENERIC_TERMINALS = [
|
|
14255
|
+
{ kind: "return", match: { type: "returnStatement" }, extraction: {} },
|
|
14256
|
+
{ kind: "throw", match: { type: "throwExpression" }, extraction: {} },
|
|
14257
|
+
{
|
|
14258
|
+
// Implicit fall-through at the end of a function body: covers
|
|
14259
|
+
// void-returning orchestrators that never write `return`.
|
|
14260
|
+
kind: "return",
|
|
14261
|
+
match: { type: "functionFallthrough" },
|
|
14262
|
+
extraction: {}
|
|
14263
|
+
}
|
|
14264
|
+
];
|
|
14014
14265
|
var reachablePack = {
|
|
14015
14266
|
name: "reachable",
|
|
14016
14267
|
languages: ["typescript"],
|
|
14017
14268
|
protocol: "in-process",
|
|
14018
14269
|
discovery: [],
|
|
14019
|
-
terminals:
|
|
14020
|
-
{ kind: "return", match: { type: "returnStatement" }, extraction: {} },
|
|
14021
|
-
{ kind: "throw", match: { type: "throwExpression" }, extraction: {} },
|
|
14022
|
-
{
|
|
14023
|
-
// Implicit fall-through at the end of a function body: covers
|
|
14024
|
-
// void-returning orchestrators that never write `return`.
|
|
14025
|
-
kind: "return",
|
|
14026
|
-
match: { type: "functionFallthrough" },
|
|
14027
|
-
extraction: {}
|
|
14028
|
-
}
|
|
14029
|
-
],
|
|
14270
|
+
terminals: GENERIC_TERMINALS,
|
|
14030
14271
|
inputMapping: { type: "allPositional" }
|
|
14031
14272
|
};
|
|
14032
14273
|
function nodeKey(func) {
|
|
@@ -15831,10 +16072,10 @@ var FUNCTION_FALLTHROUGH_TERMINAL = {
|
|
|
15831
16072
|
match: { type: "functionFallthrough" },
|
|
15832
16073
|
extraction: {}
|
|
15833
16074
|
};
|
|
15834
|
-
function
|
|
15835
|
-
return unit.pattern?.wraps?.throwParam;
|
|
16075
|
+
function frameworkValueAt(unit) {
|
|
16076
|
+
return unit.pattern?.wraps?.throwParam ?? unit.pattern?.wraps?.resultParam;
|
|
15836
16077
|
}
|
|
15837
|
-
function
|
|
16078
|
+
function pastFrameworkValue(terminals, at) {
|
|
15838
16079
|
if (at === void 0) {
|
|
15839
16080
|
return terminals;
|
|
15840
16081
|
}
|
|
@@ -15848,7 +16089,7 @@ function pastThrownValue(terminals, at) {
|
|
|
15848
16089
|
} : pattern
|
|
15849
16090
|
);
|
|
15850
16091
|
}
|
|
15851
|
-
function
|
|
16092
|
+
function rolesPastFrameworkValue(mapping, at) {
|
|
15852
16093
|
if (at === void 0 || mapping.type !== "positionalParams") {
|
|
15853
16094
|
return mapping;
|
|
15854
16095
|
}
|
|
@@ -15874,7 +16115,7 @@ function continuationTerminal(unit) {
|
|
|
15874
16115
|
}
|
|
15875
16116
|
function terminalsFor(unit, pack) {
|
|
15876
16117
|
const declared = [
|
|
15877
|
-
...unit.terminals ??
|
|
16118
|
+
...unit.terminals ?? pastFrameworkValue(pack.terminals, frameworkValueAt(unit)),
|
|
15878
16119
|
...continuationTerminal(unit)
|
|
15879
16120
|
];
|
|
15880
16121
|
if (unit.callSite === void 0) {
|
|
@@ -15892,7 +16133,7 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
|
|
|
15892
16133
|
}
|
|
15893
16134
|
const params = extractParameters(
|
|
15894
16135
|
func,
|
|
15895
|
-
unit.inputMapping ??
|
|
16136
|
+
unit.inputMapping ?? rolesPastFrameworkValue(pack.inputMapping, frameworkValueAt(unit))
|
|
15896
16137
|
);
|
|
15897
16138
|
const extracted = extractRawBranches(
|
|
15898
16139
|
func,
|
|
@@ -16394,8 +16635,10 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16394
16635
|
}
|
|
16395
16636
|
}
|
|
16396
16637
|
const summary = assembleSummary3(raw, options);
|
|
16397
|
-
if (
|
|
16398
|
-
|
|
16638
|
+
if (options?.gapHandling !== "silent") {
|
|
16639
|
+
for (const stop of unfollowedStopsOf(unit, wrappers)) {
|
|
16640
|
+
summary.gaps.push(unfollowedCallGap(stop));
|
|
16641
|
+
}
|
|
16399
16642
|
}
|
|
16400
16643
|
if (unit.metadata !== void 0 && Object.keys(unit.metadata).length > 0) {
|
|
16401
16644
|
summary.metadata = {
|
|
@@ -16448,6 +16691,13 @@ function stampWrappers(raw, unit, wrappers) {
|
|
|
16448
16691
|
recordFileDependency(wrapper.file);
|
|
16449
16692
|
}
|
|
16450
16693
|
}
|
|
16694
|
+
function unfollowedStopsOf(unit, wrappers) {
|
|
16695
|
+
const stops = unit.unfollowed === void 0 ? [] : [unit.unfollowed];
|
|
16696
|
+
if (wrappers === void 0 || unit.registrationSubjectId === void 0) {
|
|
16697
|
+
return stops;
|
|
16698
|
+
}
|
|
16699
|
+
return [...stops, ...wrappers.unfollowedFor(unit.registrationSubjectId)];
|
|
16700
|
+
}
|
|
16451
16701
|
function emitLibraryEnvReadMarkers(summaries, project, frameworks) {
|
|
16452
16702
|
for (const pack of frameworks) {
|
|
16453
16703
|
for (const declared of pack.libraryEnvVars ?? []) {
|
|
@@ -17162,7 +17412,7 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
17162
17412
|
});
|
|
17163
17413
|
const composed = timer.time(
|
|
17164
17414
|
"composeWrappers",
|
|
17165
|
-
() => composeWrappers(enriched)
|
|
17415
|
+
() => composeWrappers(enriched, config.extractorOptions ?? {})
|
|
17166
17416
|
);
|
|
17167
17417
|
if (config.onTiming !== void 0) {
|
|
17168
17418
|
config.onTiming(timer.report());
|
|
@@ -17786,6 +18036,8 @@ function stubEvidence(options) {
|
|
|
17786
18036
|
}
|
|
17787
18037
|
export {
|
|
17788
18038
|
ADAPTER_VERSION,
|
|
18039
|
+
GENERIC_TERMINALS,
|
|
18040
|
+
NO_BARRIERS,
|
|
17789
18041
|
ResolutionStore,
|
|
17790
18042
|
TypeScriptWhySession,
|
|
17791
18043
|
accessContextFor,
|
|
@@ -17806,6 +18058,7 @@ export {
|
|
|
17806
18058
|
findNearestTsconfig,
|
|
17807
18059
|
findTerminals,
|
|
17808
18060
|
functionTargetOf,
|
|
18061
|
+
hasBody,
|
|
17809
18062
|
importDeclarationsOf,
|
|
17810
18063
|
importedNamesOf,
|
|
17811
18064
|
importedRootsOf,
|
|
@@ -17821,6 +18074,7 @@ export {
|
|
|
17821
18074
|
resolveAliasedSymbol,
|
|
17822
18075
|
resolveSubject,
|
|
17823
18076
|
rootIdentifier,
|
|
18077
|
+
startsItsOwnScope,
|
|
17824
18078
|
stubEvidence,
|
|
17825
18079
|
stubEvidenceIn,
|
|
17826
18080
|
workspaceRootFor
|