@suss/adapter-typescript 0.9.0 → 0.11.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/README.md +36 -0
- package/dist/index.cjs +1735 -364
- package/dist/index.d.cts +198 -15
- package/dist/index.d.ts +198 -15
- package/dist/index.js +1726 -351
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ADAPTER_VERSION: () => ADAPTER_VERSION,
|
|
34
34
|
ResolutionStore: () => ResolutionStore,
|
|
35
|
+
WhySession: () => WhySession,
|
|
35
36
|
collectAncestorBranches: () => collectAncestorBranches,
|
|
36
37
|
collectClientFieldAccesses: () => collectClientFieldAccesses,
|
|
37
38
|
computeAdapterPacksDigest: () => computeAdapterPacksDigest,
|
|
@@ -57,7 +58,8 @@ __export(index_exports, {
|
|
|
57
58
|
readName: () => readName,
|
|
58
59
|
resolveAliasedSymbol: () => resolveAliasedSymbol,
|
|
59
60
|
resolveSubject: () => resolveSubject,
|
|
60
|
-
rootIdentifier: () =>
|
|
61
|
+
rootIdentifier: () => rootIdentifier2,
|
|
62
|
+
workspaceRootFor: () => workspaceRootFor
|
|
61
63
|
});
|
|
62
64
|
module.exports = __toCommonJS(index_exports);
|
|
63
65
|
|
|
@@ -1076,24 +1078,64 @@ function collectFallthroughCaseLabels(caseClause) {
|
|
|
1076
1078
|
}
|
|
1077
1079
|
|
|
1078
1080
|
// src/paths/pathConditions.ts
|
|
1079
|
-
var
|
|
1081
|
+
var import_ts_morph9 = require("ts-morph");
|
|
1080
1082
|
var import_extractor2 = require("@suss/extractor");
|
|
1081
1083
|
|
|
1082
|
-
// src/
|
|
1084
|
+
// src/walk/descent.ts
|
|
1083
1085
|
var import_ts_morph7 = require("ts-morph");
|
|
1086
|
+
var NO_BARRIERS = /* @__PURE__ */ new Set();
|
|
1087
|
+
function isDescentStop(node, func, barriers = NO_BARRIERS) {
|
|
1088
|
+
if (node === func) {
|
|
1089
|
+
return false;
|
|
1090
|
+
}
|
|
1091
|
+
if (import_ts_morph7.Node.isFunctionDeclaration(node) || import_ts_morph7.Node.isMethodDeclaration(node)) {
|
|
1092
|
+
return true;
|
|
1093
|
+
}
|
|
1094
|
+
if (import_ts_morph7.Node.isArrowFunction(node) || import_ts_morph7.Node.isFunctionExpression(node)) {
|
|
1095
|
+
return barriers.has(node);
|
|
1096
|
+
}
|
|
1097
|
+
return false;
|
|
1098
|
+
}
|
|
1099
|
+
function isInlineCallback(node, func, barriers = NO_BARRIERS) {
|
|
1100
|
+
if (node === func) {
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
if (!(import_ts_morph7.Node.isArrowFunction(node) || import_ts_morph7.Node.isFunctionExpression(node))) {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
return !barriers.has(node);
|
|
1107
|
+
}
|
|
1108
|
+
function isModuleScopeStop(node) {
|
|
1109
|
+
return import_ts_morph7.Node.isFunctionDeclaration(node) || import_ts_morph7.Node.isMethodDeclaration(node) || import_ts_morph7.Node.isArrowFunction(node) || import_ts_morph7.Node.isFunctionExpression(node) || import_ts_morph7.Node.isClassDeclaration(node) || import_ts_morph7.Node.isClassExpression(node);
|
|
1110
|
+
}
|
|
1111
|
+
function crossesNestedFunctionScope(node, func) {
|
|
1112
|
+
let current2 = node;
|
|
1113
|
+
while (current2 !== void 0 && current2 !== func) {
|
|
1114
|
+
if (startsItsOwnScope(current2)) {
|
|
1115
|
+
return true;
|
|
1116
|
+
}
|
|
1117
|
+
current2 = current2.getParent();
|
|
1118
|
+
}
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
function startsItsOwnScope(node) {
|
|
1122
|
+
return import_ts_morph7.Node.isArrowFunction(node) || import_ts_morph7.Node.isFunctionExpression(node) || import_ts_morph7.Node.isFunctionDeclaration(node) || import_ts_morph7.Node.isMethodDeclaration(node) || import_ts_morph7.Node.isGetAccessorDeclaration(node) || import_ts_morph7.Node.isSetAccessorDeclaration(node) || import_ts_morph7.Node.isConstructorDeclaration(node);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// src/paths/lowering.ts
|
|
1126
|
+
var import_ts_morph8 = require("ts-morph");
|
|
1084
1127
|
var import_extractor = require("@suss/extractor");
|
|
1085
|
-
var isFunctionBoundary = (node) => import_ts_morph7.Node.isFunctionDeclaration(node) || import_ts_morph7.Node.isFunctionExpression(node) || import_ts_morph7.Node.isArrowFunction(node) || import_ts_morph7.Node.isMethodDeclaration(node);
|
|
1086
1128
|
function exitKindOf(stmt) {
|
|
1087
1129
|
let sawReturn = false;
|
|
1088
1130
|
let sawThrow = false;
|
|
1089
1131
|
const visit = (node) => {
|
|
1090
|
-
if (node !== stmt &&
|
|
1132
|
+
if (node !== stmt && startsItsOwnScope(node)) {
|
|
1091
1133
|
return;
|
|
1092
1134
|
}
|
|
1093
|
-
if (
|
|
1135
|
+
if (import_ts_morph8.Node.isReturnStatement(node)) {
|
|
1094
1136
|
sawReturn = true;
|
|
1095
1137
|
}
|
|
1096
|
-
if (
|
|
1138
|
+
if (import_ts_morph8.Node.isThrowStatement(node)) {
|
|
1097
1139
|
sawThrow = true;
|
|
1098
1140
|
}
|
|
1099
1141
|
for (const child of node.getChildren()) {
|
|
@@ -1110,14 +1152,14 @@ var statementsOf = (stmt) => {
|
|
|
1110
1152
|
if (stmt === void 0) {
|
|
1111
1153
|
return [];
|
|
1112
1154
|
}
|
|
1113
|
-
if (
|
|
1155
|
+
if (import_ts_morph8.Node.isBlock(stmt)) {
|
|
1114
1156
|
return stmt.getStatements();
|
|
1115
1157
|
}
|
|
1116
1158
|
return [stmt];
|
|
1117
1159
|
};
|
|
1118
|
-
var isLoop = (stmt) =>
|
|
1160
|
+
var isLoop = (stmt) => import_ts_morph8.Node.isForOfStatement(stmt) || import_ts_morph8.Node.isForInStatement(stmt) || import_ts_morph8.Node.isForStatement(stmt) || import_ts_morph8.Node.isWhileStatement(stmt) || import_ts_morph8.Node.isDoStatement(stmt);
|
|
1119
1161
|
function getLoopBody(stmt) {
|
|
1120
|
-
if (
|
|
1162
|
+
if (import_ts_morph8.Node.isForOfStatement(stmt) || import_ts_morph8.Node.isForInStatement(stmt) || import_ts_morph8.Node.isForStatement(stmt) || import_ts_morph8.Node.isWhileStatement(stmt) || import_ts_morph8.Node.isDoStatement(stmt)) {
|
|
1121
1163
|
return stmt.getStatement();
|
|
1122
1164
|
}
|
|
1123
1165
|
return void 0;
|
|
@@ -1132,37 +1174,97 @@ var conditionOf = (expr) => ({
|
|
|
1132
1174
|
sourceText: expr.getText(),
|
|
1133
1175
|
expression: expr
|
|
1134
1176
|
});
|
|
1135
|
-
function lowerStatement(stmt,
|
|
1136
|
-
const structured =
|
|
1137
|
-
|
|
1177
|
+
function lowerStatement(stmt, ctx) {
|
|
1178
|
+
const structured = {
|
|
1179
|
+
...buildStructured(stmt, ctx),
|
|
1180
|
+
callbacks: lowerCallbacksIn(ownExpressionsOf(stmt), ctx)
|
|
1181
|
+
};
|
|
1182
|
+
ctx.rawToStructured.set(stmt, structured);
|
|
1138
1183
|
return structured;
|
|
1139
1184
|
}
|
|
1140
|
-
function lowerList(stmts,
|
|
1141
|
-
return spliceBlocks(stmts).map((s) => lowerStatement(s,
|
|
1185
|
+
function lowerList(stmts, ctx) {
|
|
1186
|
+
return spliceBlocks(stmts).map((s) => lowerStatement(s, ctx));
|
|
1187
|
+
}
|
|
1188
|
+
function ownExpressionsOf(stmt) {
|
|
1189
|
+
if (import_ts_morph8.Node.isIfStatement(stmt) || import_ts_morph8.Node.isSwitchStatement(stmt)) {
|
|
1190
|
+
return [stmt.getExpression()];
|
|
1191
|
+
}
|
|
1192
|
+
if (import_ts_morph8.Node.isWhileStatement(stmt) || import_ts_morph8.Node.isDoStatement(stmt)) {
|
|
1193
|
+
return [stmt.getExpression()];
|
|
1194
|
+
}
|
|
1195
|
+
if (import_ts_morph8.Node.isForOfStatement(stmt) || import_ts_morph8.Node.isForInStatement(stmt)) {
|
|
1196
|
+
return [stmt.getInitializer(), stmt.getExpression()];
|
|
1197
|
+
}
|
|
1198
|
+
if (import_ts_morph8.Node.isForStatement(stmt)) {
|
|
1199
|
+
return [
|
|
1200
|
+
stmt.getInitializer(),
|
|
1201
|
+
stmt.getCondition(),
|
|
1202
|
+
stmt.getIncrementor()
|
|
1203
|
+
].filter((n) => n !== void 0);
|
|
1204
|
+
}
|
|
1205
|
+
if (import_ts_morph8.Node.isTryStatement(stmt)) {
|
|
1206
|
+
return [];
|
|
1207
|
+
}
|
|
1208
|
+
if (import_ts_morph8.Node.isReturnStatement(stmt) || import_ts_morph8.Node.isThrowStatement(stmt)) {
|
|
1209
|
+
const value = stmt.getExpression();
|
|
1210
|
+
return value === void 0 ? [] : [value];
|
|
1211
|
+
}
|
|
1212
|
+
if (import_ts_morph8.Node.isBreakStatement(stmt) || import_ts_morph8.Node.isContinueStatement(stmt)) {
|
|
1213
|
+
return [];
|
|
1214
|
+
}
|
|
1215
|
+
return [stmt];
|
|
1216
|
+
}
|
|
1217
|
+
function lowerCallbacksIn(parts, ctx) {
|
|
1218
|
+
const bodies = [];
|
|
1219
|
+
const visit = (node, root) => {
|
|
1220
|
+
if (node !== root && isDescentStop(node, ctx.func, ctx.barriers)) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
if (node !== root && (import_ts_morph8.Node.isArrowFunction(node) || import_ts_morph8.Node.isFunctionExpression(node)) && isInlineCallback(node, ctx.func, ctx.barriers)) {
|
|
1224
|
+
const body = node.getBody();
|
|
1225
|
+
if (body !== void 0 && import_ts_morph8.Node.isBlock(body)) {
|
|
1226
|
+
bodies.push(lowerList(body.getStatements(), ctx));
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
} else if (node !== root && startsItsOwnScope(node)) {
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
for (const child of node.getChildren()) {
|
|
1233
|
+
visit(child, root);
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
for (const part of parts) {
|
|
1237
|
+
visit(part, part);
|
|
1238
|
+
}
|
|
1239
|
+
return bodies;
|
|
1240
|
+
}
|
|
1241
|
+
function lowerExpressionBodyCallbacks(expression, func, barriers = NO_BARRIERS) {
|
|
1242
|
+
return lowerCallbacksIn([expression], {
|
|
1243
|
+
func,
|
|
1244
|
+
barriers,
|
|
1245
|
+
rawToStructured: /* @__PURE__ */ new Map()
|
|
1246
|
+
});
|
|
1142
1247
|
}
|
|
1143
1248
|
function spliceBlocks(stmts) {
|
|
1144
1249
|
return stmts.flatMap(
|
|
1145
|
-
(s) =>
|
|
1250
|
+
(s) => import_ts_morph8.Node.isBlock(s) ? spliceBlocks(s.getStatements()) : [s]
|
|
1146
1251
|
);
|
|
1147
1252
|
}
|
|
1148
|
-
function buildStructured(stmt,
|
|
1149
|
-
if (
|
|
1253
|
+
function buildStructured(stmt, ctx) {
|
|
1254
|
+
if (import_ts_morph8.Node.isIfStatement(stmt)) {
|
|
1150
1255
|
const elseBranch = stmt.getElseStatement();
|
|
1151
1256
|
return {
|
|
1152
1257
|
kind: "if",
|
|
1153
1258
|
condition: conditionOf(stmt.getExpression()),
|
|
1154
|
-
thenBody: lowerList(
|
|
1155
|
-
|
|
1156
|
-
rawToStructured
|
|
1157
|
-
),
|
|
1158
|
-
elseBody: elseBranch === void 0 ? null : lowerList(statementsOf(elseBranch), rawToStructured),
|
|
1259
|
+
thenBody: lowerList(statementsOf(stmt.getThenStatement()), ctx),
|
|
1260
|
+
elseBody: elseBranch === void 0 ? null : lowerList(statementsOf(elseBranch), ctx),
|
|
1159
1261
|
exitKind: exitKindOf(stmt)
|
|
1160
1262
|
};
|
|
1161
1263
|
}
|
|
1162
|
-
if (
|
|
1264
|
+
if (import_ts_morph8.Node.isSwitchStatement(stmt)) {
|
|
1163
1265
|
return {
|
|
1164
1266
|
kind: "switch",
|
|
1165
|
-
groups: lowerSwitchGroups(stmt,
|
|
1267
|
+
groups: lowerSwitchGroups(stmt, ctx),
|
|
1166
1268
|
exitKind: exitKindOf(stmt)
|
|
1167
1269
|
};
|
|
1168
1270
|
}
|
|
@@ -1170,36 +1272,36 @@ function buildStructured(stmt, rawToStructured) {
|
|
|
1170
1272
|
return {
|
|
1171
1273
|
kind: "loop",
|
|
1172
1274
|
condition: { sourceText: loopHeaderText(stmt), expression: null },
|
|
1173
|
-
body: lowerList(statementsOf(getLoopBody(stmt)),
|
|
1275
|
+
body: lowerList(statementsOf(getLoopBody(stmt)), ctx),
|
|
1174
1276
|
exitKind: exitKindOf(stmt)
|
|
1175
1277
|
};
|
|
1176
1278
|
}
|
|
1177
|
-
if (
|
|
1279
|
+
if (import_ts_morph8.Node.isTryStatement(stmt)) {
|
|
1178
1280
|
const catchClause = stmt.getCatchClause();
|
|
1179
1281
|
const finallyBlock = stmt.getFinallyBlock();
|
|
1180
1282
|
return {
|
|
1181
1283
|
kind: "try",
|
|
1182
|
-
tryBody: lowerList(stmt.getTryBlock().getStatements(),
|
|
1183
|
-
catchBody: catchClause === void 0 ? null : lowerList(catchClause.getBlock().getStatements(),
|
|
1184
|
-
finallyBody: finallyBlock === void 0 ? null : lowerList(finallyBlock.getStatements(),
|
|
1284
|
+
tryBody: lowerList(stmt.getTryBlock().getStatements(), ctx),
|
|
1285
|
+
catchBody: catchClause === void 0 ? null : lowerList(catchClause.getBlock().getStatements(), ctx),
|
|
1286
|
+
finallyBody: finallyBlock === void 0 ? null : lowerList(finallyBlock.getStatements(), ctx),
|
|
1185
1287
|
exitKind: exitKindOf(stmt)
|
|
1186
1288
|
};
|
|
1187
1289
|
}
|
|
1188
|
-
if (
|
|
1290
|
+
if (import_ts_morph8.Node.isReturnStatement(stmt)) {
|
|
1189
1291
|
return { kind: "exit", exit: "return", exitKind: exitKindOf(stmt) };
|
|
1190
1292
|
}
|
|
1191
|
-
if (
|
|
1293
|
+
if (import_ts_morph8.Node.isThrowStatement(stmt)) {
|
|
1192
1294
|
return { kind: "exit", exit: "throw", exitKind: exitKindOf(stmt) };
|
|
1193
1295
|
}
|
|
1194
|
-
if (
|
|
1296
|
+
if (import_ts_morph8.Node.isBreakStatement(stmt)) {
|
|
1195
1297
|
return { kind: "exit", exit: "break", exitKind: exitKindOf(stmt) };
|
|
1196
1298
|
}
|
|
1197
|
-
if (
|
|
1299
|
+
if (import_ts_morph8.Node.isContinueStatement(stmt)) {
|
|
1198
1300
|
return { kind: "exit", exit: "continue", exitKind: exitKindOf(stmt) };
|
|
1199
1301
|
}
|
|
1200
1302
|
return { kind: "opaque", exitKind: exitKindOf(stmt) };
|
|
1201
1303
|
}
|
|
1202
|
-
function lowerSwitchGroups(stmt,
|
|
1304
|
+
function lowerSwitchGroups(stmt, ctx) {
|
|
1203
1305
|
const switchText = stmt.getExpression().getText();
|
|
1204
1306
|
const groups = [];
|
|
1205
1307
|
let pendingLabels = [];
|
|
@@ -1208,7 +1310,7 @@ function lowerSwitchGroups(stmt, rawToStructured) {
|
|
|
1208
1310
|
if (sawDefault) {
|
|
1209
1311
|
throw new import_extractor.UnmodeledFlow("default clause is not last");
|
|
1210
1312
|
}
|
|
1211
|
-
if (
|
|
1313
|
+
if (import_ts_morph8.Node.isDefaultClause(clause)) {
|
|
1212
1314
|
sawDefault = true;
|
|
1213
1315
|
const stmts2 = clause.getStatements();
|
|
1214
1316
|
if (stmts2.length === 0) {
|
|
@@ -1216,11 +1318,11 @@ function lowerSwitchGroups(stmt, rawToStructured) {
|
|
|
1216
1318
|
}
|
|
1217
1319
|
groups.push({
|
|
1218
1320
|
condition: null,
|
|
1219
|
-
...lowerGroupBody(stmts2,
|
|
1321
|
+
...lowerGroupBody(stmts2, ctx)
|
|
1220
1322
|
});
|
|
1221
1323
|
continue;
|
|
1222
1324
|
}
|
|
1223
|
-
if (!
|
|
1325
|
+
if (!import_ts_morph8.Node.isCaseClause(clause)) {
|
|
1224
1326
|
continue;
|
|
1225
1327
|
}
|
|
1226
1328
|
pendingLabels.push(clause.getExpression().getText());
|
|
@@ -1233,7 +1335,7 @@ function lowerSwitchGroups(stmt, rawToStructured) {
|
|
|
1233
1335
|
const sourceText = labels.map((l) => `${switchText} === ${l}`).join(" || ");
|
|
1234
1336
|
groups.push({
|
|
1235
1337
|
condition: { sourceText, expression: null },
|
|
1236
|
-
...lowerGroupBody(stmts,
|
|
1338
|
+
...lowerGroupBody(stmts, ctx)
|
|
1237
1339
|
});
|
|
1238
1340
|
}
|
|
1239
1341
|
return groups;
|
|
@@ -1241,41 +1343,42 @@ function lowerSwitchGroups(stmt, rawToStructured) {
|
|
|
1241
1343
|
function validateClauseBreaks(stmts) {
|
|
1242
1344
|
const last = stmts[stmts.length - 1];
|
|
1243
1345
|
for (const stmt of stmts) {
|
|
1244
|
-
if (stmt === last &&
|
|
1346
|
+
if (stmt === last && import_ts_morph8.Node.isBreakStatement(stmt)) {
|
|
1245
1347
|
continue;
|
|
1246
1348
|
}
|
|
1247
|
-
if (
|
|
1349
|
+
if (import_ts_morph8.Node.isSwitchStatement(stmt) || isLoop(stmt)) {
|
|
1248
1350
|
continue;
|
|
1249
1351
|
}
|
|
1250
1352
|
stmt.forEachDescendant((node, traversal) => {
|
|
1251
|
-
if (
|
|
1353
|
+
if (startsItsOwnScope(node) || import_ts_morph8.Node.isSwitchStatement(node) || isLoop(node)) {
|
|
1252
1354
|
traversal.skip();
|
|
1253
1355
|
return;
|
|
1254
1356
|
}
|
|
1255
|
-
if (
|
|
1357
|
+
if (import_ts_morph8.Node.isBreakStatement(node)) {
|
|
1256
1358
|
throw new import_extractor.UnmodeledFlow("non-trailing break in switch clause");
|
|
1257
1359
|
}
|
|
1258
1360
|
});
|
|
1259
|
-
if (
|
|
1361
|
+
if (import_ts_morph8.Node.isBreakStatement(stmt)) {
|
|
1260
1362
|
throw new import_extractor.UnmodeledFlow("non-trailing break in switch clause");
|
|
1261
1363
|
}
|
|
1262
1364
|
}
|
|
1263
1365
|
}
|
|
1264
|
-
function lowerGroupBody(rawStmts,
|
|
1366
|
+
function lowerGroupBody(rawStmts, ctx) {
|
|
1265
1367
|
const stmts = spliceBlocks(rawStmts);
|
|
1266
1368
|
validateClauseBreaks(stmts);
|
|
1267
1369
|
const last = stmts[stmts.length - 1];
|
|
1268
|
-
const hasTrailingBreak = last !== void 0 &&
|
|
1370
|
+
const hasTrailingBreak = last !== void 0 && import_ts_morph8.Node.isBreakStatement(last);
|
|
1269
1371
|
const kept = hasTrailingBreak ? stmts.slice(0, -1) : stmts;
|
|
1270
|
-
const body = lowerList(kept,
|
|
1372
|
+
const body = lowerList(kept, ctx);
|
|
1271
1373
|
if (hasTrailingBreak && last !== void 0) {
|
|
1272
|
-
lowerStatement(last,
|
|
1374
|
+
lowerStatement(last, ctx);
|
|
1273
1375
|
}
|
|
1274
1376
|
return { hasTrailingBreak, body };
|
|
1275
1377
|
}
|
|
1276
|
-
function lowerFunctionBody(body, terminalNodes) {
|
|
1378
|
+
function lowerFunctionBody(body, terminalNodes, func = body, barriers = NO_BARRIERS) {
|
|
1277
1379
|
const rawToStructured = /* @__PURE__ */ new Map();
|
|
1278
|
-
const
|
|
1380
|
+
const ctx = { func, barriers, rawToStructured };
|
|
1381
|
+
const statements = lowerList(body.getStatements(), ctx);
|
|
1279
1382
|
const terminalsByStmt = /* @__PURE__ */ new Map();
|
|
1280
1383
|
const terminalHomeRaw = /* @__PURE__ */ new Map();
|
|
1281
1384
|
for (const terminal of terminalNodes) {
|
|
@@ -1297,7 +1400,7 @@ function lowerFunctionBody(body, terminalNodes) {
|
|
|
1297
1400
|
function enclosingLoweredStatement(terminal, body, rawToStructured) {
|
|
1298
1401
|
let current2 = terminal;
|
|
1299
1402
|
while (current2 !== void 0 && current2 !== body) {
|
|
1300
|
-
if (
|
|
1403
|
+
if (import_ts_morph8.Node.isStatement(current2) && rawToStructured.has(current2)) {
|
|
1301
1404
|
return current2;
|
|
1302
1405
|
}
|
|
1303
1406
|
current2 = current2.getParent();
|
|
@@ -1306,39 +1409,42 @@ function enclosingLoweredStatement(terminal, body, rawToStructured) {
|
|
|
1306
1409
|
}
|
|
1307
1410
|
|
|
1308
1411
|
// src/paths/pathConditions.ts
|
|
1309
|
-
function containsUnmodeledFlow(body) {
|
|
1412
|
+
function containsUnmodeledFlow(body, func, barriers) {
|
|
1310
1413
|
let found = false;
|
|
1311
1414
|
body.forEachDescendant((node, traversal) => {
|
|
1312
|
-
if (
|
|
1415
|
+
if (isDescentStop(node, func, barriers)) {
|
|
1313
1416
|
traversal.skip();
|
|
1314
1417
|
return;
|
|
1315
1418
|
}
|
|
1316
|
-
if (
|
|
1419
|
+
if (import_ts_morph9.Node.isLabeledStatement(node)) {
|
|
1317
1420
|
found = true;
|
|
1318
1421
|
traversal.stop();
|
|
1319
1422
|
}
|
|
1320
1423
|
});
|
|
1321
1424
|
return found;
|
|
1322
1425
|
}
|
|
1323
|
-
function
|
|
1426
|
+
function loweredExpressionBody(body, terminalNodes, func, barriers) {
|
|
1427
|
+
const statement = {
|
|
1428
|
+
kind: "opaque",
|
|
1429
|
+
exitKind: null,
|
|
1430
|
+
callbacks: lowerExpressionBodyCallbacks(body, func, barriers)
|
|
1431
|
+
};
|
|
1432
|
+
return {
|
|
1433
|
+
statements: [statement],
|
|
1434
|
+
terminalsByStmt: /* @__PURE__ */ new Map([[statement, terminalNodes]]),
|
|
1435
|
+
terminalHomeRaw: /* @__PURE__ */ new Map()
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
function computePathConditions(func, terminalNodes, barriers = NO_BARRIERS) {
|
|
1324
1439
|
const body = func.getBody();
|
|
1325
1440
|
if (body === void 0) {
|
|
1326
1441
|
return { byTerminal: /* @__PURE__ */ new Map(), fallthrough: [] };
|
|
1327
1442
|
}
|
|
1328
|
-
if (
|
|
1329
|
-
const byTerminal = /* @__PURE__ */ new Map();
|
|
1330
|
-
for (const terminal of terminalNodes) {
|
|
1331
|
-
byTerminal.set(terminal, [
|
|
1332
|
-
collectAncestorConditionInfosBelow(terminal, func)
|
|
1333
|
-
]);
|
|
1334
|
-
}
|
|
1335
|
-
return { byTerminal, fallthrough: [] };
|
|
1336
|
-
}
|
|
1337
|
-
if (containsUnmodeledFlow(body)) {
|
|
1443
|
+
if (containsUnmodeledFlow(body, func, barriers)) {
|
|
1338
1444
|
return degradedResult(func, terminalNodes, "labeled statement");
|
|
1339
1445
|
}
|
|
1340
1446
|
try {
|
|
1341
|
-
const lowered = lowerFunctionBody(body, terminalNodes);
|
|
1447
|
+
const lowered = import_ts_morph9.Node.isBlock(body) ? lowerFunctionBody(body, terminalNodes, func, barriers) : loweredExpressionBody(body, terminalNodes, func, barriers);
|
|
1342
1448
|
const result = (0, import_extractor2.enumerateStructuredPaths)({
|
|
1343
1449
|
statements: lowered.statements,
|
|
1344
1450
|
terminalsByStmt: lowered.terminalsByStmt
|
|
@@ -1405,12 +1511,12 @@ function lineAt(node, pos) {
|
|
|
1405
1511
|
}
|
|
1406
1512
|
|
|
1407
1513
|
// src/moduleExports.ts
|
|
1408
|
-
var
|
|
1514
|
+
var import_ts_morph11 = require("ts-morph");
|
|
1409
1515
|
|
|
1410
1516
|
// src/bootstrap/lazyProjectInit.ts
|
|
1411
1517
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
1412
1518
|
var import_node_path = __toESM(require("path"), 1);
|
|
1413
|
-
var
|
|
1519
|
+
var import_ts_morph10 = require("ts-morph");
|
|
1414
1520
|
|
|
1415
1521
|
// src/facts/moduleGraph.ts
|
|
1416
1522
|
var import_datalog = require("@suss/datalog");
|
|
@@ -1538,7 +1644,7 @@ var ModuleGraph = class {
|
|
|
1538
1644
|
return created;
|
|
1539
1645
|
}
|
|
1540
1646
|
assert(relation, tuple) {
|
|
1541
|
-
if (this.db.add(relation, tuple)) {
|
|
1647
|
+
if (this.db.add(relation, tuple) === "added") {
|
|
1542
1648
|
this.stale = true;
|
|
1543
1649
|
}
|
|
1544
1650
|
}
|
|
@@ -1755,8 +1861,8 @@ function loadImportGraphsDepthFirstFromPaths(project, rootPaths) {
|
|
|
1755
1861
|
stack.pop();
|
|
1756
1862
|
loadOrder.push(top.path);
|
|
1757
1863
|
let deepest = 0;
|
|
1758
|
-
for (const
|
|
1759
|
-
deepest = Math.max(deepest, chainDepth.get(
|
|
1864
|
+
for (const path12 of top.deps) {
|
|
1865
|
+
deepest = Math.max(deepest, chainDepth.get(path12) ?? 0);
|
|
1760
1866
|
}
|
|
1761
1867
|
chainDepth.set(top.path, deepest + 1);
|
|
1762
1868
|
}
|
|
@@ -1828,10 +1934,10 @@ function readSpecifierPaths(project, filePath, options, host) {
|
|
|
1828
1934
|
if (text === null) {
|
|
1829
1935
|
return [];
|
|
1830
1936
|
}
|
|
1831
|
-
const scanned =
|
|
1937
|
+
const scanned = import_ts_morph10.ts.preProcessFile(text, true, true);
|
|
1832
1938
|
const paths = [];
|
|
1833
1939
|
for (const imported of scanned.importedFiles) {
|
|
1834
|
-
const resolved =
|
|
1940
|
+
const resolved = import_ts_morph10.ts.resolveModuleName(
|
|
1835
1941
|
imported.fileName,
|
|
1836
1942
|
filePath,
|
|
1837
1943
|
options,
|
|
@@ -1855,13 +1961,13 @@ function readFileText(project, filePath) {
|
|
|
1855
1961
|
}
|
|
1856
1962
|
}
|
|
1857
1963
|
function parseTsconfig(tsConfigFilePath) {
|
|
1858
|
-
const configFile =
|
|
1964
|
+
const configFile = import_ts_morph10.ts.readConfigFile(tsConfigFilePath, import_ts_morph10.ts.sys.readFile);
|
|
1859
1965
|
if (configFile.error !== void 0) {
|
|
1860
1966
|
return { fileNames: [], options: {} };
|
|
1861
1967
|
}
|
|
1862
|
-
const parsed =
|
|
1968
|
+
const parsed = import_ts_morph10.ts.parseJsonConfigFileContent(
|
|
1863
1969
|
configFile.config,
|
|
1864
|
-
|
|
1970
|
+
import_ts_morph10.ts.sys,
|
|
1865
1971
|
import_node_path.default.dirname(tsConfigFilePath),
|
|
1866
1972
|
/*existingOptions*/
|
|
1867
1973
|
void 0,
|
|
@@ -1921,17 +2027,17 @@ function addImportersOfMatches(fileImports, matched, options) {
|
|
|
1921
2027
|
}
|
|
1922
2028
|
function internalSpecifierResolver(files, options) {
|
|
1923
2029
|
const fileSet = new Set(files);
|
|
1924
|
-
const cache =
|
|
1925
|
-
|
|
2030
|
+
const cache = import_ts_morph10.ts.createModuleResolutionCache(
|
|
2031
|
+
import_ts_morph10.ts.sys.getCurrentDirectory(),
|
|
1926
2032
|
(name) => name,
|
|
1927
2033
|
options
|
|
1928
2034
|
);
|
|
1929
2035
|
return (fromFile, spec) => {
|
|
1930
|
-
const resolved =
|
|
2036
|
+
const resolved = import_ts_morph10.ts.resolveModuleName(
|
|
1931
2037
|
spec,
|
|
1932
2038
|
fromFile,
|
|
1933
2039
|
options,
|
|
1934
|
-
|
|
2040
|
+
import_ts_morph10.ts.sys,
|
|
1935
2041
|
cache
|
|
1936
2042
|
).resolvedModule?.resolvedFileName;
|
|
1937
2043
|
if (resolved === void 0) {
|
|
@@ -1940,7 +2046,7 @@ function internalSpecifierResolver(files, options) {
|
|
|
1940
2046
|
if (fileSet.has(resolved)) {
|
|
1941
2047
|
return resolved;
|
|
1942
2048
|
}
|
|
1943
|
-
const real =
|
|
2049
|
+
const real = import_ts_morph10.ts.sys.realpath?.(resolved) ?? resolved;
|
|
1944
2050
|
return fileSet.has(real) ? real : null;
|
|
1945
2051
|
};
|
|
1946
2052
|
}
|
|
@@ -1966,7 +2072,7 @@ async function readImportsConcurrently(paths) {
|
|
|
1966
2072
|
const p = paths[i];
|
|
1967
2073
|
try {
|
|
1968
2074
|
const text = await import_promises.default.readFile(p, "utf-8");
|
|
1969
|
-
const pre =
|
|
2075
|
+
const pre = import_ts_morph10.ts.preProcessFile(text, true, false);
|
|
1970
2076
|
results[i] = {
|
|
1971
2077
|
path: p,
|
|
1972
2078
|
importedModules: pre.importedFiles.map((f) => f.fileName)
|
|
@@ -1984,6 +2090,30 @@ async function readImportsConcurrently(paths) {
|
|
|
1984
2090
|
return results;
|
|
1985
2091
|
}
|
|
1986
2092
|
|
|
2093
|
+
// src/depTracking.ts
|
|
2094
|
+
function createDependencySink() {
|
|
2095
|
+
return { files: /* @__PURE__ */ new Set(), mountPrefixes: /* @__PURE__ */ new Map(), claims: [] };
|
|
2096
|
+
}
|
|
2097
|
+
var activeSink = null;
|
|
2098
|
+
function withDependencySink(sink, fn) {
|
|
2099
|
+
const previous = activeSink;
|
|
2100
|
+
activeSink = sink;
|
|
2101
|
+
try {
|
|
2102
|
+
return fn();
|
|
2103
|
+
} finally {
|
|
2104
|
+
activeSink = previous;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
function recordFileDependency(filePath) {
|
|
2108
|
+
activeSink?.files.add(filePath);
|
|
2109
|
+
}
|
|
2110
|
+
function recordMountPrefix(childId, prefix) {
|
|
2111
|
+
activeSink?.mountPrefixes.set(childId, prefix);
|
|
2112
|
+
}
|
|
2113
|
+
function recordUnitClaim(key, pack) {
|
|
2114
|
+
activeSink?.claims.push({ key, pack });
|
|
2115
|
+
}
|
|
2116
|
+
|
|
1987
2117
|
// src/perFileCache.ts
|
|
1988
2118
|
function createPerFileCache() {
|
|
1989
2119
|
const byParse = /* @__PURE__ */ new WeakMap();
|
|
@@ -1999,6 +2129,7 @@ function createPerFileCache() {
|
|
|
1999
2129
|
|
|
2000
2130
|
// src/moduleExports.ts
|
|
2001
2131
|
function exportedDeclarationsOf(sourceFile) {
|
|
2132
|
+
recordFileDependency(sourceFile.getFilePath());
|
|
2002
2133
|
const cached = exportsByFile.get(sourceFile);
|
|
2003
2134
|
if (cached !== void 0) {
|
|
2004
2135
|
return cached;
|
|
@@ -2013,7 +2144,14 @@ function resolveAliasedSymbol(symbol) {
|
|
|
2013
2144
|
warmReExportChains(declaration.getSourceFile(), "every import");
|
|
2014
2145
|
}
|
|
2015
2146
|
try {
|
|
2016
|
-
|
|
2147
|
+
const aliased = symbol.getAliasedSymbol();
|
|
2148
|
+
for (const declaration of aliased?.getDeclarations() ?? []) {
|
|
2149
|
+
const file = declaration.getSourceFile();
|
|
2150
|
+
if (!file.isInNodeModules()) {
|
|
2151
|
+
recordFileDependency(file.getFilePath());
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
return aliased;
|
|
2017
2155
|
} catch (error) {
|
|
2018
2156
|
if (!(error instanceof RangeError)) {
|
|
2019
2157
|
throw error;
|
|
@@ -2069,11 +2207,11 @@ function walkAndWarm(root, reach) {
|
|
|
2069
2207
|
if (warmedFiles.get(target) !== void 0) {
|
|
2070
2208
|
continue;
|
|
2071
2209
|
}
|
|
2072
|
-
const
|
|
2073
|
-
if (visited.has(
|
|
2210
|
+
const path12 = target.getFilePath();
|
|
2211
|
+
if (visited.has(path12)) {
|
|
2074
2212
|
continue;
|
|
2075
2213
|
}
|
|
2076
|
-
visited.add(
|
|
2214
|
+
visited.add(path12);
|
|
2077
2215
|
stack.push(frameOf(target, reach));
|
|
2078
2216
|
continue;
|
|
2079
2217
|
}
|
|
@@ -2090,7 +2228,7 @@ function sitsOnWarmChains(file) {
|
|
|
2090
2228
|
return false;
|
|
2091
2229
|
}
|
|
2092
2230
|
const imported = importedFilePathsOf(project, file.getFilePath());
|
|
2093
|
-
return imported.length > 0 && imported.every((
|
|
2231
|
+
return imported.length > 0 && imported.every((path12) => warmed.has(path12));
|
|
2094
2232
|
}
|
|
2095
2233
|
function markWarmed(file) {
|
|
2096
2234
|
warmedFiles.set(file, true);
|
|
@@ -2128,7 +2266,7 @@ function reExportShapeOf(file, reach) {
|
|
|
2128
2266
|
for (const assignment of file.getExportAssignments()) {
|
|
2129
2267
|
exportNodes.push(assignment);
|
|
2130
2268
|
const expression = assignment.getExpression();
|
|
2131
|
-
if (
|
|
2269
|
+
if (import_ts_morph11.Node.isIdentifier(expression)) {
|
|
2132
2270
|
localNames.add(expression.getText());
|
|
2133
2271
|
}
|
|
2134
2272
|
}
|
|
@@ -2204,38 +2342,6 @@ function reportUnreadableExports(file) {
|
|
|
2204
2342
|
);
|
|
2205
2343
|
}
|
|
2206
2344
|
|
|
2207
|
-
// src/walk/descent.ts
|
|
2208
|
-
var import_ts_morph11 = require("ts-morph");
|
|
2209
|
-
var NO_BARRIERS = /* @__PURE__ */ new Set();
|
|
2210
|
-
function isDescentStop(node, func, barriers = NO_BARRIERS) {
|
|
2211
|
-
if (node === func) {
|
|
2212
|
-
return false;
|
|
2213
|
-
}
|
|
2214
|
-
if (import_ts_morph11.Node.isFunctionDeclaration(node) || import_ts_morph11.Node.isMethodDeclaration(node)) {
|
|
2215
|
-
return true;
|
|
2216
|
-
}
|
|
2217
|
-
if (import_ts_morph11.Node.isArrowFunction(node) || import_ts_morph11.Node.isFunctionExpression(node)) {
|
|
2218
|
-
return barriers.has(node);
|
|
2219
|
-
}
|
|
2220
|
-
return false;
|
|
2221
|
-
}
|
|
2222
|
-
function isModuleScopeStop(node) {
|
|
2223
|
-
return import_ts_morph11.Node.isFunctionDeclaration(node) || import_ts_morph11.Node.isMethodDeclaration(node) || import_ts_morph11.Node.isArrowFunction(node) || import_ts_morph11.Node.isFunctionExpression(node) || import_ts_morph11.Node.isClassDeclaration(node) || import_ts_morph11.Node.isClassExpression(node);
|
|
2224
|
-
}
|
|
2225
|
-
function crossesNestedFunctionScope(node, func) {
|
|
2226
|
-
let current2 = node;
|
|
2227
|
-
while (current2 !== void 0 && current2 !== func) {
|
|
2228
|
-
if (startsItsOwnScope(current2)) {
|
|
2229
|
-
return true;
|
|
2230
|
-
}
|
|
2231
|
-
current2 = current2.getParent();
|
|
2232
|
-
}
|
|
2233
|
-
return false;
|
|
2234
|
-
}
|
|
2235
|
-
function startsItsOwnScope(node) {
|
|
2236
|
-
return import_ts_morph11.Node.isArrowFunction(node) || import_ts_morph11.Node.isFunctionExpression(node) || import_ts_morph11.Node.isFunctionDeclaration(node) || import_ts_morph11.Node.isMethodDeclaration(node) || import_ts_morph11.Node.isGetAccessorDeclaration(node) || import_ts_morph11.Node.isSetAccessorDeclaration(node) || import_ts_morph11.Node.isConstructorDeclaration(node);
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
2345
|
// src/resolve/invocationEffects.ts
|
|
2240
2346
|
function isImportedFrom(identifier, expectedModule) {
|
|
2241
2347
|
if (!import_ts_morph12.Node.isIdentifier(identifier)) {
|
|
@@ -2255,14 +2361,38 @@ function isImportedFrom(identifier, expectedModule) {
|
|
|
2255
2361
|
(decl) => decl.getSourceFile().getFilePath().includes(`/node_modules/${expectedModule}/`)
|
|
2256
2362
|
);
|
|
2257
2363
|
}
|
|
2258
|
-
function methodDeclaredIn(callee, expectedModule) {
|
|
2364
|
+
function methodDeclaredIn(callee, expectedModule, resolve2) {
|
|
2259
2365
|
if (!import_ts_morph12.Node.isPropertyAccessExpression(callee)) {
|
|
2260
2366
|
return false;
|
|
2261
2367
|
}
|
|
2262
2368
|
const declarations = callee.getNameNode().getSymbol()?.getDeclarations();
|
|
2263
|
-
|
|
2369
|
+
if (declarations !== void 0 && declarations.some(
|
|
2264
2370
|
(declaration) => declaration.getSourceFile().getFilePath().includes(`/node_modules/${expectedModule}/`)
|
|
2265
|
-
)
|
|
2371
|
+
)) {
|
|
2372
|
+
return true;
|
|
2373
|
+
}
|
|
2374
|
+
if (resolve2 === void 0) {
|
|
2375
|
+
return false;
|
|
2376
|
+
}
|
|
2377
|
+
const written = resolve2(callee.getExpression());
|
|
2378
|
+
const made = maker(written);
|
|
2379
|
+
return made !== null && isImportedFrom(rootIdentifier(made), expectedModule);
|
|
2380
|
+
}
|
|
2381
|
+
function maker(written) {
|
|
2382
|
+
if (written === null) {
|
|
2383
|
+
return null;
|
|
2384
|
+
}
|
|
2385
|
+
if (import_ts_morph12.Node.isNewExpression(written) || import_ts_morph12.Node.isCallExpression(written)) {
|
|
2386
|
+
return written.getExpression();
|
|
2387
|
+
}
|
|
2388
|
+
return null;
|
|
2389
|
+
}
|
|
2390
|
+
function rootIdentifier(expression) {
|
|
2391
|
+
let root = expression;
|
|
2392
|
+
while (import_ts_morph12.Node.isPropertyAccessExpression(root)) {
|
|
2393
|
+
root = root.getExpression();
|
|
2394
|
+
}
|
|
2395
|
+
return root;
|
|
2266
2396
|
}
|
|
2267
2397
|
function importSpecifierMatches(decl, expectedModule) {
|
|
2268
2398
|
if (import_ts_morph12.Node.isImportSpecifier(decl)) {
|
|
@@ -2342,6 +2472,26 @@ function extractInvocationEffects(func, barriers = NO_BARRIERS) {
|
|
|
2342
2472
|
}
|
|
2343
2473
|
return;
|
|
2344
2474
|
}
|
|
2475
|
+
if (import_ts_morph12.Node.isReturnStatement(node)) {
|
|
2476
|
+
const returned = node.getExpression();
|
|
2477
|
+
const { call, async } = returned === void 0 ? { call: null, async: false } : unwrapCall(returned);
|
|
2478
|
+
if (call !== null) {
|
|
2479
|
+
const preconditions = collectPreconditions(node, func);
|
|
2480
|
+
results.push({
|
|
2481
|
+
effect: {
|
|
2482
|
+
type: "invocation",
|
|
2483
|
+
callee: call.getExpression().getText(),
|
|
2484
|
+
args: extractArgs(call),
|
|
2485
|
+
async,
|
|
2486
|
+
...preconditions.length > 0 ? { preconditions } : {}
|
|
2487
|
+
},
|
|
2488
|
+
line: startLineOf(node),
|
|
2489
|
+
neverTerminal: false,
|
|
2490
|
+
node: call
|
|
2491
|
+
});
|
|
2492
|
+
}
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2345
2495
|
if (import_ts_morph12.Node.isCallExpression(node)) {
|
|
2346
2496
|
const parent = node.getParent();
|
|
2347
2497
|
if (parent === void 0) {
|
|
@@ -4940,7 +5090,8 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
4940
5090
|
];
|
|
4941
5091
|
const { byTerminal } = computePathConditions(
|
|
4942
5092
|
func,
|
|
4943
|
-
terminals.map(({ node }) => node)
|
|
5093
|
+
terminals.map(({ node }) => node),
|
|
5094
|
+
barriers
|
|
4944
5095
|
);
|
|
4945
5096
|
const wantsFallthrough = terminalPatterns.some(
|
|
4946
5097
|
(p) => p.match.type === "functionFallthrough"
|
|
@@ -4952,7 +5103,11 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
4952
5103
|
if (!hasDefaultTerminal) {
|
|
4953
5104
|
const synthetic = makeFallthroughTerminal(func);
|
|
4954
5105
|
terminals.push(synthetic);
|
|
4955
|
-
const pathResult = computePathConditions(
|
|
5106
|
+
const pathResult = computePathConditions(
|
|
5107
|
+
func,
|
|
5108
|
+
[synthetic.node],
|
|
5109
|
+
barriers
|
|
5110
|
+
);
|
|
4956
5111
|
byTerminal.set(
|
|
4957
5112
|
synthetic.node,
|
|
4958
5113
|
pathResult.fallthrough.length > 0 ? pathResult.fallthrough : [[]]
|
|
@@ -4998,7 +5153,10 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
4998
5153
|
const terminalLines = new Set(
|
|
4999
5154
|
distinctBranches.map((b) => b.terminal.location.start)
|
|
5000
5155
|
);
|
|
5001
|
-
|
|
5156
|
+
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
5157
|
+
defaultBranch.effects = invocations.filter(
|
|
5158
|
+
(i) => i.node !== void 0 ? !terminalNodes.has(i.node) : i.neverTerminal || !terminalLines.has(i.line)
|
|
5159
|
+
).map((i) => i.effect);
|
|
5002
5160
|
}
|
|
5003
5161
|
}
|
|
5004
5162
|
if (recognized.length > 0) {
|
|
@@ -5043,9 +5201,9 @@ function createSourceFileLookup(project) {
|
|
|
5043
5201
|
if (sf === null) {
|
|
5044
5202
|
return null;
|
|
5045
5203
|
}
|
|
5046
|
-
const
|
|
5047
|
-
const index = functionsByFile.get(
|
|
5048
|
-
functionsByFile.set(
|
|
5204
|
+
const path12 = sf.getFilePath();
|
|
5205
|
+
const index = functionsByFile.get(path12) ?? indexFunctions(sf);
|
|
5206
|
+
functionsByFile.set(path12, index);
|
|
5049
5207
|
return index.get(rangeKey(location.range)) ?? null;
|
|
5050
5208
|
}
|
|
5051
5209
|
};
|
|
@@ -5083,7 +5241,7 @@ function indexFunctions(sf) {
|
|
|
5083
5241
|
var import_node_crypto2 = require("crypto");
|
|
5084
5242
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
5085
5243
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
5086
|
-
var SCHEMA_VERSION = "
|
|
5244
|
+
var SCHEMA_VERSION = "6";
|
|
5087
5245
|
var MAX_ENTRIES = 2;
|
|
5088
5246
|
var ENTRY_PREFIX = "key-";
|
|
5089
5247
|
var ENTRY_DIR_NAME = new RegExp(`^${ENTRY_PREFIX}[0-9a-f]{16}$`);
|
|
@@ -5095,6 +5253,7 @@ function createCacheLayer(cacheDir) {
|
|
|
5095
5253
|
kind: "miss",
|
|
5096
5254
|
diagnostic: { kind: "miss", missReason: "no-manifest" }
|
|
5097
5255
|
}),
|
|
5256
|
+
plan: async () => null,
|
|
5098
5257
|
write: async () => {
|
|
5099
5258
|
}
|
|
5100
5259
|
};
|
|
@@ -5125,17 +5284,32 @@ function createCacheLayer(cacheDir) {
|
|
|
5125
5284
|
diagnostic: { kind: "hit" }
|
|
5126
5285
|
};
|
|
5127
5286
|
},
|
|
5128
|
-
async
|
|
5287
|
+
async plan(input) {
|
|
5288
|
+
const entryDir = entryDirFor(cacheDir, input);
|
|
5289
|
+
const manifest = await readManifest(import_node_path2.default.join(entryDir, "manifest.json"));
|
|
5290
|
+
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0 || manifest.owners === void 0) {
|
|
5291
|
+
return null;
|
|
5292
|
+
}
|
|
5293
|
+
const currentTsconfigStamp = await stampTsconfig(input.tsconfigPath);
|
|
5294
|
+
if (!fileStampEquals(manifest.tsconfigStamp, currentTsconfigStamp)) {
|
|
5295
|
+
return null;
|
|
5296
|
+
}
|
|
5297
|
+
await markUsed(entryDir);
|
|
5298
|
+
return buildPlan(manifest, await resolveFileStamps(input));
|
|
5299
|
+
},
|
|
5300
|
+
async write(input, summaries, attribution) {
|
|
5301
|
+
const entryDir = entryDirFor(cacheDir, input);
|
|
5302
|
+
const previous = await readManifest(import_node_path2.default.join(entryDir, "manifest.json"));
|
|
5129
5303
|
const tsconfigStamp = await stampTsconfig(input.tsconfigPath);
|
|
5130
|
-
const files = await resolveFileStamps(input);
|
|
5304
|
+
const files = await hashStamps(await resolveFileStamps(input), previous);
|
|
5131
5305
|
const manifest = {
|
|
5132
5306
|
schemaVersion: SCHEMA_VERSION,
|
|
5133
5307
|
adapterPacksDigest: input.adapterPacksDigest,
|
|
5134
5308
|
tsconfigStamp,
|
|
5135
5309
|
files,
|
|
5136
|
-
summaries
|
|
5310
|
+
summaries,
|
|
5311
|
+
...attribution === void 0 ? {} : encodeAttribution(attribution)
|
|
5137
5312
|
};
|
|
5138
|
-
const entryDir = entryDirFor(cacheDir, input);
|
|
5139
5313
|
await import_promises2.default.mkdir(entryDir, { recursive: true });
|
|
5140
5314
|
await import_promises2.default.writeFile(
|
|
5141
5315
|
import_node_path2.default.join(entryDir, "manifest.json"),
|
|
@@ -5145,6 +5319,163 @@ function createCacheLayer(cacheDir) {
|
|
|
5145
5319
|
}
|
|
5146
5320
|
};
|
|
5147
5321
|
}
|
|
5322
|
+
async function buildPlan(manifest, currentStamps) {
|
|
5323
|
+
const stored = new Map(manifest.files.map((f) => [f.path, f]));
|
|
5324
|
+
const current2 = new Map(currentStamps.map((f) => [f.path, f]));
|
|
5325
|
+
const changed = /* @__PURE__ */ new Set();
|
|
5326
|
+
const removed = /* @__PURE__ */ new Set();
|
|
5327
|
+
for (const p of stored.keys()) {
|
|
5328
|
+
if (!current2.has(p)) {
|
|
5329
|
+
removed.add(p);
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5332
|
+
const toVerify = [];
|
|
5333
|
+
for (const [p, stamp] of current2) {
|
|
5334
|
+
const before = stored.get(p);
|
|
5335
|
+
if (before === void 0) {
|
|
5336
|
+
changed.add(p);
|
|
5337
|
+
} else if (!fileStampEquals(before, stamp)) {
|
|
5338
|
+
if (before.contentHash === void 0) {
|
|
5339
|
+
changed.add(p);
|
|
5340
|
+
} else {
|
|
5341
|
+
toVerify.push(p);
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
await Promise.all(
|
|
5346
|
+
toVerify.map(async (p) => {
|
|
5347
|
+
const hash = await hashFile(p);
|
|
5348
|
+
if (hash === null || hash !== stored.get(p)?.contentHash) {
|
|
5349
|
+
changed.add(p);
|
|
5350
|
+
}
|
|
5351
|
+
})
|
|
5352
|
+
);
|
|
5353
|
+
const roots = /* @__PURE__ */ new Map();
|
|
5354
|
+
const rootNames = manifest.roots ?? [];
|
|
5355
|
+
const depPaths = manifest.depPaths ?? [];
|
|
5356
|
+
let rootsDeclined = 0;
|
|
5357
|
+
rootNames.forEach((rootPath, i) => {
|
|
5358
|
+
const meta = manifest.rootMeta?.[i];
|
|
5359
|
+
if (meta === void 0) {
|
|
5360
|
+
return;
|
|
5361
|
+
}
|
|
5362
|
+
if (!meta.cacheable) {
|
|
5363
|
+
rootsDeclined += 1;
|
|
5364
|
+
}
|
|
5365
|
+
roots.set(rootPath, {
|
|
5366
|
+
path: rootPath,
|
|
5367
|
+
cacheable: meta.cacheable,
|
|
5368
|
+
deps: meta.deps.flatMap((d) => {
|
|
5369
|
+
const p = depPaths[d];
|
|
5370
|
+
return p === void 0 ? [] : [p];
|
|
5371
|
+
}),
|
|
5372
|
+
claims: meta.claims,
|
|
5373
|
+
mountPrefixes: meta.mountPrefixes,
|
|
5374
|
+
packs: meta.packs
|
|
5375
|
+
});
|
|
5376
|
+
});
|
|
5377
|
+
const validRoots = /* @__PURE__ */ new Set();
|
|
5378
|
+
for (const [rootPath, record] of roots) {
|
|
5379
|
+
if (!record.cacheable || !current2.has(rootPath)) {
|
|
5380
|
+
continue;
|
|
5381
|
+
}
|
|
5382
|
+
if (changed.has(rootPath)) {
|
|
5383
|
+
continue;
|
|
5384
|
+
}
|
|
5385
|
+
const depMoved = record.deps.some((d) => changed.has(d) || removed.has(d));
|
|
5386
|
+
if (!depMoved) {
|
|
5387
|
+
validRoots.add(rootPath);
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
const owners = manifest.owners ?? [];
|
|
5391
|
+
return {
|
|
5392
|
+
changed,
|
|
5393
|
+
removed,
|
|
5394
|
+
roots,
|
|
5395
|
+
validRoots,
|
|
5396
|
+
rootsDeclined,
|
|
5397
|
+
reuse(valid) {
|
|
5398
|
+
const summaries = [];
|
|
5399
|
+
const reusedOwners = [];
|
|
5400
|
+
manifest.summaries.forEach((summary, i) => {
|
|
5401
|
+
const ownerPaths = (owners[i] ?? []).flatMap((o) => {
|
|
5402
|
+
const p = rootNames[o];
|
|
5403
|
+
return p === void 0 ? [] : [p];
|
|
5404
|
+
});
|
|
5405
|
+
if (ownerPaths.some((p) => valid.has(p))) {
|
|
5406
|
+
summaries.push(summary);
|
|
5407
|
+
reusedOwners.push(ownerPaths.filter((p) => valid.has(p)));
|
|
5408
|
+
}
|
|
5409
|
+
});
|
|
5410
|
+
return { summaries, owners: reusedOwners };
|
|
5411
|
+
},
|
|
5412
|
+
allSummaries() {
|
|
5413
|
+
return manifest.summaries;
|
|
5414
|
+
},
|
|
5415
|
+
attribution() {
|
|
5416
|
+
return {
|
|
5417
|
+
roots: [...roots.values()],
|
|
5418
|
+
owners: owners.map(
|
|
5419
|
+
(ownerIds) => ownerIds.flatMap((o) => {
|
|
5420
|
+
const p = rootNames[o];
|
|
5421
|
+
return p === void 0 ? [] : [p];
|
|
5422
|
+
})
|
|
5423
|
+
)
|
|
5424
|
+
};
|
|
5425
|
+
}
|
|
5426
|
+
};
|
|
5427
|
+
}
|
|
5428
|
+
function encodeAttribution(attribution) {
|
|
5429
|
+
const roots = attribution.roots.map((r) => r.path);
|
|
5430
|
+
const rootIndex = new Map(roots.map((p, i) => [p, i]));
|
|
5431
|
+
const depIndex = /* @__PURE__ */ new Map();
|
|
5432
|
+
const depPaths = [];
|
|
5433
|
+
const depIdOf = (p) => {
|
|
5434
|
+
const existing = depIndex.get(p);
|
|
5435
|
+
if (existing !== void 0) {
|
|
5436
|
+
return existing;
|
|
5437
|
+
}
|
|
5438
|
+
const id = depPaths.length;
|
|
5439
|
+
depPaths.push(p);
|
|
5440
|
+
depIndex.set(p, id);
|
|
5441
|
+
return id;
|
|
5442
|
+
};
|
|
5443
|
+
const rootMeta = attribution.roots.map((r) => ({
|
|
5444
|
+
cacheable: r.cacheable,
|
|
5445
|
+
deps: r.deps.map(depIdOf),
|
|
5446
|
+
claims: r.claims,
|
|
5447
|
+
mountPrefixes: r.mountPrefixes,
|
|
5448
|
+
packs: r.packs
|
|
5449
|
+
}));
|
|
5450
|
+
const owners = attribution.owners.map(
|
|
5451
|
+
(ownerPaths) => ownerPaths.flatMap((p) => {
|
|
5452
|
+
const i = rootIndex.get(p);
|
|
5453
|
+
return i === void 0 ? [] : [i];
|
|
5454
|
+
})
|
|
5455
|
+
);
|
|
5456
|
+
return { roots, rootMeta, depPaths, owners };
|
|
5457
|
+
}
|
|
5458
|
+
async function hashStamps(stamps, previous) {
|
|
5459
|
+
const before = new Map((previous?.files ?? []).map((f) => [f.path, f]));
|
|
5460
|
+
return Promise.all(
|
|
5461
|
+
stamps.map(async (stamp) => {
|
|
5462
|
+
const prior = before.get(stamp.path);
|
|
5463
|
+
if (prior !== void 0 && prior.contentHash !== void 0 && fileStampEquals(prior, stamp)) {
|
|
5464
|
+
return { ...stamp, contentHash: prior.contentHash };
|
|
5465
|
+
}
|
|
5466
|
+
const contentHash = await hashFile(stamp.path);
|
|
5467
|
+
return contentHash === null ? stamp : { ...stamp, contentHash };
|
|
5468
|
+
})
|
|
5469
|
+
);
|
|
5470
|
+
}
|
|
5471
|
+
async function hashFile(filePath) {
|
|
5472
|
+
try {
|
|
5473
|
+
const content = await import_promises2.default.readFile(filePath);
|
|
5474
|
+
return (0, import_node_crypto2.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
5475
|
+
} catch {
|
|
5476
|
+
return null;
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5148
5479
|
async function describeAbsentEntry(cacheDir) {
|
|
5149
5480
|
try {
|
|
5150
5481
|
const entries = await import_promises2.default.readdir(cacheDir, { withFileTypes: true });
|
|
@@ -5158,7 +5489,7 @@ function entryDirFor(cacheDir, input) {
|
|
|
5158
5489
|
SCHEMA_VERSION,
|
|
5159
5490
|
input.adapterPacksDigest,
|
|
5160
5491
|
input.tsconfigPath ?? ""
|
|
5161
|
-
].join("
|
|
5492
|
+
].join(" ");
|
|
5162
5493
|
const name = (0, import_node_crypto2.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
5163
5494
|
return import_node_path2.default.join(cacheDir, `${ENTRY_PREFIX}${name}`);
|
|
5164
5495
|
}
|
|
@@ -5399,7 +5730,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
5399
5730
|
}
|
|
5400
5731
|
const responses = [];
|
|
5401
5732
|
let method;
|
|
5402
|
-
let
|
|
5733
|
+
let path12;
|
|
5403
5734
|
for (const prop of endpointNode.getProperties()) {
|
|
5404
5735
|
if (!import_ts_morph25.Node.isPropertyAssignment(prop)) {
|
|
5405
5736
|
continue;
|
|
@@ -5414,7 +5745,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
5414
5745
|
if (propName === pattern.pathProperty) {
|
|
5415
5746
|
const val = prop.getInitializer();
|
|
5416
5747
|
if (val !== void 0 && import_ts_morph25.Node.isStringLiteral(val)) {
|
|
5417
|
-
|
|
5748
|
+
path12 = val.getLiteralValue();
|
|
5418
5749
|
}
|
|
5419
5750
|
}
|
|
5420
5751
|
if (propName === pattern.responseExtraction.property) {
|
|
@@ -5438,10 +5769,10 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
5438
5769
|
if (responses.length === 0) {
|
|
5439
5770
|
return null;
|
|
5440
5771
|
}
|
|
5441
|
-
const boundaryBinding = method !== void 0 ||
|
|
5772
|
+
const boundaryBinding = method !== void 0 || path12 !== void 0 ? (0, import_behavioral_ir.restBinding)({
|
|
5442
5773
|
transport: "http",
|
|
5443
5774
|
method: method ?? null,
|
|
5444
|
-
path:
|
|
5775
|
+
path: path12 ?? null,
|
|
5445
5776
|
recognition: framework
|
|
5446
5777
|
}) : null;
|
|
5447
5778
|
return {
|
|
@@ -6025,6 +6356,13 @@ function literalIndexOf(index) {
|
|
|
6025
6356
|
}
|
|
6026
6357
|
return null;
|
|
6027
6358
|
}
|
|
6359
|
+
function asFallbackExpression(expression) {
|
|
6360
|
+
if (!import_ts_morph28.Node.isBinaryExpression(expression)) {
|
|
6361
|
+
return null;
|
|
6362
|
+
}
|
|
6363
|
+
const operator = expression.getOperatorToken().getKind();
|
|
6364
|
+
return operator === import_ts_morph28.SyntaxKind.BarBarToken || operator === import_ts_morph28.SyntaxKind.QuestionQuestionToken ? expression : null;
|
|
6365
|
+
}
|
|
6028
6366
|
function unwrapExpression(expression) {
|
|
6029
6367
|
let current2 = expression;
|
|
6030
6368
|
for (; ; ) {
|
|
@@ -6136,6 +6474,12 @@ function emitValue(db, table, value) {
|
|
|
6136
6474
|
}
|
|
6137
6475
|
return id;
|
|
6138
6476
|
}
|
|
6477
|
+
const fallback = asFallbackExpression(expression);
|
|
6478
|
+
if (fallback !== null) {
|
|
6479
|
+
fact(db, "fallbackBranch", id, emitValue(db, table, fallback.getLeft()));
|
|
6480
|
+
fact(db, "fallbackBranch", id, emitValue(db, table, fallback.getRight()));
|
|
6481
|
+
return id;
|
|
6482
|
+
}
|
|
6139
6483
|
if (import_ts_morph28.Node.isCallExpression(expression) || import_ts_morph28.Node.isNewExpression(expression)) {
|
|
6140
6484
|
emitCallFacts(db, table, expression);
|
|
6141
6485
|
fact(db, "writtenValue", id);
|
|
@@ -6600,24 +6944,27 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
6600
6944
|
const sole = soleGraphqlClientRef(
|
|
6601
6945
|
collectGraphqlClientRefs(sourceFiles, packs, resolution)
|
|
6602
6946
|
);
|
|
6603
|
-
if (sole === null && scopes.length === 0) {
|
|
6604
|
-
return;
|
|
6605
|
-
}
|
|
6606
6947
|
const workspace = sole !== null ? boundWorkspaceFor(sole, packs) : null;
|
|
6607
6948
|
const soleClient = sole !== null ? workspace !== null ? { ...sole, workspace } : sole : null;
|
|
6949
|
+
let registry = null;
|
|
6608
6950
|
for (const summary of summaries) {
|
|
6609
6951
|
if (!(0, import_behavioral_ir3.isGraphqlOperationBinding)(summary.identity.boundaryBinding)) {
|
|
6610
6952
|
continue;
|
|
6611
6953
|
}
|
|
6954
|
+
const existing = (0, import_behavioral_ir3.readGraphqlMetadata)(summary) ?? {};
|
|
6612
6955
|
const scoped = scopedWorkspaceFor(summary.location.file, scopes);
|
|
6613
6956
|
const client = scoped !== null ? { uri: null, uriRef: null, workspace: scoped } : soleClient;
|
|
6614
|
-
|
|
6957
|
+
const dangling = (existing.unresolvedFragments?.length ?? 0) > 0;
|
|
6958
|
+
if (client === null && !dangling) {
|
|
6615
6959
|
continue;
|
|
6616
6960
|
}
|
|
6617
|
-
|
|
6961
|
+
if (dangling && registry === null) {
|
|
6962
|
+
registry = fragmentRegistryStatus(sourceFiles, packs);
|
|
6963
|
+
}
|
|
6618
6964
|
summary.metadata = (0, import_behavioral_ir3.withGraphqlMetadata)(summary.metadata, {
|
|
6619
6965
|
...existing,
|
|
6620
|
-
client
|
|
6966
|
+
...client !== null ? { client } : {},
|
|
6967
|
+
...dangling && registry !== null ? { fragmentRegistry: registry } : {}
|
|
6621
6968
|
});
|
|
6622
6969
|
}
|
|
6623
6970
|
}
|
|
@@ -6683,48 +7030,198 @@ function soleGraphqlClientRef(refs) {
|
|
|
6683
7030
|
}
|
|
6684
7031
|
return [...distinct.values()][0] ?? null;
|
|
6685
7032
|
}
|
|
6686
|
-
function
|
|
6687
|
-
const
|
|
6688
|
-
for (const
|
|
6689
|
-
const
|
|
6690
|
-
|
|
6691
|
-
|
|
7033
|
+
function fragmentRegistryStatus(sourceFiles, packs) {
|
|
7034
|
+
const statuses = [];
|
|
7035
|
+
for (const spec of packs.flatMap((pack) => pack.graphqlClients ?? [])) {
|
|
7036
|
+
const registrySpec = spec.fragmentRegistry;
|
|
7037
|
+
if (registrySpec === void 0) {
|
|
7038
|
+
continue;
|
|
7039
|
+
}
|
|
7040
|
+
for (const sourceFile of sourceFiles) {
|
|
7041
|
+
const local = localImportName(
|
|
7042
|
+
sourceFile,
|
|
7043
|
+
spec.importModule,
|
|
7044
|
+
spec.importName
|
|
7045
|
+
);
|
|
7046
|
+
if (local === null) {
|
|
6692
7047
|
continue;
|
|
6693
7048
|
}
|
|
6694
|
-
|
|
6695
|
-
if (
|
|
6696
|
-
|
|
7049
|
+
sourceFile.forEachDescendant((node) => {
|
|
7050
|
+
if (isConstructionNamed(node, local)) {
|
|
7051
|
+
statuses.push(constructionRegistryStatus(node, registrySpec));
|
|
6697
7052
|
}
|
|
6698
|
-
|
|
6699
|
-
names.set(local, spec.uriProperty);
|
|
6700
|
-
}
|
|
7053
|
+
});
|
|
6701
7054
|
}
|
|
6702
7055
|
}
|
|
6703
|
-
return
|
|
7056
|
+
return combineRegistryStatuses(statuses);
|
|
6704
7057
|
}
|
|
6705
|
-
function
|
|
6706
|
-
if (
|
|
6707
|
-
return
|
|
7058
|
+
function combineRegistryStatuses(statuses) {
|
|
7059
|
+
if (statuses.includes("configured")) {
|
|
7060
|
+
return "configured";
|
|
6708
7061
|
}
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
return null;
|
|
7062
|
+
if (statuses.length === 0 || statuses.includes("unknown")) {
|
|
7063
|
+
return "unknown";
|
|
6712
7064
|
}
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
7065
|
+
return "absent";
|
|
7066
|
+
}
|
|
7067
|
+
function constructionRegistryStatus(construction, spec) {
|
|
7068
|
+
const options = firstArgumentObjectLiteral(construction);
|
|
7069
|
+
if (options === null) {
|
|
7070
|
+
return "unknown";
|
|
6716
7071
|
}
|
|
6717
|
-
const
|
|
6718
|
-
if (
|
|
6719
|
-
return
|
|
7072
|
+
const cacheExpr = propertyValueOf2(options, spec.cacheProperty);
|
|
7073
|
+
if (cacheExpr === null) {
|
|
7074
|
+
return "unknown";
|
|
6720
7075
|
}
|
|
6721
|
-
const
|
|
6722
|
-
|
|
6723
|
-
|
|
7076
|
+
const cacheConstruction = resolveToConstructionOf(
|
|
7077
|
+
cacheExpr,
|
|
7078
|
+
spec.cacheConstructor
|
|
7079
|
+
);
|
|
7080
|
+
if (cacheConstruction === null) {
|
|
7081
|
+
return "unknown";
|
|
6724
7082
|
}
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
7083
|
+
if (!import_ts_morph30.Node.isNewExpression(cacheConstruction) && !import_ts_morph30.Node.isCallExpression(cacheConstruction)) {
|
|
7084
|
+
return "unknown";
|
|
7085
|
+
}
|
|
7086
|
+
const args = cacheConstruction.getArguments();
|
|
7087
|
+
if (args.length === 0) {
|
|
7088
|
+
return "absent";
|
|
7089
|
+
}
|
|
7090
|
+
const cacheOptions = firstArgumentObjectLiteral(cacheConstruction);
|
|
7091
|
+
if (cacheOptions === null) {
|
|
7092
|
+
return "unknown";
|
|
7093
|
+
}
|
|
7094
|
+
if (cacheOptions.getProperty(spec.registryProperty) !== void 0) {
|
|
7095
|
+
return "configured";
|
|
7096
|
+
}
|
|
7097
|
+
const hasSpread = cacheOptions.getProperties().some((property) => import_ts_morph30.Node.isSpreadAssignment(property));
|
|
7098
|
+
return hasSpread ? "unknown" : "absent";
|
|
7099
|
+
}
|
|
7100
|
+
function firstArgumentObjectLiteral(construction) {
|
|
7101
|
+
if (!import_ts_morph30.Node.isNewExpression(construction) && !import_ts_morph30.Node.isCallExpression(construction)) {
|
|
7102
|
+
return null;
|
|
7103
|
+
}
|
|
7104
|
+
const arg = construction.getArguments()[0];
|
|
7105
|
+
if (arg === void 0 || !import_ts_morph30.Node.isObjectLiteralExpression(arg)) {
|
|
7106
|
+
return null;
|
|
7107
|
+
}
|
|
7108
|
+
return arg;
|
|
7109
|
+
}
|
|
7110
|
+
function propertyValueOf2(options, name) {
|
|
7111
|
+
const property = options.getProperty(name);
|
|
7112
|
+
if (property === void 0) {
|
|
7113
|
+
return null;
|
|
7114
|
+
}
|
|
7115
|
+
if (import_ts_morph30.Node.isPropertyAssignment(property)) {
|
|
7116
|
+
return property.getInitializer() ?? null;
|
|
7117
|
+
}
|
|
7118
|
+
if (import_ts_morph30.Node.isShorthandPropertyAssignment(property)) {
|
|
7119
|
+
const symbol = property.getProject().getTypeChecker().getShorthandAssignmentValueSymbol(property);
|
|
7120
|
+
return symbol?.getValueDeclaration() ?? null;
|
|
7121
|
+
}
|
|
7122
|
+
return null;
|
|
7123
|
+
}
|
|
7124
|
+
function resolveToConstructionOf(expression, cacheClass) {
|
|
7125
|
+
let current2 = expression;
|
|
7126
|
+
for (let hop = 0; hop < 4 && current2 !== void 0; hop += 1) {
|
|
7127
|
+
current2 = unwrapExpression2(current2);
|
|
7128
|
+
if (import_ts_morph30.Node.isVariableDeclaration(current2)) {
|
|
7129
|
+
current2 = current2.getInitializer();
|
|
7130
|
+
continue;
|
|
7131
|
+
}
|
|
7132
|
+
if (import_ts_morph30.Node.isNewExpression(current2) || import_ts_morph30.Node.isCallExpression(current2)) {
|
|
7133
|
+
const callee = current2.getExpression();
|
|
7134
|
+
if (callee === void 0 || !import_ts_morph30.Node.isIdentifier(callee)) {
|
|
7135
|
+
return null;
|
|
7136
|
+
}
|
|
7137
|
+
const local = localImportName(
|
|
7138
|
+
current2.getSourceFile(),
|
|
7139
|
+
cacheClass.importModule,
|
|
7140
|
+
cacheClass.importName
|
|
7141
|
+
);
|
|
7142
|
+
return local !== null && callee.getText() === local ? current2 : null;
|
|
7143
|
+
}
|
|
7144
|
+
if (!import_ts_morph30.Node.isIdentifier(current2)) {
|
|
7145
|
+
return null;
|
|
7146
|
+
}
|
|
7147
|
+
const declaration = current2.getSymbol()?.getValueDeclaration();
|
|
7148
|
+
if (declaration === void 0 || !import_ts_morph30.Node.isVariableDeclaration(declaration)) {
|
|
7149
|
+
return null;
|
|
7150
|
+
}
|
|
7151
|
+
current2 = declaration.getInitializer();
|
|
7152
|
+
}
|
|
7153
|
+
return null;
|
|
7154
|
+
}
|
|
7155
|
+
function unwrapExpression2(node) {
|
|
7156
|
+
let current2 = node;
|
|
7157
|
+
while (import_ts_morph30.Node.isParenthesizedExpression(current2) || import_ts_morph30.Node.isAsExpression(current2) || import_ts_morph30.Node.isNonNullExpression(current2)) {
|
|
7158
|
+
current2 = current2.getExpression();
|
|
7159
|
+
}
|
|
7160
|
+
return current2;
|
|
7161
|
+
}
|
|
7162
|
+
function isConstructionNamed(node, localName) {
|
|
7163
|
+
if (!import_ts_morph30.Node.isNewExpression(node) && !import_ts_morph30.Node.isCallExpression(node)) {
|
|
7164
|
+
return false;
|
|
7165
|
+
}
|
|
7166
|
+
const callee = node.getExpression();
|
|
7167
|
+
return callee !== void 0 && import_ts_morph30.Node.isIdentifier(callee) && callee.getText() === localName;
|
|
7168
|
+
}
|
|
7169
|
+
function localImportName(sourceFile, importModule, importName) {
|
|
7170
|
+
for (const importDecl of sourceFile.getImportDeclarations()) {
|
|
7171
|
+
const module2 = importDecl.getModuleSpecifierValue();
|
|
7172
|
+
if (module2 !== importModule && !module2.startsWith(`${importModule}/`)) {
|
|
7173
|
+
continue;
|
|
7174
|
+
}
|
|
7175
|
+
for (const named2 of importDecl.getNamedImports()) {
|
|
7176
|
+
if (named2.getName() === importName) {
|
|
7177
|
+
return named2.getAliasNode()?.getText() ?? named2.getName();
|
|
7178
|
+
}
|
|
7179
|
+
}
|
|
7180
|
+
}
|
|
7181
|
+
return null;
|
|
7182
|
+
}
|
|
7183
|
+
function localNamesFor(sourceFile, specs) {
|
|
7184
|
+
const names = /* @__PURE__ */ new Map();
|
|
7185
|
+
for (const importDecl of sourceFile.getImportDeclarations()) {
|
|
7186
|
+
const module2 = importDecl.getModuleSpecifierValue();
|
|
7187
|
+
for (const spec of specs) {
|
|
7188
|
+
if (module2 !== spec.importModule) {
|
|
7189
|
+
continue;
|
|
7190
|
+
}
|
|
7191
|
+
for (const named2 of importDecl.getNamedImports()) {
|
|
7192
|
+
if (named2.getName() !== spec.importName) {
|
|
7193
|
+
continue;
|
|
7194
|
+
}
|
|
7195
|
+
const local = named2.getAliasNode()?.getText() ?? named2.getName();
|
|
7196
|
+
names.set(local, spec.uriProperty);
|
|
7197
|
+
}
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
7200
|
+
return names;
|
|
7201
|
+
}
|
|
7202
|
+
function constructionRef(node, localNames, resolution) {
|
|
7203
|
+
if (!import_ts_morph30.Node.isNewExpression(node) && !import_ts_morph30.Node.isCallExpression(node)) {
|
|
7204
|
+
return null;
|
|
7205
|
+
}
|
|
7206
|
+
const callee = node.getExpression();
|
|
7207
|
+
if (callee === void 0 || !import_ts_morph30.Node.isIdentifier(callee)) {
|
|
7208
|
+
return null;
|
|
7209
|
+
}
|
|
7210
|
+
const uriProperty = localNames.get(callee.getText());
|
|
7211
|
+
if (uriProperty === void 0) {
|
|
7212
|
+
return null;
|
|
7213
|
+
}
|
|
7214
|
+
const optionsArg = node.getArguments()[0];
|
|
7215
|
+
if (optionsArg === void 0 || !import_ts_morph30.Node.isObjectLiteralExpression(optionsArg)) {
|
|
7216
|
+
return null;
|
|
7217
|
+
}
|
|
7218
|
+
const property = optionsArg.getProperty(uriProperty);
|
|
7219
|
+
if (property === void 0 || !import_ts_morph30.Node.isPropertyAssignment(property)) {
|
|
7220
|
+
return null;
|
|
7221
|
+
}
|
|
7222
|
+
const value = property.getInitializer();
|
|
7223
|
+
if (value === void 0) {
|
|
7224
|
+
return null;
|
|
6728
7225
|
}
|
|
6729
7226
|
const literal = stringValueOf(value, resolution);
|
|
6730
7227
|
if (literal !== null) {
|
|
@@ -7010,7 +7507,7 @@ function calleeOf(decorator) {
|
|
|
7010
7507
|
|
|
7011
7508
|
// src/discovery/decoratedMethod.ts
|
|
7012
7509
|
function resolverTypeName(args) {
|
|
7013
|
-
return args.
|
|
7510
|
+
return args.typeMap[args.decoratorName] ?? args.classTypeName ?? null;
|
|
7014
7511
|
}
|
|
7015
7512
|
function resolveResolverClassTypeName(decoratorArg) {
|
|
7016
7513
|
if (import_ts_morph34.Node.isArrowFunction(decoratorArg)) {
|
|
@@ -7424,32 +7921,163 @@ function innerTemplateText(template) {
|
|
|
7424
7921
|
}
|
|
7425
7922
|
return raw;
|
|
7426
7923
|
}
|
|
7427
|
-
function
|
|
7428
|
-
|
|
7429
|
-
|
|
7924
|
+
function startAssembly(resolution) {
|
|
7925
|
+
return {
|
|
7926
|
+
resolution,
|
|
7927
|
+
seen: /* @__PURE__ */ new Set(),
|
|
7928
|
+
unresolvedInterpolations: [],
|
|
7929
|
+
unresolvedInsideSelection: false
|
|
7930
|
+
};
|
|
7931
|
+
}
|
|
7932
|
+
function assembledTemplateText(template, assembly) {
|
|
7933
|
+
if (import_ts_morph37.Node.isNoSubstitutionTemplateLiteral(template)) {
|
|
7934
|
+
return innerTemplateText(template);
|
|
7935
|
+
}
|
|
7936
|
+
if (!import_ts_morph37.Node.isTemplateExpression(template)) {
|
|
7937
|
+
return null;
|
|
7938
|
+
}
|
|
7939
|
+
let text = template.getHead().getLiteralText();
|
|
7940
|
+
for (const span of template.getTemplateSpans()) {
|
|
7941
|
+
const spliced = interpolatedDocumentText(span.getExpression(), assembly);
|
|
7942
|
+
if (spliced === null) {
|
|
7943
|
+
assembly.unresolvedInterpolations.push(
|
|
7944
|
+
singleLine(span.getExpression().getText())
|
|
7945
|
+
);
|
|
7946
|
+
if (openBraceDepth(text) > 0) {
|
|
7947
|
+
assembly.unresolvedInsideSelection = true;
|
|
7948
|
+
}
|
|
7949
|
+
} else {
|
|
7950
|
+
text += `
|
|
7951
|
+
${spliced}
|
|
7952
|
+
`;
|
|
7953
|
+
}
|
|
7954
|
+
text += span.getLiteral().getLiteralText();
|
|
7955
|
+
}
|
|
7956
|
+
return text;
|
|
7957
|
+
}
|
|
7958
|
+
function openBraceDepth(text) {
|
|
7959
|
+
let depth = 0;
|
|
7960
|
+
for (const char of text) {
|
|
7961
|
+
if (char === "{") {
|
|
7962
|
+
depth += 1;
|
|
7963
|
+
} else if (char === "}") {
|
|
7964
|
+
depth -= 1;
|
|
7965
|
+
}
|
|
7966
|
+
}
|
|
7967
|
+
return depth;
|
|
7968
|
+
}
|
|
7969
|
+
function interpolatedDocumentText(expr, assembly) {
|
|
7970
|
+
const stripped = stripDocumentNodeCasts(expr);
|
|
7971
|
+
const inline = documentTextFromExpression(stripped, assembly);
|
|
7430
7972
|
if (inline !== null) {
|
|
7431
|
-
return
|
|
7973
|
+
return inline;
|
|
7432
7974
|
}
|
|
7433
|
-
const
|
|
7434
|
-
if (
|
|
7435
|
-
return
|
|
7975
|
+
const named2 = resolveGqlTemplateText(stripped, assembly);
|
|
7976
|
+
if (named2 !== null) {
|
|
7977
|
+
return named2;
|
|
7436
7978
|
}
|
|
7437
7979
|
const objectDoc = resolveTypedDocumentSource(stripped);
|
|
7438
7980
|
if (objectDoc !== null) {
|
|
7439
|
-
return
|
|
7981
|
+
return objectDoc;
|
|
7440
7982
|
}
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7983
|
+
return resolveThroughFacts(stripped, assembly);
|
|
7984
|
+
}
|
|
7985
|
+
function resolveGraphqlDocument(arg, resolution) {
|
|
7986
|
+
const assembly = startAssembly(resolution);
|
|
7987
|
+
const stripped = stripDocumentNodeCasts(arg);
|
|
7988
|
+
const text = documentTextFromExpression(stripped, assembly) ?? resolveGqlTemplateText(stripped, assembly) ?? resolveTypedDocumentSource(stripped) ?? resolveThroughFacts(stripped, assembly);
|
|
7989
|
+
if (text !== null) {
|
|
7990
|
+
return assembledDocumentResolution(text, stripped, assembly);
|
|
7444
7991
|
}
|
|
7445
7992
|
return resolveTypedDocumentHeader(stripped);
|
|
7446
7993
|
}
|
|
7447
|
-
function
|
|
7994
|
+
function assembledDocumentResolution(text, arg, assembly) {
|
|
7995
|
+
const interpolations = assembly.unresolvedInterpolations;
|
|
7996
|
+
if (assembly.unresolvedInsideSelection) {
|
|
7997
|
+
const header = parseGraphqlOperation(text);
|
|
7998
|
+
return {
|
|
7999
|
+
...header !== null ? { operationType: header.operationType } : {},
|
|
8000
|
+
...header?.operationName !== void 0 ? { operationName: header.operationName } : {},
|
|
8001
|
+
unresolved: {
|
|
8002
|
+
reference: singleLine(arg.getText()),
|
|
8003
|
+
reason: `interpolated ${describeInterpolations(interpolations)} inside a selection set did not resolve to a GraphQL document, so what the operation selects is not statically written`
|
|
8004
|
+
}
|
|
8005
|
+
};
|
|
8006
|
+
}
|
|
8007
|
+
const dangling = danglingFragmentSpreads(text);
|
|
8008
|
+
if (dangling === null) {
|
|
8009
|
+
if (interpolations.length === 0) {
|
|
8010
|
+
return { document: text };
|
|
8011
|
+
}
|
|
8012
|
+
return {
|
|
8013
|
+
unresolved: {
|
|
8014
|
+
reference: singleLine(arg.getText()),
|
|
8015
|
+
reason: `the document did not parse after dropping interpolated ${describeInterpolations(interpolations)} that resolved to no GraphQL document`
|
|
8016
|
+
}
|
|
8017
|
+
};
|
|
8018
|
+
}
|
|
8019
|
+
if (dangling.length > 0) {
|
|
8020
|
+
return { document: text, unresolvedFragments: dangling };
|
|
8021
|
+
}
|
|
8022
|
+
if (interpolations.length > 0) {
|
|
8023
|
+
return {
|
|
8024
|
+
document: text,
|
|
8025
|
+
unresolved: {
|
|
8026
|
+
reference: singleLine(arg.getText()),
|
|
8027
|
+
reason: `interpolated ${describeInterpolations(interpolations)} did not resolve to a GraphQL document, so whatever it contributes is not part of the stored document`
|
|
8028
|
+
}
|
|
8029
|
+
};
|
|
8030
|
+
}
|
|
8031
|
+
return { document: text };
|
|
8032
|
+
}
|
|
8033
|
+
function describeInterpolations(interpolations) {
|
|
8034
|
+
const quoted = interpolations.map((text) => `\`${text}\``).join(", ");
|
|
8035
|
+
return interpolations.length === 1 ? `expression ${quoted}` : `expressions ${quoted}`;
|
|
8036
|
+
}
|
|
8037
|
+
function danglingFragmentSpreads(text) {
|
|
8038
|
+
let doc;
|
|
8039
|
+
try {
|
|
8040
|
+
doc = (0, import_graphql.parse)(text);
|
|
8041
|
+
} catch {
|
|
8042
|
+
return null;
|
|
8043
|
+
}
|
|
8044
|
+
const defined = /* @__PURE__ */ new Set();
|
|
8045
|
+
for (const def of doc.definitions) {
|
|
8046
|
+
if (def.kind === import_graphql.Kind.FRAGMENT_DEFINITION) {
|
|
8047
|
+
defined.add(def.name.value);
|
|
8048
|
+
}
|
|
8049
|
+
}
|
|
8050
|
+
const dangling = /* @__PURE__ */ new Set();
|
|
8051
|
+
for (const def of doc.definitions) {
|
|
8052
|
+
if (def.kind === import_graphql.Kind.OPERATION_DEFINITION || def.kind === import_graphql.Kind.FRAGMENT_DEFINITION) {
|
|
8053
|
+
collectDanglingSpreads(def.selectionSet, defined, dangling);
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
return [...dangling].sort();
|
|
8057
|
+
}
|
|
8058
|
+
function collectDanglingSpreads(selectionSet, defined, dangling) {
|
|
8059
|
+
for (const selection of selectionSet.selections) {
|
|
8060
|
+
if (selection.kind === import_graphql.Kind.FRAGMENT_SPREAD) {
|
|
8061
|
+
if (!defined.has(selection.name.value)) {
|
|
8062
|
+
dangling.add(selection.name.value);
|
|
8063
|
+
}
|
|
8064
|
+
continue;
|
|
8065
|
+
}
|
|
8066
|
+
if (selection.selectionSet !== void 0) {
|
|
8067
|
+
collectDanglingSpreads(selection.selectionSet, defined, dangling);
|
|
8068
|
+
}
|
|
8069
|
+
}
|
|
8070
|
+
}
|
|
8071
|
+
function documentTextFromExpression(node, assembly) {
|
|
7448
8072
|
if (import_ts_morph37.Node.isTaggedTemplateExpression(node)) {
|
|
7449
8073
|
if (!isDocumentTag(node.getTag())) {
|
|
7450
8074
|
return null;
|
|
7451
8075
|
}
|
|
7452
|
-
|
|
8076
|
+
if (assembly.seen.has(node)) {
|
|
8077
|
+
return "";
|
|
8078
|
+
}
|
|
8079
|
+
assembly.seen.add(node);
|
|
8080
|
+
return assembledTemplateText(node.getTemplate(), assembly);
|
|
7453
8081
|
}
|
|
7454
8082
|
if (!import_ts_morph37.Node.isCallExpression(node)) {
|
|
7455
8083
|
return null;
|
|
@@ -7465,7 +8093,11 @@ function documentTextFromExpression(node) {
|
|
|
7465
8093
|
if (!import_ts_morph37.Node.isNoSubstitutionTemplateLiteral(template) && !import_ts_morph37.Node.isTemplateExpression(template)) {
|
|
7466
8094
|
return null;
|
|
7467
8095
|
}
|
|
7468
|
-
|
|
8096
|
+
if (assembly.seen.has(node)) {
|
|
8097
|
+
return "";
|
|
8098
|
+
}
|
|
8099
|
+
assembly.seen.add(node);
|
|
8100
|
+
return assembledTemplateText(template, assembly);
|
|
7469
8101
|
}
|
|
7470
8102
|
function isDocumentTag(tag) {
|
|
7471
8103
|
if (!import_ts_morph37.Node.isIdentifier(tag)) {
|
|
@@ -7485,15 +8117,15 @@ function isDocumentTag(tag) {
|
|
|
7485
8117
|
}
|
|
7486
8118
|
return false;
|
|
7487
8119
|
}
|
|
7488
|
-
function resolveThroughFacts(arg,
|
|
7489
|
-
if (resolution === void 0 || !import_ts_morph37.Node.isIdentifier(arg)) {
|
|
8120
|
+
function resolveThroughFacts(arg, assembly) {
|
|
8121
|
+
if (assembly.resolution === void 0 || !import_ts_morph37.Node.isIdentifier(arg)) {
|
|
7490
8122
|
return null;
|
|
7491
8123
|
}
|
|
7492
|
-
const written = resolution.resolveWrittenValue(arg);
|
|
8124
|
+
const written = assembly.resolution.resolveWrittenValue(arg);
|
|
7493
8125
|
if (written === null) {
|
|
7494
8126
|
return null;
|
|
7495
8127
|
}
|
|
7496
|
-
const text = documentTextFromExpression(written);
|
|
8128
|
+
const text = documentTextFromExpression(written, assembly);
|
|
7497
8129
|
if (text !== null) {
|
|
7498
8130
|
return text;
|
|
7499
8131
|
}
|
|
@@ -7506,7 +8138,13 @@ function operationInfoFromResolution(resolution, callOperationType) {
|
|
|
7506
8138
|
return null;
|
|
7507
8139
|
}
|
|
7508
8140
|
const operationType = operation.operationName !== void 0 ? operation.operationType : callOperationType;
|
|
7509
|
-
return {
|
|
8141
|
+
return {
|
|
8142
|
+
...operation,
|
|
8143
|
+
operationType,
|
|
8144
|
+
document: resolution.document,
|
|
8145
|
+
...resolution.unresolvedFragments !== void 0 ? { unresolvedFragments: resolution.unresolvedFragments } : {},
|
|
8146
|
+
...resolution.unresolved !== void 0 ? { unresolved: resolution.unresolved } : {}
|
|
8147
|
+
};
|
|
7510
8148
|
}
|
|
7511
8149
|
return {
|
|
7512
8150
|
operationType: resolution.operationType ?? callOperationType,
|
|
@@ -7548,8 +8186,8 @@ function importedVariableInitializers(identifier) {
|
|
|
7548
8186
|
}
|
|
7549
8187
|
return inits;
|
|
7550
8188
|
}
|
|
7551
|
-
function resolveGqlTemplateText(arg) {
|
|
7552
|
-
const direct = documentTextFromExpression(arg);
|
|
8189
|
+
function resolveGqlTemplateText(arg, assembly) {
|
|
8190
|
+
const direct = documentTextFromExpression(arg, assembly);
|
|
7553
8191
|
if (direct !== null) {
|
|
7554
8192
|
return direct;
|
|
7555
8193
|
}
|
|
@@ -7569,7 +8207,10 @@ function resolveGqlTemplateText(arg) {
|
|
|
7569
8207
|
}
|
|
7570
8208
|
}
|
|
7571
8209
|
for (const init of importedVariableInitializers(arg)) {
|
|
7572
|
-
const text = documentTextFromExpression(
|
|
8210
|
+
const text = documentTextFromExpression(
|
|
8211
|
+
stripDocumentNodeCasts(init),
|
|
8212
|
+
assembly
|
|
8213
|
+
);
|
|
7573
8214
|
if (text !== null) {
|
|
7574
8215
|
return text;
|
|
7575
8216
|
}
|
|
@@ -8157,14 +8798,14 @@ function unitForJsxRoute(node, match, routeNames, kind, resolution) {
|
|
|
8157
8798
|
}
|
|
8158
8799
|
return routeUnit(node, kind, match.method, resolved.path, target, resolution);
|
|
8159
8800
|
}
|
|
8160
|
-
function routeUnit(at, kind, method,
|
|
8161
|
-
const routeInfo = { method, path:
|
|
8801
|
+
function routeUnit(at, kind, method, path12, target, resolution) {
|
|
8802
|
+
const routeInfo = { method, path: path12 };
|
|
8162
8803
|
if (target.kind === "unreadable") {
|
|
8163
8804
|
return {
|
|
8164
8805
|
func: null,
|
|
8165
8806
|
announcedAt: at,
|
|
8166
8807
|
kind,
|
|
8167
|
-
name:
|
|
8808
|
+
name: path12,
|
|
8168
8809
|
nameKind: "label",
|
|
8169
8810
|
routeInfo
|
|
8170
8811
|
};
|
|
@@ -9052,9 +9693,9 @@ function withMountPrefix(routeInfo, subjectNode, mountPrefixes) {
|
|
|
9052
9693
|
const prefix = mountPrefixes.effectivePrefixFor(subjectNode);
|
|
9053
9694
|
return prefix === "" ? routeInfo : { ...routeInfo, path: joinMountedPath(prefix, routeInfo.path) };
|
|
9054
9695
|
}
|
|
9055
|
-
function joinMountedPath(prefix,
|
|
9696
|
+
function joinMountedPath(prefix, path12) {
|
|
9056
9697
|
const trimmed = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
9057
|
-
return trimmed === "" ?
|
|
9698
|
+
return trimmed === "" ? path12 : trimmed + path12;
|
|
9058
9699
|
}
|
|
9059
9700
|
function registrationSubjectsOf(sourceFile, importModule, importName) {
|
|
9060
9701
|
let importedLocalName = null;
|
|
@@ -9218,11 +9859,11 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
|
|
|
9218
9859
|
return null;
|
|
9219
9860
|
}
|
|
9220
9861
|
const method2 = stringProperty(routeObject, binding.method.property);
|
|
9221
|
-
const
|
|
9222
|
-
if (method2 === null ||
|
|
9862
|
+
const path12 = stringProperty(routeObject, binding.path.property);
|
|
9863
|
+
if (method2 === null || path12 === null) {
|
|
9223
9864
|
return null;
|
|
9224
9865
|
}
|
|
9225
|
-
return { method: method2.toUpperCase(), path:
|
|
9866
|
+
return { method: method2.toUpperCase(), path: path12 };
|
|
9226
9867
|
}
|
|
9227
9868
|
if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromRegistration") {
|
|
9228
9869
|
return null;
|
|
@@ -9329,7 +9970,7 @@ function bodyReferencesLoopVar(loop, name) {
|
|
|
9329
9970
|
}
|
|
9330
9971
|
function readRouteSpec(element, shape, resolution) {
|
|
9331
9972
|
let method = null;
|
|
9332
|
-
let
|
|
9973
|
+
let path12 = null;
|
|
9333
9974
|
let handler = null;
|
|
9334
9975
|
for (const prop of element.getProperties()) {
|
|
9335
9976
|
if (import_ts_morph46.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
|
|
@@ -9347,16 +9988,16 @@ function readRouteSpec(element, shape, resolution) {
|
|
|
9347
9988
|
if (name === shape.methodKey) {
|
|
9348
9989
|
method = readStringLiteralValue(init);
|
|
9349
9990
|
} else if (name === shape.pathKey) {
|
|
9350
|
-
|
|
9991
|
+
path12 = readStringLiteralValue(init);
|
|
9351
9992
|
} else if (name === shape.handlerKey) {
|
|
9352
9993
|
const func = functionValueOf(init, resolution);
|
|
9353
9994
|
handler = func === null ? null : { func, name: handlerName(init) };
|
|
9354
9995
|
}
|
|
9355
9996
|
}
|
|
9356
|
-
if (method === null ||
|
|
9997
|
+
if (method === null || path12 === null || handler === null) {
|
|
9357
9998
|
return null;
|
|
9358
9999
|
}
|
|
9359
|
-
return { method, path:
|
|
10000
|
+
return { method, path: path12, handler: handler.func, handlerName: handler.name };
|
|
9360
10001
|
}
|
|
9361
10002
|
function readStringLiteralValue(node) {
|
|
9362
10003
|
if (import_ts_morph46.Node.isStringLiteral(node) || import_ts_morph46.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
@@ -9385,8 +10026,8 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
|
|
|
9385
10026
|
}
|
|
9386
10027
|
const args = node.getArguments();
|
|
9387
10028
|
for (const reg of match.registrations) {
|
|
9388
|
-
const
|
|
9389
|
-
if (
|
|
10029
|
+
const path12 = substitutePath(reg.pathTemplate, args);
|
|
10030
|
+
if (path12 === null) {
|
|
9390
10031
|
continue;
|
|
9391
10032
|
}
|
|
9392
10033
|
const handler = resolveHandler(reg.handlerArg, args, resolution);
|
|
@@ -9399,7 +10040,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution) {
|
|
|
9399
10040
|
name: handler.name,
|
|
9400
10041
|
routeInfo: {
|
|
9401
10042
|
method: reg.method.toUpperCase(),
|
|
9402
|
-
path:
|
|
10043
|
+
path: path12
|
|
9403
10044
|
}
|
|
9404
10045
|
});
|
|
9405
10046
|
}
|
|
@@ -9568,7 +10209,10 @@ function discoverResolverMaps(sourceFile, match, kind, resolution) {
|
|
|
9568
10209
|
resolverInfo: {
|
|
9569
10210
|
typeName,
|
|
9570
10211
|
fieldName,
|
|
9571
|
-
...schemaSdl !== null ? {
|
|
10212
|
+
...schemaSdl !== null ? {
|
|
10213
|
+
schemaSdl,
|
|
10214
|
+
schemaDocument: config.getSourceFile().getFilePath()
|
|
10215
|
+
} : {}
|
|
9572
10216
|
}
|
|
9573
10217
|
});
|
|
9574
10218
|
}
|
|
@@ -9765,7 +10409,15 @@ function discoverUnits(sourceFile, patterns, resolution, mountPrefixes) {
|
|
|
9765
10409
|
}
|
|
9766
10410
|
|
|
9767
10411
|
// src/discovery/mountPrefix.ts
|
|
9768
|
-
var NO_MOUNTS = {
|
|
10412
|
+
var NO_MOUNTS = {
|
|
10413
|
+
// Recorded even with no mounts anywhere: a mount added later in some
|
|
10414
|
+
// other file changes this router's prefix without touching its file.
|
|
10415
|
+
effectivePrefixFor: (routerNode) => {
|
|
10416
|
+
recordMountPrefix(nodeId(routerNode), "");
|
|
10417
|
+
return "";
|
|
10418
|
+
},
|
|
10419
|
+
prefixForId: () => ""
|
|
10420
|
+
};
|
|
9769
10421
|
function buildMountPrefixIndex(packsByFile, resolution) {
|
|
9770
10422
|
const subjectIdsByPack = /* @__PURE__ */ new Map();
|
|
9771
10423
|
const mountWorkByPack = /* @__PURE__ */ new Map();
|
|
@@ -9822,10 +10474,15 @@ function buildMountPrefixIndex(packsByFile, resolution) {
|
|
|
9822
10474
|
return NO_MOUNTS;
|
|
9823
10475
|
}
|
|
9824
10476
|
const memo = /* @__PURE__ */ new Map();
|
|
10477
|
+
const byId = (childId) => resolvePrefix(edgesByChild, memo, childId, /* @__PURE__ */ new Set()) ?? "";
|
|
9825
10478
|
return {
|
|
9826
10479
|
effectivePrefixFor(routerNode) {
|
|
9827
|
-
|
|
9828
|
-
|
|
10480
|
+
const childId = nodeId(routerNode);
|
|
10481
|
+
const prefix = byId(childId);
|
|
10482
|
+
recordMountPrefix(childId, prefix);
|
|
10483
|
+
return prefix;
|
|
10484
|
+
},
|
|
10485
|
+
prefixForId: byId
|
|
9829
10486
|
};
|
|
9830
10487
|
}
|
|
9831
10488
|
function recordEdge(edgesByChild, candidate) {
|
|
@@ -10071,7 +10728,8 @@ var JS_RULES = [
|
|
|
10071
10728
|
(0, import_datalog2.rule)(
|
|
10072
10729
|
"stepsTo",
|
|
10073
10730
|
[(0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("t"), import_resolution.VALUE_STEP],
|
|
10074
|
-
[(0, import_datalog2.lit)("bindCall", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("t"))]
|
|
10731
|
+
[(0, import_datalog2.lit)("bindCall", (0, import_datalog2.variable)("r"), (0, import_datalog2.variable)("t"))],
|
|
10732
|
+
"bind"
|
|
10075
10733
|
)
|
|
10076
10734
|
];
|
|
10077
10735
|
var RESOLUTION_PROGRAM = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? {
|
|
@@ -10081,6 +10739,15 @@ var RESOLUTION_PROGRAM = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? {
|
|
|
10081
10739
|
[...import_resolution.RESOLUTION_RULES, ...JS_RULES, ...import_resolution.RESOLUTION_QUESTIONS],
|
|
10082
10740
|
import_resolution.ANSWER_RELATIONS
|
|
10083
10741
|
);
|
|
10742
|
+
var WITNESS_RULES = [...import_resolution.RESOLUTION_RULES, ...JS_RULES];
|
|
10743
|
+
var NOT_BASE_FACTS = /* @__PURE__ */ new Set([
|
|
10744
|
+
...[...import_resolution.RESOLUTION_RULES, ...JS_RULES, ...import_resolution.RESOLUTION_QUESTIONS].map(
|
|
10745
|
+
(r) => r.head.relation
|
|
10746
|
+
),
|
|
10747
|
+
...RESOLUTION_PROGRAM.rules.map((r) => r.head.relation),
|
|
10748
|
+
"wanted",
|
|
10749
|
+
"wantedOrigin"
|
|
10750
|
+
]);
|
|
10084
10751
|
var QUERY_FACTS = RESOLUTION_PROGRAM.demandDriven.length === 0 ? [] : [...RESOLUTION_PROGRAM.demandDriven, "wanted", "wantedOrigin"];
|
|
10085
10752
|
var MAX_MODULE_HOPS = 6;
|
|
10086
10753
|
var ResolutionStore = class {
|
|
@@ -10089,6 +10756,8 @@ var ResolutionStore = class {
|
|
|
10089
10756
|
fullyExtracted = /* @__PURE__ */ new Set();
|
|
10090
10757
|
seededValues = /* @__PURE__ */ new Set();
|
|
10091
10758
|
importedNames = /* @__PURE__ */ new Map();
|
|
10759
|
+
/** Files the most recent wave walk entered, for the memo to keep. */
|
|
10760
|
+
lastQueryWalked = [];
|
|
10092
10761
|
declarations = /* @__PURE__ */ new Map();
|
|
10093
10762
|
graph = new ModuleGraph();
|
|
10094
10763
|
stale = true;
|
|
@@ -10106,13 +10775,64 @@ var ResolutionStore = class {
|
|
|
10106
10775
|
* the walk never reaches on its own.
|
|
10107
10776
|
*/
|
|
10108
10777
|
resolveCallable(value, alsoFrom) {
|
|
10778
|
+
const sources = this.resolveCallableSources(value, alsoFrom);
|
|
10779
|
+
const only = sources[0];
|
|
10780
|
+
return sources.length === 1 && only !== void 0 ? only : null;
|
|
10781
|
+
}
|
|
10782
|
+
/**
|
|
10783
|
+
* Every function the value comes down to. One is the answer
|
|
10784
|
+
* `resolveCallable` gives; several is a value with more than one
|
|
10785
|
+
* possible source, which a caller says at the site rather than
|
|
10786
|
+
* folding into the same nothing as a chain that went nowhere.
|
|
10787
|
+
*/
|
|
10788
|
+
resolveCallableSources(value, alsoFrom) {
|
|
10109
10789
|
const target = factKeyOf(value);
|
|
10110
10790
|
return this.resolveByWaves(
|
|
10111
10791
|
target,
|
|
10112
10792
|
"wanted",
|
|
10113
|
-
() => this.
|
|
10793
|
+
() => this.lookupSources(target),
|
|
10114
10794
|
alsoFrom
|
|
10795
|
+
) ?? [];
|
|
10796
|
+
}
|
|
10797
|
+
/**
|
|
10798
|
+
* The witness proof behind `resolveCallable`'s answer. Resolves the
|
|
10799
|
+
* value first, which walks files and extracts facts in the usual
|
|
10800
|
+
* waves, then re-evaluates the rules over those base facts under the
|
|
10801
|
+
* witness algebra and rebuilds the proof of the answer. Null when
|
|
10802
|
+
* the value does not resolve at all.
|
|
10803
|
+
*/
|
|
10804
|
+
explainCallable(value, options = {}) {
|
|
10805
|
+
const resolved = this.resolveCallable(value, options.alsoFrom);
|
|
10806
|
+
if (resolved === null) {
|
|
10807
|
+
return null;
|
|
10808
|
+
}
|
|
10809
|
+
const proofDb = new import_datalog2.Database();
|
|
10810
|
+
let baseFacts = 0;
|
|
10811
|
+
for (const relation of this.db.relationNames()) {
|
|
10812
|
+
if (NOT_BASE_FACTS.has(relation)) {
|
|
10813
|
+
continue;
|
|
10814
|
+
}
|
|
10815
|
+
for (const tuple of this.db.facts(relation)) {
|
|
10816
|
+
proofDb.add(relation, tuple);
|
|
10817
|
+
baseFacts++;
|
|
10818
|
+
}
|
|
10819
|
+
}
|
|
10820
|
+
const started = performance.now();
|
|
10821
|
+
(0, import_datalog2.evaluate)(proofDb, WITNESS_RULES, import_datalog2.witnesses);
|
|
10822
|
+
const evaluateMs = performance.now() - started;
|
|
10823
|
+
const derivedFacts = proofDb.relationNames().reduce((count, relation) => count + proofDb.size(relation), 0) - baseFacts;
|
|
10824
|
+
const proof = (0, import_datalog2.proofOf)(
|
|
10825
|
+
proofDb,
|
|
10826
|
+
"resolves",
|
|
10827
|
+
[nodeId(factKeyOf(value)), nodeId(resolved)],
|
|
10828
|
+
options.maxDepth === void 0 ? {} : { maxDepth: options.maxDepth }
|
|
10115
10829
|
);
|
|
10830
|
+
return {
|
|
10831
|
+
target: resolved,
|
|
10832
|
+
proof,
|
|
10833
|
+
nodeFor: (atom) => this.table.byId.get(String(atom)),
|
|
10834
|
+
stats: { baseFacts, derivedFacts, evaluateMs }
|
|
10835
|
+
};
|
|
10116
10836
|
}
|
|
10117
10837
|
resolveObject(value) {
|
|
10118
10838
|
const target = factKeyOf(value);
|
|
@@ -10149,7 +10869,10 @@ var ResolutionStore = class {
|
|
|
10149
10869
|
const declaration = `${nodeId(refersTo)}|${modules.join(",")}`;
|
|
10150
10870
|
const cached = this.importedNames.get(declaration);
|
|
10151
10871
|
if (cached !== void 0) {
|
|
10152
|
-
|
|
10872
|
+
for (const walkedPath of cached.walked) {
|
|
10873
|
+
recordFileDependency(walkedPath);
|
|
10874
|
+
}
|
|
10875
|
+
return cached.names;
|
|
10153
10876
|
}
|
|
10154
10877
|
const target = factKeyOf(value);
|
|
10155
10878
|
const found = this.resolveByWaves(
|
|
@@ -10157,7 +10880,10 @@ var ResolutionStore = class {
|
|
|
10157
10880
|
"wantedOrigin",
|
|
10158
10881
|
() => this.lookupImportedNames(target, modules)
|
|
10159
10882
|
) ?? [];
|
|
10160
|
-
this.importedNames.set(declaration,
|
|
10883
|
+
this.importedNames.set(declaration, {
|
|
10884
|
+
names: found,
|
|
10885
|
+
walked: [...this.lastQueryWalked]
|
|
10886
|
+
});
|
|
10161
10887
|
return found;
|
|
10162
10888
|
}
|
|
10163
10889
|
/**
|
|
@@ -10191,6 +10917,7 @@ var ResolutionStore = class {
|
|
|
10191
10917
|
this.wantValue(question, value);
|
|
10192
10918
|
this.seedValue(value);
|
|
10193
10919
|
const walked = /* @__PURE__ */ new Set();
|
|
10920
|
+
this.lastQueryWalked = [];
|
|
10194
10921
|
let frontier = alsoFrom === void 0 ? [value.getSourceFile()] : [value.getSourceFile(), alsoFrom];
|
|
10195
10922
|
for (let hop = 0; hop <= MAX_MODULE_HOPS; hop++) {
|
|
10196
10923
|
const next = [];
|
|
@@ -10199,6 +10926,8 @@ var ResolutionStore = class {
|
|
|
10199
10926
|
continue;
|
|
10200
10927
|
}
|
|
10201
10928
|
walked.add(sourceFile.getFilePath());
|
|
10929
|
+
this.lastQueryWalked.push(sourceFile.getFilePath());
|
|
10930
|
+
recordFileDependency(sourceFile.getFilePath());
|
|
10202
10931
|
this.extractFile(sourceFile);
|
|
10203
10932
|
next.push(...this.graph.importedFilesOf(sourceFile));
|
|
10204
10933
|
}
|
|
@@ -10226,7 +10955,7 @@ var ResolutionStore = class {
|
|
|
10226
10955
|
this.stale = false;
|
|
10227
10956
|
}
|
|
10228
10957
|
wantValue(question, value) {
|
|
10229
|
-
if (this.db.add(question, [nodeId(value)])) {
|
|
10958
|
+
if (this.db.add(question, [nodeId(value)]) === "added") {
|
|
10230
10959
|
this.stale = true;
|
|
10231
10960
|
}
|
|
10232
10961
|
}
|
|
@@ -10290,10 +11019,12 @@ var ResolutionStore = class {
|
|
|
10290
11019
|
return this.graph.filesReachingAnyPackage(fileSets);
|
|
10291
11020
|
}
|
|
10292
11021
|
/**
|
|
10293
|
-
*
|
|
10294
|
-
*
|
|
11022
|
+
* Null keeps the wave walk widening; any candidate at all ends it,
|
|
11023
|
+
* since more files can only add candidates, never take one away. The
|
|
11024
|
+
* single-answer policy stays with the callers: picking one of two
|
|
11025
|
+
* would make the result depend on the order the facts came in.
|
|
10295
11026
|
*/
|
|
10296
|
-
|
|
11027
|
+
lookupSources(value) {
|
|
10297
11028
|
this.derive();
|
|
10298
11029
|
const candidates = /* @__PURE__ */ new Set();
|
|
10299
11030
|
for (const target of this.answersFor("wantedResolves", nodeId(value))) {
|
|
@@ -10305,10 +11036,7 @@ var ResolutionStore = class {
|
|
|
10305
11036
|
candidates.add(resolved);
|
|
10306
11037
|
}
|
|
10307
11038
|
}
|
|
10308
|
-
|
|
10309
|
-
return null;
|
|
10310
|
-
}
|
|
10311
|
-
return [...candidates][0];
|
|
11039
|
+
return candidates.size === 0 ? null : [...candidates];
|
|
10312
11040
|
}
|
|
10313
11041
|
derive() {
|
|
10314
11042
|
if (!this.stale) {
|
|
@@ -10495,6 +11223,27 @@ function moduleInitSummary(sourceFile, effects, options) {
|
|
|
10495
11223
|
return (0, import_extractor3.assembleSummary)(raw, options);
|
|
10496
11224
|
}
|
|
10497
11225
|
|
|
11226
|
+
// src/referencedFiles.ts
|
|
11227
|
+
function createReferenceIndex(sourceFiles) {
|
|
11228
|
+
const direct = /* @__PURE__ */ new Map();
|
|
11229
|
+
for (const sourceFile of sourceFiles) {
|
|
11230
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
11231
|
+
for (const target of sourceFile.getReferencedSourceFiles()) {
|
|
11232
|
+
if (target.isInNodeModules() || target.isDeclarationFile()) {
|
|
11233
|
+
continue;
|
|
11234
|
+
}
|
|
11235
|
+
referenced.add(target.getFilePath());
|
|
11236
|
+
}
|
|
11237
|
+
direct.set(sourceFile.getFilePath(), referenced);
|
|
11238
|
+
}
|
|
11239
|
+
const none = /* @__PURE__ */ new Set();
|
|
11240
|
+
return {
|
|
11241
|
+
directOf(filePath) {
|
|
11242
|
+
return direct.get(filePath) ?? none;
|
|
11243
|
+
}
|
|
11244
|
+
};
|
|
11245
|
+
}
|
|
11246
|
+
|
|
10498
11247
|
// src/resolve/boundaryEffects.ts
|
|
10499
11248
|
var import_datalog3 = require("@suss/datalog");
|
|
10500
11249
|
var EFFECT_RULES = [
|
|
@@ -10676,6 +11425,11 @@ function classifyStop(declarations) {
|
|
|
10676
11425
|
if (declarations.length === 0) {
|
|
10677
11426
|
return "noDeclaration";
|
|
10678
11427
|
}
|
|
11428
|
+
for (const declaration of declarations) {
|
|
11429
|
+
if (!isInExternalCode(declaration.getSourceFile())) {
|
|
11430
|
+
recordFileDependency(declaration.getSourceFile().getFilePath());
|
|
11431
|
+
}
|
|
11432
|
+
}
|
|
10679
11433
|
if (declarations.every(isExternalDeclaration)) {
|
|
10680
11434
|
return "outsideRun";
|
|
10681
11435
|
}
|
|
@@ -10687,6 +11441,7 @@ function classifyStop(declarations) {
|
|
|
10687
11441
|
var RECORDED = {
|
|
10688
11442
|
noBody: true,
|
|
10689
11443
|
unsettledValue: true,
|
|
11444
|
+
multipleSources: true,
|
|
10690
11445
|
outsideRun: false,
|
|
10691
11446
|
noDeclaration: false
|
|
10692
11447
|
};
|
|
@@ -10696,6 +11451,7 @@ function worthRecording(reason) {
|
|
|
10696
11451
|
var STOP_SENTENCE = {
|
|
10697
11452
|
noBody: (callee) => `The call to ${callee} lands on a declaration with no body, so whatever runs there is missing from this summary`,
|
|
10698
11453
|
unsettledValue: (callee) => `The call to ${callee} goes through a value this run could not settle, so whatever runs there is missing from this summary`,
|
|
11454
|
+
multipleSources: (callee) => `The call to ${callee} reaches a value with more than one possible source, so whatever runs there is missing from this summary`,
|
|
10699
11455
|
outsideRun: (callee) => `The call to ${callee} lands in a package whose source is not in this run, so whatever runs there is missing from this summary`,
|
|
10700
11456
|
noDeclaration: (callee) => `The call to ${callee} has no declaration this run could find, so whatever runs there is missing from this summary`
|
|
10701
11457
|
};
|
|
@@ -10749,24 +11505,6 @@ function resolveDecl(decl, calleeName) {
|
|
|
10749
11505
|
}
|
|
10750
11506
|
return null;
|
|
10751
11507
|
}
|
|
10752
|
-
if (import_ts_morph52.Node.isImportSpecifier(decl)) {
|
|
10753
|
-
const importDecl = decl.getImportDeclaration();
|
|
10754
|
-
const sf = importDecl.getModuleSpecifierSourceFile();
|
|
10755
|
-
if (sf === void 0 || isInExternalCode(sf)) {
|
|
10756
|
-
return null;
|
|
10757
|
-
}
|
|
10758
|
-
const exported = exportedDeclarationsOf(sf).get(decl.getName());
|
|
10759
|
-
if (exported === void 0) {
|
|
10760
|
-
return null;
|
|
10761
|
-
}
|
|
10762
|
-
for (const ed of exported) {
|
|
10763
|
-
const resolved = resolveDecl(ed, calleeName);
|
|
10764
|
-
if (resolved !== null) {
|
|
10765
|
-
return resolved;
|
|
10766
|
-
}
|
|
10767
|
-
}
|
|
10768
|
-
return null;
|
|
10769
|
-
}
|
|
10770
11508
|
return null;
|
|
10771
11509
|
}
|
|
10772
11510
|
function declName(decl) {
|
|
@@ -10794,20 +11532,27 @@ function resolveCallee(call, calleeName, scan) {
|
|
|
10794
11532
|
}
|
|
10795
11533
|
const callee = call.getExpression();
|
|
10796
11534
|
const symbol = callee.getSymbol();
|
|
10797
|
-
const declarations = symbol
|
|
11535
|
+
const declarations = declarationsBehind(symbol);
|
|
10798
11536
|
for (const decl of declarations) {
|
|
10799
11537
|
const resolved = resolveDecl(decl, calleeName);
|
|
10800
11538
|
if (resolved !== null) {
|
|
10801
11539
|
return { kind: "followed", candidate: resolved };
|
|
10802
11540
|
}
|
|
10803
11541
|
}
|
|
10804
|
-
const
|
|
10805
|
-
if (
|
|
10806
|
-
const
|
|
10807
|
-
const
|
|
11542
|
+
const resolveSources = scan.resolveCallableSources;
|
|
11543
|
+
if (resolveSources !== void 0 && import_ts_morph52.Node.isPropertyAccessExpression(callee) && declarations.some(isDeclaredShape)) {
|
|
11544
|
+
const sources = resolveSources(callee, scan.reachedFrom);
|
|
11545
|
+
const only = sources.length === 1 ? sources[0] : void 0;
|
|
11546
|
+
const resolved = only === void 0 ? null : resolveDecl(only, calleeName);
|
|
10808
11547
|
if (resolved !== null) {
|
|
10809
11548
|
return { kind: "followed", candidate: resolved };
|
|
10810
11549
|
}
|
|
11550
|
+
if (sources.length > 1) {
|
|
11551
|
+
return {
|
|
11552
|
+
kind: "stopped",
|
|
11553
|
+
stop: { callee: calleeName, reason: "multipleSources" }
|
|
11554
|
+
};
|
|
11555
|
+
}
|
|
10811
11556
|
}
|
|
10812
11557
|
return {
|
|
10813
11558
|
kind: "stopped",
|
|
@@ -10882,7 +11627,7 @@ var REACHABLE_RULES = [
|
|
|
10882
11627
|
)
|
|
10883
11628
|
];
|
|
10884
11629
|
var NO_RECOGNIZERS = { invocation: [], access: [] };
|
|
10885
|
-
function expandReachableClosure(seeds, project, options, projectFileSet, facts, recognizers = NO_RECOGNIZERS) {
|
|
11630
|
+
function expandReachableClosure(seeds, project, options, projectFileSet, facts, recognizers = NO_RECOGNIZERS, alreadySummarized = []) {
|
|
10886
11631
|
const lookup = createSourceFileLookup(project);
|
|
10887
11632
|
const db = facts?.db ?? new import_datalog4.Database();
|
|
10888
11633
|
const functionByKey = /* @__PURE__ */ new Map();
|
|
@@ -10902,6 +11647,15 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
10902
11647
|
db.add("entry", [key]);
|
|
10903
11648
|
}
|
|
10904
11649
|
}
|
|
11650
|
+
const knownKeys = /* @__PURE__ */ new Set();
|
|
11651
|
+
for (const summary of alreadySummarized) {
|
|
11652
|
+
const func = lookup.functionAt(summary.location);
|
|
11653
|
+
if (func !== null) {
|
|
11654
|
+
const key = nodeKey2(func);
|
|
11655
|
+
knownKeys.add(key);
|
|
11656
|
+
facts?.unitKeyBySummary.set(summary, key);
|
|
11657
|
+
}
|
|
11658
|
+
}
|
|
10905
11659
|
for (; ; ) {
|
|
10906
11660
|
(0, import_datalog4.evaluate)(db, REACHABLE_RULES);
|
|
10907
11661
|
const frontier = db.facts("reachable").map(([key]) => String(key)).filter((key) => !scanned.has(key));
|
|
@@ -10916,10 +11670,14 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
10916
11670
|
}
|
|
10917
11671
|
const cameFrom = reachedFrom.get(key);
|
|
10918
11672
|
const scan = {
|
|
10919
|
-
...recognizers.
|
|
11673
|
+
...recognizers.resolveCallableSources === void 0 ? {} : { resolveCallableSources: recognizers.resolveCallableSources },
|
|
10920
11674
|
...cameFrom === void 0 ? {} : { reachedFrom: cameFrom }
|
|
10921
11675
|
};
|
|
10922
|
-
const { candidates, stops } =
|
|
11676
|
+
const { candidates, stops } = scanWithRecording(
|
|
11677
|
+
key,
|
|
11678
|
+
facts,
|
|
11679
|
+
() => collectReachable(source.func, scan)
|
|
11680
|
+
);
|
|
10923
11681
|
if (stops.length > 0) {
|
|
10924
11682
|
stopsByKey.set(key, stops);
|
|
10925
11683
|
}
|
|
@@ -10938,7 +11696,7 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
10938
11696
|
const reached = [];
|
|
10939
11697
|
for (const [keyAtom] of db.facts("reachable")) {
|
|
10940
11698
|
const key = String(keyAtom);
|
|
10941
|
-
if (seedKeys.has(key)) {
|
|
11699
|
+
if (seedKeys.has(key) || knownKeys.has(key)) {
|
|
10942
11700
|
continue;
|
|
10943
11701
|
}
|
|
10944
11702
|
const candidate = functionByKey.get(key);
|
|
@@ -10952,7 +11710,11 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
10952
11710
|
candidate.func.getSourceFile().getFilePath()
|
|
10953
11711
|
);
|
|
10954
11712
|
}
|
|
10955
|
-
const summary =
|
|
11713
|
+
const summary = scanWithRecording(
|
|
11714
|
+
key,
|
|
11715
|
+
facts,
|
|
11716
|
+
() => extractReachableSummary(candidate, options, recognizers)
|
|
11717
|
+
);
|
|
10956
11718
|
facts?.unitKeyBySummary.set(summary, key);
|
|
10957
11719
|
rememberSummary(summariesByKey, key, summary);
|
|
10958
11720
|
reached.push(summary);
|
|
@@ -10960,6 +11722,20 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
10960
11722
|
recordStops(stopsByKey, summariesByKey, options);
|
|
10961
11723
|
return [...seeds, ...reached];
|
|
10962
11724
|
}
|
|
11725
|
+
function scanWithRecording(key, facts, fn) {
|
|
11726
|
+
const filesByKey = facts?.filesByKey;
|
|
11727
|
+
if (filesByKey === void 0) {
|
|
11728
|
+
return fn();
|
|
11729
|
+
}
|
|
11730
|
+
const sink = createDependencySink();
|
|
11731
|
+
const result = withDependencySink(sink, fn);
|
|
11732
|
+
const bucket = filesByKey.get(key) ?? /* @__PURE__ */ new Set();
|
|
11733
|
+
for (const filePath of sink.files) {
|
|
11734
|
+
bucket.add(filePath);
|
|
11735
|
+
}
|
|
11736
|
+
filesByKey.set(key, bucket);
|
|
11737
|
+
return result;
|
|
11738
|
+
}
|
|
10963
11739
|
function rememberSummary(summariesByKey, key, summary) {
|
|
10964
11740
|
const bucket = summariesByKey.get(key) ?? [];
|
|
10965
11741
|
bucket.push(summary);
|
|
@@ -11708,20 +12484,25 @@ function readArrayLiteralText(node) {
|
|
|
11708
12484
|
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
11709
12485
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
11710
12486
|
var import_behavioral_ir5 = require("@suss/behavioral-ir");
|
|
12487
|
+
function workspaceRootFor(anchor) {
|
|
12488
|
+
return namedPackageDirAbove(anchor) ?? import_node_path7.default.resolve(anchor);
|
|
12489
|
+
}
|
|
11711
12490
|
function workspaceNameFor(root) {
|
|
11712
12491
|
if (root === void 0) {
|
|
11713
12492
|
return null;
|
|
11714
12493
|
}
|
|
11715
|
-
|
|
12494
|
+
const dir = namedPackageDirAbove(root);
|
|
12495
|
+
if (dir !== null) {
|
|
12496
|
+
return packageNameAt(dir);
|
|
12497
|
+
}
|
|
12498
|
+
const folder = import_node_path7.default.basename(import_node_path7.default.resolve(root));
|
|
12499
|
+
return folder.length > 0 ? folder : null;
|
|
12500
|
+
}
|
|
12501
|
+
function namedPackageDirAbove(start) {
|
|
12502
|
+
let at = import_node_path7.default.resolve(start);
|
|
11716
12503
|
for (let up = 0; up < 12; up += 1) {
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
import_node_fs4.default.readFileSync(import_node_path7.default.join(at, "package.json"), "utf8")
|
|
11720
|
-
);
|
|
11721
|
-
if (typeof manifest.name === "string" && manifest.name.length > 0) {
|
|
11722
|
-
return manifest.name;
|
|
11723
|
-
}
|
|
11724
|
-
} catch {
|
|
12504
|
+
if (packageNameAt(at) !== null) {
|
|
12505
|
+
return at;
|
|
11725
12506
|
}
|
|
11726
12507
|
const parent = import_node_path7.default.dirname(at);
|
|
11727
12508
|
if (parent === at) {
|
|
@@ -11729,8 +12510,19 @@ function workspaceNameFor(root) {
|
|
|
11729
12510
|
}
|
|
11730
12511
|
at = parent;
|
|
11731
12512
|
}
|
|
11732
|
-
|
|
11733
|
-
|
|
12513
|
+
return null;
|
|
12514
|
+
}
|
|
12515
|
+
function packageNameAt(dir) {
|
|
12516
|
+
try {
|
|
12517
|
+
const manifest = JSON.parse(
|
|
12518
|
+
import_node_fs4.default.readFileSync(import_node_path7.default.join(dir, "package.json"), "utf8")
|
|
12519
|
+
);
|
|
12520
|
+
if (typeof manifest.name === "string" && manifest.name.length > 0) {
|
|
12521
|
+
return manifest.name;
|
|
12522
|
+
}
|
|
12523
|
+
} catch {
|
|
12524
|
+
}
|
|
12525
|
+
return null;
|
|
11734
12526
|
}
|
|
11735
12527
|
function nameSummaries(summaries, args) {
|
|
11736
12528
|
for (const summary of summaries) {
|
|
@@ -12215,6 +13007,36 @@ function extractCodeStructure(unit, pack, invocationRecognizers = [], accessReco
|
|
|
12215
13007
|
function responseAccessorNames(pack, kind) {
|
|
12216
13008
|
return pack.responseSemantics?.filter((m) => m.semantics.type === kind).map((m) => m.name);
|
|
12217
13009
|
}
|
|
13010
|
+
var ACCESSOR_FIELD_SEMANTICS = {
|
|
13011
|
+
bodyAccessors: "body",
|
|
13012
|
+
statusAccessors: "statusCode",
|
|
13013
|
+
successAccessors: "statusRange"
|
|
13014
|
+
};
|
|
13015
|
+
function responseAccessors(pack) {
|
|
13016
|
+
const out = {};
|
|
13017
|
+
for (const [field, kind] of Object.entries(ACCESSOR_FIELD_SEMANTICS)) {
|
|
13018
|
+
const names = responseAccessorNames(pack, kind);
|
|
13019
|
+
if (names !== void 0 && names.length > 0) {
|
|
13020
|
+
out[field] = names;
|
|
13021
|
+
}
|
|
13022
|
+
}
|
|
13023
|
+
return out;
|
|
13024
|
+
}
|
|
13025
|
+
var FUNCTION_FALLTHROUGH_TERMINAL = {
|
|
13026
|
+
kind: "return",
|
|
13027
|
+
match: { type: "functionFallthrough" },
|
|
13028
|
+
extraction: {}
|
|
13029
|
+
};
|
|
13030
|
+
function terminalsFor(unit, pack) {
|
|
13031
|
+
const declared = unit.terminals ?? pack.terminals;
|
|
13032
|
+
if (unit.callSite === void 0) {
|
|
13033
|
+
return declared;
|
|
13034
|
+
}
|
|
13035
|
+
if (declared.some((p) => p.match.type === "functionFallthrough")) {
|
|
13036
|
+
return declared;
|
|
13037
|
+
}
|
|
13038
|
+
return [...declared, FUNCTION_FALLTHROUGH_TERMINAL];
|
|
13039
|
+
}
|
|
12218
13040
|
function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers, barriers, resolveWrittenValue) {
|
|
12219
13041
|
const { func, kind, name } = unit;
|
|
12220
13042
|
if (func === null) {
|
|
@@ -12226,7 +13048,7 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
|
|
|
12226
13048
|
);
|
|
12227
13049
|
const extracted = extractRawBranches(
|
|
12228
13050
|
func,
|
|
12229
|
-
unit
|
|
13051
|
+
terminalsFor(unit, pack),
|
|
12230
13052
|
invocationRecognizers,
|
|
12231
13053
|
accessRecognizers,
|
|
12232
13054
|
barriers,
|
|
@@ -12262,8 +13084,7 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
|
|
|
12262
13084
|
}
|
|
12263
13085
|
}
|
|
12264
13086
|
}
|
|
12265
|
-
const
|
|
12266
|
-
const statusAccessors = unit.callSite !== void 0 ? responseAccessorNames(pack, "statusCode") : void 0;
|
|
13087
|
+
const accessors = unit.callSite !== void 0 ? responseAccessors(pack) : {};
|
|
12267
13088
|
return {
|
|
12268
13089
|
identity: {
|
|
12269
13090
|
name,
|
|
@@ -12287,8 +13108,8 @@ function readCodeStructure(unit, pack, invocationRecognizers, accessRecognizers,
|
|
|
12287
13108
|
bodyContent: bodyContentOf(func),
|
|
12288
13109
|
dependencyCalls: depCalls,
|
|
12289
13110
|
declaredContract: null,
|
|
12290
|
-
...
|
|
12291
|
-
...
|
|
13111
|
+
...accessors,
|
|
13112
|
+
...unit.callSite !== void 0 && pack.failureDelivery !== void 0 ? { failureDelivery: pack.failureDelivery } : {}
|
|
12292
13113
|
};
|
|
12293
13114
|
}
|
|
12294
13115
|
function extractConsumerBinding(unit, pattern, pack, resolution) {
|
|
@@ -12301,11 +13122,11 @@ function extractConsumerBinding(unit, pattern, pack, resolution) {
|
|
|
12301
13122
|
return null;
|
|
12302
13123
|
}
|
|
12303
13124
|
const method = extractBindingMethod(binding, callSite, pack, resolution);
|
|
12304
|
-
const
|
|
13125
|
+
const path12 = extractBindingPath(binding, callSite, pack, resolution);
|
|
12305
13126
|
return (0, import_behavioral_ir6.restBinding)({
|
|
12306
13127
|
transport: pack.protocol,
|
|
12307
13128
|
method: method ?? null,
|
|
12308
|
-
path:
|
|
13129
|
+
path: path12 ?? null,
|
|
12309
13130
|
recognition: pack.name
|
|
12310
13131
|
});
|
|
12311
13132
|
}
|
|
@@ -12394,12 +13215,12 @@ function originEndOf(flattened) {
|
|
|
12394
13215
|
const slash = flattened.indexOf("/", opener[0].length);
|
|
12395
13216
|
return slash === -1 ? flattened.length : slash;
|
|
12396
13217
|
}
|
|
12397
|
-
function appendPathText(
|
|
13218
|
+
function appendPathText(path12, text) {
|
|
12398
13219
|
const idx = text.search(/[?#]/);
|
|
12399
13220
|
if (idx === -1) {
|
|
12400
|
-
return { path:
|
|
13221
|
+
return { path: path12 + text, stop: false };
|
|
12401
13222
|
}
|
|
12402
|
-
return { path:
|
|
13223
|
+
return { path: path12 + text.slice(0, idx), stop: true };
|
|
12403
13224
|
}
|
|
12404
13225
|
function parseAbsoluteUrl(text) {
|
|
12405
13226
|
try {
|
|
@@ -12423,8 +13244,8 @@ function pathnameOfAbsoluteLiteral(text) {
|
|
|
12423
13244
|
return stripQueryAndFragment(stripOriginManually(text));
|
|
12424
13245
|
}
|
|
12425
13246
|
function pathFromLiteralUrl(text) {
|
|
12426
|
-
const
|
|
12427
|
-
return
|
|
13247
|
+
const path12 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
|
|
13248
|
+
return path12 === "" ? void 0 : path12;
|
|
12428
13249
|
}
|
|
12429
13250
|
function pathFromTemplateUrl(arg) {
|
|
12430
13251
|
const headText = arg.getHead().getLiteralText();
|
|
@@ -12432,7 +13253,7 @@ function pathFromTemplateUrl(arg) {
|
|
|
12432
13253
|
const tails = spans.map((span) => span.getLiteral().getLiteralText());
|
|
12433
13254
|
const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
|
|
12434
13255
|
const head = appendPathText("", headText.slice(originEnd));
|
|
12435
|
-
let
|
|
13256
|
+
let path12 = head.path;
|
|
12436
13257
|
let stop = head.stop;
|
|
12437
13258
|
let at = headText.length;
|
|
12438
13259
|
for (let i = 0; i < spans.length && !stop; i++) {
|
|
@@ -12442,18 +13263,18 @@ function pathFromTemplateUrl(arg) {
|
|
|
12442
13263
|
continue;
|
|
12443
13264
|
}
|
|
12444
13265
|
if (at >= originEnd) {
|
|
12445
|
-
|
|
13266
|
+
path12 += `{${placeholderName(span.getExpression())}}`;
|
|
12446
13267
|
}
|
|
12447
13268
|
at += SUBSTITUTION.length;
|
|
12448
13269
|
const appended = appendPathText(
|
|
12449
|
-
|
|
13270
|
+
path12,
|
|
12450
13271
|
tailText.slice(Math.max(0, originEnd - at))
|
|
12451
13272
|
);
|
|
12452
|
-
|
|
13273
|
+
path12 = appended.path;
|
|
12453
13274
|
stop = appended.stop;
|
|
12454
13275
|
at += tailText.length;
|
|
12455
13276
|
}
|
|
12456
|
-
return
|
|
13277
|
+
return path12 === "" ? void 0 : path12;
|
|
12457
13278
|
}
|
|
12458
13279
|
function extractBindingPath(binding, callSite, pack, resolution) {
|
|
12459
13280
|
const p = binding.path;
|
|
@@ -12642,12 +13463,20 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
12642
13463
|
if (claimant.pack === pack.name && claimant.file === sourceFile.getFilePath() && tally !== void 0) {
|
|
12643
13464
|
tally.selfCollisions += 1;
|
|
12644
13465
|
}
|
|
13466
|
+
if (claimant.file !== sourceFile.getFilePath()) {
|
|
13467
|
+
recordFileDependency(claimant.file);
|
|
13468
|
+
}
|
|
12645
13469
|
continue;
|
|
12646
13470
|
}
|
|
12647
13471
|
claimed.set(claimKey, {
|
|
12648
13472
|
pack: pack.name,
|
|
12649
13473
|
file: sourceFile.getFilePath()
|
|
12650
13474
|
});
|
|
13475
|
+
recordUnitClaim(claimKey, pack.name);
|
|
13476
|
+
const declaringFile = unit.func?.getSourceFile().getFilePath();
|
|
13477
|
+
if (declaringFile !== void 0 && declaringFile !== sourceFile.getFilePath()) {
|
|
13478
|
+
recordFileDependency(declaringFile);
|
|
13479
|
+
}
|
|
12651
13480
|
unitsWalkedHere += 1;
|
|
12652
13481
|
if (tally !== void 0) {
|
|
12653
13482
|
tally.unitsClaimed += 1;
|
|
@@ -12686,6 +13515,9 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
12686
13515
|
}
|
|
12687
13516
|
if (unit.resolverInfo.schemaSdl !== void 0) {
|
|
12688
13517
|
raw.graphqlSchemaSdl = unit.resolverInfo.schemaSdl;
|
|
13518
|
+
if (unit.resolverInfo.schemaDocument !== void 0) {
|
|
13519
|
+
raw.sourceDocumentLabel = unit.resolverInfo.schemaDocument;
|
|
13520
|
+
}
|
|
12689
13521
|
if (unit.resolverInfo.typeName !== null) {
|
|
12690
13522
|
const contract = deriveGraphqlContract(
|
|
12691
13523
|
unit.resolverInfo.schemaSdl,
|
|
@@ -12721,6 +13553,9 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
12721
13553
|
if (unit.operationInfo.document !== void 0) {
|
|
12722
13554
|
raw.graphqlDocument = unit.operationInfo.document;
|
|
12723
13555
|
}
|
|
13556
|
+
if (unit.operationInfo.unresolvedFragments !== void 0) {
|
|
13557
|
+
raw.graphqlUnresolvedFragments = unit.operationInfo.unresolvedFragments;
|
|
13558
|
+
}
|
|
12724
13559
|
if (unit.operationInfo.unresolved !== void 0) {
|
|
12725
13560
|
raw.graphqlUnresolvedDocument = unit.operationInfo.unresolved;
|
|
12726
13561
|
}
|
|
@@ -12874,6 +13709,37 @@ function fileImporting(project, modulePrefix) {
|
|
|
12874
13709
|
}
|
|
12875
13710
|
return void 0;
|
|
12876
13711
|
}
|
|
13712
|
+
function liftSchemasOntoDocuments(summaries) {
|
|
13713
|
+
const sdlByDocument = /* @__PURE__ */ new Map();
|
|
13714
|
+
for (const summary of summaries) {
|
|
13715
|
+
const label = (0, import_behavioral_ir6.readSourceDocumentMetadata)(summary)?.label;
|
|
13716
|
+
const graphql = (0, import_behavioral_ir6.readGraphqlMetadata)(summary);
|
|
13717
|
+
if (label === void 0 || graphql?.schemaSdl === void 0) {
|
|
13718
|
+
continue;
|
|
13719
|
+
}
|
|
13720
|
+
sdlByDocument.set(label, graphql.schemaSdl);
|
|
13721
|
+
const { schemaSdl: _movedToTheDocument, ...rest } = graphql;
|
|
13722
|
+
summary.metadata = (0, import_behavioral_ir6.withGraphqlMetadata)(summary.metadata, rest);
|
|
13723
|
+
}
|
|
13724
|
+
for (const [label, schemaSdl] of sdlByDocument) {
|
|
13725
|
+
summaries.push(schemaDocumentSummary(label, schemaSdl));
|
|
13726
|
+
}
|
|
13727
|
+
}
|
|
13728
|
+
function schemaDocumentSummary(label, schemaSdl) {
|
|
13729
|
+
return {
|
|
13730
|
+
kind: "library",
|
|
13731
|
+
location: { file: label, range: { start: 0, end: 0 }, exportName: null },
|
|
13732
|
+
identity: { name: label, exportPath: null, boundaryBinding: null },
|
|
13733
|
+
inputs: [],
|
|
13734
|
+
transitions: [],
|
|
13735
|
+
gaps: [],
|
|
13736
|
+
confidence: { source: "declared", level: "high" },
|
|
13737
|
+
metadata: (0, import_behavioral_ir6.withGraphqlMetadata)(
|
|
13738
|
+
(0, import_behavioral_ir6.withSourceDocumentMetadata)(void 0, { label }),
|
|
13739
|
+
{ schemaSdl }
|
|
13740
|
+
)
|
|
13741
|
+
};
|
|
13742
|
+
}
|
|
12877
13743
|
function libraryEnvReadMarker(pack, declared, importer) {
|
|
12878
13744
|
return {
|
|
12879
13745
|
kind: "library",
|
|
@@ -12991,8 +13857,8 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
|
|
|
12991
13857
|
if (pathArg === void 0) {
|
|
12992
13858
|
continue;
|
|
12993
13859
|
}
|
|
12994
|
-
const
|
|
12995
|
-
if (
|
|
13860
|
+
const path12 = literalOrTemplate(pathArg);
|
|
13861
|
+
if (path12 === void 0) {
|
|
12996
13862
|
continue;
|
|
12997
13863
|
}
|
|
12998
13864
|
const callerFunc = enclosingFunction(callExpr);
|
|
@@ -13004,7 +13870,7 @@ function synthesizeCallerSummaries(wrapper, _project, options) {
|
|
|
13004
13870
|
continue;
|
|
13005
13871
|
}
|
|
13006
13872
|
seen.add(dedupKey);
|
|
13007
|
-
out.push(buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
13873
|
+
out.push(buildCallerSummary(wrapper, callerFunc, callExpr, path12, options));
|
|
13008
13874
|
}
|
|
13009
13875
|
return out;
|
|
13010
13876
|
}
|
|
@@ -13056,12 +13922,12 @@ function literalOrTemplate(arg) {
|
|
|
13056
13922
|
return arg.getLiteralValue();
|
|
13057
13923
|
}
|
|
13058
13924
|
if (import_ts_morph56.Node.isTemplateExpression(arg)) {
|
|
13059
|
-
let
|
|
13925
|
+
let path12 = arg.getHead().getLiteralText();
|
|
13060
13926
|
for (const span of arg.getTemplateSpans()) {
|
|
13061
|
-
|
|
13062
|
-
|
|
13927
|
+
path12 += `{${placeholderName(span.getExpression())}}`;
|
|
13928
|
+
path12 += span.getLiteral().getLiteralText();
|
|
13063
13929
|
}
|
|
13064
|
-
return
|
|
13930
|
+
return path12;
|
|
13065
13931
|
}
|
|
13066
13932
|
return void 0;
|
|
13067
13933
|
}
|
|
@@ -13078,7 +13944,7 @@ function callerName(func) {
|
|
|
13078
13944
|
}
|
|
13079
13945
|
return "anonymous";
|
|
13080
13946
|
}
|
|
13081
|
-
function buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
13947
|
+
function buildCallerSummary(wrapper, callerFunc, callExpr, path12, options) {
|
|
13082
13948
|
const wrapperBinding = wrapper.summary.identity.boundaryBinding;
|
|
13083
13949
|
const wrapperRest = wrapperBinding?.semantics.name === "rest" ? wrapperBinding.semantics : null;
|
|
13084
13950
|
const syntheticPack = {
|
|
@@ -13110,7 +13976,7 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path11, options) {
|
|
|
13110
13976
|
raw.boundaryBinding = (0, import_behavioral_ir6.restBinding)({
|
|
13111
13977
|
transport: wrapperBinding?.transport ?? "http",
|
|
13112
13978
|
method: wrapperRest?.method ?? null,
|
|
13113
|
-
path:
|
|
13979
|
+
path: path12,
|
|
13114
13980
|
recognition: wrapperBinding?.recognition ?? "unknown"
|
|
13115
13981
|
});
|
|
13116
13982
|
const summary = (0, import_extractor5.assembleSummary)(raw, options);
|
|
@@ -13124,8 +13990,8 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path11, options) {
|
|
|
13124
13990
|
summary.confidence = { source: "inferred_static", level: "low" };
|
|
13125
13991
|
return summary;
|
|
13126
13992
|
}
|
|
13127
|
-
function named(summaries, workspace) {
|
|
13128
|
-
const projectRoot = commonDirectoryOf(summaries.map((s) => s.location.file));
|
|
13993
|
+
function named(summaries, workspace, runRoot) {
|
|
13994
|
+
const projectRoot = runRoot ?? commonDirectoryOf(summaries.map((s) => s.location.file));
|
|
13129
13995
|
nameSummaries(summaries, {
|
|
13130
13996
|
workspace: workspace ?? workspaceNameFor(projectRoot),
|
|
13131
13997
|
projectRoot
|
|
@@ -13183,6 +14049,7 @@ function createTypeScriptAdapter(config) {
|
|
|
13183
14049
|
skipAddingFilesFromTsConfig: true
|
|
13184
14050
|
} : { skipAddingFilesFromTsConfig: true }
|
|
13185
14051
|
);
|
|
14052
|
+
const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(import_node_path9.default.dirname(config.tsConfigFilePath)) : void 0);
|
|
13186
14053
|
let lazyBootstrapped = false;
|
|
13187
14054
|
let projectFileSet;
|
|
13188
14055
|
const cacheDir = declineWhenRunFromSource(
|
|
@@ -13223,7 +14090,7 @@ function createTypeScriptAdapter(config) {
|
|
|
13223
14090
|
)
|
|
13224
14091
|
);
|
|
13225
14092
|
}
|
|
13226
|
-
return named(summaries, config.workspace);
|
|
14093
|
+
return named(summaries, config.workspace, runRoot);
|
|
13227
14094
|
},
|
|
13228
14095
|
async extractAll() {
|
|
13229
14096
|
const timer = createTimer();
|
|
@@ -13256,7 +14123,25 @@ function createTypeScriptAdapter(config) {
|
|
|
13256
14123
|
if (config.onTiming !== void 0) {
|
|
13257
14124
|
config.onTiming(timer.report());
|
|
13258
14125
|
}
|
|
13259
|
-
return named(lookup.summaries, config.workspace);
|
|
14126
|
+
return named(lookup.summaries, config.workspace, runRoot);
|
|
14127
|
+
}
|
|
14128
|
+
const plan = lookup.diagnostic.missReason === "files-changed" ? await timer.timeAsync("cache.plan", () => cache.plan(cacheInput)) : null;
|
|
14129
|
+
if (plan !== null && plan.changed.size === 0 && plan.removed.size === 0) {
|
|
14130
|
+
try {
|
|
14131
|
+
await cache.write(
|
|
14132
|
+
cacheInput,
|
|
14133
|
+
plan.allSummaries(),
|
|
14134
|
+
plan.attribution()
|
|
14135
|
+
);
|
|
14136
|
+
} catch {
|
|
14137
|
+
}
|
|
14138
|
+
if (config.onCacheDiagnostic !== void 0) {
|
|
14139
|
+
config.onCacheDiagnostic({ kind: "hit" });
|
|
14140
|
+
}
|
|
14141
|
+
if (config.onTiming !== void 0) {
|
|
14142
|
+
config.onTiming(timer.report());
|
|
14143
|
+
}
|
|
14144
|
+
return named(plan.allSummaries(), config.workspace, runRoot);
|
|
13260
14145
|
}
|
|
13261
14146
|
let candidatePaths = null;
|
|
13262
14147
|
if (lazyEligible) {
|
|
@@ -13287,16 +14172,58 @@ function createTypeScriptAdapter(config) {
|
|
|
13287
14172
|
"mountPrefix",
|
|
13288
14173
|
() => buildMountPrefixIndex(packsByFile, resolution)
|
|
13289
14174
|
);
|
|
14175
|
+
const caching = cacheDir !== null;
|
|
14176
|
+
const validRoots = /* @__PURE__ */ new Set();
|
|
14177
|
+
if (plan !== null) {
|
|
14178
|
+
const packNamesByPath = /* @__PURE__ */ new Map();
|
|
14179
|
+
for (const [sf, packs] of packsByFile) {
|
|
14180
|
+
packNamesByPath.set(
|
|
14181
|
+
sf.getFilePath(),
|
|
14182
|
+
packs.map((p) => p.name).sort().join(",")
|
|
14183
|
+
);
|
|
14184
|
+
}
|
|
14185
|
+
for (const rootPath of plan.validRoots) {
|
|
14186
|
+
const record = plan.roots.get(rootPath);
|
|
14187
|
+
if (record === void 0) {
|
|
14188
|
+
continue;
|
|
14189
|
+
}
|
|
14190
|
+
if (!mountAssumptionsAgree(record, mountPrefixes)) {
|
|
14191
|
+
continue;
|
|
14192
|
+
}
|
|
14193
|
+
const stored = [...record.packs].sort().join(",");
|
|
14194
|
+
if ((packNamesByPath.get(rootPath) ?? "") !== stored) {
|
|
14195
|
+
continue;
|
|
14196
|
+
}
|
|
14197
|
+
validRoots.add(rootPath);
|
|
14198
|
+
}
|
|
14199
|
+
}
|
|
14200
|
+
const reused = plan !== null && validRoots.size > 0 ? plan.reuse(validRoots) : null;
|
|
13290
14201
|
const claimedUnits = /* @__PURE__ */ new Map();
|
|
14202
|
+
if (reused !== null && plan !== null) {
|
|
14203
|
+
for (const rootPath of validRoots) {
|
|
14204
|
+
for (const claim of plan.roots.get(rootPath)?.claims ?? []) {
|
|
14205
|
+
claimedUnits.set(claim.key, { pack: claim.pack, file: rootPath });
|
|
14206
|
+
}
|
|
14207
|
+
}
|
|
14208
|
+
}
|
|
14209
|
+
const walkList = reused === null ? sourceFiles : sourceFiles.filter((sf) => !validRoots.has(sf.getFilePath()));
|
|
14210
|
+
const sinkByRoot = /* @__PURE__ */ new Map();
|
|
14211
|
+
const ownersBySummary = /* @__PURE__ */ new Map();
|
|
13291
14212
|
timer.time("extract per-file", () => {
|
|
13292
|
-
for (const sourceFile of
|
|
14213
|
+
for (const sourceFile of walkList) {
|
|
14214
|
+
const rootPath = sourceFile.getFilePath();
|
|
14215
|
+
const sink = createDependencySink();
|
|
14216
|
+
if (caching) {
|
|
14217
|
+
sinkByRoot.set(rootPath, sink);
|
|
14218
|
+
}
|
|
13293
14219
|
const applicablePacks = packsByFile.get(sourceFile);
|
|
13294
14220
|
if (applicablePacks === void 0) {
|
|
13295
14221
|
continue;
|
|
13296
14222
|
}
|
|
13297
14223
|
try {
|
|
13298
|
-
|
|
13299
|
-
|
|
14224
|
+
const walked = withDependencySink(
|
|
14225
|
+
sink,
|
|
14226
|
+
() => extractFromSourceFile(
|
|
13300
14227
|
sourceFile,
|
|
13301
14228
|
applicablePacks,
|
|
13302
14229
|
claimedUnits,
|
|
@@ -13306,6 +14233,10 @@ function createTypeScriptAdapter(config) {
|
|
|
13306
14233
|
mountPrefixes
|
|
13307
14234
|
)
|
|
13308
14235
|
);
|
|
14236
|
+
for (const summary of walked) {
|
|
14237
|
+
ownersBySummary.set(summary, /* @__PURE__ */ new Set([rootPath]));
|
|
14238
|
+
}
|
|
14239
|
+
summaries.push(...walked);
|
|
13309
14240
|
} catch (error) {
|
|
13310
14241
|
if (!(error instanceof RangeError)) {
|
|
13311
14242
|
throw error;
|
|
@@ -13314,23 +14245,32 @@ function createTypeScriptAdapter(config) {
|
|
|
13314
14245
|
}
|
|
13315
14246
|
}
|
|
13316
14247
|
});
|
|
14248
|
+
const wrapperInput = reused === null ? summaries : [...summaries, ...reused.summaries];
|
|
13317
14249
|
const withWrappers = timer.time(
|
|
13318
14250
|
"expandWrapperCallers",
|
|
13319
|
-
() => expandWrapperCallers(
|
|
14251
|
+
() => expandWrapperCallers(wrapperInput, project, config.extractorOptions)
|
|
13320
14252
|
);
|
|
14253
|
+
const pipeline = reused === null ? withWrappers : [...summaries, ...withWrappers.slice(wrapperInput.length)];
|
|
13321
14254
|
const withSubUnits = timer.time(
|
|
13322
14255
|
"synthesizeSubUnits",
|
|
13323
14256
|
() => synthesizeSubUnits(
|
|
13324
|
-
|
|
14257
|
+
pipeline,
|
|
13325
14258
|
project,
|
|
13326
14259
|
config.frameworks,
|
|
13327
14260
|
config.extractorOptions,
|
|
13328
|
-
tallies
|
|
14261
|
+
tallies,
|
|
14262
|
+
(created, parent) => {
|
|
14263
|
+
const parentOwners = ownersBySummary.get(parent);
|
|
14264
|
+
if (parentOwners !== void 0) {
|
|
14265
|
+
ownersBySummary.set(created, new Set(parentOwners));
|
|
14266
|
+
}
|
|
14267
|
+
}
|
|
13329
14268
|
)
|
|
13330
14269
|
);
|
|
13331
14270
|
const closureFacts = {
|
|
13332
14271
|
db: new import_datalog6.Database(),
|
|
13333
|
-
unitKeyBySummary: /* @__PURE__ */ new Map()
|
|
14272
|
+
unitKeyBySummary: /* @__PURE__ */ new Map(),
|
|
14273
|
+
...caching ? { filesByKey: /* @__PURE__ */ new Map() } : {}
|
|
13334
14274
|
};
|
|
13335
14275
|
const withClosure = config.includeReachable !== false ? timer.time(
|
|
13336
14276
|
"expandReachableClosure",
|
|
@@ -13347,13 +14287,29 @@ function createTypeScriptAdapter(config) {
|
|
|
13347
14287
|
),
|
|
13348
14288
|
access: collectAccessRecognizers(config.frameworks, tallies),
|
|
13349
14289
|
resolveWrittenValue: (value) => resolution.resolveWrittenValue(value),
|
|
13350
|
-
|
|
13351
|
-
}
|
|
14290
|
+
resolveCallableSources: (value, alsoFrom) => resolution.resolveCallableSources(value, alsoFrom)
|
|
14291
|
+
},
|
|
14292
|
+
// Reached units the cache already serves emit nothing,
|
|
14293
|
+
// the way a cold run's seeds do not.
|
|
14294
|
+
reused?.summaries ?? []
|
|
13352
14295
|
)
|
|
13353
14296
|
) : withSubUnits;
|
|
14297
|
+
const closureOwnership = caching && config.includeReachable !== false ? timer.time(
|
|
14298
|
+
"cache.attributeClosure",
|
|
14299
|
+
() => attributeReachedSummaries(
|
|
14300
|
+
withSubUnits,
|
|
14301
|
+
withClosure.slice(withSubUnits.length),
|
|
14302
|
+
closureFacts,
|
|
14303
|
+
ownersBySummary
|
|
14304
|
+
)
|
|
14305
|
+
) : null;
|
|
14306
|
+
const merged = timer.time(
|
|
14307
|
+
"cache.merge",
|
|
14308
|
+
() => mergeWithReused(reused, withClosure, ownersBySummary)
|
|
14309
|
+
);
|
|
13354
14310
|
const enriched = timer.time(
|
|
13355
14311
|
"enrichRethrows",
|
|
13356
|
-
() => enrichRethrows(
|
|
14312
|
+
() => enrichRethrows(merged.summaries, project, closureFacts)
|
|
13357
14313
|
);
|
|
13358
14314
|
if (config.includeReachable !== false) {
|
|
13359
14315
|
timer.time(
|
|
@@ -13369,6 +14325,10 @@ function createTypeScriptAdapter(config) {
|
|
|
13369
14325
|
"emitLibraryEnvReadMarkers",
|
|
13370
14326
|
() => emitLibraryEnvReadMarkers(enriched, project, config.frameworks)
|
|
13371
14327
|
);
|
|
14328
|
+
timer.time(
|
|
14329
|
+
"liftSchemasOntoDocuments",
|
|
14330
|
+
() => liftSchemasOntoDocuments(enriched)
|
|
14331
|
+
);
|
|
13372
14332
|
timer.time(
|
|
13373
14333
|
"stampGraphqlClientRefs",
|
|
13374
14334
|
() => stampGraphqlClientRefs(
|
|
@@ -13378,12 +14338,41 @@ function createTypeScriptAdapter(config) {
|
|
|
13378
14338
|
resolution
|
|
13379
14339
|
)
|
|
13380
14340
|
);
|
|
14341
|
+
if (config.onCacheDiagnostic !== void 0 && plan !== null) {
|
|
14342
|
+
config.onCacheDiagnostic({
|
|
14343
|
+
kind: "partial",
|
|
14344
|
+
partial: {
|
|
14345
|
+
filesChanged: plan.changed.size,
|
|
14346
|
+
filesRemoved: plan.removed.size,
|
|
14347
|
+
rootsReused: validRoots.size,
|
|
14348
|
+
rootsReextracted: walkList.length,
|
|
14349
|
+
rootsDeclined: plan.rootsDeclined,
|
|
14350
|
+
summariesReused: merged.reusedKept.length
|
|
14351
|
+
}
|
|
14352
|
+
});
|
|
14353
|
+
}
|
|
13381
14354
|
await timer.timeAsync("cache.write", async () => {
|
|
13382
|
-
if (enriched.length === 0) {
|
|
14355
|
+
if (!caching || enriched.length === 0) {
|
|
13383
14356
|
return;
|
|
13384
14357
|
}
|
|
13385
14358
|
try {
|
|
13386
|
-
|
|
14359
|
+
const attribution = buildCacheAttribution({
|
|
14360
|
+
project,
|
|
14361
|
+
plan,
|
|
14362
|
+
validRoots,
|
|
14363
|
+
sinkByRoot,
|
|
14364
|
+
ownersBySummary,
|
|
14365
|
+
closureOwnership,
|
|
14366
|
+
unitKeyBySummary: closureFacts.unitKeyBySummary,
|
|
14367
|
+
filesByKey: closureFacts.filesByKey,
|
|
14368
|
+
packsByFile,
|
|
14369
|
+
reusedKept: merged.reusedKept,
|
|
14370
|
+
reusedOwners: merged.reusedOwners,
|
|
14371
|
+
// Everything after the reused prefix, the passes' own
|
|
14372
|
+
// additions (markers, schema documents) included.
|
|
14373
|
+
fresh: enriched.slice(merged.reusedKept.length)
|
|
14374
|
+
});
|
|
14375
|
+
await cache.write(cacheInput, enriched, attribution);
|
|
13387
14376
|
} catch {
|
|
13388
14377
|
}
|
|
13389
14378
|
});
|
|
@@ -13396,7 +14385,7 @@ function createTypeScriptAdapter(config) {
|
|
|
13396
14385
|
packs: config.frameworks,
|
|
13397
14386
|
tallies,
|
|
13398
14387
|
filesInProject: tsconfigFileList?.length ?? null,
|
|
13399
|
-
filesWalked:
|
|
14388
|
+
filesWalked: walkList.length,
|
|
13400
14389
|
summaries: enriched,
|
|
13401
14390
|
tsConfigFilePath: config.tsConfigFilePath,
|
|
13402
14391
|
projectRoot: commonDirectoryOf(
|
|
@@ -13406,17 +14395,204 @@ function createTypeScriptAdapter(config) {
|
|
|
13406
14395
|
})
|
|
13407
14396
|
);
|
|
13408
14397
|
}
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
)
|
|
13413
|
-
|
|
13414
|
-
});
|
|
13415
|
-
return enriched;
|
|
14398
|
+
return named(
|
|
14399
|
+
enriched,
|
|
14400
|
+
config.workspace,
|
|
14401
|
+
runRoot ?? commonDirectoryOf(sourceFiles.map((f) => f.getFilePath()))
|
|
14402
|
+
);
|
|
13416
14403
|
}
|
|
13417
14404
|
};
|
|
13418
14405
|
}
|
|
13419
|
-
function
|
|
14406
|
+
function mountAssumptionsAgree(record, index) {
|
|
14407
|
+
return Object.entries(record.mountPrefixes).every(
|
|
14408
|
+
([childId, prefix]) => (index.prefixForId?.(childId) ?? "") === prefix
|
|
14409
|
+
);
|
|
14410
|
+
}
|
|
14411
|
+
function attributeReachedSummaries(seeds, reached, facts, owners) {
|
|
14412
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
14413
|
+
for (const [from, to] of facts.db.facts("calls")) {
|
|
14414
|
+
const key = String(from);
|
|
14415
|
+
const bucket = adjacency.get(key) ?? [];
|
|
14416
|
+
bucket.push(String(to));
|
|
14417
|
+
adjacency.set(key, bucket);
|
|
14418
|
+
}
|
|
14419
|
+
const seedKeysByRoot = /* @__PURE__ */ new Map();
|
|
14420
|
+
for (const seed of seeds) {
|
|
14421
|
+
const key = facts.unitKeyBySummary.get(seed);
|
|
14422
|
+
if (key === void 0) {
|
|
14423
|
+
continue;
|
|
14424
|
+
}
|
|
14425
|
+
for (const root of owners.get(seed) ?? []) {
|
|
14426
|
+
const bucket = seedKeysByRoot.get(root) ?? [];
|
|
14427
|
+
bucket.push(key);
|
|
14428
|
+
seedKeysByRoot.set(root, bucket);
|
|
14429
|
+
}
|
|
14430
|
+
}
|
|
14431
|
+
const reachableByRoot = /* @__PURE__ */ new Map();
|
|
14432
|
+
const rootsByKey = /* @__PURE__ */ new Map();
|
|
14433
|
+
for (const [root, seedKeys] of seedKeysByRoot) {
|
|
14434
|
+
const seen = new Set(seedKeys);
|
|
14435
|
+
const queue = [...seedKeys];
|
|
14436
|
+
while (queue.length > 0) {
|
|
14437
|
+
const key = queue.pop();
|
|
14438
|
+
if (key === void 0) {
|
|
14439
|
+
continue;
|
|
14440
|
+
}
|
|
14441
|
+
for (const next of adjacency.get(key) ?? []) {
|
|
14442
|
+
if (!seen.has(next)) {
|
|
14443
|
+
seen.add(next);
|
|
14444
|
+
queue.push(next);
|
|
14445
|
+
}
|
|
14446
|
+
}
|
|
14447
|
+
const keyRoots = rootsByKey.get(key) ?? /* @__PURE__ */ new Set();
|
|
14448
|
+
keyRoots.add(root);
|
|
14449
|
+
rootsByKey.set(key, keyRoots);
|
|
14450
|
+
}
|
|
14451
|
+
reachableByRoot.set(root, seen);
|
|
14452
|
+
}
|
|
14453
|
+
for (const summary of reached) {
|
|
14454
|
+
const key = facts.unitKeyBySummary.get(summary);
|
|
14455
|
+
if (key === void 0) {
|
|
14456
|
+
continue;
|
|
14457
|
+
}
|
|
14458
|
+
const keyRoots = rootsByKey.get(key);
|
|
14459
|
+
if (keyRoots !== void 0 && keyRoots.size > 0) {
|
|
14460
|
+
owners.set(summary, new Set(keyRoots));
|
|
14461
|
+
}
|
|
14462
|
+
}
|
|
14463
|
+
return { reachableByRoot, rootsByKey };
|
|
14464
|
+
}
|
|
14465
|
+
function fileOfNodeKey(key) {
|
|
14466
|
+
const cut = key.lastIndexOf(":");
|
|
14467
|
+
return cut <= 0 ? null : key.slice(0, cut);
|
|
14468
|
+
}
|
|
14469
|
+
function summaryMergeKey(summary) {
|
|
14470
|
+
return JSON.stringify([
|
|
14471
|
+
summary.location.file,
|
|
14472
|
+
summary.location.range.start,
|
|
14473
|
+
summary.location.range.end,
|
|
14474
|
+
summary.kind,
|
|
14475
|
+
summary.identity.name,
|
|
14476
|
+
summary.identity.exportPath,
|
|
14477
|
+
summary.identity.boundaryBinding
|
|
14478
|
+
]);
|
|
14479
|
+
}
|
|
14480
|
+
function mergeWithReused(reused, fresh, ownersBySummary) {
|
|
14481
|
+
if (reused === null) {
|
|
14482
|
+
return { summaries: fresh, reusedKept: [], reusedOwners: [] };
|
|
14483
|
+
}
|
|
14484
|
+
const freshByKey = /* @__PURE__ */ new Map();
|
|
14485
|
+
for (const summary of fresh) {
|
|
14486
|
+
freshByKey.set(summaryMergeKey(summary), summary);
|
|
14487
|
+
}
|
|
14488
|
+
const reusedKept = [];
|
|
14489
|
+
const reusedOwners = [];
|
|
14490
|
+
reused.summaries.forEach((summary, i) => {
|
|
14491
|
+
const owners = reused.owners[i] ?? [];
|
|
14492
|
+
const supersededBy = freshByKey.get(summaryMergeKey(summary));
|
|
14493
|
+
if (supersededBy !== void 0) {
|
|
14494
|
+
const freshOwners = ownersBySummary.get(supersededBy) ?? /* @__PURE__ */ new Set();
|
|
14495
|
+
for (const owner of owners) {
|
|
14496
|
+
freshOwners.add(owner);
|
|
14497
|
+
}
|
|
14498
|
+
ownersBySummary.set(supersededBy, freshOwners);
|
|
14499
|
+
return;
|
|
14500
|
+
}
|
|
14501
|
+
reusedKept.push(summary);
|
|
14502
|
+
reusedOwners.push(owners);
|
|
14503
|
+
});
|
|
14504
|
+
return { summaries: [...reusedKept, ...fresh], reusedKept, reusedOwners };
|
|
14505
|
+
}
|
|
14506
|
+
function readsRunLevelJoins(summary) {
|
|
14507
|
+
if ((0, import_behavioral_ir6.readSourceDocumentMetadata)(summary) !== void 0) {
|
|
14508
|
+
return true;
|
|
14509
|
+
}
|
|
14510
|
+
if ((0, import_behavioral_ir6.readGraphqlMetadata)(summary)?.client !== void 0) {
|
|
14511
|
+
return true;
|
|
14512
|
+
}
|
|
14513
|
+
const semantics = summary.identity.boundaryBinding?.semantics;
|
|
14514
|
+
return semantics !== void 0 && "operationType" in semantics;
|
|
14515
|
+
}
|
|
14516
|
+
function buildCacheAttribution(args) {
|
|
14517
|
+
const references = createReferenceIndex(
|
|
14518
|
+
args.project.getSourceFiles().filter((sf) => !sf.isDeclarationFile())
|
|
14519
|
+
);
|
|
14520
|
+
const packNamesByPath = /* @__PURE__ */ new Map();
|
|
14521
|
+
for (const [sf, packs] of args.packsByFile) {
|
|
14522
|
+
packNamesByPath.set(
|
|
14523
|
+
sf.getFilePath(),
|
|
14524
|
+
packs.map((p) => p.name)
|
|
14525
|
+
);
|
|
14526
|
+
}
|
|
14527
|
+
const summariesByRoot = /* @__PURE__ */ new Map();
|
|
14528
|
+
for (const summary of args.fresh) {
|
|
14529
|
+
for (const root of args.ownersBySummary.get(summary) ?? []) {
|
|
14530
|
+
const bucket = summariesByRoot.get(root) ?? [];
|
|
14531
|
+
bucket.push(summary);
|
|
14532
|
+
summariesByRoot.set(root, bucket);
|
|
14533
|
+
}
|
|
14534
|
+
}
|
|
14535
|
+
const roots = [];
|
|
14536
|
+
for (const [rootPath, sink] of args.sinkByRoot) {
|
|
14537
|
+
const deps = new Set(sink.files);
|
|
14538
|
+
for (const dep of references.directOf(rootPath)) {
|
|
14539
|
+
deps.add(dep);
|
|
14540
|
+
}
|
|
14541
|
+
let cacheable = true;
|
|
14542
|
+
for (const summary of summariesByRoot.get(rootPath) ?? []) {
|
|
14543
|
+
deps.add(summary.location.file);
|
|
14544
|
+
if (readsRunLevelJoins(summary)) {
|
|
14545
|
+
cacheable = false;
|
|
14546
|
+
}
|
|
14547
|
+
}
|
|
14548
|
+
const reachable = args.closureOwnership?.reachableByRoot.get(rootPath) ?? [];
|
|
14549
|
+
for (const key of reachable) {
|
|
14550
|
+
const keyFile = fileOfNodeKey(key);
|
|
14551
|
+
if (keyFile !== null) {
|
|
14552
|
+
deps.add(keyFile);
|
|
14553
|
+
for (const hop of references.directOf(keyFile)) {
|
|
14554
|
+
deps.add(hop);
|
|
14555
|
+
}
|
|
14556
|
+
}
|
|
14557
|
+
for (const filePath of args.filesByKey?.get(key) ?? []) {
|
|
14558
|
+
deps.add(filePath);
|
|
14559
|
+
}
|
|
14560
|
+
}
|
|
14561
|
+
deps.delete(rootPath);
|
|
14562
|
+
roots.push({
|
|
14563
|
+
path: rootPath,
|
|
14564
|
+
cacheable,
|
|
14565
|
+
deps: [...deps].sort(),
|
|
14566
|
+
claims: sink.claims,
|
|
14567
|
+
mountPrefixes: Object.fromEntries(sink.mountPrefixes),
|
|
14568
|
+
packs: packNamesByPath.get(rootPath) ?? []
|
|
14569
|
+
});
|
|
14570
|
+
}
|
|
14571
|
+
if (args.plan !== null) {
|
|
14572
|
+
for (const rootPath of args.validRoots) {
|
|
14573
|
+
const record = args.plan.roots.get(rootPath);
|
|
14574
|
+
if (record !== void 0) {
|
|
14575
|
+
roots.push(record);
|
|
14576
|
+
}
|
|
14577
|
+
}
|
|
14578
|
+
}
|
|
14579
|
+
const reusedOwners = args.reusedKept.map((summary, i) => {
|
|
14580
|
+
const combined = new Set(args.reusedOwners[i] ?? []);
|
|
14581
|
+
const key = args.unitKeyBySummary.get(summary);
|
|
14582
|
+
if (key !== void 0) {
|
|
14583
|
+
for (const root of args.closureOwnership?.rootsByKey.get(key) ?? []) {
|
|
14584
|
+
combined.add(root);
|
|
14585
|
+
}
|
|
14586
|
+
}
|
|
14587
|
+
return [...combined];
|
|
14588
|
+
});
|
|
14589
|
+
const owners = [
|
|
14590
|
+
...reusedOwners,
|
|
14591
|
+
...args.fresh.map((s) => [...args.ownersBySummary.get(s) ?? []])
|
|
14592
|
+
];
|
|
14593
|
+
return { roots, owners };
|
|
14594
|
+
}
|
|
14595
|
+
function synthesizeSubUnits(summaries, project, frameworks, options, tallies, onCreated) {
|
|
13420
14596
|
const packByRecognition = /* @__PURE__ */ new Map();
|
|
13421
14597
|
for (const pack of frameworks) {
|
|
13422
14598
|
packByRecognition.set(pack.name, pack);
|
|
@@ -13459,6 +14635,7 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies) {
|
|
|
13459
14635
|
);
|
|
13460
14636
|
if (summary !== null) {
|
|
13461
14637
|
synthesized.push(summary);
|
|
14638
|
+
onCreated?.(summary, parent);
|
|
13462
14639
|
}
|
|
13463
14640
|
}
|
|
13464
14641
|
}
|
|
@@ -13467,14 +14644,7 @@ function synthesizeSubUnits(summaries, project, frameworks, options, tallies) {
|
|
|
13467
14644
|
var DEFAULT_SUB_UNIT_TERMINALS = [
|
|
13468
14645
|
{ kind: "return", match: { type: "returnStatement" }, extraction: {} },
|
|
13469
14646
|
{ kind: "throw", match: { type: "throwExpression" }, extraction: {} },
|
|
13470
|
-
|
|
13471
|
-
// fall-through gives it a default transition. HTTP packs do not opt in:
|
|
13472
|
-
// a handler that sends no response should come out with none.
|
|
13473
|
-
{
|
|
13474
|
-
kind: "return",
|
|
13475
|
-
match: { type: "functionFallthrough" },
|
|
13476
|
-
extraction: {}
|
|
13477
|
-
}
|
|
14647
|
+
FUNCTION_FALLTHROUGH_TERMINAL
|
|
13478
14648
|
];
|
|
13479
14649
|
var DEFAULT_SUB_UNIT_INPUT_MAPPING = {
|
|
13480
14650
|
type: "positionalParams",
|
|
@@ -13659,7 +14829,7 @@ function readStringArg(arg) {
|
|
|
13659
14829
|
}
|
|
13660
14830
|
return candidate.value;
|
|
13661
14831
|
}
|
|
13662
|
-
function
|
|
14832
|
+
function rootIdentifier2(node) {
|
|
13663
14833
|
let current2 = node;
|
|
13664
14834
|
while (import_ts_morph58.Node.isPropertyAccessExpression(current2)) {
|
|
13665
14835
|
current2 = current2.getExpression();
|
|
@@ -13667,10 +14837,165 @@ function rootIdentifier(node) {
|
|
|
13667
14837
|
return import_ts_morph58.Node.isIdentifier(current2) ? current2 : null;
|
|
13668
14838
|
}
|
|
13669
14839
|
|
|
14840
|
+
// src/facts/why.ts
|
|
14841
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
14842
|
+
var import_ts_morph59 = require("ts-morph");
|
|
14843
|
+
var import_resolution2 = require("@suss/resolution");
|
|
14844
|
+
var JS_PHRASES = {
|
|
14845
|
+
bind: ({ tuple, describe }) => ({
|
|
14846
|
+
reason: `${describe(tuple[0])} is a .bind of ${describe(tuple[1])}, which runs the same function`
|
|
14847
|
+
})
|
|
14848
|
+
};
|
|
14849
|
+
var WhySession = class {
|
|
14850
|
+
project;
|
|
14851
|
+
store;
|
|
14852
|
+
root;
|
|
14853
|
+
constructor(options) {
|
|
14854
|
+
this.root = import_node_path11.default.resolve(options.dir);
|
|
14855
|
+
const tsconfig = findNearestTsconfig(this.root);
|
|
14856
|
+
this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph59.Project({ tsConfigFilePath: tsconfig });
|
|
14857
|
+
this.store = new ResolutionStore();
|
|
14858
|
+
}
|
|
14859
|
+
/**
|
|
14860
|
+
* The smallest expression on `line` of `file` whose text is exactly
|
|
14861
|
+
* `text`, or null. Spelled from the person's side: the name as
|
|
14862
|
+
* written, not a node id.
|
|
14863
|
+
*/
|
|
14864
|
+
findExpression(file, line, text) {
|
|
14865
|
+
const sourceFile = this.sourceFileAt(file);
|
|
14866
|
+
if (sourceFile === null) {
|
|
14867
|
+
return null;
|
|
14868
|
+
}
|
|
14869
|
+
let found = null;
|
|
14870
|
+
sourceFile.forEachDescendant((node) => {
|
|
14871
|
+
if (import_ts_morph59.Node.isExpression(node) && node.getStartLineNumber() === line && node.getText() === text && (found === null || node.getWidth() <= found.getWidth())) {
|
|
14872
|
+
found = node;
|
|
14873
|
+
}
|
|
14874
|
+
});
|
|
14875
|
+
return found;
|
|
14876
|
+
}
|
|
14877
|
+
/**
|
|
14878
|
+
* The callee of the call written as `calleeText` between `startLine`
|
|
14879
|
+
* and `endLine` of `file`, or null. This is how a summary's recorded
|
|
14880
|
+
* callee gets back to its node: the summary keeps source text and a
|
|
14881
|
+
* range, not ids.
|
|
14882
|
+
*/
|
|
14883
|
+
findCallee(file, startLine, endLine, calleeText) {
|
|
14884
|
+
const sourceFile = this.sourceFileAt(file);
|
|
14885
|
+
if (sourceFile === null) {
|
|
14886
|
+
return null;
|
|
14887
|
+
}
|
|
14888
|
+
for (const call of sourceFile.getDescendantsOfKind(
|
|
14889
|
+
import_ts_morph59.SyntaxKind.CallExpression
|
|
14890
|
+
)) {
|
|
14891
|
+
const line = call.getStartLineNumber();
|
|
14892
|
+
if (line < startLine || line > endLine) {
|
|
14893
|
+
continue;
|
|
14894
|
+
}
|
|
14895
|
+
if (call.getExpression().getText() === calleeText) {
|
|
14896
|
+
return call.getExpression();
|
|
14897
|
+
}
|
|
14898
|
+
}
|
|
14899
|
+
return null;
|
|
14900
|
+
}
|
|
14901
|
+
/**
|
|
14902
|
+
* Why `value` resolves to what it does: the witness proof, flattened
|
|
14903
|
+
* to the chain and rendered. Null when the value does not resolve,
|
|
14904
|
+
* which the caller says in its own words.
|
|
14905
|
+
*/
|
|
14906
|
+
explain(value, options = {}) {
|
|
14907
|
+
const explained = this.store.explainCallable(value, options);
|
|
14908
|
+
if (explained === null) {
|
|
14909
|
+
return null;
|
|
14910
|
+
}
|
|
14911
|
+
const describe = (atom) => {
|
|
14912
|
+
const node = explained.nodeFor(atom);
|
|
14913
|
+
if (node === void 0) {
|
|
14914
|
+
return this.displayPath(String(atom));
|
|
14915
|
+
}
|
|
14916
|
+
const at = this.locate(node);
|
|
14917
|
+
return `${at.name} (${at.file}:${at.line})`;
|
|
14918
|
+
};
|
|
14919
|
+
const explanation = (0, import_resolution2.explainResolutionProof)(explained.proof, {
|
|
14920
|
+
describe,
|
|
14921
|
+
phrases: JS_PHRASES
|
|
14922
|
+
});
|
|
14923
|
+
if (explanation === null) {
|
|
14924
|
+
return null;
|
|
14925
|
+
}
|
|
14926
|
+
return {
|
|
14927
|
+
explanation,
|
|
14928
|
+
chain: explanation.atoms.map((atom) => describe(atom)),
|
|
14929
|
+
lines: (0, import_resolution2.renderExplanation)(explanation, describe),
|
|
14930
|
+
target: this.locate(explained.target),
|
|
14931
|
+
stats: explained.stats
|
|
14932
|
+
};
|
|
14933
|
+
}
|
|
14934
|
+
/** Where a found node is, in the terms an answer prints. */
|
|
14935
|
+
locate(node) {
|
|
14936
|
+
return {
|
|
14937
|
+
name: displayNameOf(node),
|
|
14938
|
+
file: this.displayPath(node.getSourceFile().getFilePath()),
|
|
14939
|
+
line: node.getStartLineNumber()
|
|
14940
|
+
};
|
|
14941
|
+
}
|
|
14942
|
+
sourceFileAt(file) {
|
|
14943
|
+
const absolute = import_node_path11.default.resolve(this.root, file);
|
|
14944
|
+
const loaded = this.project.getSourceFile(absolute);
|
|
14945
|
+
if (loaded !== void 0) {
|
|
14946
|
+
return loaded;
|
|
14947
|
+
}
|
|
14948
|
+
try {
|
|
14949
|
+
return this.project.addSourceFileAtPath(absolute);
|
|
14950
|
+
} catch {
|
|
14951
|
+
return null;
|
|
14952
|
+
}
|
|
14953
|
+
}
|
|
14954
|
+
/** A module key: a file path said relative to the root, or a package name. */
|
|
14955
|
+
displayPath(key) {
|
|
14956
|
+
if (key.startsWith(this.root)) {
|
|
14957
|
+
return import_node_path11.default.relative(this.root, key);
|
|
14958
|
+
}
|
|
14959
|
+
return key;
|
|
14960
|
+
}
|
|
14961
|
+
};
|
|
14962
|
+
function displayNameOf(node) {
|
|
14963
|
+
if (import_ts_morph59.Node.isIdentifier(node) || import_ts_morph59.Node.isPropertyAccessExpression(node)) {
|
|
14964
|
+
return node.getText();
|
|
14965
|
+
}
|
|
14966
|
+
if (import_ts_morph59.Node.isCallExpression(node) || import_ts_morph59.Node.isNewExpression(node)) {
|
|
14967
|
+
return `${node.getExpression()?.getText() ?? "call"}(...)`;
|
|
14968
|
+
}
|
|
14969
|
+
if (import_ts_morph59.Node.isFunctionDeclaration(node) || import_ts_morph59.Node.isClassDeclaration(node) || import_ts_morph59.Node.isMethodDeclaration(node) || import_ts_morph59.Node.isVariableDeclaration(node)) {
|
|
14970
|
+
const name = node.getName();
|
|
14971
|
+
if (name !== void 0) {
|
|
14972
|
+
return name;
|
|
14973
|
+
}
|
|
14974
|
+
}
|
|
14975
|
+
if (import_ts_morph59.Node.isArrowFunction(node) || import_ts_morph59.Node.isFunctionExpression(node)) {
|
|
14976
|
+
const parent = node.getParent();
|
|
14977
|
+
if (parent !== void 0 && import_ts_morph59.Node.isVariableDeclaration(parent)) {
|
|
14978
|
+
return parent.getName();
|
|
14979
|
+
}
|
|
14980
|
+
}
|
|
14981
|
+
const text = node.getText().split("\n")[0].trim();
|
|
14982
|
+
return text.length > 40 ? `${text.slice(0, 40)}...` : text;
|
|
14983
|
+
}
|
|
14984
|
+
|
|
13670
14985
|
// src/packHealth.ts
|
|
13671
14986
|
function stagesOf(funnel) {
|
|
13672
14987
|
const stages = [];
|
|
13673
14988
|
const gateSaysSomething = funnel.gates.length > 0 && funnel.unresolvedGates.length === 0;
|
|
14989
|
+
if (funnel.recognizes && !funnel.discovers && gateSaysSomething) {
|
|
14990
|
+
stages.push({
|
|
14991
|
+
from: {
|
|
14992
|
+
name: "unit bodies to look inside",
|
|
14993
|
+
count: funnel.unitsInGatedFiles
|
|
14994
|
+
},
|
|
14995
|
+
to: { name: "effects recognized", count: funnel.effectsRecognized },
|
|
14996
|
+
meaning: "its import gate found the library and it matched nothing in the bodies it saw"
|
|
14997
|
+
});
|
|
14998
|
+
}
|
|
13674
14999
|
if (funnel.discovers && gateSaysSomething) {
|
|
13675
15000
|
stages.push({
|
|
13676
15001
|
from: { name: "candidate files", count: funnel.candidateFiles },
|
|
@@ -13780,7 +15105,8 @@ function formatPackHealth(checks, audiences) {
|
|
|
13780
15105
|
}
|
|
13781
15106
|
|
|
13782
15107
|
// src/resolve/readName.ts
|
|
13783
|
-
var
|
|
15108
|
+
var import_ts_morph60 = require("ts-morph");
|
|
15109
|
+
var import_behavioral_ir7 = require("@suss/behavioral-ir");
|
|
13784
15110
|
var MAX_HELPER_HOPS = 2;
|
|
13785
15111
|
var UNNAMED_HOLE = "param";
|
|
13786
15112
|
function readName(expr, options = {}) {
|
|
@@ -13794,6 +15120,14 @@ function readName(expr, options = {}) {
|
|
|
13794
15120
|
if (name !== null || options.unsettled !== "reference") {
|
|
13795
15121
|
return name;
|
|
13796
15122
|
}
|
|
15123
|
+
const reference = referenceIn(expr);
|
|
15124
|
+
return reference === null ? null : (0, import_behavioral_ir7.referenceName)(reference);
|
|
15125
|
+
}
|
|
15126
|
+
function referenceIn(expr) {
|
|
15127
|
+
const fromParameter = parameterPath(expr);
|
|
15128
|
+
if (fromParameter !== null) {
|
|
15129
|
+
return fromParameter;
|
|
15130
|
+
}
|
|
13797
15131
|
const asked = holeName(expr, {
|
|
13798
15132
|
resolve: () => null,
|
|
13799
15133
|
bindings: /* @__PURE__ */ new Map(),
|
|
@@ -13801,7 +15135,25 @@ function readName(expr, options = {}) {
|
|
|
13801
15135
|
seen: /* @__PURE__ */ new Set(),
|
|
13802
15136
|
insideHole: true
|
|
13803
15137
|
});
|
|
13804
|
-
return asked === UNNAMED_HOLE ? null :
|
|
15138
|
+
return asked === UNNAMED_HOLE ? null : { root: asked, fields: [] };
|
|
15139
|
+
}
|
|
15140
|
+
function parameterPath(expr) {
|
|
15141
|
+
const fields = [];
|
|
15142
|
+
let step = expr;
|
|
15143
|
+
while (import_ts_morph60.Node.isPropertyAccessExpression(step)) {
|
|
15144
|
+
fields.unshift(step.getName());
|
|
15145
|
+
step = step.getExpression();
|
|
15146
|
+
}
|
|
15147
|
+
if (!import_ts_morph60.Node.isIdentifier(step) || !isParameter(step)) {
|
|
15148
|
+
return null;
|
|
15149
|
+
}
|
|
15150
|
+
return { root: step.getText(), fields };
|
|
15151
|
+
}
|
|
15152
|
+
function isParameter(identifier) {
|
|
15153
|
+
const declarations = identifier.getSymbol()?.getDeclarations() ?? [];
|
|
15154
|
+
return declarations.some(
|
|
15155
|
+
(declaration) => import_ts_morph60.Node.isParameterDeclaration(declaration)
|
|
15156
|
+
);
|
|
13805
15157
|
}
|
|
13806
15158
|
function read(expr, ctx) {
|
|
13807
15159
|
if (ctx.seen.has(expr)) {
|
|
@@ -13809,35 +15161,52 @@ function read(expr, ctx) {
|
|
|
13809
15161
|
}
|
|
13810
15162
|
const seen = new Set(ctx.seen).add(expr);
|
|
13811
15163
|
const inner = { ...ctx, seen };
|
|
13812
|
-
if (
|
|
15164
|
+
if (import_ts_morph60.Node.isStringLiteral(expr) || import_ts_morph60.Node.isNoSubstitutionTemplateLiteral(expr)) {
|
|
13813
15165
|
return expr.getLiteralValue();
|
|
13814
15166
|
}
|
|
13815
|
-
if (
|
|
15167
|
+
if (import_ts_morph60.Node.isNumericLiteral(expr)) {
|
|
13816
15168
|
return expr.getLiteralText();
|
|
13817
15169
|
}
|
|
13818
|
-
if (
|
|
15170
|
+
if (import_ts_morph60.Node.isTemplateExpression(expr)) {
|
|
13819
15171
|
return fromTemplate(expr, inner);
|
|
13820
15172
|
}
|
|
13821
|
-
if (
|
|
15173
|
+
if (import_ts_morph60.Node.isParenthesizedExpression(expr)) {
|
|
13822
15174
|
return read(expr.getExpression(), inner);
|
|
13823
15175
|
}
|
|
13824
|
-
if (
|
|
15176
|
+
if (import_ts_morph60.Node.isBinaryExpression(expr)) {
|
|
13825
15177
|
return fromBinary(expr, inner);
|
|
13826
15178
|
}
|
|
13827
|
-
if (
|
|
15179
|
+
if (import_ts_morph60.Node.isCallExpression(expr)) {
|
|
13828
15180
|
return fromCall(expr, inner);
|
|
13829
15181
|
}
|
|
13830
|
-
if (
|
|
15182
|
+
if (import_ts_morph60.Node.isIdentifier(expr)) {
|
|
13831
15183
|
const only = boundOnce(expr, ctx);
|
|
13832
15184
|
if (only !== null) {
|
|
13833
15185
|
return read(only.node, { ...inner, bindings: only.scope });
|
|
13834
15186
|
}
|
|
13835
15187
|
}
|
|
13836
15188
|
const written = ctx.resolve(expr);
|
|
13837
|
-
|
|
15189
|
+
if (written === null || written === expr) {
|
|
15190
|
+
return null;
|
|
15191
|
+
}
|
|
15192
|
+
if (ctx.insideHole && isFallbackBranch(written)) {
|
|
15193
|
+
return null;
|
|
15194
|
+
}
|
|
15195
|
+
return read(written, inner);
|
|
15196
|
+
}
|
|
15197
|
+
function isFallbackBranch(node) {
|
|
15198
|
+
let step = node.getParent();
|
|
15199
|
+
while (step !== void 0 && import_ts_morph60.Node.isParenthesizedExpression(step)) {
|
|
15200
|
+
step = step.getParent();
|
|
15201
|
+
}
|
|
15202
|
+
if (step === void 0 || !import_ts_morph60.Node.isBinaryExpression(step)) {
|
|
15203
|
+
return false;
|
|
15204
|
+
}
|
|
15205
|
+
const operator = step.getOperatorToken().getKind();
|
|
15206
|
+
return operator === import_ts_morph60.SyntaxKind.BarBarToken || operator === import_ts_morph60.SyntaxKind.QuestionQuestionToken;
|
|
13838
15207
|
}
|
|
13839
15208
|
function fromTemplate(expr, ctx) {
|
|
13840
|
-
if (!
|
|
15209
|
+
if (!import_ts_morph60.Node.isTemplateExpression(expr)) {
|
|
13841
15210
|
return null;
|
|
13842
15211
|
}
|
|
13843
15212
|
let name = expr.getHead().getLiteralText();
|
|
@@ -13848,28 +15217,28 @@ function fromTemplate(expr, ctx) {
|
|
|
13848
15217
|
return name;
|
|
13849
15218
|
}
|
|
13850
15219
|
function fromBinary(expr, ctx) {
|
|
13851
|
-
if (!
|
|
15220
|
+
if (!import_ts_morph60.Node.isBinaryExpression(expr)) {
|
|
13852
15221
|
return null;
|
|
13853
15222
|
}
|
|
13854
15223
|
const operator = expr.getOperatorToken().getKind();
|
|
13855
|
-
if (operator ===
|
|
15224
|
+
if (operator === import_ts_morph60.SyntaxKind.BarBarToken || operator === import_ts_morph60.SyntaxKind.QuestionQuestionToken) {
|
|
13856
15225
|
return ctx.insideHole ? null : read(expr.getRight(), ctx);
|
|
13857
15226
|
}
|
|
13858
|
-
if (operator !==
|
|
15227
|
+
if (operator !== import_ts_morph60.SyntaxKind.PlusToken) {
|
|
13859
15228
|
return null;
|
|
13860
15229
|
}
|
|
13861
15230
|
const parts = { ...ctx, insideHole: true };
|
|
13862
15231
|
return readOrHole(expr.getLeft(), parts) + readOrHole(expr.getRight(), parts);
|
|
13863
15232
|
}
|
|
13864
15233
|
function fromCall(expr, ctx) {
|
|
13865
|
-
if (!
|
|
15234
|
+
if (!import_ts_morph60.Node.isCallExpression(expr)) {
|
|
13866
15235
|
return null;
|
|
13867
15236
|
}
|
|
13868
15237
|
const callee = expr.getExpression();
|
|
13869
|
-
if (
|
|
15238
|
+
if (import_ts_morph60.Node.isPropertyAccessExpression(callee) && callee.getName() === "join") {
|
|
13870
15239
|
return fromJoin(callee.getExpression(), expr.getArguments(), ctx);
|
|
13871
15240
|
}
|
|
13872
|
-
if (
|
|
15241
|
+
if (import_ts_morph60.Node.isIdentifier(callee) && callee.getText() === "String") {
|
|
13873
15242
|
const only = expr.getArguments()[0];
|
|
13874
15243
|
return only === void 0 ? null : readOrHole(only, ctx);
|
|
13875
15244
|
}
|
|
@@ -13888,7 +15257,7 @@ function fromCall(expr, ctx) {
|
|
|
13888
15257
|
}
|
|
13889
15258
|
function fromJoin(subject, args, ctx) {
|
|
13890
15259
|
const separator = args[0];
|
|
13891
|
-
if (separator === void 0 || !
|
|
15260
|
+
if (separator === void 0 || !import_ts_morph60.Node.isStringLiteral(separator)) {
|
|
13892
15261
|
return null;
|
|
13893
15262
|
}
|
|
13894
15263
|
const parts = elementsOf(subject, ctx);
|
|
@@ -13904,17 +15273,17 @@ function fromJoin(subject, args, ctx) {
|
|
|
13904
15273
|
).join(separator.getLiteralValue());
|
|
13905
15274
|
}
|
|
13906
15275
|
function elementsOf(subject, ctx) {
|
|
13907
|
-
if (
|
|
15276
|
+
if (import_ts_morph60.Node.isArrayLiteralExpression(subject)) {
|
|
13908
15277
|
return subject.getElements().map((element) => here(element, ctx));
|
|
13909
15278
|
}
|
|
13910
|
-
if (
|
|
15279
|
+
if (import_ts_morph60.Node.isCallExpression(subject)) {
|
|
13911
15280
|
const callee = subject.getExpression();
|
|
13912
|
-
if (
|
|
15281
|
+
if (import_ts_morph60.Node.isPropertyAccessExpression(callee) && callee.getName() === "map") {
|
|
13913
15282
|
return elementsOf(callee.getExpression(), ctx);
|
|
13914
15283
|
}
|
|
13915
15284
|
return null;
|
|
13916
15285
|
}
|
|
13917
|
-
if (!
|
|
15286
|
+
if (!import_ts_morph60.Node.isIdentifier(subject)) {
|
|
13918
15287
|
return null;
|
|
13919
15288
|
}
|
|
13920
15289
|
const bound = ctx.bindings.get(subject.getText());
|
|
@@ -13922,7 +15291,7 @@ function elementsOf(subject, ctx) {
|
|
|
13922
15291
|
return null;
|
|
13923
15292
|
}
|
|
13924
15293
|
const only = bound.length === 1 ? bound[0] : void 0;
|
|
13925
|
-
return only !== void 0 &&
|
|
15294
|
+
return only !== void 0 && import_ts_morph60.Node.isArrayLiteralExpression(only.node) ? only.node.getElements().map((element) => here(element, ctx)) : bound;
|
|
13926
15295
|
}
|
|
13927
15296
|
function singleReturnBody(callee, ctx) {
|
|
13928
15297
|
const declaration = declarationOf2(callee, ctx);
|
|
@@ -13937,22 +15306,22 @@ function singleReturnBody(callee, ctx) {
|
|
|
13937
15306
|
if (body === void 0) {
|
|
13938
15307
|
return null;
|
|
13939
15308
|
}
|
|
13940
|
-
if (
|
|
15309
|
+
if (import_ts_morph60.Node.isExpression(body)) {
|
|
13941
15310
|
return { parameters, returned: body };
|
|
13942
15311
|
}
|
|
13943
|
-
if (!
|
|
15312
|
+
if (!import_ts_morph60.Node.isBlock(body)) {
|
|
13944
15313
|
return null;
|
|
13945
15314
|
}
|
|
13946
15315
|
const statements = body.getStatements();
|
|
13947
15316
|
const only = statements[0];
|
|
13948
|
-
if (statements.length !== 1 || only === void 0 || !
|
|
15317
|
+
if (statements.length !== 1 || only === void 0 || !import_ts_morph60.Node.isReturnStatement(only)) {
|
|
13949
15318
|
return null;
|
|
13950
15319
|
}
|
|
13951
15320
|
const returned = only.getExpression();
|
|
13952
15321
|
return returned === void 0 ? null : { parameters, returned };
|
|
13953
15322
|
}
|
|
13954
15323
|
function declarationOf2(callee, ctx) {
|
|
13955
|
-
const symbol =
|
|
15324
|
+
const symbol = import_ts_morph60.Node.isPropertyAccessExpression(callee) ? callee.getNameNode().getSymbol() : callee.getSymbol();
|
|
13956
15325
|
const declarations = symbol?.getAliasedSymbol()?.getDeclarations() ?? symbol?.getDeclarations() ?? [];
|
|
13957
15326
|
for (const declaration of declarations) {
|
|
13958
15327
|
const callable = asCallable(declaration);
|
|
@@ -13964,14 +15333,14 @@ function declarationOf2(callee, ctx) {
|
|
|
13964
15333
|
return written === null || written === callee ? null : declarationOf2(written, { ...ctx, resolve: () => null });
|
|
13965
15334
|
}
|
|
13966
15335
|
function asCallable(declaration) {
|
|
13967
|
-
if (
|
|
15336
|
+
if (import_ts_morph60.Node.isFunctionDeclaration(declaration) || import_ts_morph60.Node.isMethodDeclaration(declaration) || import_ts_morph60.Node.isArrowFunction(declaration) || import_ts_morph60.Node.isFunctionExpression(declaration)) {
|
|
13968
15337
|
return declaration;
|
|
13969
15338
|
}
|
|
13970
|
-
if (!
|
|
15339
|
+
if (!import_ts_morph60.Node.isVariableDeclaration(declaration)) {
|
|
13971
15340
|
return null;
|
|
13972
15341
|
}
|
|
13973
15342
|
const initializer = declaration.getInitializer();
|
|
13974
|
-
if (initializer !== void 0 && (
|
|
15343
|
+
if (initializer !== void 0 && (import_ts_morph60.Node.isArrowFunction(initializer) || import_ts_morph60.Node.isFunctionExpression(initializer))) {
|
|
13975
15344
|
return initializer;
|
|
13976
15345
|
}
|
|
13977
15346
|
return null;
|
|
@@ -13993,22 +15362,22 @@ function here(node, ctx) {
|
|
|
13993
15362
|
return { node, scope: ctx.bindings };
|
|
13994
15363
|
}
|
|
13995
15364
|
function boundOnce(expr, ctx) {
|
|
13996
|
-
const bound =
|
|
15365
|
+
const bound = import_ts_morph60.Node.isIdentifier(expr) ? ctx.bindings.get(expr.getText()) : void 0;
|
|
13997
15366
|
return bound !== void 0 && bound.length === 1 ? bound[0] : null;
|
|
13998
15367
|
}
|
|
13999
15368
|
function readOrHole(expr, ctx) {
|
|
14000
15369
|
const name = read(expr, ctx);
|
|
14001
|
-
return name ??
|
|
15370
|
+
return name ?? (0, import_behavioral_ir7.patternHole)(holeName(expr, ctx));
|
|
14002
15371
|
}
|
|
14003
15372
|
function holeName(expr, ctx) {
|
|
14004
15373
|
const bound = boundOnce(expr, ctx);
|
|
14005
15374
|
if (bound !== null) {
|
|
14006
15375
|
return holeName(bound.node, { ...ctx, bindings: bound.scope });
|
|
14007
15376
|
}
|
|
14008
|
-
if (
|
|
15377
|
+
if (import_ts_morph60.Node.isIdentifier(expr)) {
|
|
14009
15378
|
return expr.getText();
|
|
14010
15379
|
}
|
|
14011
|
-
if (
|
|
15380
|
+
if (import_ts_morph60.Node.isPropertyAccessExpression(expr)) {
|
|
14012
15381
|
return expr.getName();
|
|
14013
15382
|
}
|
|
14014
15383
|
return UNNAMED_HOLE;
|
|
@@ -14017,6 +15386,7 @@ function holeName(expr, ctx) {
|
|
|
14017
15386
|
0 && (module.exports = {
|
|
14018
15387
|
ADAPTER_VERSION,
|
|
14019
15388
|
ResolutionStore,
|
|
15389
|
+
WhySession,
|
|
14020
15390
|
collectAncestorBranches,
|
|
14021
15391
|
collectClientFieldAccesses,
|
|
14022
15392
|
computeAdapterPacksDigest,
|
|
@@ -14042,5 +15412,6 @@ function holeName(expr, ctx) {
|
|
|
14042
15412
|
readName,
|
|
14043
15413
|
resolveAliasedSymbol,
|
|
14044
15414
|
resolveSubject,
|
|
14045
|
-
rootIdentifier
|
|
15415
|
+
rootIdentifier,
|
|
15416
|
+
workspaceRootFor
|
|
14046
15417
|
});
|