@suss/adapter-typescript 0.21.0 → 0.22.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 +1 -35
- package/dist/index.cjs +949 -1507
- package/dist/index.d.cts +74 -414
- package/dist/index.d.ts +74 -414
- package/dist/index.js +913 -1453
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -32,26 +32,24 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ADAPTER_VERSION: () => ADAPTER_VERSION,
|
|
34
34
|
ResolutionStore: () => ResolutionStore,
|
|
35
|
-
|
|
35
|
+
TypeScriptWhySession: () => TypeScriptWhySession,
|
|
36
36
|
accessContextFor: () => accessContextFor,
|
|
37
37
|
buildProjectHelperIndex: () => buildProjectHelperIndex,
|
|
38
38
|
callOpsFor: () => callOpsFor,
|
|
39
39
|
collectAncestorBranches: () => collectAncestorBranches,
|
|
40
40
|
collectClientFieldAccesses: () => collectClientFieldAccesses,
|
|
41
41
|
computeAdapterPacksDigest: () => computeAdapterPacksDigest,
|
|
42
|
-
computeContentHash: () => computeContentHash,
|
|
42
|
+
computeContentHash: () => import_extractor10.computeContentHash,
|
|
43
43
|
createProjectWithoutTsconfig: () => createProjectWithoutTsconfig,
|
|
44
44
|
createTsDiscoveryContext: () => createTsDiscoveryContext,
|
|
45
45
|
createTsSubUnitContext: () => createTsSubUnitContext,
|
|
46
46
|
createTypeScriptAdapter: () => createTypeScriptAdapter,
|
|
47
47
|
discoverUnits: () => discoverUnits,
|
|
48
|
-
evaluatePackHealth: () => evaluatePackHealth,
|
|
49
48
|
exportedDeclarationsOf: () => exportedDeclarationsOf,
|
|
50
49
|
extractCodeStructure: () => extractCodeStructure,
|
|
51
50
|
extractRawBranches: () => extractRawBranches,
|
|
52
51
|
findNearestTsconfig: () => findNearestTsconfig,
|
|
53
52
|
findTerminals: () => findTerminals,
|
|
54
|
-
formatPackHealth: () => formatPackHealth,
|
|
55
53
|
functionTargetOf: () => functionTargetOf,
|
|
56
54
|
importDeclarationsOf: () => importDeclarationsOf,
|
|
57
55
|
importedNamesOf: () => importedNamesOf,
|
|
@@ -75,15 +73,15 @@ __export(index_exports, {
|
|
|
75
73
|
module.exports = __toCommonJS(index_exports);
|
|
76
74
|
|
|
77
75
|
// src/adapter.ts
|
|
78
|
-
var
|
|
76
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
79
77
|
var import_ts_morph66 = require("ts-morph");
|
|
80
|
-
var
|
|
78
|
+
var import_behavioral_ir9 = require("@suss/behavioral-ir");
|
|
81
79
|
var import_datalog6 = require("@suss/datalog");
|
|
82
|
-
var
|
|
80
|
+
var import_extractor11 = require("@suss/extractor");
|
|
83
81
|
|
|
84
82
|
// src/assembly.ts
|
|
85
83
|
var import_ts_morph54 = require("ts-morph");
|
|
86
|
-
var
|
|
84
|
+
var import_extractor5 = require("@suss/extractor");
|
|
87
85
|
|
|
88
86
|
// src/conditions.ts
|
|
89
87
|
var import_ts_morph6 = require("ts-morph");
|
|
@@ -95,6 +93,7 @@ var import_ts_morph5 = require("ts-morph");
|
|
|
95
93
|
var import_ts_morph2 = require("ts-morph");
|
|
96
94
|
|
|
97
95
|
// src/walk/nodeKeys.ts
|
|
96
|
+
var import_behavioral_ir = require("@suss/behavioral-ir");
|
|
98
97
|
function offsetKeyOf(node) {
|
|
99
98
|
return offsetKeyFor(node.getSourceFile().getFilePath(), {
|
|
100
99
|
start: node.getStart(),
|
|
@@ -102,7 +101,7 @@ function offsetKeyOf(node) {
|
|
|
102
101
|
});
|
|
103
102
|
}
|
|
104
103
|
function offsetKeyFor(file, span) {
|
|
105
|
-
return
|
|
104
|
+
return (0, import_behavioral_ir.declarationKey)(file, span);
|
|
106
105
|
}
|
|
107
106
|
function lineRangeKey(file, startLine, endLine) {
|
|
108
107
|
return `${file}:${startLine}-${endLine}`;
|
|
@@ -1542,7 +1541,7 @@ function degradedResult(func, terminalNodes, reason) {
|
|
|
1542
1541
|
|
|
1543
1542
|
// src/resolve/invocationEffects.ts
|
|
1544
1543
|
var import_ts_morph43 = require("ts-morph");
|
|
1545
|
-
var
|
|
1544
|
+
var import_extractor4 = require("@suss/extractor");
|
|
1546
1545
|
|
|
1547
1546
|
// src/lines.ts
|
|
1548
1547
|
function startLineOf(node) {
|
|
@@ -1910,8 +1909,8 @@ function loadImportGraphsDepthFirstFromPaths(project, rootPaths) {
|
|
|
1910
1909
|
stack.pop();
|
|
1911
1910
|
loadOrder.push(top.path);
|
|
1912
1911
|
let deepest = 0;
|
|
1913
|
-
for (const
|
|
1914
|
-
deepest = Math.max(deepest, chainDepth.get(
|
|
1912
|
+
for (const path14 of top.deps) {
|
|
1913
|
+
deepest = Math.max(deepest, chainDepth.get(path14) ?? 0);
|
|
1915
1914
|
}
|
|
1916
1915
|
chainDepth.set(top.path, deepest + 1);
|
|
1917
1916
|
}
|
|
@@ -1958,6 +1957,20 @@ function importedFilePathsOf(project, filePath) {
|
|
|
1958
1957
|
cache.set(filePath, paths);
|
|
1959
1958
|
return paths;
|
|
1960
1959
|
}
|
|
1960
|
+
function resolutionCacheFor(project, options) {
|
|
1961
|
+
const existing = resolutionCachesByProject.get(project);
|
|
1962
|
+
if (existing !== void 0) {
|
|
1963
|
+
return existing;
|
|
1964
|
+
}
|
|
1965
|
+
const fresh = import_ts_morph10.ts.createModuleResolutionCache(
|
|
1966
|
+
project.getFileSystem().getCurrentDirectory(),
|
|
1967
|
+
(name) => name,
|
|
1968
|
+
options
|
|
1969
|
+
);
|
|
1970
|
+
resolutionCachesByProject.set(project, fresh);
|
|
1971
|
+
return fresh;
|
|
1972
|
+
}
|
|
1973
|
+
var resolutionCachesByProject = /* @__PURE__ */ new WeakMap();
|
|
1961
1974
|
function specifierCacheFor(project) {
|
|
1962
1975
|
const existing = specifiersByProject.get(project);
|
|
1963
1976
|
if (existing !== void 0) {
|
|
@@ -1984,13 +1997,15 @@ function readSpecifierPaths(project, filePath, options, host) {
|
|
|
1984
1997
|
return [];
|
|
1985
1998
|
}
|
|
1986
1999
|
const scanned = import_ts_morph10.ts.preProcessFile(text, true, true);
|
|
2000
|
+
const cache = resolutionCacheFor(project, options);
|
|
1987
2001
|
const paths = [];
|
|
1988
2002
|
for (const imported of scanned.importedFiles) {
|
|
1989
2003
|
const resolved = import_ts_morph10.ts.resolveModuleName(
|
|
1990
2004
|
imported.fileName,
|
|
1991
2005
|
filePath,
|
|
1992
2006
|
options,
|
|
1993
|
-
host
|
|
2007
|
+
host,
|
|
2008
|
+
cache
|
|
1994
2009
|
).resolvedModule?.resolvedFileName;
|
|
1995
2010
|
if (resolved !== void 0 && !resolved.includes("/node_modules/")) {
|
|
1996
2011
|
paths.push(resolved);
|
|
@@ -2247,11 +2262,11 @@ function walkAndWarm(root, reach) {
|
|
|
2247
2262
|
if (warmedFiles.get(target) !== void 0) {
|
|
2248
2263
|
continue;
|
|
2249
2264
|
}
|
|
2250
|
-
const
|
|
2251
|
-
if (visited.has(
|
|
2265
|
+
const path14 = target.getFilePath();
|
|
2266
|
+
if (visited.has(path14)) {
|
|
2252
2267
|
continue;
|
|
2253
2268
|
}
|
|
2254
|
-
visited.add(
|
|
2269
|
+
visited.add(path14);
|
|
2255
2270
|
stack.push(frameOf(target, reach));
|
|
2256
2271
|
continue;
|
|
2257
2272
|
}
|
|
@@ -2268,7 +2283,7 @@ function sitsOnWarmChains(file) {
|
|
|
2268
2283
|
return false;
|
|
2269
2284
|
}
|
|
2270
2285
|
const imported = importedFilePathsOf(project, file.getFilePath());
|
|
2271
|
-
return imported.length > 0 && imported.every((
|
|
2286
|
+
return imported.length > 0 && imported.every((path14) => warmed.has(path14));
|
|
2272
2287
|
}
|
|
2273
2288
|
function markWarmed(file) {
|
|
2274
2289
|
warmedFiles.set(file, true);
|
|
@@ -2563,6 +2578,32 @@ function writesToBindingUncached(declaration) {
|
|
|
2563
2578
|
}
|
|
2564
2579
|
return { values, inOrder: writesRunInOrder(declaration, writes) };
|
|
2565
2580
|
}
|
|
2581
|
+
function sameConstructionAcrossWrites(values) {
|
|
2582
|
+
const candidates = values.filter((value) => !isNotYetPlaceholder(value));
|
|
2583
|
+
if (candidates.length === 0) {
|
|
2584
|
+
return null;
|
|
2585
|
+
}
|
|
2586
|
+
let construction = null;
|
|
2587
|
+
for (const value of candidates) {
|
|
2588
|
+
if (!isConstruction(value)) {
|
|
2589
|
+
return null;
|
|
2590
|
+
}
|
|
2591
|
+
if (construction !== null && sourceOf(value) !== sourceOf(construction)) {
|
|
2592
|
+
return null;
|
|
2593
|
+
}
|
|
2594
|
+
construction = value;
|
|
2595
|
+
}
|
|
2596
|
+
return construction;
|
|
2597
|
+
}
|
|
2598
|
+
function isNotYetPlaceholder(value) {
|
|
2599
|
+
return value.getKind() === import_ts_morph14.SyntaxKind.NullKeyword || import_ts_morph14.Node.isIdentifier(value) && value.getText() === "undefined";
|
|
2600
|
+
}
|
|
2601
|
+
function isConstruction(value) {
|
|
2602
|
+
return import_ts_morph14.Node.isCallExpression(value) || import_ts_morph14.Node.isNewExpression(value);
|
|
2603
|
+
}
|
|
2604
|
+
function sourceOf(node) {
|
|
2605
|
+
return node.getText().replace(/\s+/g, " ").trim();
|
|
2606
|
+
}
|
|
2566
2607
|
function writesToField(declaration) {
|
|
2567
2608
|
const remembered = byField.get(declaration);
|
|
2568
2609
|
if (remembered !== void 0) {
|
|
@@ -2653,6 +2694,9 @@ function assignmentsInFile(sourceFile) {
|
|
|
2653
2694
|
function isAssignmentOperator(kind) {
|
|
2654
2695
|
return kind >= import_ts_morph14.SyntaxKind.FirstAssignment && kind <= import_ts_morph14.SyntaxKind.LastAssignment;
|
|
2655
2696
|
}
|
|
2697
|
+
function writesItsWholeValue(kind) {
|
|
2698
|
+
return kind === import_ts_morph14.SyntaxKind.EqualsToken || kind === import_ts_morph14.SyntaxKind.QuestionQuestionEqualsToken || kind === import_ts_morph14.SyntaxKind.BarBarEqualsToken;
|
|
2699
|
+
}
|
|
2656
2700
|
function writeAt(node) {
|
|
2657
2701
|
if (import_ts_morph14.Node.isBinaryExpression(node)) {
|
|
2658
2702
|
const operator = node.getOperatorToken().getKind();
|
|
@@ -2660,7 +2704,7 @@ function writeAt(node) {
|
|
|
2660
2704
|
if (!isAssignmentOperator(operator) || !(import_ts_morph14.Node.isIdentifier(target) || import_ts_morph14.Node.isPropertyAccessExpression(target))) {
|
|
2661
2705
|
return null;
|
|
2662
2706
|
}
|
|
2663
|
-
const value = operator
|
|
2707
|
+
const value = writesItsWholeValue(operator) ? node.getRight() : null;
|
|
2664
2708
|
return { target, write: { value, node } };
|
|
2665
2709
|
}
|
|
2666
2710
|
if (import_ts_morph14.Node.isPrefixUnaryExpression(node) || import_ts_morph14.Node.isPostfixUnaryExpression(node)) {
|
|
@@ -3051,11 +3095,16 @@ function emitBindingValues(db, table, declaration) {
|
|
|
3051
3095
|
}
|
|
3052
3096
|
const { values, inOrder } = writesToBinding(declaration);
|
|
3053
3097
|
const last = values[values.length - 1];
|
|
3054
|
-
if (
|
|
3055
|
-
|
|
3098
|
+
if (inOrder && last !== void 0) {
|
|
3099
|
+
fact(db, "endsHolding", declarationId, emitValue(db, table, last));
|
|
3100
|
+
return;
|
|
3101
|
+
}
|
|
3102
|
+
const construction = sameConstructionAcrossWrites(values);
|
|
3103
|
+
if (construction !== null) {
|
|
3104
|
+
fact(db, "endsHolding", declarationId, emitValue(db, table, construction));
|
|
3056
3105
|
return;
|
|
3057
3106
|
}
|
|
3058
|
-
|
|
3107
|
+
reassignedUnstated.add(declarationId);
|
|
3059
3108
|
}
|
|
3060
3109
|
var reassignedUnstated = /* @__PURE__ */ new Set();
|
|
3061
3110
|
function reassignedNamesUnstated() {
|
|
@@ -3067,23 +3116,31 @@ function forgetReassignedNamesUnstated() {
|
|
|
3067
3116
|
function emitFieldValues(db, table, declaration) {
|
|
3068
3117
|
const { values, inOrder } = writesToField(declaration);
|
|
3069
3118
|
const last = values[values.length - 1];
|
|
3070
|
-
if (
|
|
3119
|
+
if (inOrder && last !== void 0 && import_ts_morph15.Node.isExpression(last)) {
|
|
3120
|
+
fact(db, "binds", nodeId(declaration), emitValue(db, table, last));
|
|
3071
3121
|
return;
|
|
3072
3122
|
}
|
|
3073
|
-
|
|
3123
|
+
const construction = sameConstructionAcrossWrites(values);
|
|
3124
|
+
if (construction !== null) {
|
|
3125
|
+
fact(db, "binds", nodeId(declaration), emitValue(db, table, construction));
|
|
3126
|
+
}
|
|
3074
3127
|
}
|
|
3075
3128
|
function emitParameterPropertyRead(db, table, referenceId, declaration) {
|
|
3076
3129
|
const { values, inOrder } = writesToField(declaration);
|
|
3077
3130
|
const last = values[values.length - 1];
|
|
3078
|
-
if (
|
|
3131
|
+
if (inOrder && last !== void 0 && import_ts_morph15.Node.isExpression(last)) {
|
|
3132
|
+
fact(db, "binds", referenceId, emitValue(db, table, last));
|
|
3079
3133
|
return;
|
|
3080
3134
|
}
|
|
3081
|
-
if (
|
|
3135
|
+
if (inOrder && last !== void 0) {
|
|
3082
3136
|
table.byId.set(nodeId(last), last);
|
|
3083
3137
|
fact(db, "binds", referenceId, nodeId(last));
|
|
3084
3138
|
return;
|
|
3085
3139
|
}
|
|
3086
|
-
|
|
3140
|
+
const construction = sameConstructionAcrossWrites(values);
|
|
3141
|
+
if (construction !== null) {
|
|
3142
|
+
fact(db, "binds", referenceId, emitValue(db, table, construction));
|
|
3143
|
+
}
|
|
3087
3144
|
}
|
|
3088
3145
|
function emitBindingElementFacts(db, table, element) {
|
|
3089
3146
|
const id = nodeId(element);
|
|
@@ -3547,7 +3604,8 @@ var JS_RULES = [
|
|
|
3547
3604
|
];
|
|
3548
3605
|
var RESOLUTION_PROGRAM = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? {
|
|
3549
3606
|
rules: [...import_resolution2.RESOLUTION_RULES, ...JS_RULES, ...import_resolution2.RESOLUTION_QUESTIONS],
|
|
3550
|
-
demandDriven: []
|
|
3607
|
+
demandDriven: [],
|
|
3608
|
+
demands: []
|
|
3551
3609
|
} : (0, import_datalog2.deriveOnDemand)(
|
|
3552
3610
|
[...import_resolution2.RESOLUTION_RULES, ...JS_RULES, ...import_resolution2.RESOLUTION_QUESTIONS],
|
|
3553
3611
|
import_resolution2.ANSWER_RELATIONS
|
|
@@ -3574,7 +3632,9 @@ var QUERY_FACTS = RESOLUTION_PROGRAM.demandDriven.length === 0 ? [] : [
|
|
|
3574
3632
|
"wantedAnchor",
|
|
3575
3633
|
"wantedSubject"
|
|
3576
3634
|
];
|
|
3577
|
-
var
|
|
3635
|
+
var MODULE_DEMANDS = RESOLUTION_PROGRAM.demands.filter(
|
|
3636
|
+
(one) => (one.relation === "moduleExport" || one.relation === "moduleForwards") && one.bound[0] === true
|
|
3637
|
+
).map((one) => one.demand);
|
|
3578
3638
|
var ResolutionStore = class {
|
|
3579
3639
|
db = new import_datalog2.Database();
|
|
3580
3640
|
table = createNodeTable();
|
|
@@ -3590,7 +3650,7 @@ var ResolutionStore = class {
|
|
|
3590
3650
|
* extraction elsewhere cannot change an entry.
|
|
3591
3651
|
*/
|
|
3592
3652
|
exportTables = /* @__PURE__ */ new Map();
|
|
3593
|
-
/** Files the most recent
|
|
3653
|
+
/** Files the most recent query read, for the memo to keep. */
|
|
3594
3654
|
lastQueryWalked = [];
|
|
3595
3655
|
declarations = /* @__PURE__ */ new Map();
|
|
3596
3656
|
graph = new ModuleGraph();
|
|
@@ -3621,19 +3681,19 @@ var ResolutionStore = class {
|
|
|
3621
3681
|
*/
|
|
3622
3682
|
resolveCallableSources(value, alsoFrom) {
|
|
3623
3683
|
const target = factKeyOf(value);
|
|
3624
|
-
return this.
|
|
3684
|
+
return this.askAbout(
|
|
3625
3685
|
target,
|
|
3626
3686
|
"wanted",
|
|
3627
3687
|
() => this.lookupSources(target),
|
|
3628
3688
|
alsoFrom
|
|
3629
|
-
)
|
|
3689
|
+
);
|
|
3630
3690
|
}
|
|
3631
3691
|
/**
|
|
3632
3692
|
* The witness proof behind `resolveCallable`'s answer. Resolves the
|
|
3633
|
-
* value first, which
|
|
3634
|
-
*
|
|
3635
|
-
*
|
|
3636
|
-
*
|
|
3693
|
+
* value first, which extracts the files the question demands, then
|
|
3694
|
+
* re-evaluates the rules over those base facts under the witness
|
|
3695
|
+
* algebra and rebuilds the proof of the answer. Null when the value
|
|
3696
|
+
* does not resolve at all.
|
|
3637
3697
|
*/
|
|
3638
3698
|
explainCallable(value, options = {}) {
|
|
3639
3699
|
const resolved = this.resolveCallable(value, options.alsoFrom);
|
|
@@ -3670,11 +3730,7 @@ var ResolutionStore = class {
|
|
|
3670
3730
|
}
|
|
3671
3731
|
resolveObject(value) {
|
|
3672
3732
|
const target = factKeyOf(value);
|
|
3673
|
-
return this.
|
|
3674
|
-
target,
|
|
3675
|
-
"wanted",
|
|
3676
|
-
() => this.lookupObject(target)
|
|
3677
|
-
);
|
|
3733
|
+
return this.askAbout(target, "wanted", () => this.lookupObject(target));
|
|
3678
3734
|
}
|
|
3679
3735
|
/**
|
|
3680
3736
|
* For a value that is neither a function nor an object, such as a
|
|
@@ -3690,17 +3746,17 @@ var ResolutionStore = class {
|
|
|
3690
3746
|
}
|
|
3691
3747
|
return cached.written;
|
|
3692
3748
|
}
|
|
3693
|
-
const
|
|
3749
|
+
const written = this.askAbout(
|
|
3694
3750
|
target,
|
|
3695
3751
|
"wanted",
|
|
3696
3752
|
() => this.lookupWritten(target)
|
|
3697
3753
|
);
|
|
3698
3754
|
this.writtenValues.set(key, {
|
|
3699
|
-
written
|
|
3755
|
+
written,
|
|
3700
3756
|
walked: [...this.lastQueryWalked],
|
|
3701
3757
|
extractedAt: this.fullyExtracted.size
|
|
3702
3758
|
});
|
|
3703
|
-
return
|
|
3759
|
+
return written;
|
|
3704
3760
|
}
|
|
3705
3761
|
/**
|
|
3706
3762
|
* The construction behind a registration subject: the call or `new`
|
|
@@ -3720,18 +3776,29 @@ var ResolutionStore = class {
|
|
|
3720
3776
|
}
|
|
3721
3777
|
return cached.construction;
|
|
3722
3778
|
}
|
|
3723
|
-
const settled2 = this.
|
|
3779
|
+
const settled2 = this.askAbout(
|
|
3724
3780
|
target,
|
|
3725
3781
|
"wantedSubject",
|
|
3726
3782
|
() => this.lookupSubjectConstruction(target, importModule, importName)
|
|
3727
3783
|
);
|
|
3784
|
+
const walked = [...this.lastQueryWalked];
|
|
3785
|
+
let resolved = settled2;
|
|
3786
|
+
if (settled2.construction === null && settled2.candidate !== null && import_ts_morph16.Node.isCallExpression(settled2.candidate) && this.resolveCallable(settled2.candidate.getExpression()) !== null) {
|
|
3787
|
+
const call = settled2.candidate;
|
|
3788
|
+
resolved = this.askAbout(
|
|
3789
|
+
call,
|
|
3790
|
+
"wantedSubject",
|
|
3791
|
+
() => this.lookupSubjectConstruction(call, importModule, importName)
|
|
3792
|
+
);
|
|
3793
|
+
walked.push(...this.lastQueryWalked);
|
|
3794
|
+
}
|
|
3728
3795
|
this.subjectConstructions.set(key, {
|
|
3729
|
-
construction:
|
|
3730
|
-
candidates:
|
|
3731
|
-
walked
|
|
3796
|
+
construction: resolved.construction,
|
|
3797
|
+
candidates: resolved.candidates,
|
|
3798
|
+
walked,
|
|
3732
3799
|
extractedAt: this.fullyExtracted.size
|
|
3733
3800
|
});
|
|
3734
|
-
return
|
|
3801
|
+
return resolved.construction;
|
|
3735
3802
|
}
|
|
3736
3803
|
/**
|
|
3737
3804
|
* How many constructions this value was written as, which is what
|
|
@@ -3745,10 +3812,8 @@ var ResolutionStore = class {
|
|
|
3745
3812
|
)?.candidates ?? 0;
|
|
3746
3813
|
}
|
|
3747
3814
|
/**
|
|
3748
|
-
* The single-answer policy over the written-value
|
|
3749
|
-
* origin check on the one candidate.
|
|
3750
|
-
* is settled refusal rather than a reason to widen: its own file's
|
|
3751
|
-
* import facts are already in, and more files only add candidates.
|
|
3815
|
+
* The single-answer policy over the written-value chain, then the
|
|
3816
|
+
* origin check on the one candidate.
|
|
3752
3817
|
*/
|
|
3753
3818
|
lookupSubjectConstruction(value, importModule, importName) {
|
|
3754
3819
|
this.derive();
|
|
@@ -3764,6 +3829,7 @@ var ResolutionStore = class {
|
|
|
3764
3829
|
if (candidates.size > 1) {
|
|
3765
3830
|
return {
|
|
3766
3831
|
construction: null,
|
|
3832
|
+
candidate: null,
|
|
3767
3833
|
candidates: [...candidates].filter(
|
|
3768
3834
|
(one) => this.constructionComesFrom(valueId, one, importModule, importName)
|
|
3769
3835
|
).length
|
|
@@ -3771,7 +3837,7 @@ var ResolutionStore = class {
|
|
|
3771
3837
|
}
|
|
3772
3838
|
const single = [...candidates][0];
|
|
3773
3839
|
if (single === void 0) {
|
|
3774
|
-
return
|
|
3840
|
+
return { construction: null, candidate: null, candidates: 0 };
|
|
3775
3841
|
}
|
|
3776
3842
|
return {
|
|
3777
3843
|
construction: this.constructionComesFrom(
|
|
@@ -3780,6 +3846,7 @@ var ResolutionStore = class {
|
|
|
3780
3846
|
importModule,
|
|
3781
3847
|
importName
|
|
3782
3848
|
) ? single : null,
|
|
3849
|
+
candidate: single,
|
|
3783
3850
|
candidates: 1
|
|
3784
3851
|
};
|
|
3785
3852
|
}
|
|
@@ -3839,11 +3906,11 @@ var ResolutionStore = class {
|
|
|
3839
3906
|
return cached.names;
|
|
3840
3907
|
}
|
|
3841
3908
|
const target = factKeyOf(value);
|
|
3842
|
-
const found = this.
|
|
3909
|
+
const found = this.askAbout(
|
|
3843
3910
|
target,
|
|
3844
3911
|
"wantedOrigin",
|
|
3845
3912
|
() => this.lookupImportedNames(target, modules)
|
|
3846
|
-
)
|
|
3913
|
+
);
|
|
3847
3914
|
this.importedNames.set(declaration, {
|
|
3848
3915
|
names: found,
|
|
3849
3916
|
walked: [...this.lastQueryWalked]
|
|
@@ -3862,8 +3929,8 @@ var ResolutionStore = class {
|
|
|
3862
3929
|
return this.importOriginsOfMany([value], modules).get(value) ?? [];
|
|
3863
3930
|
}
|
|
3864
3931
|
/**
|
|
3865
|
-
* The batched form: one demand set, one derivation, one
|
|
3866
|
-
*
|
|
3932
|
+
* The batched form: one demand set, one derivation, one round of
|
|
3933
|
+
* extraction shared by every value. A discovery pass asks about every
|
|
3867
3934
|
* callee in a file, and per-value queries would re-pay demand
|
|
3868
3935
|
* clearing and re-derivation once per call site.
|
|
3869
3936
|
*/
|
|
@@ -3891,49 +3958,12 @@ var ResolutionStore = class {
|
|
|
3891
3958
|
this.wantValue("wantedCallOrigin", one.target);
|
|
3892
3959
|
this.seedValue(one.target);
|
|
3893
3960
|
}
|
|
3894
|
-
|
|
3895
|
-
this.lastQueryWalked = [];
|
|
3896
|
-
let frontier = [];
|
|
3961
|
+
this.extractDemanded(pending.map((one) => one.target.getSourceFile()));
|
|
3897
3962
|
for (const one of pending) {
|
|
3898
|
-
const
|
|
3899
|
-
|
|
3900
|
-
frontier.push(file);
|
|
3901
|
-
}
|
|
3902
|
-
}
|
|
3903
|
-
const open = new Set(pending);
|
|
3904
|
-
for (let hop = 0; hop <= MAX_MODULE_HOPS && open.size > 0; hop++) {
|
|
3905
|
-
const next = [];
|
|
3906
|
-
for (const sourceFile of frontier) {
|
|
3907
|
-
if (walked.has(sourceFile.getFilePath())) {
|
|
3908
|
-
continue;
|
|
3909
|
-
}
|
|
3910
|
-
walked.add(sourceFile.getFilePath());
|
|
3911
|
-
this.lastQueryWalked.push(sourceFile.getFilePath());
|
|
3912
|
-
recordFileDependency(sourceFile.getFilePath());
|
|
3913
|
-
this.extractFile(sourceFile);
|
|
3914
|
-
next.push(...this.graph.importedFilesOf(sourceFile));
|
|
3915
|
-
}
|
|
3916
|
-
for (const one of [...open]) {
|
|
3917
|
-
const found = this.lookupImportOrigins(one.target, modules);
|
|
3918
|
-
if (found !== null) {
|
|
3919
|
-
results.set(one.value, found);
|
|
3920
|
-
this.importOrigins.set(one.key, {
|
|
3921
|
-
origins: found,
|
|
3922
|
-
walked: [...this.lastQueryWalked],
|
|
3923
|
-
extractedAt: this.fullyExtracted.size
|
|
3924
|
-
});
|
|
3925
|
-
open.delete(one);
|
|
3926
|
-
}
|
|
3927
|
-
}
|
|
3928
|
-
if (next.length === 0) {
|
|
3929
|
-
break;
|
|
3930
|
-
}
|
|
3931
|
-
frontier = next;
|
|
3932
|
-
}
|
|
3933
|
-
for (const one of open) {
|
|
3934
|
-
results.set(one.value, []);
|
|
3963
|
+
const origins = this.lookupImportOrigins(one.target, modules);
|
|
3964
|
+
results.set(one.value, origins);
|
|
3935
3965
|
this.importOrigins.set(one.key, {
|
|
3936
|
-
origins
|
|
3966
|
+
origins,
|
|
3937
3967
|
walked: [...this.lastQueryWalked],
|
|
3938
3968
|
extractedAt: this.fullyExtracted.size
|
|
3939
3969
|
});
|
|
@@ -3992,67 +4022,89 @@ var ResolutionStore = class {
|
|
|
3992
4022
|
const refined = new Set(
|
|
3993
4023
|
[...byPath.values()].filter((one) => one.path.length > 1).map((one) => (0, import_datalog2.tupleKey)(one.path.slice(0, -1)))
|
|
3994
4024
|
);
|
|
3995
|
-
|
|
3996
|
-
if (origins.length > 0) {
|
|
3997
|
-
return origins;
|
|
3998
|
-
}
|
|
3999
|
-
return all.some((one) => namesAPackage(one.module)) ? [] : null;
|
|
4025
|
+
return [...byPath.values()].filter((one) => !refined.has((0, import_datalog2.tupleKey)(one.path))).sort((a, b) => a.path.join(".").localeCompare(b.path.join(".")));
|
|
4000
4026
|
}
|
|
4001
|
-
/**
|
|
4002
|
-
* Null tells the walk to keep widening. A value that landed in a
|
|
4003
|
-
* package returns empty instead, because a library's own body is not
|
|
4004
|
-
* here to read and widening would never find anything.
|
|
4005
|
-
*/
|
|
4006
4027
|
lookupImportedNames(value, modules) {
|
|
4007
4028
|
this.derive();
|
|
4008
|
-
const
|
|
4009
|
-
|
|
4029
|
+
const reached = new Set(
|
|
4030
|
+
this.answerPairsFor("wantedComesFrom", nodeId(value))
|
|
4031
|
+
);
|
|
4010
4032
|
for (const target of this.answersFor("wantedComesTo", nodeId(value))) {
|
|
4011
4033
|
for (const entry of this.answerPairsFor("wantedCallsInto", target)) {
|
|
4012
4034
|
reached.add(entry);
|
|
4013
4035
|
}
|
|
4014
4036
|
}
|
|
4015
|
-
|
|
4016
|
-
if (names.length > 0) {
|
|
4017
|
-
return names;
|
|
4018
|
-
}
|
|
4019
|
-
return origins.some((pair) => namesAPackage(pairHalves(pair).module)) ? [] : null;
|
|
4037
|
+
return namesFrom([...reached], modules);
|
|
4020
4038
|
}
|
|
4021
|
-
|
|
4039
|
+
askAbout(value, question, read2, alsoFrom) {
|
|
4022
4040
|
try {
|
|
4023
|
-
|
|
4041
|
+
this.wantValue(question, value);
|
|
4042
|
+
this.seedValue(value);
|
|
4043
|
+
this.extractDemanded(
|
|
4044
|
+
alsoFrom === void 0 ? [value.getSourceFile()] : [value.getSourceFile(), alsoFrom]
|
|
4045
|
+
);
|
|
4046
|
+
return read2();
|
|
4024
4047
|
} finally {
|
|
4025
4048
|
this.forgetQuery();
|
|
4026
4049
|
}
|
|
4027
4050
|
}
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4051
|
+
/**
|
|
4052
|
+
* Extract the seed files, then every module the rules ask for, until
|
|
4053
|
+
* they ask for nothing new. The files a question reads are then fixed
|
|
4054
|
+
* by the question alone, so its answer does not depend on what an
|
|
4055
|
+
* earlier question left in the store.
|
|
4056
|
+
*/
|
|
4057
|
+
extractDemanded(seeds) {
|
|
4058
|
+
const project = seeds[0]?.getProject();
|
|
4059
|
+
if (project === void 0) {
|
|
4060
|
+
return;
|
|
4061
|
+
}
|
|
4062
|
+
const read2 = /* @__PURE__ */ new Set();
|
|
4063
|
+
const considered = /* @__PURE__ */ new Set();
|
|
4032
4064
|
this.lastQueryWalked = [];
|
|
4033
|
-
let
|
|
4034
|
-
|
|
4035
|
-
const
|
|
4036
|
-
for (const sourceFile of
|
|
4037
|
-
|
|
4065
|
+
let pending = [...seeds];
|
|
4066
|
+
while (pending.length > 0) {
|
|
4067
|
+
const readThisRound = [];
|
|
4068
|
+
for (const sourceFile of pending) {
|
|
4069
|
+
const filePath = sourceFile.getFilePath();
|
|
4070
|
+
if (read2.has(filePath)) {
|
|
4038
4071
|
continue;
|
|
4039
4072
|
}
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4073
|
+
read2.add(filePath);
|
|
4074
|
+
readThisRound.push(filePath);
|
|
4075
|
+
this.lastQueryWalked.push(filePath);
|
|
4076
|
+
recordFileDependency(filePath);
|
|
4043
4077
|
this.extractFile(sourceFile);
|
|
4044
|
-
next.push(...this.graph.importedFilesOf(sourceFile));
|
|
4045
|
-
}
|
|
4046
|
-
const found = ask();
|
|
4047
|
-
if (found !== null) {
|
|
4048
|
-
return found;
|
|
4049
4078
|
}
|
|
4050
|
-
|
|
4051
|
-
|
|
4079
|
+
this.derive();
|
|
4080
|
+
pending = [];
|
|
4081
|
+
for (const moduleKey of this.demandedModules(readThisRound)) {
|
|
4082
|
+
if (considered.has(moduleKey)) {
|
|
4083
|
+
continue;
|
|
4084
|
+
}
|
|
4085
|
+
considered.add(moduleKey);
|
|
4086
|
+
const sourceFile = sourceFileFor(project, moduleKey);
|
|
4087
|
+
if (sourceFile !== void 0 && !read2.has(sourceFile.getFilePath())) {
|
|
4088
|
+
pending.push(sourceFile);
|
|
4089
|
+
}
|
|
4052
4090
|
}
|
|
4053
|
-
frontier = next;
|
|
4054
4091
|
}
|
|
4055
|
-
|
|
4092
|
+
}
|
|
4093
|
+
/**
|
|
4094
|
+
* Module keys the rules are waiting on. Demand facts are cleared
|
|
4095
|
+
* between queries, so the demand relations contain this query's
|
|
4096
|
+
* alone; the unrestricted program has none, and follows the imports
|
|
4097
|
+
* of the files read this round instead.
|
|
4098
|
+
*/
|
|
4099
|
+
demandedModules(readThisRound) {
|
|
4100
|
+
if (RESOLUTION_PROGRAM.demands.length === 0) {
|
|
4101
|
+
return readThisRound.flatMap(
|
|
4102
|
+
(filePath) => this.db.lookup("importsModule", 0, filePath).map((tuple) => String(tuple[1]))
|
|
4103
|
+
);
|
|
4104
|
+
}
|
|
4105
|
+
return MODULE_DEMANDS.flatMap(
|
|
4106
|
+
(relation) => this.db.facts(relation).map((tuple) => String(tuple[0]))
|
|
4107
|
+
);
|
|
4056
4108
|
}
|
|
4057
4109
|
/**
|
|
4058
4110
|
* The question and the chain that settled it are dropped. The files
|
|
@@ -4071,6 +4123,27 @@ var ResolutionStore = class {
|
|
|
4071
4123
|
this.stale = true;
|
|
4072
4124
|
}
|
|
4073
4125
|
}
|
|
4126
|
+
wantExportsOf(filePath) {
|
|
4127
|
+
if (this.db.add("wantedExportsOf", [filePath]) === "added") {
|
|
4128
|
+
this.stale = true;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
/**
|
|
4132
|
+
* Discovery walks the table in order, and the rounds derive it in
|
|
4133
|
+
* the order files arrived. Deriving it again from the demand alone,
|
|
4134
|
+
* over the loaded closure, orders it by the file's own statements.
|
|
4135
|
+
*/
|
|
4136
|
+
rederiveExportsOf(filePath) {
|
|
4137
|
+
if (QUERY_FACTS.length === 0) {
|
|
4138
|
+
return;
|
|
4139
|
+
}
|
|
4140
|
+
this.db.retract("wantedModuleExport", [
|
|
4141
|
+
...this.db.lookup("wantedModuleExport", 0, filePath)
|
|
4142
|
+
]);
|
|
4143
|
+
this.forgetQuery();
|
|
4144
|
+
this.wantExportsOf(filePath);
|
|
4145
|
+
this.derive();
|
|
4146
|
+
}
|
|
4074
4147
|
/**
|
|
4075
4148
|
* File extraction only reaches values hanging off exports, and a query
|
|
4076
4149
|
* can be rooted anywhere, so the queried value gets its own facts.
|
|
@@ -4120,24 +4193,18 @@ var ResolutionStore = class {
|
|
|
4120
4193
|
}
|
|
4121
4194
|
candidates.add(node);
|
|
4122
4195
|
}
|
|
4123
|
-
if (candidates.size
|
|
4124
|
-
return
|
|
4125
|
-
}
|
|
4126
|
-
if (candidates.size > 1) {
|
|
4127
|
-
return { written: null };
|
|
4128
|
-
}
|
|
4129
|
-
if (neverWritable(value)) {
|
|
4130
|
-
return { written: null };
|
|
4196
|
+
if (candidates.size !== 1) {
|
|
4197
|
+
return null;
|
|
4131
4198
|
}
|
|
4132
|
-
return
|
|
4199
|
+
return [...candidates][0];
|
|
4133
4200
|
}
|
|
4134
4201
|
/**
|
|
4135
4202
|
* Read these files' facts now, before anything asks a question.
|
|
4136
4203
|
*
|
|
4137
|
-
* A query
|
|
4138
|
-
*
|
|
4204
|
+
* A query follows the imports of the file it starts in, which is
|
|
4205
|
+
* where a value's definition is. What a caller passed is the other
|
|
4139
4206
|
* direction, so a question about a parameter is answered only by
|
|
4140
|
-
* files the
|
|
4207
|
+
* files the query never reaches on its own.
|
|
4141
4208
|
*/
|
|
4142
4209
|
extractFiles(sourceFiles) {
|
|
4143
4210
|
for (const sourceFile of sourceFiles) {
|
|
@@ -4153,15 +4220,14 @@ var ResolutionStore = class {
|
|
|
4153
4220
|
return this.graph.filesReachingAnyPackage(fileSets);
|
|
4154
4221
|
}
|
|
4155
4222
|
/**
|
|
4156
|
-
* The calls behind a receiver that `matches` accepts
|
|
4157
|
-
*
|
|
4158
|
-
*
|
|
4159
|
-
*
|
|
4160
|
-
* cannot rank a nearer call above a farther one.
|
|
4223
|
+
* The calls behind a receiver that `matches` accepts. The caller
|
|
4224
|
+
* applies the single-answer policy to the set; the resolution
|
|
4225
|
+
* README's anchor section says why the rules cannot rank a nearer
|
|
4226
|
+
* call above a farther one.
|
|
4161
4227
|
*/
|
|
4162
4228
|
anchorCallsOf(value, matches) {
|
|
4163
4229
|
const target = factKeyOf(value);
|
|
4164
|
-
return this.
|
|
4230
|
+
return this.askAbout(target, "wantedAnchor", () => {
|
|
4165
4231
|
this.derive();
|
|
4166
4232
|
const found = [];
|
|
4167
4233
|
for (const id of this.answersFor("wantedAnchorCall", nodeId(target))) {
|
|
@@ -4170,12 +4236,12 @@ var ResolutionStore = class {
|
|
|
4170
4236
|
found.push(node);
|
|
4171
4237
|
}
|
|
4172
4238
|
}
|
|
4173
|
-
return found
|
|
4174
|
-
})
|
|
4239
|
+
return found;
|
|
4240
|
+
});
|
|
4175
4241
|
}
|
|
4176
4242
|
/**
|
|
4177
4243
|
* Every name a module exports and the values behind each, with
|
|
4178
|
-
* re-export chains flattened by the rules. The
|
|
4244
|
+
* re-export chains flattened by the rules. The demand follows
|
|
4179
4245
|
* re-export targets only, so a barrel of barrels extracts its own
|
|
4180
4246
|
* chain and nothing beside it, to any depth.
|
|
4181
4247
|
*/
|
|
@@ -4195,33 +4261,10 @@ var ResolutionStore = class {
|
|
|
4195
4261
|
}
|
|
4196
4262
|
}
|
|
4197
4263
|
collectExports(sourceFile) {
|
|
4198
|
-
const project = sourceFile.getProject();
|
|
4199
|
-
const walked = /* @__PURE__ */ new Set();
|
|
4200
|
-
let frontier = [sourceFile];
|
|
4201
|
-
while (frontier.length > 0) {
|
|
4202
|
-
const next = [];
|
|
4203
|
-
for (const file of frontier) {
|
|
4204
|
-
const filePath2 = file.getFilePath();
|
|
4205
|
-
if (walked.has(filePath2)) {
|
|
4206
|
-
continue;
|
|
4207
|
-
}
|
|
4208
|
-
walked.add(filePath2);
|
|
4209
|
-
recordFileDependency(filePath2);
|
|
4210
|
-
this.extractFile(file);
|
|
4211
|
-
for (const target of this.reExportTargetsOf(filePath2)) {
|
|
4212
|
-
const targetFile = sourceFileFor(project, target);
|
|
4213
|
-
if (targetFile !== void 0) {
|
|
4214
|
-
next.push(targetFile);
|
|
4215
|
-
}
|
|
4216
|
-
}
|
|
4217
|
-
}
|
|
4218
|
-
frontier = next;
|
|
4219
|
-
}
|
|
4220
4264
|
const filePath = sourceFile.getFilePath();
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
this.derive();
|
|
4265
|
+
this.wantExportsOf(filePath);
|
|
4266
|
+
this.extractDemanded([sourceFile]);
|
|
4267
|
+
this.rederiveExportsOf(filePath);
|
|
4225
4268
|
const exports2 = /* @__PURE__ */ new Map();
|
|
4226
4269
|
for (const tuple of this.db.lookup("wantedModuleExport", 0, filePath)) {
|
|
4227
4270
|
const node = this.table.byId.get(String(tuple[2]));
|
|
@@ -4238,22 +4281,9 @@ var ResolutionStore = class {
|
|
|
4238
4281
|
}
|
|
4239
4282
|
return exports2;
|
|
4240
4283
|
}
|
|
4241
|
-
/** Module keys this file re-exports from, read off its own facts. */
|
|
4242
|
-
reExportTargetsOf(filePath) {
|
|
4243
|
-
const targets = /* @__PURE__ */ new Set();
|
|
4244
|
-
for (const tuple of this.db.lookup("reExports", 0, filePath)) {
|
|
4245
|
-
targets.add(String(tuple[2]));
|
|
4246
|
-
}
|
|
4247
|
-
for (const tuple of this.db.lookup("reExportsAll", 0, filePath)) {
|
|
4248
|
-
targets.add(String(tuple[1]));
|
|
4249
|
-
}
|
|
4250
|
-
return [...targets];
|
|
4251
|
-
}
|
|
4252
4284
|
/**
|
|
4253
|
-
*
|
|
4254
|
-
*
|
|
4255
|
-
* single-answer policy stays with the callers: picking one of two
|
|
4256
|
-
* would make the result depend on the order the facts came in.
|
|
4285
|
+
* The single-answer policy stays with the callers: a value with two
|
|
4286
|
+
* sources is something to say at the site, not something to pick from.
|
|
4257
4287
|
*/
|
|
4258
4288
|
lookupSources(value) {
|
|
4259
4289
|
this.derive();
|
|
@@ -4267,7 +4297,7 @@ var ResolutionStore = class {
|
|
|
4267
4297
|
candidates.add(resolved);
|
|
4268
4298
|
}
|
|
4269
4299
|
}
|
|
4270
|
-
return
|
|
4300
|
+
return [...candidates];
|
|
4271
4301
|
}
|
|
4272
4302
|
derive() {
|
|
4273
4303
|
if (!this.stale) {
|
|
@@ -4326,18 +4356,6 @@ function pairHalves(pair) {
|
|
|
4326
4356
|
const [module2 = "", name = ""] = (0, import_datalog2.tupleKeyParts)(pair);
|
|
4327
4357
|
return { module: module2, name };
|
|
4328
4358
|
}
|
|
4329
|
-
function namesAPackage(moduleKey) {
|
|
4330
|
-
return !moduleKey.startsWith("/") || moduleKey.includes("/node_modules/");
|
|
4331
|
-
}
|
|
4332
|
-
function neverWritable(value) {
|
|
4333
|
-
if (!import_ts_morph16.Node.isIdentifier(value)) {
|
|
4334
|
-
return false;
|
|
4335
|
-
}
|
|
4336
|
-
const declarations = value.getSymbol()?.getDeclarations() ?? [];
|
|
4337
|
-
return declarations.some(
|
|
4338
|
-
(declaration) => declaration.getSourceFile().getFilePath().includes("/node_modules/")
|
|
4339
|
-
);
|
|
4340
|
-
}
|
|
4341
4359
|
function namesPackage2(moduleKey, packages) {
|
|
4342
4360
|
return namesAnyPackage(
|
|
4343
4361
|
[moduleKey, ...packagesDeclaring(moduleKey)],
|
|
@@ -4358,35 +4376,7 @@ var import_node_path3 = __toESM(require("path"), 1);
|
|
|
4358
4376
|
// src/diagnostics.ts
|
|
4359
4377
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
4360
4378
|
var import_ts_morph17 = require("ts-morph");
|
|
4361
|
-
var
|
|
4362
|
-
var emptyTally = () => ({
|
|
4363
|
-
candidateFiles: 0,
|
|
4364
|
-
unitsDiscovered: 0,
|
|
4365
|
-
unitsInGatedFiles: 0,
|
|
4366
|
-
effectsRecognized: 0,
|
|
4367
|
-
unitsClaimed: 0,
|
|
4368
|
-
selfCollisions: 0,
|
|
4369
|
-
summariesProduced: 0,
|
|
4370
|
-
failures: [],
|
|
4371
|
-
helpersMatched: /* @__PURE__ */ new Set()
|
|
4372
|
-
});
|
|
4373
|
-
function recordPackFailure(tally, failure) {
|
|
4374
|
-
const message = failure.error instanceof Error ? failure.error.message : String(failure.error);
|
|
4375
|
-
tally?.failures.push({
|
|
4376
|
-
hook: failure.hook,
|
|
4377
|
-
file: failure.file,
|
|
4378
|
-
message
|
|
4379
|
-
});
|
|
4380
|
-
return `[suss] pack "${failure.pack}" threw from ${failure.hook} while reading ${failure.file}: ${message}
|
|
4381
|
-
`;
|
|
4382
|
-
}
|
|
4383
|
-
function createPackTallies(packs) {
|
|
4384
|
-
const tallies = /* @__PURE__ */ new Map();
|
|
4385
|
-
for (const pack of packs) {
|
|
4386
|
-
tallies.set(pack.name, emptyTally());
|
|
4387
|
-
}
|
|
4388
|
-
return tallies;
|
|
4389
|
-
}
|
|
4379
|
+
var import_extractor3 = require("@suss/extractor");
|
|
4390
4380
|
function commonDirectoryOf(files) {
|
|
4391
4381
|
const absolute = files.filter((f) => import_node_path2.default.isAbsolute(f));
|
|
4392
4382
|
const first = absolute[0];
|
|
@@ -4463,30 +4453,6 @@ function unresolvedGatesFor(gates, args) {
|
|
|
4463
4453
|
}
|
|
4464
4454
|
return unresolved;
|
|
4465
4455
|
}
|
|
4466
|
-
var emptyCounts = () => ({
|
|
4467
|
-
bound: 0,
|
|
4468
|
-
providers: 0,
|
|
4469
|
-
withBehavior: 0
|
|
4470
|
-
});
|
|
4471
|
-
function summaryCountsByPack(summaries) {
|
|
4472
|
-
const counts = /* @__PURE__ */ new Map();
|
|
4473
|
-
for (const summary of summaries) {
|
|
4474
|
-
const recognition = summary.identity.boundaryBinding?.recognition;
|
|
4475
|
-
if (recognition === void 0 || recognition === null) {
|
|
4476
|
-
continue;
|
|
4477
|
-
}
|
|
4478
|
-
const entry = counts.get(recognition) ?? emptyCounts();
|
|
4479
|
-
entry.bound += 1;
|
|
4480
|
-
if (import_behavioral_ir.BOUNDARY_ROLE[summary.kind] === "provider") {
|
|
4481
|
-
entry.providers += 1;
|
|
4482
|
-
}
|
|
4483
|
-
if (summary.transitions.length > 0) {
|
|
4484
|
-
entry.withBehavior += 1;
|
|
4485
|
-
}
|
|
4486
|
-
counts.set(recognition, entry);
|
|
4487
|
-
}
|
|
4488
|
-
return counts;
|
|
4489
|
-
}
|
|
4490
4456
|
function helpersWithNoCall(patterns, matched, projectRoot) {
|
|
4491
4457
|
const missing = [];
|
|
4492
4458
|
for (const pattern of patterns) {
|
|
@@ -4507,11 +4473,15 @@ function shortModule(module2, projectRoot) {
|
|
|
4507
4473
|
return import_node_path2.default.relative(projectRoot, module2);
|
|
4508
4474
|
}
|
|
4509
4475
|
function buildExtractionReport(args) {
|
|
4510
|
-
const bySummary = summaryCountsByPack(args.summaries);
|
|
4476
|
+
const bySummary = (0, import_extractor3.summaryCountsByPack)(args.summaries);
|
|
4511
4477
|
const packFunnels = args.packs.map((pack) => {
|
|
4512
4478
|
const gates = packIsUngated(pack) ? [] : collectPackGates(pack);
|
|
4513
|
-
const tally = args.tallies.get(pack.name) ?? emptyTally();
|
|
4514
|
-
const counted = bySummary.get(pack.name) ??
|
|
4479
|
+
const tally = args.tallies.get(pack.name) ?? (0, import_extractor3.emptyTally)();
|
|
4480
|
+
const counted = bySummary.get(pack.name) ?? {
|
|
4481
|
+
bound: 0,
|
|
4482
|
+
providers: 0,
|
|
4483
|
+
withBehavior: 0
|
|
4484
|
+
};
|
|
4515
4485
|
return {
|
|
4516
4486
|
pack: pack.name,
|
|
4517
4487
|
version: pack.version ?? null,
|
|
@@ -4740,13 +4710,26 @@ function propertiesReached(object, resolution, seen) {
|
|
|
4740
4710
|
}
|
|
4741
4711
|
function writtenNodeOf(value, resolution) {
|
|
4742
4712
|
const written = factKeyOf(value);
|
|
4743
|
-
if (import_ts_morph18.Node.
|
|
4713
|
+
if (import_ts_morph18.Node.isNewExpression(written)) {
|
|
4744
4714
|
return written;
|
|
4745
4715
|
}
|
|
4716
|
+
if (import_ts_morph18.Node.isCallExpression(written)) {
|
|
4717
|
+
return writtenThroughCall(written, resolution);
|
|
4718
|
+
}
|
|
4746
4719
|
if (resolution === void 0 || !couldNameAValue(written)) {
|
|
4747
4720
|
return null;
|
|
4748
4721
|
}
|
|
4749
|
-
|
|
4722
|
+
const resolved = resolution.resolveWrittenValue(written);
|
|
4723
|
+
return resolved !== null && import_ts_morph18.Node.isCallExpression(resolved) ? writtenThroughCall(resolved, resolution) : resolved;
|
|
4724
|
+
}
|
|
4725
|
+
function writtenThroughCall(call, resolution) {
|
|
4726
|
+
if (resolution !== void 0 && resolution.resolveCallable(call.getExpression()) !== null) {
|
|
4727
|
+
const resolved = resolution.resolveWrittenValue(call);
|
|
4728
|
+
if (resolved !== null) {
|
|
4729
|
+
return resolved;
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
return call;
|
|
4750
4733
|
}
|
|
4751
4734
|
function stringValueOf(value, resolution) {
|
|
4752
4735
|
const written = factKeyOf(value);
|
|
@@ -4808,7 +4791,7 @@ function discoverClientCalls(sourceFile, match, kind, resolution) {
|
|
|
4808
4791
|
}
|
|
4809
4792
|
} else if (import_ts_morph19.Node.isPropertyAccessExpression(callee)) {
|
|
4810
4793
|
const subject = callee.getExpression();
|
|
4811
|
-
if (import_ts_morph19.Node.isIdentifier(subject) && (isClientImport(subject, match, resolution, true) || clientVarNames.has(subject.getText()) || resolvesToKnownInstance(subject, match, resolution))
|
|
4794
|
+
if (import_ts_morph19.Node.isIdentifier(subject) && (isClientImport(subject, match, resolution, true) || clientVarNames.has(subject.getText())) || resolvesToKnownInstance(subject, match, resolution)) {
|
|
4812
4795
|
methodName = callee.getName();
|
|
4813
4796
|
if (methodFilter === null || methodFilter.has(methodName)) {
|
|
4814
4797
|
matched = true;
|
|
@@ -6412,14 +6395,14 @@ function unitForJsxRoute(node, match, routeNames, kind, resolution) {
|
|
|
6412
6395
|
}
|
|
6413
6396
|
return routeUnit(node, kind, match.method, resolved.path, target, resolution);
|
|
6414
6397
|
}
|
|
6415
|
-
function routeUnit(at, kind, method,
|
|
6416
|
-
const routeInfo = { method, path:
|
|
6398
|
+
function routeUnit(at, kind, method, path14, target, resolution) {
|
|
6399
|
+
const routeInfo = { method, path: path14 };
|
|
6417
6400
|
if (target.kind === "unreadable") {
|
|
6418
6401
|
return {
|
|
6419
6402
|
func: null,
|
|
6420
6403
|
announcedAt: at,
|
|
6421
6404
|
kind,
|
|
6422
|
-
name:
|
|
6405
|
+
name: path14,
|
|
6423
6406
|
nameKind: "label",
|
|
6424
6407
|
routeInfo
|
|
6425
6408
|
};
|
|
@@ -6618,7 +6601,6 @@ function labelOfExpression(node) {
|
|
|
6618
6601
|
}
|
|
6619
6602
|
|
|
6620
6603
|
// src/discovery/packageExports.ts
|
|
6621
|
-
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
6622
6604
|
var import_ts_morph31 = require("ts-morph");
|
|
6623
6605
|
|
|
6624
6606
|
// src/packageExports.ts
|
|
@@ -6647,7 +6629,8 @@ function resolvePackageExports(packageJsonPath, opts = {}) {
|
|
|
6647
6629
|
packageName,
|
|
6648
6630
|
subPath,
|
|
6649
6631
|
exportPathPrefix: subPathToPrefix(subPath),
|
|
6650
|
-
sourceFile: src
|
|
6632
|
+
sourceFile: src,
|
|
6633
|
+
publishedFile: import_node_path5.default.resolve(pkgDir, distPath)
|
|
6651
6634
|
});
|
|
6652
6635
|
};
|
|
6653
6636
|
const exportsField = pkg.exports;
|
|
@@ -6667,6 +6650,53 @@ function resolvePackageExports(packageJsonPath, opts = {}) {
|
|
|
6667
6650
|
}
|
|
6668
6651
|
return { packageName, entries, warnings };
|
|
6669
6652
|
}
|
|
6653
|
+
var packageExportsCache = /* @__PURE__ */ new Map();
|
|
6654
|
+
var PATH_STAMP_SEPARATOR = "";
|
|
6655
|
+
function packageJsonStamp(packageJsonPath) {
|
|
6656
|
+
try {
|
|
6657
|
+
const stat = import_node_fs2.default.statSync(packageJsonPath);
|
|
6658
|
+
return `${stat.mtimeMs}:${stat.size}`;
|
|
6659
|
+
} catch {
|
|
6660
|
+
return "unreadable";
|
|
6661
|
+
}
|
|
6662
|
+
}
|
|
6663
|
+
function resolvePackageExportsCached(packageJsonPath) {
|
|
6664
|
+
const stamp2 = packageJsonStamp(packageJsonPath);
|
|
6665
|
+
const key = `${packageJsonPath}${PATH_STAMP_SEPARATOR}${stamp2}`;
|
|
6666
|
+
const cached = packageExportsCache.get(key);
|
|
6667
|
+
if (cached !== void 0) {
|
|
6668
|
+
return cached;
|
|
6669
|
+
}
|
|
6670
|
+
const fresh = resolvePackageExports(packageJsonPath);
|
|
6671
|
+
packageExportsCache.set(key, fresh);
|
|
6672
|
+
return fresh;
|
|
6673
|
+
}
|
|
6674
|
+
function namedPackageDirAbove(start) {
|
|
6675
|
+
let at = import_node_path5.default.resolve(start);
|
|
6676
|
+
for (let up = 0; up < 12; up += 1) {
|
|
6677
|
+
if (packageNameAt(at) !== null) {
|
|
6678
|
+
return at;
|
|
6679
|
+
}
|
|
6680
|
+
const parent = import_node_path5.default.dirname(at);
|
|
6681
|
+
if (parent === at) {
|
|
6682
|
+
break;
|
|
6683
|
+
}
|
|
6684
|
+
at = parent;
|
|
6685
|
+
}
|
|
6686
|
+
return null;
|
|
6687
|
+
}
|
|
6688
|
+
function packageNameAt(dir) {
|
|
6689
|
+
try {
|
|
6690
|
+
const manifest = JSON.parse(
|
|
6691
|
+
import_node_fs2.default.readFileSync(import_node_path5.default.join(dir, "package.json"), "utf8")
|
|
6692
|
+
);
|
|
6693
|
+
if (typeof manifest.name === "string" && manifest.name.length > 0) {
|
|
6694
|
+
return manifest.name;
|
|
6695
|
+
}
|
|
6696
|
+
} catch {
|
|
6697
|
+
}
|
|
6698
|
+
return null;
|
|
6699
|
+
}
|
|
6670
6700
|
function pickConditional(value, warnings, key) {
|
|
6671
6701
|
if (value === void 0 || value === null) {
|
|
6672
6702
|
if (value === null) {
|
|
@@ -6716,8 +6746,55 @@ function resolveSourceFor(pkgDir, distPath, srcRoot) {
|
|
|
6716
6746
|
return null;
|
|
6717
6747
|
}
|
|
6718
6748
|
|
|
6749
|
+
// src/resolve/sourceDeclaration.ts
|
|
6750
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
6751
|
+
function sourceDeclarationsBehind(decl, resolution, visited = /* @__PURE__ */ new Set()) {
|
|
6752
|
+
const file = decl.getSourceFile();
|
|
6753
|
+
if (!file.isDeclarationFile() || file.isInNodeModules()) {
|
|
6754
|
+
return [decl];
|
|
6755
|
+
}
|
|
6756
|
+
const packageDir = namedPackageDirAbove(import_node_path6.default.dirname(file.getFilePath()));
|
|
6757
|
+
if (packageDir === null || visited.has(packageDir)) {
|
|
6758
|
+
return [decl];
|
|
6759
|
+
}
|
|
6760
|
+
visited.add(packageDir);
|
|
6761
|
+
const project = file.getProject();
|
|
6762
|
+
const { entries } = resolvePackageExportsCached(
|
|
6763
|
+
import_node_path6.default.join(packageDir, "package.json")
|
|
6764
|
+
);
|
|
6765
|
+
const found = [];
|
|
6766
|
+
for (const entry of entries) {
|
|
6767
|
+
const published = sourceFileFor(project, entry.publishedFile);
|
|
6768
|
+
const source = sourceFileFor(project, entry.sourceFile);
|
|
6769
|
+
if (published === void 0 || source === void 0) {
|
|
6770
|
+
continue;
|
|
6771
|
+
}
|
|
6772
|
+
for (const [name, nodes] of resolution.exportsOf(published)) {
|
|
6773
|
+
if (!nodes.some((node) => sameDeclaration(node, decl))) {
|
|
6774
|
+
continue;
|
|
6775
|
+
}
|
|
6776
|
+
for (const behind of resolution.exportsOf(source).get(name) ?? []) {
|
|
6777
|
+
for (const candidate of sourceDeclarationsBehind(
|
|
6778
|
+
behind,
|
|
6779
|
+
resolution,
|
|
6780
|
+
visited
|
|
6781
|
+
)) {
|
|
6782
|
+
if (!found.includes(candidate)) {
|
|
6783
|
+
found.push(candidate);
|
|
6784
|
+
}
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
}
|
|
6789
|
+
return found.length > 0 ? found : [decl];
|
|
6790
|
+
}
|
|
6791
|
+
function sameDeclaration(a, b) {
|
|
6792
|
+
return a === b || a.getSourceFile().getFilePath() === b.getSourceFile().getFilePath() && a.getStart() === b.getStart() && a.getEnd() === b.getEnd();
|
|
6793
|
+
}
|
|
6794
|
+
|
|
6719
6795
|
// src/discovery/factorySurface.ts
|
|
6720
6796
|
var import_ts_morph30 = require("ts-morph");
|
|
6797
|
+
var MAX_BUILDER_HOPS = 2;
|
|
6721
6798
|
function surfaceMethods(decl) {
|
|
6722
6799
|
if (import_ts_morph30.Node.isClassDeclaration(decl)) {
|
|
6723
6800
|
return surfaceClassMethods(decl);
|
|
@@ -6757,16 +6834,20 @@ function surfaceClassMethods(cls) {
|
|
|
6757
6834
|
function surfaceFactoryReturnMethods(fn) {
|
|
6758
6835
|
const out = [];
|
|
6759
6836
|
const seen = /* @__PURE__ */ new Set();
|
|
6837
|
+
collectFromFunctionReturns(fn, out, seen, 0);
|
|
6838
|
+
return out;
|
|
6839
|
+
}
|
|
6840
|
+
function collectFromFunctionReturns(fn, out, seen, depth) {
|
|
6760
6841
|
if (import_ts_morph30.Node.isArrowFunction(fn)) {
|
|
6761
6842
|
const body2 = fn.getBody();
|
|
6762
6843
|
if (import_ts_morph30.Node.isExpression(body2)) {
|
|
6763
|
-
|
|
6764
|
-
return
|
|
6844
|
+
collectFromReturnValue(body2, out, seen, depth);
|
|
6845
|
+
return;
|
|
6765
6846
|
}
|
|
6766
6847
|
}
|
|
6767
6848
|
const body = fn.getBody?.();
|
|
6768
6849
|
if (body === void 0) {
|
|
6769
|
-
return
|
|
6850
|
+
return;
|
|
6770
6851
|
}
|
|
6771
6852
|
const returns = [];
|
|
6772
6853
|
body.forEachDescendant((node, traversal) => {
|
|
@@ -6783,9 +6864,53 @@ function surfaceFactoryReturnMethods(fn) {
|
|
|
6783
6864
|
if (expr === void 0) {
|
|
6784
6865
|
continue;
|
|
6785
6866
|
}
|
|
6867
|
+
collectFromReturnValue(expr, out, seen, depth);
|
|
6868
|
+
}
|
|
6869
|
+
}
|
|
6870
|
+
function collectFromReturnValue(node, out, seen, depth) {
|
|
6871
|
+
const expr = peelParens(node);
|
|
6872
|
+
if (import_ts_morph30.Node.isObjectLiteralExpression(expr)) {
|
|
6786
6873
|
collectFromObjectLiteral(expr, out, seen);
|
|
6874
|
+
return;
|
|
6787
6875
|
}
|
|
6788
|
-
|
|
6876
|
+
if (depth >= MAX_BUILDER_HOPS || !import_ts_morph30.Node.isCallExpression(expr)) {
|
|
6877
|
+
return;
|
|
6878
|
+
}
|
|
6879
|
+
const callee = expr.getExpression();
|
|
6880
|
+
if (!import_ts_morph30.Node.isIdentifier(callee)) {
|
|
6881
|
+
return;
|
|
6882
|
+
}
|
|
6883
|
+
const helper = sameFileFunctionBehind(callee);
|
|
6884
|
+
if (helper !== null) {
|
|
6885
|
+
collectFromFunctionReturns(helper, out, seen, depth + 1);
|
|
6886
|
+
}
|
|
6887
|
+
}
|
|
6888
|
+
function sameFileFunctionBehind(id) {
|
|
6889
|
+
const symbol = id.getSymbol();
|
|
6890
|
+
if (symbol === void 0) {
|
|
6891
|
+
return null;
|
|
6892
|
+
}
|
|
6893
|
+
return functionAmong(
|
|
6894
|
+
symbol.getDeclarations(),
|
|
6895
|
+
id.getSourceFile().getFilePath()
|
|
6896
|
+
);
|
|
6897
|
+
}
|
|
6898
|
+
function functionAmong(declarations, filePath) {
|
|
6899
|
+
for (const decl of declarations) {
|
|
6900
|
+
if (decl.getSourceFile().getFilePath() !== filePath) {
|
|
6901
|
+
continue;
|
|
6902
|
+
}
|
|
6903
|
+
if (import_ts_morph30.Node.isFunctionDeclaration(decl)) {
|
|
6904
|
+
return decl;
|
|
6905
|
+
}
|
|
6906
|
+
if (import_ts_morph30.Node.isVariableDeclaration(decl)) {
|
|
6907
|
+
const init = decl.getInitializer();
|
|
6908
|
+
if (init !== void 0 && (import_ts_morph30.Node.isArrowFunction(init) || import_ts_morph30.Node.isFunctionExpression(init))) {
|
|
6909
|
+
return init;
|
|
6910
|
+
}
|
|
6911
|
+
}
|
|
6912
|
+
}
|
|
6913
|
+
return null;
|
|
6789
6914
|
}
|
|
6790
6915
|
function collectFromObjectLiteral(node, out, seen) {
|
|
6791
6916
|
const e = peelParens(node);
|
|
@@ -6820,31 +6945,31 @@ function collectFromObjectLiteral(node, out, seen) {
|
|
|
6820
6945
|
out.push({ func: v3, name });
|
|
6821
6946
|
}
|
|
6822
6947
|
}
|
|
6948
|
+
if (import_ts_morph30.Node.isShorthandPropertyAssignment(prop)) {
|
|
6949
|
+
collectShorthandFunction(prop, out, seen);
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
}
|
|
6953
|
+
function collectShorthandFunction(prop, out, seen) {
|
|
6954
|
+
const name = prop.getName();
|
|
6955
|
+
if (seen.has(name)) {
|
|
6956
|
+
return;
|
|
6957
|
+
}
|
|
6958
|
+
const symbol = prop.getValueSymbol();
|
|
6959
|
+
if (symbol === void 0) {
|
|
6960
|
+
return;
|
|
6961
|
+
}
|
|
6962
|
+
const fn = functionAmong(
|
|
6963
|
+
symbol.getDeclarations(),
|
|
6964
|
+
prop.getSourceFile().getFilePath()
|
|
6965
|
+
);
|
|
6966
|
+
if (fn !== null) {
|
|
6967
|
+
seen.add(name);
|
|
6968
|
+
out.push({ func: fn, name });
|
|
6823
6969
|
}
|
|
6824
6970
|
}
|
|
6825
6971
|
|
|
6826
6972
|
// src/discovery/packageExports.ts
|
|
6827
|
-
var packageExportsCache = /* @__PURE__ */ new Map();
|
|
6828
|
-
var PATH_STAMP_SEPARATOR = "";
|
|
6829
|
-
function packageJsonStamp(packageJsonPath) {
|
|
6830
|
-
try {
|
|
6831
|
-
const stat = import_node_fs3.default.statSync(packageJsonPath);
|
|
6832
|
-
return `${stat.mtimeMs}:${stat.size}`;
|
|
6833
|
-
} catch {
|
|
6834
|
-
return "unreadable";
|
|
6835
|
-
}
|
|
6836
|
-
}
|
|
6837
|
-
function resolvePackageExportsCached(packageJsonPath) {
|
|
6838
|
-
const stamp = packageJsonStamp(packageJsonPath);
|
|
6839
|
-
const key = `${packageJsonPath}${PATH_STAMP_SEPARATOR}${stamp}`;
|
|
6840
|
-
const cached = packageExportsCache.get(key);
|
|
6841
|
-
if (cached !== void 0) {
|
|
6842
|
-
return cached;
|
|
6843
|
-
}
|
|
6844
|
-
const fresh = resolvePackageExports(packageJsonPath);
|
|
6845
|
-
packageExportsCache.set(key, fresh);
|
|
6846
|
-
return fresh;
|
|
6847
|
-
}
|
|
6848
6973
|
function discoverPackageExports(sourceFile, match, kind, resolution) {
|
|
6849
6974
|
if (match.packageJsonPath === void 0) {
|
|
6850
6975
|
return [];
|
|
@@ -6879,7 +7004,10 @@ function discoverPackageExports(sourceFile, match, kind, resolution) {
|
|
|
6879
7004
|
if (seenNames.has(key)) {
|
|
6880
7005
|
continue;
|
|
6881
7006
|
}
|
|
6882
|
-
|
|
7007
|
+
const candidates = decls.flatMap(
|
|
7008
|
+
(decl) => sourceDeclarationsBehind(decl, resolution)
|
|
7009
|
+
);
|
|
7010
|
+
for (const decl of candidates) {
|
|
6883
7011
|
if (import_ts_morph31.Node.isVariableDeclaration(decl)) {
|
|
6884
7012
|
const init = decl.getInitializer();
|
|
6885
7013
|
if (init !== void 0 && (import_ts_morph31.Node.isArrowFunction(init) || import_ts_morph31.Node.isFunctionExpression(init))) {
|
|
@@ -7032,7 +7160,7 @@ function attributedCalls(sourceFile, packages, resolution) {
|
|
|
7032
7160
|
return null;
|
|
7033
7161
|
}
|
|
7034
7162
|
if (!methodComesFromSource(callee)) {
|
|
7035
|
-
return
|
|
7163
|
+
return null;
|
|
7036
7164
|
}
|
|
7037
7165
|
return {
|
|
7038
7166
|
packageName: subject.packageName,
|
|
@@ -7146,12 +7274,12 @@ function originEndOf(flattened) {
|
|
|
7146
7274
|
const slash = flattened.indexOf("/", opener[0].length);
|
|
7147
7275
|
return slash === -1 ? flattened.length : slash;
|
|
7148
7276
|
}
|
|
7149
|
-
function appendPathText(
|
|
7277
|
+
function appendPathText(path14, text) {
|
|
7150
7278
|
const idx = text.search(/[?#]/);
|
|
7151
7279
|
if (idx === -1) {
|
|
7152
|
-
return { path:
|
|
7280
|
+
return { path: path14 + text, stop: false };
|
|
7153
7281
|
}
|
|
7154
|
-
return { path:
|
|
7282
|
+
return { path: path14 + text.slice(0, idx), stop: true };
|
|
7155
7283
|
}
|
|
7156
7284
|
function parseAbsoluteUrl(text) {
|
|
7157
7285
|
try {
|
|
@@ -7175,8 +7303,8 @@ function pathnameOfAbsoluteLiteral(text) {
|
|
|
7175
7303
|
return stripQueryAndFragment(stripOriginManually(text));
|
|
7176
7304
|
}
|
|
7177
7305
|
function pathFromLiteralUrl(text) {
|
|
7178
|
-
const
|
|
7179
|
-
return
|
|
7306
|
+
const path14 = isAbsoluteUrlLiteral(text) ? pathnameOfAbsoluteLiteral(text) : stripQueryAndFragment(text);
|
|
7307
|
+
return path14 === "" ? void 0 : path14;
|
|
7180
7308
|
}
|
|
7181
7309
|
function pathFromTemplateUrl(arg, resolution) {
|
|
7182
7310
|
const headText = arg.getHead().getLiteralText();
|
|
@@ -7184,7 +7312,7 @@ function pathFromTemplateUrl(arg, resolution) {
|
|
|
7184
7312
|
const tails = spans.map((span) => span.getLiteral().getLiteralText());
|
|
7185
7313
|
const originEnd = originEndOf([headText, ...tails].join(SUBSTITUTION));
|
|
7186
7314
|
const head = appendPathText("", headText.slice(originEnd));
|
|
7187
|
-
let
|
|
7315
|
+
let path14 = head.path;
|
|
7188
7316
|
let stop = head.stop;
|
|
7189
7317
|
let at = headText.length;
|
|
7190
7318
|
for (let i = 0; i < spans.length && !stop; i++) {
|
|
@@ -7194,18 +7322,18 @@ function pathFromTemplateUrl(arg, resolution) {
|
|
|
7194
7322
|
continue;
|
|
7195
7323
|
}
|
|
7196
7324
|
if (at >= originEnd) {
|
|
7197
|
-
|
|
7325
|
+
path14 += holeText(span.getExpression(), resolution);
|
|
7198
7326
|
}
|
|
7199
7327
|
at += SUBSTITUTION.length;
|
|
7200
7328
|
const appended = appendPathText(
|
|
7201
|
-
|
|
7329
|
+
path14,
|
|
7202
7330
|
tailText.slice(Math.max(0, originEnd - at))
|
|
7203
7331
|
);
|
|
7204
|
-
|
|
7332
|
+
path14 = appended.path;
|
|
7205
7333
|
stop = appended.stop;
|
|
7206
7334
|
at += tailText.length;
|
|
7207
7335
|
}
|
|
7208
|
-
return
|
|
7336
|
+
return path14 === "" ? void 0 : path14;
|
|
7209
7337
|
}
|
|
7210
7338
|
function pathFromUrlNode(node, resolution) {
|
|
7211
7339
|
if (import_ts_morph33.Node.isStringLiteral(node)) {
|
|
@@ -7275,12 +7403,12 @@ function discoverRegistrationCalls(sourceFile, match, kind, bindingExtraction, r
|
|
|
7275
7403
|
match.importName,
|
|
7276
7404
|
resolution
|
|
7277
7405
|
);
|
|
7278
|
-
if (registrationSubjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution)) {
|
|
7279
|
-
return results;
|
|
7280
|
-
}
|
|
7281
7406
|
const registrationMethods = match.registrationChain.map(
|
|
7282
7407
|
(c) => c.startsWith(".") ? c.slice(1) : c
|
|
7283
7408
|
);
|
|
7409
|
+
if (registrationSubjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution, registrationMethods)) {
|
|
7410
|
+
return results;
|
|
7411
|
+
}
|
|
7284
7412
|
sourceFile.forEachDescendant((node) => {
|
|
7285
7413
|
if (!import_ts_morph34.Node.isCallExpression(node)) {
|
|
7286
7414
|
return;
|
|
@@ -7474,8 +7602,54 @@ function receiverOf(subject, subjects, match, resolution) {
|
|
|
7474
7602
|
);
|
|
7475
7603
|
return candidates > 1 ? { kind: "several", candidates } : NOT_A_ROUTABLE;
|
|
7476
7604
|
}
|
|
7477
|
-
function storeCanFindSubjects(sourceFile, match, resolution) {
|
|
7478
|
-
|
|
7605
|
+
function storeCanFindSubjects(sourceFile, match, resolution, methods = []) {
|
|
7606
|
+
if (resolution === void 0) {
|
|
7607
|
+
return false;
|
|
7608
|
+
}
|
|
7609
|
+
if (importDeclarationsOf(sourceFile, [match.importModule]).length > 0) {
|
|
7610
|
+
return true;
|
|
7611
|
+
}
|
|
7612
|
+
return methods.length > 0 && callsOnCallResult(sourceFile, methods);
|
|
7613
|
+
}
|
|
7614
|
+
function callsOnCallResult(sourceFile, methods) {
|
|
7615
|
+
let called = methodsCalledOnCallResults.get(sourceFile);
|
|
7616
|
+
if (called === void 0) {
|
|
7617
|
+
called = collectMethodsCalledOnCallResults(sourceFile);
|
|
7618
|
+
methodsCalledOnCallResults.set(sourceFile, called);
|
|
7619
|
+
}
|
|
7620
|
+
return methods.some((method) => called.has(method));
|
|
7621
|
+
}
|
|
7622
|
+
var methodsCalledOnCallResults = /* @__PURE__ */ new WeakMap();
|
|
7623
|
+
function collectMethodsCalledOnCallResults(sourceFile) {
|
|
7624
|
+
const setToCalls = /* @__PURE__ */ new Set();
|
|
7625
|
+
const calledOn = /* @__PURE__ */ new Map();
|
|
7626
|
+
sourceFile.forEachDescendant((node) => {
|
|
7627
|
+
if (import_ts_morph34.Node.isVariableDeclaration(node)) {
|
|
7628
|
+
const init = node.getInitializer();
|
|
7629
|
+
if (init !== void 0 && import_ts_morph34.Node.isCallExpression(init)) {
|
|
7630
|
+
setToCalls.add(node.getName());
|
|
7631
|
+
}
|
|
7632
|
+
return;
|
|
7633
|
+
}
|
|
7634
|
+
if (!import_ts_morph34.Node.isCallExpression(node)) {
|
|
7635
|
+
return;
|
|
7636
|
+
}
|
|
7637
|
+
const callee = node.getExpression();
|
|
7638
|
+
if (!import_ts_morph34.Node.isPropertyAccessExpression(callee) || !import_ts_morph34.Node.isIdentifier(callee.getExpression())) {
|
|
7639
|
+
return;
|
|
7640
|
+
}
|
|
7641
|
+
const receiver = callee.getExpression().getText();
|
|
7642
|
+
const methods = calledOn.get(receiver) ?? /* @__PURE__ */ new Set();
|
|
7643
|
+
methods.add(callee.getName());
|
|
7644
|
+
calledOn.set(receiver, methods);
|
|
7645
|
+
});
|
|
7646
|
+
const called = /* @__PURE__ */ new Set();
|
|
7647
|
+
for (const name of setToCalls) {
|
|
7648
|
+
for (const method of calledOn.get(name) ?? []) {
|
|
7649
|
+
called.add(method);
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
return called;
|
|
7479
7653
|
}
|
|
7480
7654
|
function registrationSubjectsOf(sourceFile, importModule, importName, resolution) {
|
|
7481
7655
|
const importedLocalName = resolveImportedLocalName(
|
|
@@ -7540,9 +7714,33 @@ function registrationSubjectIdsOf(sourceFile, matches, resolution) {
|
|
|
7540
7714
|
).values()) {
|
|
7541
7715
|
ids.add(nodeId(node));
|
|
7542
7716
|
}
|
|
7717
|
+
for (const node of unboundConstructionsOf(
|
|
7718
|
+
sourceFile,
|
|
7719
|
+
match.importModule,
|
|
7720
|
+
match.importName
|
|
7721
|
+
)) {
|
|
7722
|
+
ids.add(nodeId(node));
|
|
7723
|
+
}
|
|
7543
7724
|
}
|
|
7544
7725
|
return ids;
|
|
7545
7726
|
}
|
|
7727
|
+
function unboundConstructionsOf(sourceFile, importModule, importName) {
|
|
7728
|
+
const importedLocalName = resolveImportedLocalName(
|
|
7729
|
+
sourceFile,
|
|
7730
|
+
importModule,
|
|
7731
|
+
importName
|
|
7732
|
+
);
|
|
7733
|
+
if (importedLocalName === null) {
|
|
7734
|
+
return [];
|
|
7735
|
+
}
|
|
7736
|
+
const constructions = [];
|
|
7737
|
+
sourceFile.forEachDescendant((node) => {
|
|
7738
|
+
if ((import_ts_morph34.Node.isCallExpression(node) || import_ts_morph34.Node.isNewExpression(node)) && node.getExpression().getText() === importedLocalName && !import_ts_morph34.Node.isVariableDeclaration(node.getParent())) {
|
|
7739
|
+
constructions.push(node);
|
|
7740
|
+
}
|
|
7741
|
+
});
|
|
7742
|
+
return constructions;
|
|
7743
|
+
}
|
|
7546
7744
|
function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolution) {
|
|
7547
7745
|
const subjects = registrationSubjectsOf(
|
|
7548
7746
|
sourceFile,
|
|
@@ -7550,7 +7748,7 @@ function discoverMountEdges(sourceFile, match, mount, knownSubjectIds, resolutio
|
|
|
7550
7748
|
match.importName,
|
|
7551
7749
|
resolution
|
|
7552
7750
|
);
|
|
7553
|
-
if (subjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution)) {
|
|
7751
|
+
if (subjects.size === 0 && !storeCanFindSubjects(sourceFile, match, resolution, [mount.method])) {
|
|
7554
7752
|
return [];
|
|
7555
7753
|
}
|
|
7556
7754
|
const edges = [];
|
|
@@ -7631,11 +7829,11 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
|
|
|
7631
7829
|
return null;
|
|
7632
7830
|
}
|
|
7633
7831
|
const method2 = stringProperty(routeObject, binding.method.property);
|
|
7634
|
-
const
|
|
7635
|
-
if (method2 === null ||
|
|
7832
|
+
const path15 = stringProperty(routeObject, binding.path.property);
|
|
7833
|
+
if (method2 === null || path15 === null) {
|
|
7636
7834
|
return null;
|
|
7637
7835
|
}
|
|
7638
|
-
return { method: method2.toUpperCase(), path:
|
|
7836
|
+
return { method: method2.toUpperCase(), path: path15 };
|
|
7639
7837
|
}
|
|
7640
7838
|
if (binding.method.type !== "fromRegistration" || binding.path.type !== "fromArgument") {
|
|
7641
7839
|
return null;
|
|
@@ -7652,8 +7850,8 @@ function extractRouteInfoFromBinding(call, methodName, binding, resolution) {
|
|
|
7652
7850
|
method = arg.getLiteralValue().toUpperCase();
|
|
7653
7851
|
}
|
|
7654
7852
|
const pathArg = call.getArguments()[binding.path.position];
|
|
7655
|
-
const
|
|
7656
|
-
return
|
|
7853
|
+
const path14 = pathArg === void 0 ? void 0 : pathFromArgument(pathArg, resolution);
|
|
7854
|
+
return path14 === void 0 ? null : { method, path: path14 };
|
|
7657
7855
|
}
|
|
7658
7856
|
|
|
7659
7857
|
// src/discovery/registrationLoop.ts
|
|
@@ -7785,7 +7983,7 @@ function bodyCallsOnRoutable(loop, guard, resolution) {
|
|
|
7785
7983
|
}
|
|
7786
7984
|
function readRouteSpec(element, shape, resolution) {
|
|
7787
7985
|
let method = null;
|
|
7788
|
-
let
|
|
7986
|
+
let path14 = null;
|
|
7789
7987
|
let handler = null;
|
|
7790
7988
|
for (const prop of element.getProperties()) {
|
|
7791
7989
|
if (import_ts_morph35.Node.isMethodDeclaration(prop) && prop.getName() === shape.handlerKey) {
|
|
@@ -7803,16 +8001,16 @@ function readRouteSpec(element, shape, resolution) {
|
|
|
7803
8001
|
if (name === shape.methodKey) {
|
|
7804
8002
|
method = readStringLiteralValue(init);
|
|
7805
8003
|
} else if (name === shape.pathKey) {
|
|
7806
|
-
|
|
8004
|
+
path14 = readStringLiteralValue(init);
|
|
7807
8005
|
} else if (name === shape.handlerKey) {
|
|
7808
8006
|
const func = functionValueOf(init, resolution);
|
|
7809
8007
|
handler = func === null ? null : { func, name: handlerName(init) };
|
|
7810
8008
|
}
|
|
7811
8009
|
}
|
|
7812
|
-
if (method === null ||
|
|
8010
|
+
if (method === null || path14 === null || handler === null) {
|
|
7813
8011
|
return null;
|
|
7814
8012
|
}
|
|
7815
|
-
return { method, path:
|
|
8013
|
+
return { method, path: path14, handler: handler.func, handlerName: handler.name };
|
|
7816
8014
|
}
|
|
7817
8015
|
function readStringLiteralValue(node) {
|
|
7818
8016
|
if (import_ts_morph35.Node.isStringLiteral(node) || import_ts_morph35.Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
@@ -7825,12 +8023,13 @@ function handlerName(value) {
|
|
|
7825
8023
|
}
|
|
7826
8024
|
|
|
7827
8025
|
// src/discovery/registrationTemplate.ts
|
|
7828
|
-
var
|
|
8026
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
7829
8027
|
var import_ts_morph37 = require("ts-morph");
|
|
7830
8028
|
var import_resolution4 = require("@suss/resolution");
|
|
7831
8029
|
|
|
7832
8030
|
// src/resolve/unfollowedCall.ts
|
|
7833
8031
|
var import_ts_morph36 = require("ts-morph");
|
|
8032
|
+
var import_behavioral_ir3 = require("@suss/behavioral-ir");
|
|
7834
8033
|
function isInExternalCode(sourceFile) {
|
|
7835
8034
|
if (sourceFile.isDeclarationFile()) {
|
|
7836
8035
|
return true;
|
|
@@ -7884,6 +8083,19 @@ function declarationsBehind(symbol) {
|
|
|
7884
8083
|
function isParameterOf(declaration, scanning) {
|
|
7885
8084
|
return import_ts_morph36.Node.isParameterDeclaration(declaration) && declaration.getParent() === scanning;
|
|
7886
8085
|
}
|
|
8086
|
+
function parameterIndexOf(declarations, scanning) {
|
|
8087
|
+
if (scanning === void 0) {
|
|
8088
|
+
return void 0;
|
|
8089
|
+
}
|
|
8090
|
+
const params = scanning.getParameters();
|
|
8091
|
+
for (const declaration of declarations) {
|
|
8092
|
+
const index = params.findIndex((param) => param === declaration);
|
|
8093
|
+
if (index !== -1) {
|
|
8094
|
+
return index;
|
|
8095
|
+
}
|
|
8096
|
+
}
|
|
8097
|
+
return void 0;
|
|
8098
|
+
}
|
|
7887
8099
|
function classifyStop(declarations, scanning) {
|
|
7888
8100
|
if (declarations.length === 0) {
|
|
7889
8101
|
return "noDeclaration";
|
|
@@ -7904,36 +8116,6 @@ function classifyStop(declarations, scanning) {
|
|
|
7904
8116
|
}
|
|
7905
8117
|
return "unsettledValue";
|
|
7906
8118
|
}
|
|
7907
|
-
var RECORDED = {
|
|
7908
|
-
noBody: true,
|
|
7909
|
-
unsettledValue: true,
|
|
7910
|
-
multipleSources: true,
|
|
7911
|
-
outsideRun: false,
|
|
7912
|
-
noDeclaration: false,
|
|
7913
|
-
callerSupplied: false,
|
|
7914
|
-
multipleReceivers: true
|
|
7915
|
-
};
|
|
7916
|
-
function worthRecording(reason) {
|
|
7917
|
-
return RECORDED[reason];
|
|
7918
|
-
}
|
|
7919
|
-
var STOP_SENTENCE = {
|
|
7920
|
-
noBody: ({ callee }) => `The call to ${callee} lands on a declaration with no body, so whatever runs there is missing from this summary`,
|
|
7921
|
-
unsettledValue: ({ callee }) => `The call to ${callee} goes through a value this run could not settle, so whatever runs there is missing from this summary`,
|
|
7922
|
-
multipleSources: ({ callee }) => `The call to ${callee} reaches a value with more than one possible source, so whatever runs there is missing from this summary`,
|
|
7923
|
-
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`,
|
|
7924
|
-
noDeclaration: ({ callee }) => `The call to ${callee} has no declaration this run could find, so whatever runs there is missing from this summary`,
|
|
7925
|
-
callerSupplied: ({ callee }) => `The call to ${callee} runs the function this unit's caller passed in, so what happens there is decided at the call site`,
|
|
7926
|
-
multipleReceivers: ({ callee, candidates }) => `The call to ${callee} is made on a receiver this run reads as ${candidates ?? "several"} different values, so nothing says which one it registers on and the registration is left out`
|
|
7927
|
-
};
|
|
7928
|
-
function unfollowedCallGap(stop) {
|
|
7929
|
-
return {
|
|
7930
|
-
type: "unfollowedCall",
|
|
7931
|
-
conditions: [],
|
|
7932
|
-
consequence: "unknown",
|
|
7933
|
-
description: STOP_SENTENCE[stop.reason](stop),
|
|
7934
|
-
callee: stop.callee
|
|
7935
|
-
};
|
|
7936
|
-
}
|
|
7937
8119
|
|
|
7938
8120
|
// src/discovery/registrationTemplate.ts
|
|
7939
8121
|
function discoverRegistrationTemplates(sourceFile, match, kind, resolution, mountPrefixes) {
|
|
@@ -7943,8 +8125,8 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution, moun
|
|
|
7943
8125
|
const subject = subjectOfCall(sourceFile, args, match, resolution);
|
|
7944
8126
|
const prefix = subject === void 0 ? "" : mountPrefixes?.effectivePrefixFor(subject) ?? "";
|
|
7945
8127
|
for (const reg of match.registrations) {
|
|
7946
|
-
const
|
|
7947
|
-
if (
|
|
8128
|
+
const path14 = substitutePath(reg.pathTemplate, args);
|
|
8129
|
+
if (path14 === null) {
|
|
7948
8130
|
continue;
|
|
7949
8131
|
}
|
|
7950
8132
|
const handler = resolveHandler(reg.handlerArg, args, resolution);
|
|
@@ -7958,7 +8140,7 @@ function discoverRegistrationTemplates(sourceFile, match, kind, resolution, moun
|
|
|
7958
8140
|
...subject === void 0 ? {} : { registrationSubjectId: nodeId(subject) },
|
|
7959
8141
|
routeInfo: {
|
|
7960
8142
|
method: reg.method.toUpperCase(),
|
|
7961
|
-
path: prefix === "" ?
|
|
8143
|
+
path: prefix === "" ? path14 : (0, import_resolution4.joinMountedPath)(prefix, path14)
|
|
7962
8144
|
}
|
|
7963
8145
|
});
|
|
7964
8146
|
}
|
|
@@ -7991,7 +8173,7 @@ function subjectOfCall(sourceFile, args, match, resolution) {
|
|
|
7991
8173
|
}
|
|
7992
8174
|
function helperCallsOf(sourceFile, match, resolution) {
|
|
7993
8175
|
const module2 = match.importModule;
|
|
7994
|
-
if (module2 !== void 0 && !
|
|
8176
|
+
if (module2 !== void 0 && !import_node_path7.default.isAbsolute(module2)) {
|
|
7995
8177
|
const store = resolution ?? new ResolutionStore();
|
|
7996
8178
|
return callsResolvingTo(sourceFile, store, {
|
|
7997
8179
|
module: module2,
|
|
@@ -8437,24 +8619,24 @@ function declName(decl) {
|
|
|
8437
8619
|
|
|
8438
8620
|
// src/parameterReads.ts
|
|
8439
8621
|
function pathAbove(reference) {
|
|
8440
|
-
const
|
|
8622
|
+
const path14 = [];
|
|
8441
8623
|
let current2 = reference;
|
|
8442
8624
|
for (; ; ) {
|
|
8443
8625
|
const parent = current2.getParent();
|
|
8444
8626
|
if (parent !== void 0 && import_ts_morph40.Node.isPropertyAccessExpression(parent) && parent.getExpression() === current2) {
|
|
8445
|
-
|
|
8627
|
+
path14.push(parent.getName());
|
|
8446
8628
|
current2 = parent;
|
|
8447
8629
|
continue;
|
|
8448
8630
|
}
|
|
8449
8631
|
if (parent !== void 0 && import_ts_morph40.Node.isElementAccessExpression(parent) && parent.getExpression() === current2) {
|
|
8450
8632
|
const argument = parent.getArgumentExpression();
|
|
8451
8633
|
if (argument !== void 0 && import_ts_morph40.Node.isStringLiteral(argument)) {
|
|
8452
|
-
|
|
8634
|
+
path14.push(argument.getLiteralValue());
|
|
8453
8635
|
current2 = parent;
|
|
8454
8636
|
continue;
|
|
8455
8637
|
}
|
|
8456
8638
|
}
|
|
8457
|
-
return
|
|
8639
|
+
return path14;
|
|
8458
8640
|
}
|
|
8459
8641
|
}
|
|
8460
8642
|
function declaresParameterOf(node, func) {
|
|
@@ -8502,7 +8684,7 @@ function parameterReads(func, parameterNames2, barriers = NO_BARRIERS) {
|
|
|
8502
8684
|
|
|
8503
8685
|
// src/resolve/readName.ts
|
|
8504
8686
|
var import_ts_morph41 = require("ts-morph");
|
|
8505
|
-
var
|
|
8687
|
+
var import_behavioral_ir4 = require("@suss/behavioral-ir");
|
|
8506
8688
|
var MAX_HELPER_HOPS = 2;
|
|
8507
8689
|
var UNNAMED_HOLE = "param";
|
|
8508
8690
|
function readName(expr, options = {}) {
|
|
@@ -8517,7 +8699,7 @@ function readName(expr, options = {}) {
|
|
|
8517
8699
|
return name;
|
|
8518
8700
|
}
|
|
8519
8701
|
const reference = referenceIn(expr);
|
|
8520
|
-
return reference === null ? null : (0,
|
|
8702
|
+
return reference === null ? null : (0, import_behavioral_ir4.referenceName)(reference);
|
|
8521
8703
|
}
|
|
8522
8704
|
function referenceIn(expr) {
|
|
8523
8705
|
const fromParameter = parameterPath(expr);
|
|
@@ -8766,7 +8948,7 @@ function boundOnce(expr, ctx) {
|
|
|
8766
8948
|
}
|
|
8767
8949
|
function readOrHole(expr, ctx) {
|
|
8768
8950
|
const name = read(expr, ctx);
|
|
8769
|
-
return name ?? (0,
|
|
8951
|
+
return name ?? (0, import_behavioral_ir4.patternHole)(holeName(expr, ctx));
|
|
8770
8952
|
}
|
|
8771
8953
|
function holeName(expr, ctx) {
|
|
8772
8954
|
const bound = boundOnce(expr, ctx);
|
|
@@ -9153,142 +9335,40 @@ function importSpecifierMatches(decl, expectedModule) {
|
|
|
9153
9335
|
return import_ts_morph43.Node.isImportDeclaration(importDecl) && importDecl.getModuleSpecifierValue() === expectedModule;
|
|
9154
9336
|
}
|
|
9155
9337
|
function extractInvocationEffects(func, barriers = NO_BARRIERS) {
|
|
9156
|
-
const
|
|
9338
|
+
const calls = [];
|
|
9157
9339
|
func.forEachDescendant((node, traversal) => {
|
|
9158
|
-
if (isDescentStop(node, func, barriers)) {
|
|
9340
|
+
if (isDescentStop(node, func, barriers) || import_ts_morph43.Node.isDecorator(node)) {
|
|
9159
9341
|
traversal.skip();
|
|
9160
9342
|
return;
|
|
9161
9343
|
}
|
|
9162
|
-
if (import_ts_morph43.Node.isExpressionStatement(node)) {
|
|
9163
|
-
const { call, async } = unwrapCall(node.getExpression());
|
|
9164
|
-
if (call !== null) {
|
|
9165
|
-
const preconditions = collectPreconditions(node, func);
|
|
9166
|
-
results.push({
|
|
9167
|
-
effect: {
|
|
9168
|
-
type: "invocation",
|
|
9169
|
-
callee: call.getExpression().getText(),
|
|
9170
|
-
args: extractArgs(call),
|
|
9171
|
-
async,
|
|
9172
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9173
|
-
},
|
|
9174
|
-
line: startLineOf(node),
|
|
9175
|
-
neverTerminal: false,
|
|
9176
|
-
alwaysRuns: runsOnEveryPath(node, func)
|
|
9177
|
-
});
|
|
9178
|
-
}
|
|
9179
|
-
return;
|
|
9180
|
-
}
|
|
9181
|
-
if (import_ts_morph43.Node.isSpreadElement(node)) {
|
|
9182
|
-
const parent = node.getParent();
|
|
9183
|
-
if (parent !== void 0 && (import_ts_morph43.Node.isArrayLiteralExpression(parent) || import_ts_morph43.Node.isObjectLiteralExpression(parent))) {
|
|
9184
|
-
const { call, async } = unwrapCall(node.getExpression());
|
|
9185
|
-
if (call !== null) {
|
|
9186
|
-
const preconditions = collectPreconditions(node, func);
|
|
9187
|
-
results.push({
|
|
9188
|
-
effect: {
|
|
9189
|
-
type: "invocation",
|
|
9190
|
-
callee: call.getExpression().getText(),
|
|
9191
|
-
args: extractArgs(call),
|
|
9192
|
-
async,
|
|
9193
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9194
|
-
},
|
|
9195
|
-
line: enclosingStatementLine(node),
|
|
9196
|
-
neverTerminal: true,
|
|
9197
|
-
alwaysRuns: runsOnEveryPath(node, func)
|
|
9198
|
-
});
|
|
9199
|
-
}
|
|
9200
|
-
}
|
|
9201
|
-
return;
|
|
9202
|
-
}
|
|
9203
|
-
if (import_ts_morph43.Node.isVariableDeclaration(node)) {
|
|
9204
|
-
const initializer = node.getInitializer();
|
|
9205
|
-
if (initializer !== void 0) {
|
|
9206
|
-
const { call, async } = unwrapCall(initializer);
|
|
9207
|
-
if (call !== null) {
|
|
9208
|
-
const preconditions = collectPreconditions(node, func);
|
|
9209
|
-
results.push({
|
|
9210
|
-
effect: {
|
|
9211
|
-
type: "invocation",
|
|
9212
|
-
callee: call.getExpression().getText(),
|
|
9213
|
-
args: extractArgs(call),
|
|
9214
|
-
async,
|
|
9215
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9216
|
-
},
|
|
9217
|
-
line: enclosingStatementLine(node),
|
|
9218
|
-
neverTerminal: true,
|
|
9219
|
-
alwaysRuns: runsOnEveryPath(node, func)
|
|
9220
|
-
});
|
|
9221
|
-
}
|
|
9222
|
-
}
|
|
9223
|
-
return;
|
|
9224
|
-
}
|
|
9225
|
-
if (import_ts_morph43.Node.isReturnStatement(node)) {
|
|
9226
|
-
const returned = node.getExpression();
|
|
9227
|
-
const { call, async } = returned === void 0 ? { call: null, async: false } : unwrapCall(returned);
|
|
9228
|
-
if (call !== null) {
|
|
9229
|
-
const preconditions = collectPreconditions(node, func);
|
|
9230
|
-
results.push({
|
|
9231
|
-
effect: {
|
|
9232
|
-
type: "invocation",
|
|
9233
|
-
callee: call.getExpression().getText(),
|
|
9234
|
-
args: extractArgs(call),
|
|
9235
|
-
async,
|
|
9236
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9237
|
-
},
|
|
9238
|
-
line: startLineOf(node),
|
|
9239
|
-
neverTerminal: false,
|
|
9240
|
-
alwaysRuns: runsOnEveryPath(node, func),
|
|
9241
|
-
node: call
|
|
9242
|
-
});
|
|
9243
|
-
}
|
|
9244
|
-
return;
|
|
9245
|
-
}
|
|
9246
|
-
if (import_ts_morph43.Node.isArrowFunction(node)) {
|
|
9247
|
-
const body = node.getBody();
|
|
9248
|
-
const { call, async } = import_ts_morph43.Node.isExpression(body) ? unwrapCall(body) : { call: null, async: false };
|
|
9249
|
-
if (call !== null) {
|
|
9250
|
-
const preconditions = collectPreconditions(node, func);
|
|
9251
|
-
results.push({
|
|
9252
|
-
effect: {
|
|
9253
|
-
type: "invocation",
|
|
9254
|
-
callee: call.getExpression().getText(),
|
|
9255
|
-
args: extractArgs(call),
|
|
9256
|
-
async: async || node.isAsync(),
|
|
9257
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9258
|
-
},
|
|
9259
|
-
line: startLineOf(node),
|
|
9260
|
-
neverTerminal: false,
|
|
9261
|
-
alwaysRuns: runsOnEveryPath(node, func),
|
|
9262
|
-
node: call
|
|
9263
|
-
});
|
|
9264
|
-
}
|
|
9265
|
-
return;
|
|
9266
|
-
}
|
|
9267
9344
|
if (import_ts_morph43.Node.isCallExpression(node)) {
|
|
9268
|
-
|
|
9269
|
-
if (parent === void 0) {
|
|
9270
|
-
return;
|
|
9271
|
-
}
|
|
9272
|
-
const isArrayElement = import_ts_morph43.Node.isArrayLiteralExpression(parent);
|
|
9273
|
-
const isPropertyValue = import_ts_morph43.Node.isPropertyAssignment(parent) && parent.getInitializer() === node;
|
|
9274
|
-
if (isArrayElement || isPropertyValue) {
|
|
9275
|
-
const preconditions = collectPreconditions(node, func);
|
|
9276
|
-
results.push({
|
|
9277
|
-
effect: {
|
|
9278
|
-
type: "invocation",
|
|
9279
|
-
callee: node.getExpression().getText(),
|
|
9280
|
-
args: extractArgs(node),
|
|
9281
|
-
async: false,
|
|
9282
|
-
...preconditions.length > 0 ? { preconditions } : {}
|
|
9283
|
-
},
|
|
9284
|
-
line: enclosingStatementLine(node),
|
|
9285
|
-
neverTerminal: true,
|
|
9286
|
-
alwaysRuns: runsOnEveryPath(node, func)
|
|
9287
|
-
});
|
|
9288
|
-
}
|
|
9345
|
+
calls.push(node);
|
|
9289
9346
|
}
|
|
9290
9347
|
});
|
|
9291
|
-
|
|
9348
|
+
calls.sort((a, b) => a.getEnd() - b.getEnd());
|
|
9349
|
+
return calls.map((call) => invocationAt(call, func));
|
|
9350
|
+
}
|
|
9351
|
+
function invocationAt(call, func) {
|
|
9352
|
+
const preconditions = collectPreconditions(call, func);
|
|
9353
|
+
return {
|
|
9354
|
+
effect: {
|
|
9355
|
+
type: "invocation",
|
|
9356
|
+
callee: call.getExpression().getText(),
|
|
9357
|
+
args: extractArgs(call),
|
|
9358
|
+
async: isAwaited(call),
|
|
9359
|
+
...preconditions.length > 0 ? { preconditions } : {}
|
|
9360
|
+
},
|
|
9361
|
+
node: call,
|
|
9362
|
+
line: enclosingStatementLine(call),
|
|
9363
|
+
alwaysRuns: runsOnEveryPath(call, func)
|
|
9364
|
+
};
|
|
9365
|
+
}
|
|
9366
|
+
function isAwaited(call) {
|
|
9367
|
+
let current2 = call.getParent();
|
|
9368
|
+
while (current2 !== void 0 && import_ts_morph43.Node.isParenthesizedExpression(current2)) {
|
|
9369
|
+
current2 = current2.getParent();
|
|
9370
|
+
}
|
|
9371
|
+
return current2 !== void 0 && import_ts_morph43.Node.isAwaitExpression(current2);
|
|
9292
9372
|
}
|
|
9293
9373
|
function runInvocationRecognizers(func, recognizers, barriers = NO_BARRIERS, resolveWrittenValue, originatesFrom, anchorCallsOf) {
|
|
9294
9374
|
if (recognizers.length === 0) {
|
|
@@ -9574,7 +9654,7 @@ function withPreconditions(effect, preconditions) {
|
|
|
9574
9654
|
}
|
|
9575
9655
|
return {
|
|
9576
9656
|
...effect,
|
|
9577
|
-
preconditions: preconditions.map(
|
|
9657
|
+
preconditions: preconditions.map(import_extractor4.rawConditionToPredicate)
|
|
9578
9658
|
};
|
|
9579
9659
|
}
|
|
9580
9660
|
function inlineModuleBinding(ident, depth) {
|
|
@@ -9631,22 +9711,6 @@ function enclosingStatementLine(node) {
|
|
|
9631
9711
|
}
|
|
9632
9712
|
return startLineOf(node);
|
|
9633
9713
|
}
|
|
9634
|
-
function unwrapCall(node) {
|
|
9635
|
-
if (import_ts_morph43.Node.isAwaitExpression(node)) {
|
|
9636
|
-
const inner = node.getExpression();
|
|
9637
|
-
if (import_ts_morph43.Node.isCallExpression(inner)) {
|
|
9638
|
-
return { call: inner, async: true };
|
|
9639
|
-
}
|
|
9640
|
-
return { call: null, async: false };
|
|
9641
|
-
}
|
|
9642
|
-
if (import_ts_morph43.Node.isParenthesizedExpression(node)) {
|
|
9643
|
-
return unwrapCall(node.getExpression());
|
|
9644
|
-
}
|
|
9645
|
-
if (import_ts_morph43.Node.isCallExpression(node)) {
|
|
9646
|
-
return { call: node, async: false };
|
|
9647
|
-
}
|
|
9648
|
-
return { call: null, async: false };
|
|
9649
|
-
}
|
|
9650
9714
|
|
|
9651
9715
|
// src/terminals/index.ts
|
|
9652
9716
|
var import_ts_morph53 = require("ts-morph");
|
|
@@ -11676,10 +11740,26 @@ function makeFallthroughTerminal(func) {
|
|
|
11676
11740
|
// src/assembly.ts
|
|
11677
11741
|
var preconditionsOf = (effect) => effect.type === "invocation" ? effect.preconditions : void 0;
|
|
11678
11742
|
function firesOn(site, branch) {
|
|
11679
|
-
if (!(0,
|
|
11743
|
+
if (!(0, import_extractor5.guardsHoldOn)(site.preconditions, branch.conditions)) {
|
|
11680
11744
|
return false;
|
|
11681
11745
|
}
|
|
11682
|
-
return site.alwaysRuns || (0,
|
|
11746
|
+
return site.alwaysRuns || (0, import_extractor5.runsBefore)(site.line, branch.terminal.location.end);
|
|
11747
|
+
}
|
|
11748
|
+
function writesTerminal(call, terminalNodes) {
|
|
11749
|
+
let current2 = call;
|
|
11750
|
+
for (; ; ) {
|
|
11751
|
+
if (terminalNodes.has(current2)) {
|
|
11752
|
+
return true;
|
|
11753
|
+
}
|
|
11754
|
+
const parent = current2.getParent();
|
|
11755
|
+
if (parent === void 0 || !isReceiverOf(current2, parent)) {
|
|
11756
|
+
return false;
|
|
11757
|
+
}
|
|
11758
|
+
current2 = parent;
|
|
11759
|
+
}
|
|
11760
|
+
}
|
|
11761
|
+
function isReceiverOf(node, parent) {
|
|
11762
|
+
return (import_ts_morph54.Node.isPropertyAccessExpression(parent) || import_ts_morph54.Node.isElementAccessExpression(parent) || import_ts_morph54.Node.isCallExpression(parent)) && parent.getExpression() === node;
|
|
11683
11763
|
}
|
|
11684
11764
|
var isDefaultConditionList = (conditions) => conditions.length === 0 || conditions.every(
|
|
11685
11765
|
(c) => c.source === "earlyReturn" || c.source === "earlyThrow"
|
|
@@ -11819,11 +11899,8 @@ function extractRawBranches(func, terminalPatterns, invocationRecognizers = [],
|
|
|
11819
11899
|
});
|
|
11820
11900
|
if (invocations.length > 0) {
|
|
11821
11901
|
const terminalNodes = new Set(terminals.map(({ node }) => node));
|
|
11822
|
-
const terminalLines = new Set(
|
|
11823
|
-
distinctBranches.map((b) => b.terminal.location.start)
|
|
11824
|
-
);
|
|
11825
11902
|
const sideEffects = invocations.filter(
|
|
11826
|
-
(i) =>
|
|
11903
|
+
(i) => !writesTerminal(i.node, terminalNodes)
|
|
11827
11904
|
);
|
|
11828
11905
|
for (const branch of distinctBranches) {
|
|
11829
11906
|
branch.effects = sideEffects.filter(
|
|
@@ -11869,9 +11946,9 @@ function createSourceFileLookup(project) {
|
|
|
11869
11946
|
if (sf === null) {
|
|
11870
11947
|
return null;
|
|
11871
11948
|
}
|
|
11872
|
-
const
|
|
11873
|
-
const index = functionsByFile.get(
|
|
11874
|
-
functionsByFile.set(
|
|
11949
|
+
const path14 = sf.getFilePath();
|
|
11950
|
+
const index = functionsByFile.get(path14) ?? indexFunctions(sf);
|
|
11951
|
+
functionsByFile.set(path14, index);
|
|
11875
11952
|
if (location.span !== void 0) {
|
|
11876
11953
|
const bySpan = index.get(spanKey(location.span));
|
|
11877
11954
|
if (bySpan !== void 0) {
|
|
@@ -11916,390 +11993,40 @@ function indexFunctions(sf) {
|
|
|
11916
11993
|
return index;
|
|
11917
11994
|
}
|
|
11918
11995
|
|
|
11919
|
-
// src/
|
|
11920
|
-
var
|
|
11921
|
-
var
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
var ENTRY_PREFIX = "key-";
|
|
11926
|
-
var ENTRY_DIR_NAME = new RegExp(`^${ENTRY_PREFIX}[0-9a-f]{16}$`);
|
|
11927
|
-
function createCacheLayer(cacheDir) {
|
|
11928
|
-
if (cacheDir === null) {
|
|
11929
|
-
return {
|
|
11930
|
-
tryHit: async () => null,
|
|
11931
|
-
lookup: async () => ({
|
|
11932
|
-
kind: "miss",
|
|
11933
|
-
diagnostic: { kind: "miss", missReason: "no-manifest" }
|
|
11934
|
-
}),
|
|
11935
|
-
plan: async () => null,
|
|
11936
|
-
write: async () => {
|
|
11937
|
-
}
|
|
11938
|
-
};
|
|
11996
|
+
// src/contract.ts
|
|
11997
|
+
var import_ts_morph56 = require("ts-morph");
|
|
11998
|
+
var import_behavioral_ir5 = require("@suss/behavioral-ir");
|
|
11999
|
+
function extractDeclaredBody(node) {
|
|
12000
|
+
if (node === void 0) {
|
|
12001
|
+
return null;
|
|
11939
12002
|
}
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
const result = await this.lookup(input);
|
|
11943
|
-
return result.kind === "hit" ? result.summaries : null;
|
|
11944
|
-
},
|
|
11945
|
-
async lookup(input) {
|
|
11946
|
-
const entryDir = entryDirFor(cacheDir, input);
|
|
11947
|
-
const manifest = await readManifest(import_node_path7.default.join(entryDir, "manifest.json"));
|
|
11948
|
-
if (manifest === null) {
|
|
11949
|
-
return missDiag(await describeAbsentEntry(cacheDir));
|
|
11950
|
-
}
|
|
11951
|
-
const currentTsconfigStamp = await stampTsconfig(input.tsconfigPath);
|
|
11952
|
-
if (!fileStampEquals(manifest.tsconfigStamp, currentTsconfigStamp)) {
|
|
11953
|
-
return missDiag("tsconfig-changed");
|
|
11954
|
-
}
|
|
11955
|
-
const currentFiles = await resolveFileStamps(input);
|
|
11956
|
-
if (!fileStampsEqual(manifest.files, currentFiles)) {
|
|
11957
|
-
return missDiag("files-changed");
|
|
11958
|
-
}
|
|
11959
|
-
await markUsed(entryDir);
|
|
11960
|
-
return {
|
|
11961
|
-
kind: "hit",
|
|
11962
|
-
summaries: manifest.summaries,
|
|
11963
|
-
diagnostic: { kind: "hit" }
|
|
11964
|
-
};
|
|
11965
|
-
},
|
|
11966
|
-
async plan(input) {
|
|
11967
|
-
const entryDir = entryDirFor(cacheDir, input);
|
|
11968
|
-
const manifest = await readManifest(import_node_path7.default.join(entryDir, "manifest.json"));
|
|
11969
|
-
if (manifest === null || manifest.roots === void 0 || manifest.rootMeta === void 0 || manifest.owners === void 0) {
|
|
11970
|
-
return null;
|
|
11971
|
-
}
|
|
11972
|
-
const currentTsconfigStamp = await stampTsconfig(input.tsconfigPath);
|
|
11973
|
-
if (!fileStampEquals(manifest.tsconfigStamp, currentTsconfigStamp)) {
|
|
11974
|
-
return null;
|
|
11975
|
-
}
|
|
11976
|
-
await markUsed(entryDir);
|
|
11977
|
-
return buildPlan(manifest, await resolveFileStamps(input));
|
|
11978
|
-
},
|
|
11979
|
-
async write(input, summaries, attribution) {
|
|
11980
|
-
const entryDir = entryDirFor(cacheDir, input);
|
|
11981
|
-
const previous = await readManifest(import_node_path7.default.join(entryDir, "manifest.json"));
|
|
11982
|
-
const tsconfigStamp = await stampTsconfig(input.tsconfigPath);
|
|
11983
|
-
const files = await hashStamps(await resolveFileStamps(input), previous);
|
|
11984
|
-
const manifest = {
|
|
11985
|
-
schemaVersion: SCHEMA_VERSION,
|
|
11986
|
-
adapterPacksDigest: input.adapterPacksDigest,
|
|
11987
|
-
tsconfigStamp,
|
|
11988
|
-
files,
|
|
11989
|
-
summaries,
|
|
11990
|
-
...attribution === void 0 ? {} : encodeAttribution(attribution)
|
|
11991
|
-
};
|
|
11992
|
-
await import_promises2.default.mkdir(entryDir, { recursive: true });
|
|
11993
|
-
await import_promises2.default.writeFile(
|
|
11994
|
-
import_node_path7.default.join(entryDir, "manifest.json"),
|
|
11995
|
-
JSON.stringify(manifest)
|
|
11996
|
-
);
|
|
11997
|
-
await evictOldEntries(cacheDir, entryDir);
|
|
11998
|
-
}
|
|
11999
|
-
};
|
|
12000
|
-
}
|
|
12001
|
-
async function buildPlan(manifest, currentStamps) {
|
|
12002
|
-
const stored = new Map(manifest.files.map((f) => [f.path, f]));
|
|
12003
|
-
const current2 = new Map(currentStamps.map((f) => [f.path, f]));
|
|
12004
|
-
const changed = /* @__PURE__ */ new Set();
|
|
12005
|
-
const removed = /* @__PURE__ */ new Set();
|
|
12006
|
-
for (const p of stored.keys()) {
|
|
12007
|
-
if (!current2.has(p)) {
|
|
12008
|
-
removed.add(p);
|
|
12009
|
-
}
|
|
12010
|
-
}
|
|
12011
|
-
const toVerify = [];
|
|
12012
|
-
for (const [p, stamp] of current2) {
|
|
12013
|
-
const before = stored.get(p);
|
|
12014
|
-
if (before === void 0) {
|
|
12015
|
-
changed.add(p);
|
|
12016
|
-
} else if (!fileStampEquals(before, stamp)) {
|
|
12017
|
-
if (before.contentHash === void 0) {
|
|
12018
|
-
changed.add(p);
|
|
12019
|
-
} else {
|
|
12020
|
-
toVerify.push(p);
|
|
12021
|
-
}
|
|
12022
|
-
}
|
|
12003
|
+
if (!import_ts_morph56.Node.isCallExpression(node)) {
|
|
12004
|
+
return null;
|
|
12023
12005
|
}
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
if (hash === null || hash !== stored.get(p)?.contentHash) {
|
|
12028
|
-
changed.add(p);
|
|
12029
|
-
}
|
|
12030
|
-
})
|
|
12031
|
-
);
|
|
12032
|
-
const roots = /* @__PURE__ */ new Map();
|
|
12033
|
-
const rootNames = manifest.roots ?? [];
|
|
12034
|
-
const depPaths = manifest.depPaths ?? [];
|
|
12035
|
-
let rootsDeclined = 0;
|
|
12036
|
-
rootNames.forEach((rootPath, i) => {
|
|
12037
|
-
const meta = manifest.rootMeta?.[i];
|
|
12038
|
-
if (meta === void 0) {
|
|
12039
|
-
return;
|
|
12040
|
-
}
|
|
12041
|
-
if (!meta.cacheable) {
|
|
12042
|
-
rootsDeclined += 1;
|
|
12043
|
-
}
|
|
12044
|
-
roots.set(rootPath, {
|
|
12045
|
-
path: rootPath,
|
|
12046
|
-
cacheable: meta.cacheable,
|
|
12047
|
-
deps: meta.deps.flatMap((d) => {
|
|
12048
|
-
const p = depPaths[d];
|
|
12049
|
-
return p === void 0 ? [] : [p];
|
|
12050
|
-
}),
|
|
12051
|
-
claims: meta.claims,
|
|
12052
|
-
mountPrefixes: meta.mountPrefixes,
|
|
12053
|
-
packs: meta.packs
|
|
12054
|
-
});
|
|
12055
|
-
});
|
|
12056
|
-
const validRoots = /* @__PURE__ */ new Set();
|
|
12057
|
-
for (const [rootPath, record2] of roots) {
|
|
12058
|
-
if (!record2.cacheable || !current2.has(rootPath)) {
|
|
12059
|
-
continue;
|
|
12060
|
-
}
|
|
12061
|
-
if (changed.has(rootPath)) {
|
|
12062
|
-
continue;
|
|
12063
|
-
}
|
|
12064
|
-
const depMoved = record2.deps.some((d) => changed.has(d) || removed.has(d));
|
|
12065
|
-
if (!depMoved) {
|
|
12066
|
-
validRoots.add(rootPath);
|
|
12067
|
-
}
|
|
12006
|
+
const typeArgs = node.getTypeArguments();
|
|
12007
|
+
if (typeArgs.length === 0) {
|
|
12008
|
+
return null;
|
|
12068
12009
|
}
|
|
12069
|
-
|
|
12070
|
-
return {
|
|
12071
|
-
changed,
|
|
12072
|
-
removed,
|
|
12073
|
-
roots,
|
|
12074
|
-
validRoots,
|
|
12075
|
-
rootsDeclined,
|
|
12076
|
-
reuse(valid) {
|
|
12077
|
-
const summaries = [];
|
|
12078
|
-
const reusedOwners = [];
|
|
12079
|
-
manifest.summaries.forEach((summary, i) => {
|
|
12080
|
-
const ownerPaths = (owners[i] ?? []).flatMap((o) => {
|
|
12081
|
-
const p = rootNames[o];
|
|
12082
|
-
return p === void 0 ? [] : [p];
|
|
12083
|
-
});
|
|
12084
|
-
if (ownerPaths.some((p) => valid.has(p))) {
|
|
12085
|
-
summaries.push(summary);
|
|
12086
|
-
reusedOwners.push(ownerPaths.filter((p) => valid.has(p)));
|
|
12087
|
-
}
|
|
12088
|
-
});
|
|
12089
|
-
return { summaries, owners: reusedOwners };
|
|
12090
|
-
},
|
|
12091
|
-
allSummaries() {
|
|
12092
|
-
return manifest.summaries;
|
|
12093
|
-
},
|
|
12094
|
-
attribution() {
|
|
12095
|
-
return {
|
|
12096
|
-
roots: [...roots.values()],
|
|
12097
|
-
owners: owners.map(
|
|
12098
|
-
(ownerIds) => ownerIds.flatMap((o) => {
|
|
12099
|
-
const p = rootNames[o];
|
|
12100
|
-
return p === void 0 ? [] : [p];
|
|
12101
|
-
})
|
|
12102
|
-
)
|
|
12103
|
-
};
|
|
12104
|
-
}
|
|
12105
|
-
};
|
|
12106
|
-
}
|
|
12107
|
-
function encodeAttribution(attribution) {
|
|
12108
|
-
const roots = attribution.roots.map((r) => r.path);
|
|
12109
|
-
const rootIndex = new Map(roots.map((p, i) => [p, i]));
|
|
12110
|
-
const depIndex = /* @__PURE__ */ new Map();
|
|
12111
|
-
const depPaths = [];
|
|
12112
|
-
const depIdOf = (p) => {
|
|
12113
|
-
const existing = depIndex.get(p);
|
|
12114
|
-
if (existing !== void 0) {
|
|
12115
|
-
return existing;
|
|
12116
|
-
}
|
|
12117
|
-
const id = depPaths.length;
|
|
12118
|
-
depPaths.push(p);
|
|
12119
|
-
depIndex.set(p, id);
|
|
12120
|
-
return id;
|
|
12121
|
-
};
|
|
12122
|
-
const rootMeta = attribution.roots.map((r) => ({
|
|
12123
|
-
cacheable: r.cacheable,
|
|
12124
|
-
deps: r.deps.map(depIdOf),
|
|
12125
|
-
claims: r.claims,
|
|
12126
|
-
mountPrefixes: r.mountPrefixes,
|
|
12127
|
-
packs: r.packs
|
|
12128
|
-
}));
|
|
12129
|
-
const owners = attribution.owners.map(
|
|
12130
|
-
(ownerPaths) => ownerPaths.flatMap((p) => {
|
|
12131
|
-
const i = rootIndex.get(p);
|
|
12132
|
-
return i === void 0 ? [] : [i];
|
|
12133
|
-
})
|
|
12134
|
-
);
|
|
12135
|
-
return { roots, rootMeta, depPaths, owners };
|
|
12136
|
-
}
|
|
12137
|
-
async function hashStamps(stamps, previous) {
|
|
12138
|
-
const before = new Map((previous?.files ?? []).map((f) => [f.path, f]));
|
|
12139
|
-
return Promise.all(
|
|
12140
|
-
stamps.map(async (stamp) => {
|
|
12141
|
-
const prior = before.get(stamp.path);
|
|
12142
|
-
if (prior !== void 0 && prior.contentHash !== void 0 && fileStampEquals(prior, stamp)) {
|
|
12143
|
-
return { ...stamp, contentHash: prior.contentHash };
|
|
12144
|
-
}
|
|
12145
|
-
const contentHash = await hashFile(stamp.path);
|
|
12146
|
-
return contentHash === null ? stamp : { ...stamp, contentHash };
|
|
12147
|
-
})
|
|
12148
|
-
);
|
|
12010
|
+
return shapeFromNodeType(typeArgs[0]);
|
|
12149
12011
|
}
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
return (0, import_node_crypto2.createHash)("sha256").update(content).digest("hex").slice(0, 16);
|
|
12154
|
-
} catch {
|
|
12012
|
+
function resolveHandlerPropNode(func) {
|
|
12013
|
+
const parent = func.getParent();
|
|
12014
|
+
if (parent === void 0) {
|
|
12155
12015
|
return null;
|
|
12156
12016
|
}
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
try {
|
|
12160
|
-
const entries = await import_promises2.default.readdir(cacheDir, { withFileTypes: true });
|
|
12161
|
-
return entries.some((e) => e.isDirectory() && isEntryDir(e.name)) ? "key-changed" : "no-manifest";
|
|
12162
|
-
} catch {
|
|
12163
|
-
return "no-manifest";
|
|
12017
|
+
if (import_ts_morph56.Node.isPropertyAssignment(parent)) {
|
|
12018
|
+
return parent;
|
|
12164
12019
|
}
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
const key = [
|
|
12168
|
-
SCHEMA_VERSION,
|
|
12169
|
-
input.adapterPacksDigest,
|
|
12170
|
-
input.tsconfigPath ?? ""
|
|
12171
|
-
].join(" ");
|
|
12172
|
-
const name = (0, import_node_crypto2.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
12173
|
-
return import_node_path7.default.join(cacheDir, `${ENTRY_PREFIX}${name}`);
|
|
12174
|
-
}
|
|
12175
|
-
function isEntryDir(name) {
|
|
12176
|
-
return ENTRY_DIR_NAME.test(name);
|
|
12177
|
-
}
|
|
12178
|
-
async function markUsed(entryDir) {
|
|
12179
|
-
const now = /* @__PURE__ */ new Date();
|
|
12180
|
-
try {
|
|
12181
|
-
await import_promises2.default.utimes(entryDir, now, now);
|
|
12182
|
-
} catch {
|
|
12020
|
+
if (import_ts_morph56.Node.isMethodDeclaration(func)) {
|
|
12021
|
+
return func;
|
|
12183
12022
|
}
|
|
12023
|
+
return null;
|
|
12184
12024
|
}
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
entries.filter((e) => e.isDirectory() && isEntryDir(e.name)).map(async (e) => {
|
|
12191
|
-
const dir = import_node_path7.default.join(cacheDir, e.name);
|
|
12192
|
-
const stat = await import_promises2.default.stat(dir);
|
|
12193
|
-
return { dir, mtimeMs: stat.mtimeMs };
|
|
12194
|
-
})
|
|
12195
|
-
);
|
|
12196
|
-
const doomed = dirs.filter((d) => d.dir !== keepDir).sort((a, b) => b.mtimeMs - a.mtimeMs).slice(MAX_ENTRIES - 1);
|
|
12197
|
-
await Promise.all(
|
|
12198
|
-
doomed.map((d) => import_promises2.default.rm(d.dir, { recursive: true, force: true }))
|
|
12199
|
-
);
|
|
12200
|
-
} catch {
|
|
12201
|
-
}
|
|
12202
|
-
}
|
|
12203
|
-
function missDiag(reason) {
|
|
12204
|
-
return {
|
|
12205
|
-
kind: "miss",
|
|
12206
|
-
diagnostic: { kind: "miss", missReason: reason }
|
|
12207
|
-
};
|
|
12208
|
-
}
|
|
12209
|
-
async function readManifest(manifestPath) {
|
|
12210
|
-
try {
|
|
12211
|
-
const raw = await import_promises2.default.readFile(manifestPath, "utf-8");
|
|
12212
|
-
return JSON.parse(raw);
|
|
12213
|
-
} catch {
|
|
12214
|
-
return null;
|
|
12215
|
-
}
|
|
12216
|
-
}
|
|
12217
|
-
async function stampTsconfig(tsconfigPath) {
|
|
12218
|
-
if (tsconfigPath === void 0) {
|
|
12219
|
-
return null;
|
|
12220
|
-
}
|
|
12221
|
-
try {
|
|
12222
|
-
const stat = await import_promises2.default.stat(tsconfigPath);
|
|
12223
|
-
return { path: tsconfigPath, mtimeMs: stat.mtimeMs, size: stat.size };
|
|
12224
|
-
} catch {
|
|
12225
|
-
return null;
|
|
12226
|
-
}
|
|
12227
|
-
}
|
|
12228
|
-
async function resolveFileStamps(input) {
|
|
12229
|
-
if (input.files !== void 0) {
|
|
12230
|
-
return stampPaths(input.files);
|
|
12231
|
-
}
|
|
12232
|
-
if (input.project !== void 0) {
|
|
12233
|
-
return stampProjectFiles(input.project);
|
|
12234
|
-
}
|
|
12235
|
-
return [];
|
|
12236
|
-
}
|
|
12237
|
-
async function stampProjectFiles(project) {
|
|
12238
|
-
const files = project.getSourceFiles().filter((sf) => !sf.isDeclarationFile()).map((sf) => sf.getFilePath());
|
|
12239
|
-
return stampPaths(files);
|
|
12240
|
-
}
|
|
12241
|
-
async function stampPaths(paths) {
|
|
12242
|
-
const files = paths;
|
|
12243
|
-
const stamped = await Promise.all(
|
|
12244
|
-
files.map(async (p) => {
|
|
12245
|
-
try {
|
|
12246
|
-
const stat = await import_promises2.default.stat(p);
|
|
12247
|
-
return { path: p, mtimeMs: stat.mtimeMs, size: stat.size };
|
|
12248
|
-
} catch {
|
|
12249
|
-
return { path: p, mtimeMs: -1, size: -1 };
|
|
12250
|
-
}
|
|
12251
|
-
})
|
|
12252
|
-
);
|
|
12253
|
-
stamped.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
12254
|
-
return stamped;
|
|
12255
|
-
}
|
|
12256
|
-
function fileStampsEqual(a, b) {
|
|
12257
|
-
return a.length === b.length && a.every((s, i) => fileStampEquals(s, b[i]));
|
|
12258
|
-
}
|
|
12259
|
-
function fileStampEquals(a, b) {
|
|
12260
|
-
if (a === null && b === null) {
|
|
12261
|
-
return true;
|
|
12262
|
-
}
|
|
12263
|
-
if (a === null || b === null) {
|
|
12264
|
-
return false;
|
|
12265
|
-
}
|
|
12266
|
-
return a.path === b.path && a.mtimeMs === b.mtimeMs && a.size === b.size;
|
|
12267
|
-
}
|
|
12268
|
-
|
|
12269
|
-
// src/contract.ts
|
|
12270
|
-
var import_ts_morph56 = require("ts-morph");
|
|
12271
|
-
var import_behavioral_ir4 = require("@suss/behavioral-ir");
|
|
12272
|
-
function extractDeclaredBody(node) {
|
|
12273
|
-
if (node === void 0) {
|
|
12274
|
-
return null;
|
|
12275
|
-
}
|
|
12276
|
-
if (!import_ts_morph56.Node.isCallExpression(node)) {
|
|
12277
|
-
return null;
|
|
12278
|
-
}
|
|
12279
|
-
const typeArgs = node.getTypeArguments();
|
|
12280
|
-
if (typeArgs.length === 0) {
|
|
12281
|
-
return null;
|
|
12282
|
-
}
|
|
12283
|
-
return shapeFromNodeType(typeArgs[0]);
|
|
12284
|
-
}
|
|
12285
|
-
function resolveHandlerPropNode(func) {
|
|
12286
|
-
const parent = func.getParent();
|
|
12287
|
-
if (parent === void 0) {
|
|
12288
|
-
return null;
|
|
12289
|
-
}
|
|
12290
|
-
if (import_ts_morph56.Node.isPropertyAssignment(parent)) {
|
|
12291
|
-
return parent;
|
|
12292
|
-
}
|
|
12293
|
-
if (import_ts_morph56.Node.isMethodDeclaration(func)) {
|
|
12294
|
-
return func;
|
|
12295
|
-
}
|
|
12296
|
-
return null;
|
|
12297
|
-
}
|
|
12298
|
-
function findRouterCall(unit) {
|
|
12299
|
-
const func = unit.func;
|
|
12300
|
-
const propNode = func === null ? null : resolveHandlerPropNode(func);
|
|
12301
|
-
if (propNode === null) {
|
|
12302
|
-
return null;
|
|
12025
|
+
function findRouterCall(unit) {
|
|
12026
|
+
const func = unit.func;
|
|
12027
|
+
const propNode = func === null ? null : resolveHandlerPropNode(func);
|
|
12028
|
+
if (propNode === null) {
|
|
12029
|
+
return null;
|
|
12303
12030
|
}
|
|
12304
12031
|
const handlersObj = propNode.getParent();
|
|
12305
12032
|
if (handlersObj === void 0 || !import_ts_morph56.Node.isObjectLiteralExpression(handlersObj)) {
|
|
@@ -12408,7 +12135,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
12408
12135
|
}
|
|
12409
12136
|
const responses = [];
|
|
12410
12137
|
let method;
|
|
12411
|
-
let
|
|
12138
|
+
let path14;
|
|
12412
12139
|
for (const prop of endpointNode.getProperties()) {
|
|
12413
12140
|
if (!import_ts_morph56.Node.isPropertyAssignment(prop)) {
|
|
12414
12141
|
continue;
|
|
@@ -12423,7 +12150,7 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
12423
12150
|
if (propName === pattern.pathProperty) {
|
|
12424
12151
|
const val = prop.getInitializer();
|
|
12425
12152
|
if (val !== void 0 && import_ts_morph56.Node.isStringLiteral(val)) {
|
|
12426
|
-
|
|
12153
|
+
path14 = val.getLiteralValue();
|
|
12427
12154
|
}
|
|
12428
12155
|
}
|
|
12429
12156
|
if (propName === pattern.responseExtraction.property) {
|
|
@@ -12447,10 +12174,10 @@ function extractEndpointContract(endpointNode, pattern, framework) {
|
|
|
12447
12174
|
if (responses.length === 0) {
|
|
12448
12175
|
return null;
|
|
12449
12176
|
}
|
|
12450
|
-
const boundaryBinding = method !== void 0 ||
|
|
12177
|
+
const boundaryBinding = method !== void 0 || path14 !== void 0 ? (0, import_behavioral_ir5.restBinding)({
|
|
12451
12178
|
transport: "http",
|
|
12452
12179
|
method: method ?? null,
|
|
12453
|
-
path:
|
|
12180
|
+
path: path14 ?? null,
|
|
12454
12181
|
recognition: framework
|
|
12455
12182
|
}) : null;
|
|
12456
12183
|
return {
|
|
@@ -12648,7 +12375,7 @@ function parameterName(segment, convention) {
|
|
|
12648
12375
|
// src/discovery/graphqlClientConstruction.ts
|
|
12649
12376
|
var import_picomatch2 = __toESM(require("picomatch"), 1);
|
|
12650
12377
|
var import_ts_morph57 = require("ts-morph");
|
|
12651
|
-
var
|
|
12378
|
+
var import_behavioral_ir6 = require("@suss/behavioral-ir");
|
|
12652
12379
|
function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
12653
12380
|
const scopes = compileOperationScopes(packs);
|
|
12654
12381
|
const sole = soleGraphqlClientRef(
|
|
@@ -12658,10 +12385,10 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12658
12385
|
const soleClient = sole !== null ? workspace !== null ? { ...sole, workspace } : sole : null;
|
|
12659
12386
|
let registry = null;
|
|
12660
12387
|
for (const summary of summaries) {
|
|
12661
|
-
if (!(0,
|
|
12388
|
+
if (!(0, import_behavioral_ir6.isGraphqlOperationBinding)(summary.identity.boundaryBinding)) {
|
|
12662
12389
|
continue;
|
|
12663
12390
|
}
|
|
12664
|
-
const existing = (0,
|
|
12391
|
+
const existing = (0, import_behavioral_ir6.readGraphqlMetadata)(summary) ?? {};
|
|
12665
12392
|
const scoped = scopedWorkspaceFor(summary.location.file, scopes);
|
|
12666
12393
|
const client = scoped !== null ? { uri: null, uriRef: null, workspace: scoped } : soleClient;
|
|
12667
12394
|
const dangling = (existing.unresolvedFragments?.length ?? 0) > 0;
|
|
@@ -12671,7 +12398,7 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12671
12398
|
if (dangling && registry === null) {
|
|
12672
12399
|
registry = fragmentRegistryStatus(sourceFiles, packs);
|
|
12673
12400
|
}
|
|
12674
|
-
summary.metadata = (0,
|
|
12401
|
+
summary.metadata = (0, import_behavioral_ir6.withGraphqlMetadata)(summary.metadata, {
|
|
12675
12402
|
...existing,
|
|
12676
12403
|
...client !== null ? { client } : {},
|
|
12677
12404
|
...dangling && registry !== null ? { fragmentRegistry: registry } : {}
|
|
@@ -13083,8 +12810,8 @@ function noteExpanded(expanded, readings, discovery) {
|
|
|
13083
12810
|
const paths = new Set(match.registrations.map((one) => one.pathTemplate));
|
|
13084
12811
|
const methods = expanded.get(reading.declarationId) ?? /* @__PURE__ */ new Set();
|
|
13085
12812
|
for (const sink of reading.helper.sinks) {
|
|
13086
|
-
const
|
|
13087
|
-
if (sink.method !== null &&
|
|
12813
|
+
const path14 = sink.arguments[0];
|
|
12814
|
+
if (sink.method !== null && path14?.as === "text" && paths.has(path14.text)) {
|
|
13088
12815
|
methods.add(sink.method);
|
|
13089
12816
|
}
|
|
13090
12817
|
}
|
|
@@ -13673,7 +13400,7 @@ function scalarOrRef(node) {
|
|
|
13673
13400
|
}
|
|
13674
13401
|
|
|
13675
13402
|
// src/moduleInit.ts
|
|
13676
|
-
var
|
|
13403
|
+
var import_extractor6 = require("@suss/extractor");
|
|
13677
13404
|
function moduleInitName(sourceFile) {
|
|
13678
13405
|
return sourceFile.getBaseName();
|
|
13679
13406
|
}
|
|
@@ -13681,44 +13408,15 @@ function moduleInitSummary(sourceFile, effects, options) {
|
|
|
13681
13408
|
if (effects.length === 0) {
|
|
13682
13409
|
return null;
|
|
13683
13410
|
}
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
identity: {
|
|
13411
|
+
return (0, import_extractor6.assembleSummary)(
|
|
13412
|
+
(0, import_extractor6.moduleInitStructure)({
|
|
13687
13413
|
name: moduleInitName(sourceFile),
|
|
13688
|
-
kind: "module-init",
|
|
13689
13414
|
file: sourceFile.getFilePath(),
|
|
13690
|
-
range: { start: 0, end },
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
parameters: [],
|
|
13696
|
-
branches: [
|
|
13697
|
-
{
|
|
13698
|
-
conditions: [],
|
|
13699
|
-
terminal: {
|
|
13700
|
-
kind: "void",
|
|
13701
|
-
statusCode: null,
|
|
13702
|
-
body: null,
|
|
13703
|
-
exceptionType: null,
|
|
13704
|
-
message: null,
|
|
13705
|
-
component: null,
|
|
13706
|
-
renderTree: null,
|
|
13707
|
-
delegateTarget: null,
|
|
13708
|
-
emitEvent: null,
|
|
13709
|
-
location: { start: 0, end }
|
|
13710
|
-
},
|
|
13711
|
-
effects: [],
|
|
13712
|
-
extraEffects: effects,
|
|
13713
|
-
location: { start: 0, end },
|
|
13714
|
-
isDefault: true
|
|
13715
|
-
}
|
|
13716
|
-
],
|
|
13717
|
-
unmatchedReturns: 0,
|
|
13718
|
-
dependencyCalls: [],
|
|
13719
|
-
declaredContract: null
|
|
13720
|
-
};
|
|
13721
|
-
return (0, import_extractor5.assembleSummary)(raw, options);
|
|
13415
|
+
range: { start: 0, end: sourceFile.getEnd() },
|
|
13416
|
+
effects
|
|
13417
|
+
}),
|
|
13418
|
+
options
|
|
13419
|
+
);
|
|
13722
13420
|
}
|
|
13723
13421
|
|
|
13724
13422
|
// src/referencedFiles.ts
|
|
@@ -13866,9 +13564,9 @@ function deriveBoundaryEffects(summaries, facts) {
|
|
|
13866
13564
|
|
|
13867
13565
|
// src/resolve/reachableClosure.ts
|
|
13868
13566
|
var import_ts_morph62 = require("ts-morph");
|
|
13869
|
-
var
|
|
13567
|
+
var import_behavioral_ir7 = require("@suss/behavioral-ir");
|
|
13870
13568
|
var import_datalog4 = require("@suss/datalog");
|
|
13871
|
-
var
|
|
13569
|
+
var import_extractor7 = require("@suss/extractor");
|
|
13872
13570
|
var reachablePack = {
|
|
13873
13571
|
name: "reachable",
|
|
13874
13572
|
languages: ["typescript"],
|
|
@@ -13890,6 +13588,12 @@ var reachablePack = {
|
|
|
13890
13588
|
function nodeKey(func) {
|
|
13891
13589
|
return offsetKeyOf(func);
|
|
13892
13590
|
}
|
|
13591
|
+
function targetOf(node) {
|
|
13592
|
+
return {
|
|
13593
|
+
file: node.getSourceFile().getFilePath(),
|
|
13594
|
+
span: { start: node.getStart(), end: node.getEnd() }
|
|
13595
|
+
};
|
|
13596
|
+
}
|
|
13893
13597
|
function resolveCallee(call, calleeName, scan) {
|
|
13894
13598
|
if (!import_ts_morph62.Node.isCallExpression(call)) {
|
|
13895
13599
|
return null;
|
|
@@ -13914,19 +13618,42 @@ function resolveCallee(call, calleeName, scan) {
|
|
|
13914
13618
|
if (sources.length > 1) {
|
|
13915
13619
|
return {
|
|
13916
13620
|
kind: "stopped",
|
|
13917
|
-
stop: { callee: calleeName, reason: "multipleSources" }
|
|
13621
|
+
stop: { callee: calleeName, reason: "multipleSources" },
|
|
13622
|
+
declaration: declarationToReport(declarations, calleeName, scan)
|
|
13918
13623
|
};
|
|
13919
13624
|
}
|
|
13920
13625
|
}
|
|
13626
|
+
const reason = classifyStop(declarations, scan.scanning);
|
|
13627
|
+
const parameterIndex = reason === "callerSupplied" ? parameterIndexOf(declarations, scan.scanning) : void 0;
|
|
13921
13628
|
return {
|
|
13922
13629
|
kind: "stopped",
|
|
13923
|
-
stop: {
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
}
|
|
13630
|
+
stop: { callee: calleeName, reason },
|
|
13631
|
+
declaration: declarationToReport(declarations, calleeName, scan),
|
|
13632
|
+
...parameterIndex === void 0 ? {} : { parameterIndex }
|
|
13927
13633
|
};
|
|
13928
13634
|
}
|
|
13929
|
-
function
|
|
13635
|
+
function declarationToReport(declarations, calleeName, scan) {
|
|
13636
|
+
const first = declarations[0];
|
|
13637
|
+
if (first === void 0) {
|
|
13638
|
+
return null;
|
|
13639
|
+
}
|
|
13640
|
+
const sources = scan.sourceDeclarationsBehind?.(first) ?? [first];
|
|
13641
|
+
const only = sources.length === 1 ? sources[0] : void 0;
|
|
13642
|
+
if (only === void 0 || only === first) {
|
|
13643
|
+
return first;
|
|
13644
|
+
}
|
|
13645
|
+
return resolveDecl(only, calleeName)?.func ?? only;
|
|
13646
|
+
}
|
|
13647
|
+
function declaredAtOf(outcome) {
|
|
13648
|
+
if (outcome.kind === "followed") {
|
|
13649
|
+
return targetOf(outcome.candidate.func);
|
|
13650
|
+
}
|
|
13651
|
+
return outcome.declaration === null ? null : targetOf(outcome.declaration);
|
|
13652
|
+
}
|
|
13653
|
+
function passedPositionKey(target, position) {
|
|
13654
|
+
return `${offsetKeyFor(target.file, target.span)}#${position}`;
|
|
13655
|
+
}
|
|
13656
|
+
function resolveJsxReference(node, scan) {
|
|
13930
13657
|
if (!import_ts_morph62.Node.isJsxOpeningElement(node) && !import_ts_morph62.Node.isJsxSelfClosingElement(node)) {
|
|
13931
13658
|
return null;
|
|
13932
13659
|
}
|
|
@@ -13946,7 +13673,8 @@ function resolveJsxReference(node) {
|
|
|
13946
13673
|
tag: name,
|
|
13947
13674
|
outcome: {
|
|
13948
13675
|
kind: "stopped",
|
|
13949
|
-
stop: { callee: name, reason: classifyStop(declarations) }
|
|
13676
|
+
stop: { callee: name, reason: classifyStop(declarations) },
|
|
13677
|
+
declaration: declarationToReport(declarations, name, scan)
|
|
13950
13678
|
}
|
|
13951
13679
|
};
|
|
13952
13680
|
}
|
|
@@ -13954,11 +13682,15 @@ function collectReachable(func, scan) {
|
|
|
13954
13682
|
const inFunc = { ...scan, scanning: func };
|
|
13955
13683
|
const candidates = [];
|
|
13956
13684
|
const stops = [];
|
|
13685
|
+
const placements = new import_behavioral_ir7.TargetPlacements();
|
|
13686
|
+
const parameterCalls = [];
|
|
13687
|
+
const passedPositions = /* @__PURE__ */ new Set();
|
|
13957
13688
|
const seen = /* @__PURE__ */ new Set();
|
|
13689
|
+
const parameterCallsSeen = /* @__PURE__ */ new Set();
|
|
13958
13690
|
const record2 = (outcome) => {
|
|
13959
13691
|
if (outcome.kind === "stopped") {
|
|
13960
13692
|
const stopKey = `${outcome.stop.reason}:${outcome.stop.callee}`;
|
|
13961
|
-
if (!seen.has(stopKey) && worthRecording(outcome.stop.reason)) {
|
|
13693
|
+
if (!seen.has(stopKey) && (0, import_behavioral_ir3.worthRecording)(outcome.stop.reason)) {
|
|
13962
13694
|
seen.add(stopKey);
|
|
13963
13695
|
stops.push(outcome.stop);
|
|
13964
13696
|
}
|
|
@@ -13971,8 +13703,28 @@ function collectReachable(func, scan) {
|
|
|
13971
13703
|
seen.add(key);
|
|
13972
13704
|
candidates.push(outcome.candidate);
|
|
13973
13705
|
};
|
|
13706
|
+
const recordPassedArgs = (call, calleeText, calleeOutcome) => {
|
|
13707
|
+
if (!import_ts_morph62.Node.isCallExpression(call)) {
|
|
13708
|
+
return;
|
|
13709
|
+
}
|
|
13710
|
+
const calleeTarget = declaredAtOf(calleeOutcome);
|
|
13711
|
+
call.getArguments().forEach((arg, position) => {
|
|
13712
|
+
if (!import_ts_morph62.Node.isIdentifier(arg)) {
|
|
13713
|
+
return;
|
|
13714
|
+
}
|
|
13715
|
+
const resolved = functionTargetOf(arg);
|
|
13716
|
+
if (resolved === null) {
|
|
13717
|
+
return;
|
|
13718
|
+
}
|
|
13719
|
+
record2({ kind: "followed", candidate: resolved });
|
|
13720
|
+
placements.placeArg(calleeText, position, targetOf(resolved.func));
|
|
13721
|
+
if (calleeTarget !== null) {
|
|
13722
|
+
passedPositions.add(passedPositionKey(calleeTarget, position));
|
|
13723
|
+
}
|
|
13724
|
+
});
|
|
13725
|
+
};
|
|
13974
13726
|
func.forEachDescendant((node) => {
|
|
13975
|
-
const jsx = resolveJsxReference(node);
|
|
13727
|
+
const jsx = resolveJsxReference(node, inFunc);
|
|
13976
13728
|
if (jsx !== null) {
|
|
13977
13729
|
record2(jsx.outcome);
|
|
13978
13730
|
return;
|
|
@@ -13986,8 +13738,24 @@ function collectReachable(func, scan) {
|
|
|
13986
13738
|
return;
|
|
13987
13739
|
}
|
|
13988
13740
|
record2(outcome);
|
|
13741
|
+
placements.place(calleeText, declaredAtOf(outcome));
|
|
13742
|
+
recordPassedArgs(node, calleeText, outcome);
|
|
13743
|
+
if (outcome.kind === "stopped" && outcome.stop.reason === "callerSupplied" && outcome.parameterIndex !== void 0 && !parameterCallsSeen.has(calleeText)) {
|
|
13744
|
+
parameterCallsSeen.add(calleeText);
|
|
13745
|
+
parameterCalls.push({
|
|
13746
|
+
callee: calleeText,
|
|
13747
|
+
parameterIndex: outcome.parameterIndex
|
|
13748
|
+
});
|
|
13749
|
+
}
|
|
13989
13750
|
});
|
|
13990
|
-
return {
|
|
13751
|
+
return {
|
|
13752
|
+
candidates,
|
|
13753
|
+
stops,
|
|
13754
|
+
targets: placements.targets,
|
|
13755
|
+
argTargets: placements.argTargets,
|
|
13756
|
+
parameterCalls,
|
|
13757
|
+
passedPositions
|
|
13758
|
+
};
|
|
13991
13759
|
}
|
|
13992
13760
|
function normalizeCallee(text) {
|
|
13993
13761
|
return text.replace(/\s+/g, " ").trim();
|
|
@@ -14006,11 +13774,11 @@ function extractReachableSummary(candidate, options, recognizers) {
|
|
|
14006
13774
|
void 0,
|
|
14007
13775
|
recognizers.resolveWrittenValue
|
|
14008
13776
|
);
|
|
14009
|
-
raw.boundaryBinding = (0,
|
|
13777
|
+
raw.boundaryBinding = (0, import_behavioral_ir7.functionCallBinding)({
|
|
14010
13778
|
transport: "in-process",
|
|
14011
13779
|
recognition: "reachable"
|
|
14012
13780
|
});
|
|
14013
|
-
return (0,
|
|
13781
|
+
return (0, import_extractor7.assembleSummary)(raw, options);
|
|
14014
13782
|
}
|
|
14015
13783
|
var REACHABLE_RULES = [
|
|
14016
13784
|
(0, import_datalog4.rule)("reachable", [(0, import_datalog4.variable)("f")], [(0, import_datalog4.lit)("entry", (0, import_datalog4.variable)("f"))]),
|
|
@@ -14062,6 +13830,10 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
14062
13830
|
const seedKeys = /* @__PURE__ */ new Set();
|
|
14063
13831
|
const scanned = /* @__PURE__ */ new Set();
|
|
14064
13832
|
const stopsByKey = /* @__PURE__ */ new Map();
|
|
13833
|
+
const targetsByKey = /* @__PURE__ */ new Map();
|
|
13834
|
+
const argTargetsByKey = /* @__PURE__ */ new Map();
|
|
13835
|
+
const parameterCallsByKey = /* @__PURE__ */ new Map();
|
|
13836
|
+
const passedPositions = /* @__PURE__ */ new Set();
|
|
14065
13837
|
const summariesByKey = /* @__PURE__ */ new Map();
|
|
14066
13838
|
const reachedFrom = /* @__PURE__ */ new Map();
|
|
14067
13839
|
for (const seed of seeds) {
|
|
@@ -14106,9 +13878,17 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
14106
13878
|
const cameFrom = reachedFrom.get(key);
|
|
14107
13879
|
const scan = {
|
|
14108
13880
|
...recognizers.resolveCallableSources === void 0 ? {} : { resolveCallableSources: recognizers.resolveCallableSources },
|
|
13881
|
+
...recognizers.sourceDeclarationsBehind === void 0 ? {} : { sourceDeclarationsBehind: recognizers.sourceDeclarationsBehind },
|
|
14109
13882
|
...cameFrom === void 0 ? {} : { reachedFrom: cameFrom }
|
|
14110
13883
|
};
|
|
14111
|
-
const {
|
|
13884
|
+
const {
|
|
13885
|
+
candidates,
|
|
13886
|
+
stops,
|
|
13887
|
+
targets,
|
|
13888
|
+
argTargets,
|
|
13889
|
+
parameterCalls,
|
|
13890
|
+
passedPositions: scanPassedPositions
|
|
13891
|
+
} = scanWithRecording(
|
|
14112
13892
|
key,
|
|
14113
13893
|
facts,
|
|
14114
13894
|
() => collectReachable(source.func, scan)
|
|
@@ -14116,6 +13896,14 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
14116
13896
|
if (stops.length > 0) {
|
|
14117
13897
|
stopsByKey.set(key, stops);
|
|
14118
13898
|
}
|
|
13899
|
+
targetsByKey.set(key, targets);
|
|
13900
|
+
argTargetsByKey.set(key, argTargets);
|
|
13901
|
+
if (parameterCalls.length > 0) {
|
|
13902
|
+
parameterCallsByKey.set(key, parameterCalls);
|
|
13903
|
+
}
|
|
13904
|
+
for (const position of scanPassedPositions) {
|
|
13905
|
+
passedPositions.add(position);
|
|
13906
|
+
}
|
|
14119
13907
|
for (const candidate of candidates) {
|
|
14120
13908
|
const calleeKey = nodeKey(candidate.func);
|
|
14121
13909
|
if (!functionByKey.has(calleeKey)) {
|
|
@@ -14155,6 +13943,15 @@ function expandReachableClosure(seeds, project, options, projectFileSet, facts,
|
|
|
14155
13943
|
reached.push(summary);
|
|
14156
13944
|
}
|
|
14157
13945
|
recordStops(stopsByKey, summariesByKey, options);
|
|
13946
|
+
recordTargets(targetsByKey, summariesByKey);
|
|
13947
|
+
recordArgTargets(argTargetsByKey, summariesByKey);
|
|
13948
|
+
recordCalleeParameters(parameterCallsByKey, summariesByKey);
|
|
13949
|
+
recordParameterGaps(
|
|
13950
|
+
parameterCallsByKey,
|
|
13951
|
+
summariesByKey,
|
|
13952
|
+
passedPositions,
|
|
13953
|
+
options
|
|
13954
|
+
);
|
|
14158
13955
|
return [...seeds, ...reached];
|
|
14159
13956
|
}
|
|
14160
13957
|
function scanWithRecording(key, facts, fn) {
|
|
@@ -14182,7 +13979,91 @@ function recordStops(stopsByKey, summariesByKey, options) {
|
|
|
14182
13979
|
}
|
|
14183
13980
|
for (const [key, stops] of stopsByKey) {
|
|
14184
13981
|
for (const summary of summariesByKey.get(key) ?? []) {
|
|
14185
|
-
summary.gaps.push(...stops.map(unfollowedCallGap));
|
|
13982
|
+
summary.gaps.push(...stops.map(import_behavioral_ir3.unfollowedCallGap));
|
|
13983
|
+
}
|
|
13984
|
+
}
|
|
13985
|
+
}
|
|
13986
|
+
function recordTargets(targetsByKey, summariesByKey) {
|
|
13987
|
+
for (const [key, targets] of targetsByKey) {
|
|
13988
|
+
for (const summary of summariesByKey.get(key) ?? []) {
|
|
13989
|
+
for (const transition of summary.transitions) {
|
|
13990
|
+
for (const effect of transition.effects) {
|
|
13991
|
+
if (effect.type !== "invocation") {
|
|
13992
|
+
continue;
|
|
13993
|
+
}
|
|
13994
|
+
const target = targets.get(normalizeCallee(effect.callee));
|
|
13995
|
+
if (target !== void 0) {
|
|
13996
|
+
effect.declaredAt = target;
|
|
13997
|
+
}
|
|
13998
|
+
}
|
|
13999
|
+
}
|
|
14000
|
+
}
|
|
14001
|
+
}
|
|
14002
|
+
}
|
|
14003
|
+
function recordArgTargets(argTargetsByKey, summariesByKey) {
|
|
14004
|
+
for (const [key, argTargets] of argTargetsByKey) {
|
|
14005
|
+
for (const summary of summariesByKey.get(key) ?? []) {
|
|
14006
|
+
for (const transition of summary.transitions) {
|
|
14007
|
+
for (const effect of transition.effects) {
|
|
14008
|
+
if (effect.type !== "invocation") {
|
|
14009
|
+
continue;
|
|
14010
|
+
}
|
|
14011
|
+
const byPosition = argTargets.get(normalizeCallee(effect.callee));
|
|
14012
|
+
if (byPosition === void 0) {
|
|
14013
|
+
continue;
|
|
14014
|
+
}
|
|
14015
|
+
const argsDeclaredAt = {};
|
|
14016
|
+
for (const [position, target] of byPosition) {
|
|
14017
|
+
argsDeclaredAt[position] = target;
|
|
14018
|
+
}
|
|
14019
|
+
if (Object.keys(argsDeclaredAt).length > 0) {
|
|
14020
|
+
effect.argsDeclaredAt = argsDeclaredAt;
|
|
14021
|
+
}
|
|
14022
|
+
}
|
|
14023
|
+
}
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
}
|
|
14027
|
+
function recordCalleeParameters(parameterCallsByKey, summariesByKey) {
|
|
14028
|
+
for (const [key, parameterCalls] of parameterCallsByKey) {
|
|
14029
|
+
const byCallee = new Map(
|
|
14030
|
+
parameterCalls.map(({ callee, parameterIndex }) => [
|
|
14031
|
+
callee,
|
|
14032
|
+
parameterIndex
|
|
14033
|
+
])
|
|
14034
|
+
);
|
|
14035
|
+
for (const summary of summariesByKey.get(key) ?? []) {
|
|
14036
|
+
for (const transition of summary.transitions) {
|
|
14037
|
+
for (const effect of transition.effects) {
|
|
14038
|
+
if (effect.type !== "invocation") {
|
|
14039
|
+
continue;
|
|
14040
|
+
}
|
|
14041
|
+
const parameterIndex = byCallee.get(normalizeCallee(effect.callee));
|
|
14042
|
+
if (parameterIndex !== void 0) {
|
|
14043
|
+
effect.calleeParameter = parameterIndex;
|
|
14044
|
+
}
|
|
14045
|
+
}
|
|
14046
|
+
}
|
|
14047
|
+
}
|
|
14048
|
+
}
|
|
14049
|
+
}
|
|
14050
|
+
function recordParameterGaps(parameterCallsByKey, summariesByKey, passedPositions, options) {
|
|
14051
|
+
if (options?.gapHandling === "silent") {
|
|
14052
|
+
return;
|
|
14053
|
+
}
|
|
14054
|
+
for (const [key, parameterCalls] of parameterCallsByKey) {
|
|
14055
|
+
const unbound = parameterCalls.filter(
|
|
14056
|
+
({ parameterIndex }) => !passedPositions.has(`${key}#${parameterIndex}`)
|
|
14057
|
+
);
|
|
14058
|
+
if (unbound.length === 0) {
|
|
14059
|
+
continue;
|
|
14060
|
+
}
|
|
14061
|
+
for (const summary of summariesByKey.get(key) ?? []) {
|
|
14062
|
+
summary.gaps.push(
|
|
14063
|
+
...unbound.map(
|
|
14064
|
+
({ callee }) => (0, import_behavioral_ir3.unfollowedCallGap)({ callee, reason: "unboundParameter" })
|
|
14065
|
+
)
|
|
14066
|
+
);
|
|
14186
14067
|
}
|
|
14187
14068
|
}
|
|
14188
14069
|
}
|
|
@@ -14917,9 +14798,8 @@ function readArrayLiteralText(node) {
|
|
|
14917
14798
|
}
|
|
14918
14799
|
|
|
14919
14800
|
// src/summaryIdentity.ts
|
|
14920
|
-
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
14921
14801
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
14922
|
-
var
|
|
14802
|
+
var import_behavioral_ir8 = require("@suss/behavioral-ir");
|
|
14923
14803
|
function workspaceRootFor(anchor) {
|
|
14924
14804
|
return namedPackageDirAbove(anchor) ?? import_node_path8.default.resolve(anchor);
|
|
14925
14805
|
}
|
|
@@ -14934,32 +14814,6 @@ function workspaceNameFor(root) {
|
|
|
14934
14814
|
const folder = import_node_path8.default.basename(import_node_path8.default.resolve(root));
|
|
14935
14815
|
return folder.length > 0 ? folder : null;
|
|
14936
14816
|
}
|
|
14937
|
-
function namedPackageDirAbove(start) {
|
|
14938
|
-
let at = import_node_path8.default.resolve(start);
|
|
14939
|
-
for (let up = 0; up < 12; up += 1) {
|
|
14940
|
-
if (packageNameAt(at) !== null) {
|
|
14941
|
-
return at;
|
|
14942
|
-
}
|
|
14943
|
-
const parent = import_node_path8.default.dirname(at);
|
|
14944
|
-
if (parent === at) {
|
|
14945
|
-
break;
|
|
14946
|
-
}
|
|
14947
|
-
at = parent;
|
|
14948
|
-
}
|
|
14949
|
-
return null;
|
|
14950
|
-
}
|
|
14951
|
-
function packageNameAt(dir) {
|
|
14952
|
-
try {
|
|
14953
|
-
const manifest = JSON.parse(
|
|
14954
|
-
import_node_fs4.default.readFileSync(import_node_path8.default.join(dir, "package.json"), "utf8")
|
|
14955
|
-
);
|
|
14956
|
-
if (typeof manifest.name === "string" && manifest.name.length > 0) {
|
|
14957
|
-
return manifest.name;
|
|
14958
|
-
}
|
|
14959
|
-
} catch {
|
|
14960
|
-
}
|
|
14961
|
-
return null;
|
|
14962
|
-
}
|
|
14963
14817
|
function nameSummaries(summaries, args) {
|
|
14964
14818
|
for (const summary of summaries) {
|
|
14965
14819
|
const file = relativeFile(summary.location.file, args.projectRoot);
|
|
@@ -14968,8 +14822,8 @@ function nameSummaries(summaries, args) {
|
|
|
14968
14822
|
}
|
|
14969
14823
|
summary.identity.id = idFor(args.workspace, file, summary);
|
|
14970
14824
|
}
|
|
14971
|
-
(0,
|
|
14972
|
-
|
|
14825
|
+
(0, import_behavioral_ir8.disambiguateSummaryIds)(summaries);
|
|
14826
|
+
(0, import_behavioral_ir8.linkCallsToSummaries)(summaries);
|
|
14973
14827
|
}
|
|
14974
14828
|
function relativeFile(file, projectRoot) {
|
|
14975
14829
|
if (projectRoot === void 0 || !import_node_path8.default.isAbsolute(file)) {
|
|
@@ -14979,193 +14833,39 @@ function relativeFile(file, projectRoot) {
|
|
|
14979
14833
|
return relative.startsWith("..") ? file : relative;
|
|
14980
14834
|
}
|
|
14981
14835
|
function idFor(workspace, file, summary) {
|
|
14982
|
-
return (0,
|
|
14836
|
+
return (0, import_behavioral_ir8.summaryIdFromParts)({
|
|
14983
14837
|
workspace: workspace ?? void 0,
|
|
14984
14838
|
file,
|
|
14985
14839
|
name: summary.identity.name,
|
|
14986
14840
|
exportPath: summary.identity.exportPath
|
|
14987
14841
|
});
|
|
14988
14842
|
}
|
|
14989
|
-
function nameWhatEachCallReaches(summaries) {
|
|
14990
|
-
const byName = /* @__PURE__ */ new Map();
|
|
14991
|
-
const byFileAndName = /* @__PURE__ */ new Map();
|
|
14992
|
-
const remember = (index, key, summary) => {
|
|
14993
|
-
const found = index.get(key);
|
|
14994
|
-
if (found === void 0) {
|
|
14995
|
-
index.set(key, [summary]);
|
|
14996
|
-
return;
|
|
14997
|
-
}
|
|
14998
|
-
found.push(summary);
|
|
14999
|
-
};
|
|
15000
|
-
for (const summary of summaries) {
|
|
15001
|
-
if (summary.identity.nameKind === "label") {
|
|
15002
|
-
continue;
|
|
15003
|
-
}
|
|
15004
|
-
remember(byName, summary.identity.name, summary);
|
|
15005
|
-
remember(
|
|
15006
|
-
byFileAndName,
|
|
15007
|
-
`${summary.location.file}::${summary.identity.name}`,
|
|
15008
|
-
summary
|
|
15009
|
-
);
|
|
15010
|
-
}
|
|
15011
|
-
const onlyAnswer = (index, key) => {
|
|
15012
|
-
const found = index.get(key) ?? [];
|
|
15013
|
-
return found.length === 1 ? found[0] : null;
|
|
15014
|
-
};
|
|
15015
|
-
for (const summary of summaries) {
|
|
15016
|
-
for (const transition of summary.transitions) {
|
|
15017
|
-
for (const effect of transition.effects) {
|
|
15018
|
-
if (effect.type !== "invocation") {
|
|
15019
|
-
continue;
|
|
15020
|
-
}
|
|
15021
|
-
const called = effect.callee.split(".").pop() ?? effect.callee;
|
|
15022
|
-
const reached = onlyAnswer(byFileAndName, `${summary.location.file}::${called}`) ?? onlyAnswer(byName, called);
|
|
15023
|
-
if (reached?.identity.id !== void 0) {
|
|
15024
|
-
effect.summary = reached.identity.id;
|
|
15025
|
-
}
|
|
15026
|
-
}
|
|
15027
|
-
}
|
|
15028
|
-
}
|
|
15029
|
-
}
|
|
15030
14843
|
|
|
15031
14844
|
// src/timing.ts
|
|
15032
|
-
|
|
15033
|
-
const phases = /* @__PURE__ */ new Map();
|
|
15034
|
-
const start = performance.now();
|
|
15035
|
-
function record2(label, deltaMs) {
|
|
15036
|
-
const existing = phases.get(label);
|
|
15037
|
-
if (existing === void 0) {
|
|
15038
|
-
phases.set(label, { durationMs: deltaMs, calls: 1 });
|
|
15039
|
-
} else {
|
|
15040
|
-
existing.durationMs += deltaMs;
|
|
15041
|
-
existing.calls += 1;
|
|
15042
|
-
}
|
|
15043
|
-
}
|
|
15044
|
-
return {
|
|
15045
|
-
time(label, fn) {
|
|
15046
|
-
const t0 = performance.now();
|
|
15047
|
-
try {
|
|
15048
|
-
return fn();
|
|
15049
|
-
} finally {
|
|
15050
|
-
record2(label, performance.now() - t0);
|
|
15051
|
-
}
|
|
15052
|
-
},
|
|
15053
|
-
async timeAsync(label, fn) {
|
|
15054
|
-
const t0 = performance.now();
|
|
15055
|
-
try {
|
|
15056
|
-
return await fn();
|
|
15057
|
-
} finally {
|
|
15058
|
-
record2(label, performance.now() - t0);
|
|
15059
|
-
}
|
|
15060
|
-
},
|
|
15061
|
-
report() {
|
|
15062
|
-
const totalMs = performance.now() - start;
|
|
15063
|
-
const ordered = [...phases.entries()].map(([label, s]) => ({
|
|
15064
|
-
label,
|
|
15065
|
-
durationMs: s.durationMs,
|
|
15066
|
-
calls: s.calls
|
|
15067
|
-
})).sort((a, b) => b.durationMs - a.durationMs);
|
|
15068
|
-
return { totalMs, phases: ordered };
|
|
15069
|
-
}
|
|
15070
|
-
};
|
|
15071
|
-
}
|
|
14845
|
+
var import_extractor8 = require("@suss/extractor");
|
|
15072
14846
|
|
|
15073
14847
|
// src/version.ts
|
|
15074
|
-
var
|
|
15075
|
-
var
|
|
15076
|
-
var import_node_module = require("module");
|
|
15077
|
-
var import_node_path9 = __toESM(require("path"), 1);
|
|
15078
|
-
var import_node_url = require("url");
|
|
14848
|
+
var import_extractor9 = require("@suss/extractor");
|
|
14849
|
+
var import_extractor10 = require("@suss/extractor");
|
|
15079
14850
|
var import_meta = {};
|
|
15080
14851
|
var ADAPTER_VERSION = "0.2.1";
|
|
15081
|
-
var
|
|
15082
|
-
|
|
15083
|
-
|
|
15084
|
-
|
|
15085
|
-
"@suss/behavioral-ir"
|
|
15086
|
-
];
|
|
15087
|
-
var SOURCE_STAMP = { kind: "source" };
|
|
15088
|
-
var cachedCodeStamp = null;
|
|
15089
|
-
function adapterCodeStamp() {
|
|
15090
|
-
if (cachedCodeStamp !== null) {
|
|
15091
|
-
return cachedCodeStamp;
|
|
15092
|
-
}
|
|
15093
|
-
cachedCodeStamp = readAdapterCodeStamp();
|
|
15094
|
-
return cachedCodeStamp;
|
|
15095
|
-
}
|
|
15096
|
-
function readAdapterCodeStamp() {
|
|
15097
|
-
try {
|
|
15098
|
-
const selfPath = (0, import_node_url.fileURLToPath)(import_meta.url);
|
|
15099
|
-
const hash = computeDistHashFrom(import_node_path9.default.dirname(selfPath));
|
|
15100
|
-
return hash.length > 0 ? { kind: "bundle", hash } : SOURCE_STAMP;
|
|
15101
|
-
} catch {
|
|
15102
|
-
return SOURCE_STAMP;
|
|
15103
|
-
}
|
|
15104
|
-
}
|
|
15105
|
-
function computeDistHashFrom(dir) {
|
|
15106
|
-
const candidates = [import_node_path9.default.join(dir, "index.js"), import_node_path9.default.join(dir, "index.cjs")];
|
|
15107
|
-
for (const candidate of candidates) {
|
|
15108
|
-
if (!import_node_fs5.default.existsSync(candidate)) {
|
|
15109
|
-
continue;
|
|
15110
|
-
}
|
|
15111
|
-
return computeContentHash([candidate, ...analysisBundles()]);
|
|
15112
|
-
}
|
|
15113
|
-
return "";
|
|
15114
|
-
}
|
|
15115
|
-
function computeContentHash(paths) {
|
|
15116
|
-
if (paths.length === 0) {
|
|
15117
|
-
return "";
|
|
15118
|
-
}
|
|
15119
|
-
const hash = (0, import_node_crypto3.createHash)("sha256");
|
|
15120
|
-
for (const file of paths) {
|
|
15121
|
-
try {
|
|
15122
|
-
hash.update(import_node_fs5.default.readFileSync(file));
|
|
15123
|
-
} catch {
|
|
15124
|
-
return "";
|
|
15125
|
-
}
|
|
15126
|
-
}
|
|
15127
|
-
return hash.digest("hex").slice(0, 16);
|
|
15128
|
-
}
|
|
15129
|
-
function projectFileStamp(paths) {
|
|
15130
|
-
if (paths.length === 0) {
|
|
15131
|
-
return "none";
|
|
15132
|
-
}
|
|
15133
|
-
const hash = (0, import_node_crypto3.createHash)("sha256");
|
|
15134
|
-
for (const file of [...paths].sort()) {
|
|
15135
|
-
hash.update(file);
|
|
15136
|
-
hash.update("\0");
|
|
15137
|
-
try {
|
|
15138
|
-
hash.update(import_node_fs5.default.readFileSync(file));
|
|
15139
|
-
} catch {
|
|
15140
|
-
hash.update("absent");
|
|
15141
|
-
}
|
|
15142
|
-
}
|
|
15143
|
-
return hash.digest("hex").slice(0, 16);
|
|
15144
|
-
}
|
|
15145
|
-
function analysisBundles() {
|
|
15146
|
-
const require2 = (0, import_node_module.createRequire)(import_meta.url);
|
|
15147
|
-
const found = [];
|
|
15148
|
-
for (const name of ANALYSIS_PACKAGES) {
|
|
15149
|
-
try {
|
|
15150
|
-
found.push(require2.resolve(name));
|
|
15151
|
-
} catch {
|
|
15152
|
-
}
|
|
15153
|
-
}
|
|
15154
|
-
return found;
|
|
15155
|
-
}
|
|
14852
|
+
var stamp = (0, import_extractor9.createAdapterStamp)({
|
|
14853
|
+
moduleUrl: import_meta.url,
|
|
14854
|
+
version: ADAPTER_VERSION
|
|
14855
|
+
});
|
|
15156
14856
|
function computeAdapterPacksDigest(packVersions) {
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
return
|
|
14857
|
+
return stamp.packsDigest(packVersions);
|
|
14858
|
+
}
|
|
14859
|
+
function declineWhenRunFromSource(cacheDir) {
|
|
14860
|
+
return stamp.declineWhenRunFromSource(cacheDir);
|
|
15161
14861
|
}
|
|
15162
14862
|
|
|
15163
14863
|
// src/workspacePatterns.ts
|
|
15164
|
-
var
|
|
15165
|
-
var
|
|
14864
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
14865
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
15166
14866
|
function readJson(filePath) {
|
|
15167
14867
|
try {
|
|
15168
|
-
return JSON.parse(
|
|
14868
|
+
return JSON.parse(import_node_fs3.default.readFileSync(filePath, "utf8"));
|
|
15169
14869
|
} catch {
|
|
15170
14870
|
return void 0;
|
|
15171
14871
|
}
|
|
@@ -15192,7 +14892,7 @@ function pnpmWorkspaceGlobs(yamlText) {
|
|
|
15192
14892
|
return globs;
|
|
15193
14893
|
}
|
|
15194
14894
|
function workspaceGlobsAt(dir) {
|
|
15195
|
-
const pkg = readJson(
|
|
14895
|
+
const pkg = readJson(import_node_path9.default.join(dir, "package.json"));
|
|
15196
14896
|
if (typeof pkg === "object" && pkg !== null && "workspaces" in pkg) {
|
|
15197
14897
|
const ws = pkg.workspaces;
|
|
15198
14898
|
if (Array.isArray(ws)) {
|
|
@@ -15204,10 +14904,10 @@ function workspaceGlobsAt(dir) {
|
|
|
15204
14904
|
);
|
|
15205
14905
|
}
|
|
15206
14906
|
}
|
|
15207
|
-
const pnpmPath =
|
|
15208
|
-
if (
|
|
14907
|
+
const pnpmPath = import_node_path9.default.join(dir, "pnpm-workspace.yaml");
|
|
14908
|
+
if (import_node_fs3.default.existsSync(pnpmPath)) {
|
|
15209
14909
|
try {
|
|
15210
|
-
return pnpmWorkspaceGlobs(
|
|
14910
|
+
return pnpmWorkspaceGlobs(import_node_fs3.default.readFileSync(pnpmPath, "utf8"));
|
|
15211
14911
|
} catch {
|
|
15212
14912
|
return null;
|
|
15213
14913
|
}
|
|
@@ -15216,14 +14916,14 @@ function workspaceGlobsAt(dir) {
|
|
|
15216
14916
|
}
|
|
15217
14917
|
function isDirectory(candidate) {
|
|
15218
14918
|
try {
|
|
15219
|
-
return
|
|
14919
|
+
return import_node_fs3.default.statSync(candidate).isDirectory();
|
|
15220
14920
|
} catch {
|
|
15221
14921
|
return false;
|
|
15222
14922
|
}
|
|
15223
14923
|
}
|
|
15224
14924
|
function subdirectoriesOf(dir) {
|
|
15225
14925
|
try {
|
|
15226
|
-
return
|
|
14926
|
+
return import_node_fs3.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
15227
14927
|
} catch {
|
|
15228
14928
|
return [];
|
|
15229
14929
|
}
|
|
@@ -15241,13 +14941,13 @@ function directoriesMatchingGlob(root, glob) {
|
|
|
15241
14941
|
for (const dir of current2) {
|
|
15242
14942
|
for (const entry of subdirectoriesOf(dir)) {
|
|
15243
14943
|
if (pattern.test(entry)) {
|
|
15244
|
-
next.push(
|
|
14944
|
+
next.push(import_node_path9.default.join(dir, entry));
|
|
15245
14945
|
}
|
|
15246
14946
|
}
|
|
15247
14947
|
}
|
|
15248
14948
|
} else {
|
|
15249
14949
|
for (const dir of current2) {
|
|
15250
|
-
next.push(
|
|
14950
|
+
next.push(import_node_path9.default.join(dir, segment));
|
|
15251
14951
|
}
|
|
15252
14952
|
}
|
|
15253
14953
|
current2 = next.filter(isDirectory);
|
|
@@ -15255,7 +14955,7 @@ function directoriesMatchingGlob(root, glob) {
|
|
|
15255
14955
|
return current2;
|
|
15256
14956
|
}
|
|
15257
14957
|
function packageAt(dir) {
|
|
15258
|
-
const packageJsonPath =
|
|
14958
|
+
const packageJsonPath = import_node_path9.default.join(dir, "package.json");
|
|
15259
14959
|
const pkg = readJson(packageJsonPath);
|
|
15260
14960
|
if (typeof pkg === "object" && pkg !== null && typeof pkg.name === "string") {
|
|
15261
14961
|
return { name: pkg.name, packageJsonPath };
|
|
@@ -15263,7 +14963,7 @@ function packageAt(dir) {
|
|
|
15263
14963
|
return null;
|
|
15264
14964
|
}
|
|
15265
14965
|
function workspacePackagesFrom(anchor) {
|
|
15266
|
-
let dir =
|
|
14966
|
+
let dir = import_node_path9.default.resolve(anchor);
|
|
15267
14967
|
for (; ; ) {
|
|
15268
14968
|
const globs = workspaceGlobsAt(dir);
|
|
15269
14969
|
if (globs !== null) {
|
|
@@ -15283,7 +14983,7 @@ function workspacePackagesFrom(anchor) {
|
|
|
15283
14983
|
(a, b) => a.packageJsonPath.localeCompare(b.packageJsonPath)
|
|
15284
14984
|
);
|
|
15285
14985
|
}
|
|
15286
|
-
const parent =
|
|
14986
|
+
const parent = import_node_path9.default.dirname(dir);
|
|
15287
14987
|
if (parent === dir) {
|
|
15288
14988
|
return [];
|
|
15289
14989
|
}
|
|
@@ -15317,7 +15017,7 @@ function workspaceExpansionStamp(frameworks) {
|
|
|
15317
15017
|
const paths = frameworks.flatMap((pack) => pack.discovery).flatMap(
|
|
15318
15018
|
(pattern) => pattern.match.type === "packageExports" && pattern.match.packageJsonPath !== void 0 ? [pattern.match.packageJsonPath] : []
|
|
15319
15019
|
);
|
|
15320
|
-
return projectFileStamp(paths);
|
|
15020
|
+
return (0, import_extractor10.projectFileStamp)(paths);
|
|
15321
15021
|
}
|
|
15322
15022
|
function expandWorkspacePatterns(frameworks, anchor) {
|
|
15323
15023
|
const marked = frameworks.some(
|
|
@@ -15825,11 +15525,11 @@ function extractConsumerBinding(unit, pattern, pack, resolution) {
|
|
|
15825
15525
|
return null;
|
|
15826
15526
|
}
|
|
15827
15527
|
const method = extractBindingMethod(binding, callSite, pack, resolution);
|
|
15828
|
-
const
|
|
15829
|
-
return (0,
|
|
15528
|
+
const path14 = extractBindingPath(binding, callSite, pack, resolution);
|
|
15529
|
+
return (0, import_behavioral_ir9.restBinding)({
|
|
15830
15530
|
transport: pack.protocol,
|
|
15831
15531
|
method: method ?? null,
|
|
15832
|
-
path:
|
|
15532
|
+
path: path14 ?? null,
|
|
15833
15533
|
recognition: pack.name
|
|
15834
15534
|
});
|
|
15835
15535
|
}
|
|
@@ -15845,7 +15545,7 @@ function fileRouteBinding(filePath, unit, binding, pack) {
|
|
|
15845
15545
|
if (method === void 0) {
|
|
15846
15546
|
return null;
|
|
15847
15547
|
}
|
|
15848
|
-
return (0,
|
|
15548
|
+
return (0, import_behavioral_ir9.restBinding)({
|
|
15849
15549
|
transport: pack.protocol,
|
|
15850
15550
|
recognition: pack.name,
|
|
15851
15551
|
method,
|
|
@@ -15975,7 +15675,7 @@ function computeSubUnitBarriers(unit, packs, ctx, tallies, file) {
|
|
|
15975
15675
|
}
|
|
15976
15676
|
} catch (err) {
|
|
15977
15677
|
process.stderr.write(
|
|
15978
|
-
recordPackFailure(tallies?.get(pack.name), {
|
|
15678
|
+
(0, import_extractor3.recordPackFailure)(tallies?.get(pack.name), {
|
|
15979
15679
|
pack: pack.name,
|
|
15980
15680
|
hook: "subUnits",
|
|
15981
15681
|
file,
|
|
@@ -16037,7 +15737,7 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16037
15737
|
}
|
|
16038
15738
|
} catch (err) {
|
|
16039
15739
|
process.stderr.write(
|
|
16040
|
-
recordPackFailure(tally, {
|
|
15740
|
+
(0, import_extractor3.recordPackFailure)(tally, {
|
|
16041
15741
|
pack: pack.name,
|
|
16042
15742
|
hook: "discoverUnits",
|
|
16043
15743
|
file: sourceFile.getFilePath(),
|
|
@@ -16098,7 +15798,7 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16098
15798
|
stampWrappers(raw, unit, wrappers);
|
|
16099
15799
|
const matchedPattern = unit.pattern ?? pack.discovery.find((d) => d.kind === unit.kind);
|
|
16100
15800
|
if (unit.resolverInfo !== void 0) {
|
|
16101
|
-
raw.boundaryBinding = (0,
|
|
15801
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.graphqlResolverBinding)({
|
|
16102
15802
|
transport: pack.protocol,
|
|
16103
15803
|
recognition: pack.name,
|
|
16104
15804
|
typeName: unit.resolverInfo.typeName,
|
|
@@ -16125,26 +15825,26 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16125
15825
|
}
|
|
16126
15826
|
}
|
|
16127
15827
|
} else if (unit.routeInfo !== void 0) {
|
|
16128
|
-
raw.boundaryBinding = (0,
|
|
15828
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.restBinding)({
|
|
16129
15829
|
transport: pack.protocol,
|
|
16130
15830
|
recognition: pack.name,
|
|
16131
15831
|
method: unit.routeInfo.method,
|
|
16132
15832
|
path: unit.routeInfo.path
|
|
16133
15833
|
});
|
|
16134
15834
|
} else if (unit.channelInfo !== void 0) {
|
|
16135
|
-
raw.boundaryBinding = (0,
|
|
15835
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.messageBusBinding)({
|
|
16136
15836
|
recognition: pack.name,
|
|
16137
15837
|
messageBus: unit.channelInfo.messageBus,
|
|
16138
15838
|
channel: unit.channelInfo.channel
|
|
16139
15839
|
});
|
|
16140
15840
|
} else if (unit.invocationInfo !== void 0) {
|
|
16141
|
-
raw.boundaryBinding = (0,
|
|
15841
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.unitInvocationBinding)({
|
|
16142
15842
|
recognition: pack.name,
|
|
16143
15843
|
deploymentTarget: unit.invocationInfo.deploymentTarget,
|
|
16144
15844
|
instanceName: unit.invocationInfo.instanceName
|
|
16145
15845
|
});
|
|
16146
15846
|
} else if (unit.operationInfo !== void 0) {
|
|
16147
|
-
raw.boundaryBinding = (0,
|
|
15847
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.graphqlOperationBinding)({
|
|
16148
15848
|
transport: pack.protocol,
|
|
16149
15849
|
recognition: pack.name,
|
|
16150
15850
|
operationType: unit.operationInfo.operationType,
|
|
@@ -16233,14 +15933,14 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16233
15933
|
}
|
|
16234
15934
|
if (raw.boundaryBinding === null) {
|
|
16235
15935
|
if (unit.packageExportInfo !== void 0) {
|
|
16236
|
-
raw.boundaryBinding = (0,
|
|
15936
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.packageExportBinding)({
|
|
16237
15937
|
transport: pack.protocol,
|
|
16238
15938
|
recognition: pack.name,
|
|
16239
15939
|
packageName: unit.packageExportInfo.packageName,
|
|
16240
15940
|
exportPath: unit.packageExportInfo.exportPath
|
|
16241
15941
|
});
|
|
16242
15942
|
} else {
|
|
16243
|
-
raw.boundaryBinding = (0,
|
|
15943
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.functionCallBinding)({
|
|
16244
15944
|
transport: pack.protocol,
|
|
16245
15945
|
recognition: pack.name,
|
|
16246
15946
|
...unit.functionCallInfo !== void 0 ? {
|
|
@@ -16250,9 +15950,9 @@ function extractFromSourceFile(sourceFile, frameworks, claimedUnits, options, ta
|
|
|
16250
15950
|
});
|
|
16251
15951
|
}
|
|
16252
15952
|
}
|
|
16253
|
-
const summary = (0,
|
|
15953
|
+
const summary = (0, import_extractor11.assembleSummary)(raw, options);
|
|
16254
15954
|
if (unit.unfollowed !== void 0 && options?.gapHandling !== "silent") {
|
|
16255
|
-
summary.gaps.push(unfollowedCallGap(unit.unfollowed));
|
|
15955
|
+
summary.gaps.push((0, import_behavioral_ir3.unfollowedCallGap)(unit.unfollowed));
|
|
16256
15956
|
}
|
|
16257
15957
|
if (unit.metadata !== void 0 && Object.keys(unit.metadata).length > 0) {
|
|
16258
15958
|
summary.metadata = {
|
|
@@ -16305,24 +16005,6 @@ function stampWrappers(raw, unit, wrappers) {
|
|
|
16305
16005
|
recordFileDependency(wrapper.file);
|
|
16306
16006
|
}
|
|
16307
16007
|
}
|
|
16308
|
-
function stampModuleImports(summaries, project) {
|
|
16309
|
-
const byFile2 = /* @__PURE__ */ new Map();
|
|
16310
|
-
for (const summary of summaries) {
|
|
16311
|
-
const file = summary.location.file;
|
|
16312
|
-
let imports = byFile2.get(file);
|
|
16313
|
-
if (imports === void 0) {
|
|
16314
|
-
imports = internalImportsOf(project, file);
|
|
16315
|
-
byFile2.set(file, imports);
|
|
16316
|
-
}
|
|
16317
|
-
if (imports.length === 0) {
|
|
16318
|
-
continue;
|
|
16319
|
-
}
|
|
16320
|
-
summary.metadata = {
|
|
16321
|
-
...summary.metadata ?? {},
|
|
16322
|
-
moduleImports: imports
|
|
16323
|
-
};
|
|
16324
|
-
}
|
|
16325
|
-
}
|
|
16326
16008
|
function emitLibraryEnvReadMarkers(summaries, project, frameworks) {
|
|
16327
16009
|
for (const pack of frameworks) {
|
|
16328
16010
|
for (const declared of pack.libraryEnvVars ?? []) {
|
|
@@ -16350,14 +16032,14 @@ function fileImporting(project, modulePrefix) {
|
|
|
16350
16032
|
function liftSchemasOntoDocuments(summaries) {
|
|
16351
16033
|
const sdlByDocument = /* @__PURE__ */ new Map();
|
|
16352
16034
|
for (const summary of summaries) {
|
|
16353
|
-
const label = (0,
|
|
16354
|
-
const graphql = (0,
|
|
16035
|
+
const label = (0, import_behavioral_ir9.readSourceDocumentMetadata)(summary)?.label;
|
|
16036
|
+
const graphql = (0, import_behavioral_ir9.readGraphqlMetadata)(summary);
|
|
16355
16037
|
if (label === void 0 || graphql?.schemaSdl === void 0) {
|
|
16356
16038
|
continue;
|
|
16357
16039
|
}
|
|
16358
16040
|
sdlByDocument.set(label, graphql.schemaSdl);
|
|
16359
16041
|
const { schemaSdl: _movedToTheDocument, ...rest } = graphql;
|
|
16360
|
-
summary.metadata = (0,
|
|
16042
|
+
summary.metadata = (0, import_behavioral_ir9.withGraphqlMetadata)(summary.metadata, rest);
|
|
16361
16043
|
}
|
|
16362
16044
|
for (const [label, schemaSdl] of sdlByDocument) {
|
|
16363
16045
|
summaries.push(schemaDocumentSummary(label, schemaSdl));
|
|
@@ -16372,8 +16054,8 @@ function schemaDocumentSummary(label, schemaSdl) {
|
|
|
16372
16054
|
transitions: [],
|
|
16373
16055
|
gaps: [],
|
|
16374
16056
|
confidence: { source: "declared", level: "high" },
|
|
16375
|
-
metadata: (0,
|
|
16376
|
-
(0,
|
|
16057
|
+
metadata: (0, import_behavioral_ir9.withGraphqlMetadata)(
|
|
16058
|
+
(0, import_behavioral_ir9.withSourceDocumentMetadata)(void 0, { label }),
|
|
16377
16059
|
{ schemaSdl }
|
|
16378
16060
|
)
|
|
16379
16061
|
};
|
|
@@ -16385,7 +16067,7 @@ function libraryEnvReadMarker(pack, declared, importer) {
|
|
|
16385
16067
|
identity: {
|
|
16386
16068
|
name: `${declared.module} env reads`,
|
|
16387
16069
|
exportPath: null,
|
|
16388
|
-
boundaryBinding: (0,
|
|
16070
|
+
boundaryBinding: (0, import_behavioral_ir9.functionCallBinding)({
|
|
16389
16071
|
transport: "in-process",
|
|
16390
16072
|
recognition: pack.name
|
|
16391
16073
|
})
|
|
@@ -16497,8 +16179,8 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
|
|
|
16497
16179
|
if (pathArg === void 0) {
|
|
16498
16180
|
continue;
|
|
16499
16181
|
}
|
|
16500
|
-
const
|
|
16501
|
-
if (
|
|
16182
|
+
const path14 = pathFromArgument(pathArg, resolution);
|
|
16183
|
+
if (path14 === void 0) {
|
|
16502
16184
|
continue;
|
|
16503
16185
|
}
|
|
16504
16186
|
const callerFunc = enclosingFunction(callExpr);
|
|
@@ -16510,7 +16192,7 @@ function synthesizeCallerSummaries(wrapper, _project, options, resolution) {
|
|
|
16510
16192
|
continue;
|
|
16511
16193
|
}
|
|
16512
16194
|
seen.add(dedupKey);
|
|
16513
|
-
out.push(buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
16195
|
+
out.push(buildCallerSummary(wrapper, callerFunc, callExpr, path14, options));
|
|
16514
16196
|
}
|
|
16515
16197
|
return out;
|
|
16516
16198
|
}
|
|
@@ -16567,7 +16249,7 @@ function callerName(func) {
|
|
|
16567
16249
|
}
|
|
16568
16250
|
return "anonymous";
|
|
16569
16251
|
}
|
|
16570
|
-
function buildCallerSummary(wrapper, callerFunc, callExpr,
|
|
16252
|
+
function buildCallerSummary(wrapper, callerFunc, callExpr, path14, options) {
|
|
16571
16253
|
const wrapperBinding = wrapper.summary.identity.boundaryBinding;
|
|
16572
16254
|
const wrapperRest = wrapperBinding?.semantics.name === "rest" ? wrapperBinding.semantics : null;
|
|
16573
16255
|
const syntheticPack = {
|
|
@@ -16596,13 +16278,13 @@ function buildCallerSummary(wrapper, callerFunc, callExpr, path15, options) {
|
|
|
16596
16278
|
}
|
|
16597
16279
|
};
|
|
16598
16280
|
const raw = extractCodeStructure(unit, syntheticPack);
|
|
16599
|
-
raw.boundaryBinding = (0,
|
|
16281
|
+
raw.boundaryBinding = (0, import_behavioral_ir9.restBinding)({
|
|
16600
16282
|
transport: wrapperBinding?.transport ?? "http",
|
|
16601
16283
|
method: wrapperRest?.method ?? null,
|
|
16602
|
-
path:
|
|
16284
|
+
path: path14,
|
|
16603
16285
|
recognition: wrapperBinding?.recognition ?? "unknown"
|
|
16604
16286
|
});
|
|
16605
|
-
const summary = (0,
|
|
16287
|
+
const summary = (0, import_extractor11.assembleSummary)(raw, options);
|
|
16606
16288
|
summary.metadata = {
|
|
16607
16289
|
...summary.metadata ?? {},
|
|
16608
16290
|
derivedFromWrapper: {
|
|
@@ -16621,25 +16303,12 @@ function named(summaries, workspace, runRoot) {
|
|
|
16621
16303
|
});
|
|
16622
16304
|
return summaries;
|
|
16623
16305
|
}
|
|
16624
|
-
var saidWhyNoCache = false;
|
|
16625
16306
|
function extractionConfigStamp(config) {
|
|
16626
16307
|
return [
|
|
16627
16308
|
`includeReachable=${config.includeReachable !== false}`,
|
|
16628
16309
|
`gapHandling=${config.extractorOptions?.gapHandling ?? "default"}`
|
|
16629
16310
|
].join(",");
|
|
16630
16311
|
}
|
|
16631
|
-
function declineWhenRunFromSource(cacheDir) {
|
|
16632
|
-
if (cacheDir === null || adapterCodeStamp().kind === "bundle") {
|
|
16633
|
-
return cacheDir;
|
|
16634
|
-
}
|
|
16635
|
-
if (!saidWhyNoCache) {
|
|
16636
|
-
saidWhyNoCache = true;
|
|
16637
|
-
process.stderr.write(
|
|
16638
|
-
"[suss] extraction cache off: this process loaded the adapter from source, where nothing can tell one build of it from another. Run the built adapter to cache.\n"
|
|
16639
|
-
);
|
|
16640
|
-
}
|
|
16641
|
-
return null;
|
|
16642
|
-
}
|
|
16643
16312
|
function loadRunFiles(project, candidatePaths, timer) {
|
|
16644
16313
|
if (candidatePaths !== null) {
|
|
16645
16314
|
const deep2 = timer.time(
|
|
@@ -16670,7 +16339,7 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16670
16339
|
...suppliedConfig,
|
|
16671
16340
|
frameworks: expandWorkspacePatterns(
|
|
16672
16341
|
suppliedConfig.frameworks,
|
|
16673
|
-
suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ?
|
|
16342
|
+
suppliedConfig.projectRoot ?? (suppliedConfig.tsConfigFilePath !== void 0 ? import_node_path10.default.dirname(suppliedConfig.tsConfigFilePath) : void 0)
|
|
16674
16343
|
)
|
|
16675
16344
|
};
|
|
16676
16345
|
const project = config.project ?? new import_ts_morph66.Project(
|
|
@@ -16679,24 +16348,18 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16679
16348
|
skipAddingFilesFromTsConfig: true
|
|
16680
16349
|
} : { skipAddingFilesFromTsConfig: true }
|
|
16681
16350
|
);
|
|
16682
|
-
const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(
|
|
16351
|
+
const runRoot = config.projectRoot ?? (config.tsConfigFilePath !== void 0 ? workspaceRootFor(import_node_path10.default.dirname(config.tsConfigFilePath)) : void 0);
|
|
16683
16352
|
let lazyBootstrapped = false;
|
|
16684
16353
|
let projectFileSet;
|
|
16685
16354
|
const cacheDir = declineWhenRunFromSource(
|
|
16686
|
-
config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ?
|
|
16355
|
+
config.cacheDir === null ? null : config.cacheDir ?? (config.tsConfigFilePath !== void 0 ? import_node_path10.default.join(import_node_path10.default.dirname(config.tsConfigFilePath), ".suss", "cache") : null)
|
|
16687
16356
|
);
|
|
16688
|
-
const cache = createCacheLayer(cacheDir);
|
|
16357
|
+
const cache = (0, import_extractor11.createCacheLayer)(cacheDir);
|
|
16689
16358
|
const packsDigest = `${computeAdapterPacksDigest(
|
|
16690
16359
|
config.frameworks.map(
|
|
16691
16360
|
(p) => p.version !== void 0 ? { name: p.name, version: p.version } : { name: p.name }
|
|
16692
16361
|
)
|
|
16693
16362
|
)}|${extractionConfigStamp(config)}|ws:${workspaceExpansionStamp(config.frameworks)}`;
|
|
16694
|
-
const digestFor = (files) => {
|
|
16695
|
-
const inputs = config.frameworks.flatMap(
|
|
16696
|
-
(pack) => pack.discoveryInputs?.(files) ?? []
|
|
16697
|
-
);
|
|
16698
|
-
return `${packsDigest}|reads:${projectFileStamp(inputs)}`;
|
|
16699
|
-
};
|
|
16700
16363
|
const packWrappers = config.frameworks.flatMap(
|
|
16701
16364
|
(pack) => pack.transparentWrappers ?? []
|
|
16702
16365
|
);
|
|
@@ -16729,8 +16392,8 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16729
16392
|
return named(summaries, config.workspace, runRoot);
|
|
16730
16393
|
},
|
|
16731
16394
|
async extractAll() {
|
|
16732
|
-
const timer = createTimer();
|
|
16733
|
-
const tallies = createPackTallies(config.frameworks);
|
|
16395
|
+
const timer = (0, import_extractor8.createTimer)();
|
|
16396
|
+
const tallies = (0, import_extractor3.createPackTallies)(config.frameworks);
|
|
16734
16397
|
forgetUnreadableExportFiles();
|
|
16735
16398
|
forgetReassignedNamesUnstated();
|
|
16736
16399
|
const lazyEligible = !lazyBootstrapped && config.tsConfigFilePath !== void 0 && config.project === void 0;
|
|
@@ -16740,20 +16403,17 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16740
16403
|
config.tsConfigFilePath ?? raise("lazy bootstrap requires tsConfigFilePath")
|
|
16741
16404
|
)
|
|
16742
16405
|
) : null;
|
|
16743
|
-
|
|
16744
|
-
|
|
16745
|
-
() =>
|
|
16746
|
-
|
|
16747
|
-
|
|
16748
|
-
|
|
16749
|
-
|
|
16750
|
-
|
|
16751
|
-
|
|
16752
|
-
tsconfigPath: config.tsConfigFilePath ?? raise("lazy bootstrap requires tsConfigFilePath")
|
|
16753
|
-
} : {
|
|
16754
|
-
project,
|
|
16406
|
+
let cacheFiles = null;
|
|
16407
|
+
const adapterPacksDigest = cacheDir === null ? packsDigest : timer.time("cache.digest", () => {
|
|
16408
|
+
cacheFiles = tsconfigFileList ?? project.getSourceFiles().map((sf) => sf.getFilePath());
|
|
16409
|
+
return (0, import_extractor11.runDigest)(packsDigest, config.frameworks, cacheFiles);
|
|
16410
|
+
});
|
|
16411
|
+
const cacheInput = {
|
|
16412
|
+
// Empty when cacheDir is null: a no-op cache layer never reads
|
|
16413
|
+
// the file list, so there is nothing worth resolving early.
|
|
16414
|
+
files: cacheFiles ?? [],
|
|
16755
16415
|
adapterPacksDigest,
|
|
16756
|
-
...config.tsConfigFilePath !== void 0 ? {
|
|
16416
|
+
...config.tsConfigFilePath !== void 0 ? { configPath: config.tsConfigFilePath } : {}
|
|
16757
16417
|
};
|
|
16758
16418
|
const lookup = await timer.timeAsync(
|
|
16759
16419
|
"cache.lookup",
|
|
@@ -16959,7 +16619,8 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16959
16619
|
],
|
|
16960
16620
|
access: collectAccessRecognizers(config.frameworks, tallies),
|
|
16961
16621
|
resolveWrittenValue: (value) => resolution.resolveWrittenValue(value),
|
|
16962
|
-
resolveCallableSources: (value, alsoFrom) => resolution.resolveCallableSources(value, alsoFrom)
|
|
16622
|
+
resolveCallableSources: (value, alsoFrom) => resolution.resolveCallableSources(value, alsoFrom),
|
|
16623
|
+
sourceDeclarationsBehind: (declaration) => sourceDeclarationsBehind(declaration, resolution)
|
|
16963
16624
|
},
|
|
16964
16625
|
// Reached units the cache already serves emit nothing,
|
|
16965
16626
|
// the way a cold run's seeds do not.
|
|
@@ -16996,7 +16657,10 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
16996
16657
|
}
|
|
16997
16658
|
timer.time(
|
|
16998
16659
|
"stampModuleImports",
|
|
16999
|
-
() => stampModuleImports(enriched,
|
|
16660
|
+
() => (0, import_extractor11.stampModuleImports)(enriched, (file) => {
|
|
16661
|
+
const imports = internalImportsOf(project, file);
|
|
16662
|
+
return imports.length === 0 ? void 0 : imports;
|
|
16663
|
+
})
|
|
17000
16664
|
);
|
|
17001
16665
|
timer.time(
|
|
17002
16666
|
"emitLibraryEnvReadMarkers",
|
|
@@ -17055,7 +16719,7 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
17055
16719
|
});
|
|
17056
16720
|
const composed = timer.time(
|
|
17057
16721
|
"composeWrappers",
|
|
17058
|
-
() => (0,
|
|
16722
|
+
() => (0, import_extractor11.composeWrappers)(enriched)
|
|
17059
16723
|
);
|
|
17060
16724
|
if (config.onTiming !== void 0) {
|
|
17061
16725
|
config.onTiming(timer.report());
|
|
@@ -17087,7 +16751,7 @@ function createTypeScriptAdapter(suppliedConfig) {
|
|
|
17087
16751
|
};
|
|
17088
16752
|
}
|
|
17089
16753
|
function mountAssumptionsAgree(record2, index) {
|
|
17090
|
-
return Object.entries(record2.mountPrefixes).every(
|
|
16754
|
+
return Object.entries(record2.meta.mountPrefixes).every(
|
|
17091
16755
|
([childId, prefix]) => (index.prefixForId?.(childId) ?? "") === prefix
|
|
17092
16756
|
);
|
|
17093
16757
|
}
|
|
@@ -17187,10 +16851,10 @@ function mergeWithReused(reused, fresh, ownersBySummary) {
|
|
|
17187
16851
|
return { summaries: [...reusedKept, ...fresh], reusedKept, reusedOwners };
|
|
17188
16852
|
}
|
|
17189
16853
|
function readsRunLevelJoins(summary) {
|
|
17190
|
-
if ((0,
|
|
16854
|
+
if ((0, import_behavioral_ir9.readSourceDocumentMetadata)(summary) !== void 0) {
|
|
17191
16855
|
return true;
|
|
17192
16856
|
}
|
|
17193
|
-
if ((0,
|
|
16857
|
+
if ((0, import_behavioral_ir9.readGraphqlMetadata)(summary)?.client !== void 0) {
|
|
17194
16858
|
return true;
|
|
17195
16859
|
}
|
|
17196
16860
|
const semantics = summary.identity.boundaryBinding?.semantics;
|
|
@@ -17247,7 +16911,7 @@ function buildCacheAttribution(args) {
|
|
|
17247
16911
|
cacheable,
|
|
17248
16912
|
deps: [...deps].sort(),
|
|
17249
16913
|
claims: sink.claims,
|
|
17250
|
-
mountPrefixes: Object.fromEntries(sink.mountPrefixes),
|
|
16914
|
+
meta: { mountPrefixes: Object.fromEntries(sink.mountPrefixes) },
|
|
17251
16915
|
packs: packNamesByPath.get(rootPath) ?? []
|
|
17252
16916
|
});
|
|
17253
16917
|
}
|
|
@@ -17380,7 +17044,7 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
|
|
|
17380
17044
|
if (parent.identity.boundaryBinding !== null) {
|
|
17381
17045
|
raw.boundaryBinding = parent.identity.boundaryBinding;
|
|
17382
17046
|
}
|
|
17383
|
-
const summary = (0,
|
|
17047
|
+
const summary = (0, import_extractor11.assembleSummary)(raw, options);
|
|
17384
17048
|
if (subUnit.metadata !== void 0 && Object.keys(subUnit.metadata).length > 0) {
|
|
17385
17049
|
summary.metadata = {
|
|
17386
17050
|
...summary.metadata ?? {},
|
|
@@ -17392,8 +17056,8 @@ function buildSubUnitSummary(subUnit, parent, invocationRecognizers, accessRecog
|
|
|
17392
17056
|
}
|
|
17393
17057
|
|
|
17394
17058
|
// src/bootstrap/noTsconfigProject.ts
|
|
17395
|
-
var
|
|
17396
|
-
var
|
|
17059
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
17060
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
17397
17061
|
var import_ts_morph67 = require("ts-morph");
|
|
17398
17062
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
17399
17063
|
".ts",
|
|
@@ -17424,7 +17088,7 @@ function findSourceFiles(rootDir, depth = 0) {
|
|
|
17424
17088
|
const found = [];
|
|
17425
17089
|
let entries;
|
|
17426
17090
|
try {
|
|
17427
|
-
entries =
|
|
17091
|
+
entries = import_node_fs4.default.readdirSync(rootDir, { withFileTypes: true });
|
|
17428
17092
|
} catch {
|
|
17429
17093
|
return [];
|
|
17430
17094
|
}
|
|
@@ -17432,10 +17096,10 @@ function findSourceFiles(rootDir, depth = 0) {
|
|
|
17432
17096
|
if (entry.name.startsWith(".") || SKIP_DIRECTORIES.has(entry.name)) {
|
|
17433
17097
|
continue;
|
|
17434
17098
|
}
|
|
17435
|
-
const full =
|
|
17099
|
+
const full = import_node_path11.default.join(rootDir, entry.name);
|
|
17436
17100
|
if (entry.isDirectory()) {
|
|
17437
17101
|
found.push(...findSourceFiles(full, depth + 1));
|
|
17438
|
-
} else if (SOURCE_EXTENSIONS.has(
|
|
17102
|
+
} else if (SOURCE_EXTENSIONS.has(import_node_path11.default.extname(entry.name)) && !entry.name.endsWith(".d.ts")) {
|
|
17439
17103
|
found.push(full);
|
|
17440
17104
|
}
|
|
17441
17105
|
}
|
|
@@ -17470,15 +17134,15 @@ function createProjectWithoutTsconfig(rootDir) {
|
|
|
17470
17134
|
return { project, files };
|
|
17471
17135
|
}
|
|
17472
17136
|
function findNearestTsconfig(startDir) {
|
|
17473
|
-
let dir =
|
|
17137
|
+
let dir = import_node_path11.default.resolve(startDir);
|
|
17474
17138
|
while (true) {
|
|
17475
17139
|
for (const name of ["tsconfig.json", "jsconfig.json"]) {
|
|
17476
|
-
const candidate =
|
|
17477
|
-
if (
|
|
17140
|
+
const candidate = import_node_path11.default.join(dir, name);
|
|
17141
|
+
if (import_node_fs4.default.existsSync(candidate)) {
|
|
17478
17142
|
return candidate;
|
|
17479
17143
|
}
|
|
17480
17144
|
}
|
|
17481
|
-
const parent =
|
|
17145
|
+
const parent = import_node_path11.default.dirname(dir);
|
|
17482
17146
|
if (parent === dir) {
|
|
17483
17147
|
return null;
|
|
17484
17148
|
}
|
|
@@ -17487,7 +17151,7 @@ function findNearestTsconfig(startDir) {
|
|
|
17487
17151
|
}
|
|
17488
17152
|
|
|
17489
17153
|
// src/facts/why.ts
|
|
17490
|
-
var
|
|
17154
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
17491
17155
|
var import_ts_morph68 = require("ts-morph");
|
|
17492
17156
|
var import_resolution7 = require("@suss/resolution");
|
|
17493
17157
|
var JS_PHRASES = {
|
|
@@ -17495,12 +17159,12 @@ var JS_PHRASES = {
|
|
|
17495
17159
|
reason: `${describe(tuple[0])} is a .bind of ${describe(tuple[1])}, which runs the same function`
|
|
17496
17160
|
})
|
|
17497
17161
|
};
|
|
17498
|
-
var
|
|
17162
|
+
var TypeScriptWhySession = class {
|
|
17499
17163
|
project;
|
|
17500
17164
|
store;
|
|
17501
17165
|
root;
|
|
17502
17166
|
constructor(options) {
|
|
17503
|
-
this.root =
|
|
17167
|
+
this.root = import_node_path12.default.resolve(options.dir);
|
|
17504
17168
|
const tsconfig = findNearestTsconfig(this.root);
|
|
17505
17169
|
this.project = tsconfig === null ? createProjectWithoutTsconfig(this.root).project : new import_ts_morph68.Project({ tsConfigFilePath: tsconfig });
|
|
17506
17170
|
this.store = new ResolutionStore();
|
|
@@ -17589,7 +17253,7 @@ var WhySession = class {
|
|
|
17589
17253
|
};
|
|
17590
17254
|
}
|
|
17591
17255
|
sourceFileAt(file) {
|
|
17592
|
-
const absolute =
|
|
17256
|
+
const absolute = import_node_path12.default.resolve(this.root, file);
|
|
17593
17257
|
const loaded = this.project.getSourceFile(absolute);
|
|
17594
17258
|
if (loaded !== void 0) {
|
|
17595
17259
|
return loaded;
|
|
@@ -17603,7 +17267,7 @@ var WhySession = class {
|
|
|
17603
17267
|
/** A module key: a file path said relative to the root, or a package name. */
|
|
17604
17268
|
displayPath(key) {
|
|
17605
17269
|
if (key.startsWith(this.root)) {
|
|
17606
|
-
return
|
|
17270
|
+
return import_node_path12.default.relative(this.root, key);
|
|
17607
17271
|
}
|
|
17608
17272
|
return key;
|
|
17609
17273
|
}
|
|
@@ -17631,228 +17295,8 @@ function displayNameOf(node) {
|
|
|
17631
17295
|
return text.length > 40 ? `${text.slice(0, 40)}...` : text;
|
|
17632
17296
|
}
|
|
17633
17297
|
|
|
17634
|
-
// src/packHealth.ts
|
|
17635
|
-
function stagesOf(funnel) {
|
|
17636
|
-
const stages = [];
|
|
17637
|
-
const gateSaysSomething = funnel.gates.length > 0 && funnel.unresolvedGates.length === 0;
|
|
17638
|
-
if (funnel.recognizes && !funnel.discovers && gateSaysSomething) {
|
|
17639
|
-
stages.push({
|
|
17640
|
-
from: { count: funnel.unitsInGatedFiles, name: "unit bodies" },
|
|
17641
|
-
to: { count: funnel.effectsRecognized, name: "effects" }
|
|
17642
|
-
});
|
|
17643
|
-
}
|
|
17644
|
-
if (funnel.discovers && gateSaysSomething) {
|
|
17645
|
-
stages.push({
|
|
17646
|
-
from: { count: funnel.candidateFiles, name: "source files" },
|
|
17647
|
-
to: { count: funnel.unitsDiscovered, name: "units" }
|
|
17648
|
-
});
|
|
17649
|
-
}
|
|
17650
|
-
stages.push(
|
|
17651
|
-
{
|
|
17652
|
-
from: { count: funnel.unitsClaimed, name: "units" },
|
|
17653
|
-
to: { count: funnel.summariesBound, name: "summaries" }
|
|
17654
|
-
},
|
|
17655
|
-
{
|
|
17656
|
-
from: { count: funnel.summariesBound, name: "summaries" },
|
|
17657
|
-
to: { count: funnel.summariesWithBehavior, name: "transitions" }
|
|
17658
|
-
}
|
|
17659
|
-
);
|
|
17660
|
-
return stages;
|
|
17661
|
-
}
|
|
17662
|
-
function funnelDrops(packs) {
|
|
17663
|
-
const violations = [];
|
|
17664
|
-
for (const funnel of packs) {
|
|
17665
|
-
for (const stage of stagesOf(funnel)) {
|
|
17666
|
-
if (stage.from.count === 0 || stage.to.count > 0) {
|
|
17667
|
-
continue;
|
|
17668
|
-
}
|
|
17669
|
-
violations.push({
|
|
17670
|
-
label: funnel.pack,
|
|
17671
|
-
detail: `${stage.from.count} ${stage.from.name} -> 0 ${stage.to.name}`
|
|
17672
|
-
});
|
|
17673
|
-
}
|
|
17674
|
-
}
|
|
17675
|
-
return violations;
|
|
17676
|
-
}
|
|
17677
|
-
function recognizersWithNoUnits(packs) {
|
|
17678
|
-
return packs.filter(
|
|
17679
|
-
(funnel) => funnel.recognizes && !funnel.discovers && funnel.gates.length > 0 && funnel.unresolvedGates.length === 0 && funnel.candidateFiles > 0 && funnel.unitsInGatedFiles === 0 && // The closure walks a recognizer-only pack's gated exports as
|
|
17680
|
-
// roots, so effects recognized there mean the run worked and
|
|
17681
|
-
// the missing framework pack costs attribution, not existence.
|
|
17682
|
-
funnel.effectsRecognized === 0
|
|
17683
|
-
).map((funnel) => ({
|
|
17684
|
-
label: funnel.pack,
|
|
17685
|
-
detail: `${funnel.candidateFiles} gated files, and no pack in this run discovered a unit in them. ${funnel.pack} reads calls inside units another pack finds, so add the pack that finds this project's handlers (-f express, -f fastify, ...), or run suss init to work out which.`
|
|
17686
|
-
}));
|
|
17687
|
-
}
|
|
17688
|
-
function helpersThatMatchedNothing(packs) {
|
|
17689
|
-
return packs.flatMap(
|
|
17690
|
-
(funnel) => funnel.helpersUnmatched.map((helper) => ({
|
|
17691
|
-
label: funnel.pack,
|
|
17692
|
-
detail: `${helper} matched no call in this run, so whatever it registers is missing. suss read that helper out of the project and then failed to match a call to it, which is a bug in suss rather than in your code.`
|
|
17693
|
-
}))
|
|
17694
|
-
);
|
|
17695
|
-
}
|
|
17696
|
-
function unversionedPacks(packs) {
|
|
17697
|
-
return packs.filter((funnel) => funnel.version === null).map((funnel) => ({
|
|
17698
|
-
label: funnel.pack,
|
|
17699
|
-
detail: "no version declared"
|
|
17700
|
-
}));
|
|
17701
|
-
}
|
|
17702
|
-
function selfCollisions(packs) {
|
|
17703
|
-
return packs.filter((funnel) => funnel.selfCollisions > 0).map((funnel) => ({
|
|
17704
|
-
label: funnel.pack,
|
|
17705
|
-
detail: `${funnel.selfCollisions} ${funnel.selfCollisions === 1 ? "unit" : "units"} matched twice, second dropped`
|
|
17706
|
-
}));
|
|
17707
|
-
}
|
|
17708
|
-
function threwWhileReading(packs) {
|
|
17709
|
-
return packs.filter((funnel) => funnel.failures.length > 0).map((funnel) => {
|
|
17710
|
-
const first = funnel.failures[0];
|
|
17711
|
-
const rest = funnel.failures.length - 1;
|
|
17712
|
-
const alsoIn = rest > 0 ? ` (+${rest} more)` : "";
|
|
17713
|
-
return {
|
|
17714
|
-
label: funnel.pack,
|
|
17715
|
-
detail: `${first.hook} on ${first.file}${alsoIn}: ${first.message}`
|
|
17716
|
-
};
|
|
17717
|
-
});
|
|
17718
|
-
}
|
|
17719
|
-
function packGradients(report) {
|
|
17720
|
-
const gradients = [];
|
|
17721
|
-
for (const funnel of report.packs) {
|
|
17722
|
-
if (funnel.declarations === null) {
|
|
17723
|
-
continue;
|
|
17724
|
-
}
|
|
17725
|
-
gradients.push(gradientOf(funnel.pack, funnel.declarations.declarations));
|
|
17726
|
-
}
|
|
17727
|
-
return gradients;
|
|
17728
|
-
}
|
|
17729
|
-
function gradientOf(pack, declarations) {
|
|
17730
|
-
const gradient = {
|
|
17731
|
-
pack,
|
|
17732
|
-
dataLinks: 0,
|
|
17733
|
-
functionLinks: [],
|
|
17734
|
-
astLinks: [],
|
|
17735
|
-
withoutExample: []
|
|
17736
|
-
};
|
|
17737
|
-
for (const declaration of declarations) {
|
|
17738
|
-
gradient.dataLinks += declaration.dataLinks;
|
|
17739
|
-
for (const question of declaration.functionLinks) {
|
|
17740
|
-
gradient.functionLinks.push(`${declaration.name}.${question}`);
|
|
17741
|
-
}
|
|
17742
|
-
for (const question of declaration.astLinks) {
|
|
17743
|
-
gradient.astLinks.push(`${declaration.name}.${question}`);
|
|
17744
|
-
}
|
|
17745
|
-
if (declaration.example === null) {
|
|
17746
|
-
gradient.withoutExample.push(declaration.name);
|
|
17747
|
-
}
|
|
17748
|
-
}
|
|
17749
|
-
return gradient;
|
|
17750
|
-
}
|
|
17751
|
-
function opaqueLinks(gradients) {
|
|
17752
|
-
return gradients.filter((gradient) => gradient.functionLinks.length > 0).map((gradient) => ({
|
|
17753
|
-
label: gradient.pack,
|
|
17754
|
-
detail: `${gradient.functionLinks.join(", ")} (${gradient.dataLinks} data)`
|
|
17755
|
-
}));
|
|
17756
|
-
}
|
|
17757
|
-
function reachesTheSyntaxTree(gradients) {
|
|
17758
|
-
return gradients.filter((gradient) => gradient.astLinks.length > 0).map((gradient) => ({
|
|
17759
|
-
label: gradient.pack,
|
|
17760
|
-
detail: gradient.astLinks.join(", ")
|
|
17761
|
-
}));
|
|
17762
|
-
}
|
|
17763
|
-
function undocumentedDeclarations(gradients) {
|
|
17764
|
-
return gradients.filter((gradient) => gradient.withoutExample.length > 0).map((gradient) => ({
|
|
17765
|
-
label: gradient.pack,
|
|
17766
|
-
detail: gradient.withoutExample.join(", ")
|
|
17767
|
-
}));
|
|
17768
|
-
}
|
|
17769
|
-
function evaluatePackHealth(report) {
|
|
17770
|
-
const gradients = packGradients(report);
|
|
17771
|
-
return [
|
|
17772
|
-
{
|
|
17773
|
-
name: "no pack throws while it reads",
|
|
17774
|
-
code: "threw",
|
|
17775
|
-
audience: "run",
|
|
17776
|
-
violations: threwWhileReading(report.packs)
|
|
17777
|
-
},
|
|
17778
|
-
{
|
|
17779
|
-
name: "no pack finds something and records nothing",
|
|
17780
|
-
code: "no-output",
|
|
17781
|
-
audience: "run",
|
|
17782
|
-
violations: funnelDrops(report.packs)
|
|
17783
|
-
},
|
|
17784
|
-
{
|
|
17785
|
-
name: "no pack collides with itself",
|
|
17786
|
-
code: "double-match",
|
|
17787
|
-
audience: "run",
|
|
17788
|
-
violations: selfCollisions(report.packs)
|
|
17789
|
-
},
|
|
17790
|
-
{
|
|
17791
|
-
name: "every recognizer had units to look inside",
|
|
17792
|
-
code: "no-units",
|
|
17793
|
-
audience: "run",
|
|
17794
|
-
violations: recognizersWithNoUnits(report.packs)
|
|
17795
|
-
},
|
|
17796
|
-
{
|
|
17797
|
-
name: "every registration helper the run read matched a call",
|
|
17798
|
-
code: "no-helper",
|
|
17799
|
-
audience: "run",
|
|
17800
|
-
violations: helpersThatMatchedNothing(report.packs)
|
|
17801
|
-
},
|
|
17802
|
-
{
|
|
17803
|
-
name: "every pack declares a version",
|
|
17804
|
-
code: "no-version",
|
|
17805
|
-
audience: "pack",
|
|
17806
|
-
violations: unversionedPacks(report.packs)
|
|
17807
|
-
},
|
|
17808
|
-
{
|
|
17809
|
-
name: "every link a declared pack states is data",
|
|
17810
|
-
code: "fn-link",
|
|
17811
|
-
audience: "pack",
|
|
17812
|
-
violations: opaqueLinks(gradients)
|
|
17813
|
-
},
|
|
17814
|
-
{
|
|
17815
|
-
name: "no declared pack reads the syntax tree",
|
|
17816
|
-
code: "ast-link",
|
|
17817
|
-
audience: "pack",
|
|
17818
|
-
violations: reachesTheSyntaxTree(gradients)
|
|
17819
|
-
},
|
|
17820
|
-
{
|
|
17821
|
-
name: "every declaration states an example",
|
|
17822
|
-
code: "no-example",
|
|
17823
|
-
audience: "pack",
|
|
17824
|
-
violations: undocumentedDeclarations(gradients)
|
|
17825
|
-
}
|
|
17826
|
-
];
|
|
17827
|
-
}
|
|
17828
|
-
function formatPackHealth(checks, audiences) {
|
|
17829
|
-
const fired = checks.filter(
|
|
17830
|
-
(check) => check.violations.length > 0 && audiences.includes(check.audience)
|
|
17831
|
-
);
|
|
17832
|
-
if (fired.length === 0) {
|
|
17833
|
-
return "";
|
|
17834
|
-
}
|
|
17835
|
-
const rows = fired.flatMap(
|
|
17836
|
-
(check) => check.violations.map((violation) => ({
|
|
17837
|
-
code: check.code,
|
|
17838
|
-
pack: violation.label,
|
|
17839
|
-
detail: violation.detail
|
|
17840
|
-
}))
|
|
17841
|
-
);
|
|
17842
|
-
const codeWidth = Math.max(...rows.map((row) => row.code.length));
|
|
17843
|
-
const packWidth = Math.max(...rows.map((row) => row.pack.length));
|
|
17844
|
-
const lines = ["", `Pack health (${rows.length}):`];
|
|
17845
|
-
for (const row of rows) {
|
|
17846
|
-
lines.push(
|
|
17847
|
-
` ${row.code.padEnd(codeWidth)} ${row.pack.padEnd(packWidth)} ${row.detail}`
|
|
17848
|
-
);
|
|
17849
|
-
}
|
|
17850
|
-
return `${lines.join("\n")}
|
|
17851
|
-
`;
|
|
17852
|
-
}
|
|
17853
|
-
|
|
17854
17298
|
// src/stubEvidence.ts
|
|
17855
|
-
var
|
|
17299
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
17856
17300
|
var import_ts_morph69 = require("ts-morph");
|
|
17857
17301
|
function stubEvidenceIn(project, packageName, root) {
|
|
17858
17302
|
const resolution = new ResolutionStore();
|
|
@@ -17868,7 +17312,7 @@ function stubEvidenceIn(project, packageName, root) {
|
|
|
17868
17312
|
calls: []
|
|
17869
17313
|
};
|
|
17870
17314
|
entry.calls.push({
|
|
17871
|
-
file:
|
|
17315
|
+
file: import_node_path13.default.relative(root, sourceFile.getFilePath()).split(import_node_path13.default.sep).join("/"),
|
|
17872
17316
|
line: one.call.getStartLineNumber(),
|
|
17873
17317
|
args: one.call.getArguments().map((arg) => effectArgOf(arg))
|
|
17874
17318
|
});
|
|
@@ -17883,7 +17327,7 @@ function stubEvidence(options) {
|
|
|
17883
17327
|
const project = new import_ts_morph69.Project(
|
|
17884
17328
|
options.tsConfigFilePath !== void 0 ? { tsConfigFilePath: options.tsConfigFilePath } : { compilerOptions: { allowJs: true } }
|
|
17885
17329
|
);
|
|
17886
|
-
const root = options.tsConfigFilePath !== void 0 ?
|
|
17330
|
+
const root = options.tsConfigFilePath !== void 0 ? import_node_path13.default.dirname(options.tsConfigFilePath) : import_node_path13.default.resolve(options.directory ?? process.cwd());
|
|
17887
17331
|
if (options.tsConfigFilePath === void 0) {
|
|
17888
17332
|
project.addSourceFilesAtPaths([
|
|
17889
17333
|
`${root}/**/*.{ts,tsx,js,jsx}`,
|
|
@@ -17896,7 +17340,7 @@ function stubEvidence(options) {
|
|
|
17896
17340
|
0 && (module.exports = {
|
|
17897
17341
|
ADAPTER_VERSION,
|
|
17898
17342
|
ResolutionStore,
|
|
17899
|
-
|
|
17343
|
+
TypeScriptWhySession,
|
|
17900
17344
|
accessContextFor,
|
|
17901
17345
|
buildProjectHelperIndex,
|
|
17902
17346
|
callOpsFor,
|
|
@@ -17909,13 +17353,11 @@ function stubEvidence(options) {
|
|
|
17909
17353
|
createTsSubUnitContext,
|
|
17910
17354
|
createTypeScriptAdapter,
|
|
17911
17355
|
discoverUnits,
|
|
17912
|
-
evaluatePackHealth,
|
|
17913
17356
|
exportedDeclarationsOf,
|
|
17914
17357
|
extractCodeStructure,
|
|
17915
17358
|
extractRawBranches,
|
|
17916
17359
|
findNearestTsconfig,
|
|
17917
17360
|
findTerminals,
|
|
17918
|
-
formatPackHealth,
|
|
17919
17361
|
functionTargetOf,
|
|
17920
17362
|
importDeclarationsOf,
|
|
17921
17363
|
importedNamesOf,
|