@suss/resolution 0.27.0 → 0.29.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 +4 -4
- package/dist/index.cjs +824 -352
- package/dist/index.d.cts +242 -2
- package/dist/index.d.ts +242 -2
- package/dist/index.js +463 -2
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ANSWER_RELATIONS: () => ANSWER_RELATIONS,
|
|
24
|
+
ASKING_RELATIONS: () => ASKING_RELATIONS,
|
|
24
25
|
FACT_CONTRACT_CASES: () => FACT_CONTRACT_CASES,
|
|
25
26
|
NAMESPACE_IMPORT: () => NAMESPACE_IMPORT,
|
|
26
27
|
NAMESPACE_IMPORT_NAME: () => NAMESPACE_IMPORT_NAME,
|
|
@@ -29,19 +30,289 @@ __export(index_exports, {
|
|
|
29
30
|
RESULT_STEP: () => RESULT_STEP,
|
|
30
31
|
VALUE_STEP: () => VALUE_STEP,
|
|
31
32
|
agreedMountPrefix: () => agreedMountPrefix,
|
|
33
|
+
askResolution: () => askResolution,
|
|
34
|
+
calleeOutcomeOf: () => calleeOutcomeOf,
|
|
35
|
+
calleeOutcomes: () => calleeOutcomes,
|
|
32
36
|
checkFactContract: () => checkFactContract,
|
|
37
|
+
couldBeSettled: () => couldBeSettled,
|
|
33
38
|
explainResolutionProof: () => explainResolutionProof,
|
|
34
39
|
explainResolvedKey: () => explainResolvedKey,
|
|
35
40
|
joinMountedPath: () => joinMountedPath,
|
|
36
41
|
mountPathsOf: () => mountPathsOf,
|
|
37
42
|
nodeOfKey: () => nodeOfKey,
|
|
38
43
|
placeholderValues: () => placeholderValues,
|
|
44
|
+
queryFacts: () => queryFacts,
|
|
39
45
|
renderExplanation: () => renderExplanation,
|
|
46
|
+
resolutionProgram: () => resolutionProgram,
|
|
40
47
|
singleAnswers: () => singleAnswers,
|
|
48
|
+
startsAtName: () => startsAtName,
|
|
49
|
+
valueLeftByWrites: () => valueLeftByWrites,
|
|
50
|
+
writesRunInOrder: () => writesRunInOrder,
|
|
51
|
+
writtenSourcesOf: () => writtenSourcesOf,
|
|
41
52
|
writtenValueOf: () => writtenValueOf
|
|
42
53
|
});
|
|
43
54
|
module.exports = __toCommonJS(index_exports);
|
|
44
55
|
|
|
56
|
+
// src/program.ts
|
|
57
|
+
var import_datalog = require("@suss/datalog");
|
|
58
|
+
var ASKING_RELATIONS = [
|
|
59
|
+
"wanted",
|
|
60
|
+
"wantedOrigin",
|
|
61
|
+
"wantedCallOrigin",
|
|
62
|
+
"wantedExportsOf",
|
|
63
|
+
"wantedSubject",
|
|
64
|
+
"wantedAnchor",
|
|
65
|
+
"wantedAncestry"
|
|
66
|
+
];
|
|
67
|
+
var NO_LANGUAGE_RULES = [];
|
|
68
|
+
var programs = /* @__PURE__ */ new WeakMap();
|
|
69
|
+
function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
|
|
70
|
+
const built = programs.get(languageRules);
|
|
71
|
+
if (built !== void 0) {
|
|
72
|
+
return built;
|
|
73
|
+
}
|
|
74
|
+
const rules = [
|
|
75
|
+
...RESOLUTION_RULES,
|
|
76
|
+
...languageRules,
|
|
77
|
+
...RESOLUTION_QUESTIONS
|
|
78
|
+
];
|
|
79
|
+
const program = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? { rules, demandDriven: [], demands: [] } : (0, import_datalog.deriveOnDemand)(rules, ANSWER_RELATIONS);
|
|
80
|
+
programs.set(languageRules, program);
|
|
81
|
+
return program;
|
|
82
|
+
}
|
|
83
|
+
function queryFacts(program) {
|
|
84
|
+
if (program.demandDriven.length === 0) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
return [...program.demandDriven, ...ASKING_RELATIONS];
|
|
88
|
+
}
|
|
89
|
+
var askedByDb = /* @__PURE__ */ new WeakMap();
|
|
90
|
+
function askedOf(db, asking) {
|
|
91
|
+
let byRelation = askedByDb.get(db);
|
|
92
|
+
if (byRelation === void 0) {
|
|
93
|
+
byRelation = /* @__PURE__ */ new Map();
|
|
94
|
+
askedByDb.set(db, byRelation);
|
|
95
|
+
}
|
|
96
|
+
let asked = byRelation.get(asking);
|
|
97
|
+
if (asked === void 0) {
|
|
98
|
+
asked = /* @__PURE__ */ new Set();
|
|
99
|
+
byRelation.set(asking, asked);
|
|
100
|
+
}
|
|
101
|
+
return asked;
|
|
102
|
+
}
|
|
103
|
+
function askResolution(db, keys, asking = "wanted", program = resolutionProgram()) {
|
|
104
|
+
const asked = askedOf(db, asking);
|
|
105
|
+
const fresh = [...keys].filter((key) => !asked.has(key));
|
|
106
|
+
if (fresh.length === 0) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
for (const key of fresh) {
|
|
110
|
+
asked.add(key);
|
|
111
|
+
db.add(asking, [key]);
|
|
112
|
+
}
|
|
113
|
+
(0, import_datalog.evaluate)(db, program.rules);
|
|
114
|
+
const forget = queryFacts(program);
|
|
115
|
+
if (forget.length > 0) {
|
|
116
|
+
(0, import_datalog.clearRelations)(db, program.rules, forget);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/callee.ts
|
|
121
|
+
var UNDECLARED = { kind: "undeclared" };
|
|
122
|
+
var UNSETTLED = { kind: "unsettled" };
|
|
123
|
+
var OUTSIDE_RUN = { kind: "outsideRun" };
|
|
124
|
+
function calleeOutcomes(db, keys, program = resolutionProgram()) {
|
|
125
|
+
askAboutSources(db, keys, program);
|
|
126
|
+
const reading = new Reading(db);
|
|
127
|
+
const outcomes = /* @__PURE__ */ new Map();
|
|
128
|
+
for (const key of keys) {
|
|
129
|
+
outcomes.set(key, reading.outcomeOf(key));
|
|
130
|
+
}
|
|
131
|
+
return outcomes;
|
|
132
|
+
}
|
|
133
|
+
function calleeOutcomeOf(db, key, program = resolutionProgram()) {
|
|
134
|
+
return calleeOutcomes(db, [key], program).get(key) ?? UNDECLARED;
|
|
135
|
+
}
|
|
136
|
+
function askAboutSources(db, keys, program) {
|
|
137
|
+
let wave = [...new Set(keys)];
|
|
138
|
+
const asked = new Set(wave);
|
|
139
|
+
while (wave.length > 0) {
|
|
140
|
+
askResolution(db, wave, "wanted", program);
|
|
141
|
+
const next = [];
|
|
142
|
+
for (const key of wave) {
|
|
143
|
+
if (!decidedByCallers(db, key) && answersFor(db, key).length > 0) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
for (const source of sourcesOf(db, key)) {
|
|
147
|
+
if (!asked.has(source)) {
|
|
148
|
+
asked.add(source);
|
|
149
|
+
next.push(source);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
wave = next;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function couldBeSettled(db, key) {
|
|
157
|
+
return db.has("func", [key]) || db.has("objectValue", [key]) || sourcesOf(db, key).length > 0;
|
|
158
|
+
}
|
|
159
|
+
function sourcesOf(db, key) {
|
|
160
|
+
const base = db.lookup("readsProperty", 0, key)[0];
|
|
161
|
+
if (base !== void 0) {
|
|
162
|
+
return [String(base[1])];
|
|
163
|
+
}
|
|
164
|
+
const call = db.lookup("call", 0, key)[0];
|
|
165
|
+
if (call !== void 0) {
|
|
166
|
+
return [String(call[1])];
|
|
167
|
+
}
|
|
168
|
+
return writtenSourcesOf(db, key);
|
|
169
|
+
}
|
|
170
|
+
var WRITE_RELATIONS = ["binds", "endsHolding", "mayHold"];
|
|
171
|
+
function writtenSourcesOf(db, key) {
|
|
172
|
+
const found = [];
|
|
173
|
+
for (const relation of WRITE_RELATIONS) {
|
|
174
|
+
for (const row of db.lookup(relation, 0, key)) {
|
|
175
|
+
found.push(String(row[1]));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return found;
|
|
179
|
+
}
|
|
180
|
+
function answersFor(db, key) {
|
|
181
|
+
const found = /* @__PURE__ */ new Map();
|
|
182
|
+
for (const row of db.lookup("wantedComesTo", 0, key)) {
|
|
183
|
+
const answer = String(row[1]);
|
|
184
|
+
if (db.has("func", [answer])) {
|
|
185
|
+
found.set(answer, { kind: "function", key: answer });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (db.has("objectValue", [answer])) {
|
|
189
|
+
found.set(answer, { kind: "object", key: answer });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return [...found.values()];
|
|
193
|
+
}
|
|
194
|
+
function outcomeKey(outcome) {
|
|
195
|
+
if (outcome.kind === "function" || outcome.kind === "object") {
|
|
196
|
+
return `${outcome.kind}:${outcome.key}`;
|
|
197
|
+
}
|
|
198
|
+
return outcome.kind;
|
|
199
|
+
}
|
|
200
|
+
var THROUGH_BASE = {
|
|
201
|
+
function: UNDECLARED,
|
|
202
|
+
object: UNDECLARED
|
|
203
|
+
};
|
|
204
|
+
var THROUGH_CALL = {
|
|
205
|
+
function: UNSETTLED,
|
|
206
|
+
object: UNSETTLED
|
|
207
|
+
};
|
|
208
|
+
var Reading = class {
|
|
209
|
+
constructor(db) {
|
|
210
|
+
this.db = db;
|
|
211
|
+
}
|
|
212
|
+
db;
|
|
213
|
+
memo = /* @__PURE__ */ new Map();
|
|
214
|
+
walking = /* @__PURE__ */ new Set();
|
|
215
|
+
outcomeOf(key) {
|
|
216
|
+
return this.walk(key).outcome;
|
|
217
|
+
}
|
|
218
|
+
walk(key) {
|
|
219
|
+
const known = this.memo.get(key);
|
|
220
|
+
if (known !== void 0) {
|
|
221
|
+
return { outcome: known, looped: false };
|
|
222
|
+
}
|
|
223
|
+
if (this.walking.has(key)) {
|
|
224
|
+
return { outcome: UNDECLARED, looped: true };
|
|
225
|
+
}
|
|
226
|
+
this.walking.add(key);
|
|
227
|
+
const found = this.decide(key);
|
|
228
|
+
this.walking.delete(key);
|
|
229
|
+
if (!found.looped) {
|
|
230
|
+
this.memo.set(key, found.outcome);
|
|
231
|
+
}
|
|
232
|
+
return found;
|
|
233
|
+
}
|
|
234
|
+
decide(key) {
|
|
235
|
+
if (decidedByCallers(this.db, key)) {
|
|
236
|
+
return this.fromWrites(key);
|
|
237
|
+
}
|
|
238
|
+
const answers = answersFor(this.db, key);
|
|
239
|
+
if (answers.length > 1) {
|
|
240
|
+
return {
|
|
241
|
+
outcome: { kind: "severalSources", sources: answers.map(outcomeKey) },
|
|
242
|
+
looped: false
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const only = answers[0];
|
|
246
|
+
if (only !== void 0) {
|
|
247
|
+
return { outcome: only, looped: false };
|
|
248
|
+
}
|
|
249
|
+
return this.refusal(key);
|
|
250
|
+
}
|
|
251
|
+
refusal(key) {
|
|
252
|
+
const base = this.db.lookup("readsProperty", 0, key)[0];
|
|
253
|
+
if (base !== void 0) {
|
|
254
|
+
return this.through(THROUGH_BASE, String(base[1]));
|
|
255
|
+
}
|
|
256
|
+
const call = this.db.lookup("call", 0, key)[0];
|
|
257
|
+
if (call !== void 0) {
|
|
258
|
+
return this.through(THROUGH_CALL, String(call[1]));
|
|
259
|
+
}
|
|
260
|
+
return this.fromWrites(key);
|
|
261
|
+
}
|
|
262
|
+
through(table, source) {
|
|
263
|
+
const found = this.walk(source);
|
|
264
|
+
return {
|
|
265
|
+
outcome: table[found.outcome.kind] ?? found.outcome,
|
|
266
|
+
looped: found.looped
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* What the writes to a name, and the arguments a call put in a
|
|
271
|
+
* parameter, agree the value is. A source that says nothing is left
|
|
272
|
+
* out, so a name narrowed through a second name keeps the outcome it
|
|
273
|
+
* started with rather than counting as a second source.
|
|
274
|
+
*/
|
|
275
|
+
fromWrites(key) {
|
|
276
|
+
const found = /* @__PURE__ */ new Map();
|
|
277
|
+
let looped = false;
|
|
278
|
+
for (const source of writtenSourcesOf(this.db, key)) {
|
|
279
|
+
const from = this.walk(source);
|
|
280
|
+
looped = looped || from.looped;
|
|
281
|
+
if (from.outcome.kind !== "undeclared") {
|
|
282
|
+
found.set(outcomeKey(from.outcome), from.outcome);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (isParameter(this.db, key)) {
|
|
286
|
+
found.set("callerSupplied", { kind: "callerSupplied", key });
|
|
287
|
+
}
|
|
288
|
+
if (found.size > 1) {
|
|
289
|
+
return {
|
|
290
|
+
outcome: { kind: "severalSources", sources: [...found.keys()] },
|
|
291
|
+
looped
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
const only = [...found.values()][0];
|
|
295
|
+
return { outcome: only ?? whereItCameFrom(this.db, key), looped };
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
function isParameter(db, key) {
|
|
299
|
+
return db.lookup("paramNamed", 2, key).length > 0 || db.lookup("paramOf", 2, key).length > 0;
|
|
300
|
+
}
|
|
301
|
+
function decidedByCallers(db, key) {
|
|
302
|
+
return isParameter(db, key) && db.lookup("binds", 0, key).length === 0;
|
|
303
|
+
}
|
|
304
|
+
function whereItCameFrom(db, key) {
|
|
305
|
+
for (const row of db.lookup("imports", 0, key)) {
|
|
306
|
+
if (db.lookup("exportsAs", 0, String(row[1])).length === 0) {
|
|
307
|
+
return OUTSIDE_RUN;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (db.has("writtenValue", [key])) {
|
|
311
|
+
return OUTSIDE_RUN;
|
|
312
|
+
}
|
|
313
|
+
return db.has("writesUnstated", [key]) ? UNSETTLED : UNDECLARED;
|
|
314
|
+
}
|
|
315
|
+
|
|
45
316
|
// src/contract.ts
|
|
46
317
|
var distinct = (values) => new Set(values).size;
|
|
47
318
|
var RELATIONS_THAT_CAN_CROSS = ["imports", "binds", "reExports"];
|
|
@@ -236,12 +507,12 @@ function checkFactContract(sources, emit, options = {}) {
|
|
|
236
507
|
}
|
|
237
508
|
|
|
238
509
|
// src/explain.ts
|
|
239
|
-
var
|
|
510
|
+
var import_datalog2 = require("@suss/datalog");
|
|
240
511
|
function exportTrail(proof, describe) {
|
|
241
512
|
if (proof.kind !== "derived") {
|
|
242
513
|
return [];
|
|
243
514
|
}
|
|
244
|
-
const name = (0,
|
|
515
|
+
const name = (0, import_datalog2.ruleLabel)(proof.rule);
|
|
245
516
|
if (name === "re-export") {
|
|
246
517
|
const [m, n, m2, n2] = proof.premises[0].tuple;
|
|
247
518
|
return [
|
|
@@ -317,6 +588,38 @@ var DEFAULT_PHRASES = {
|
|
|
317
588
|
]
|
|
318
589
|
};
|
|
319
590
|
},
|
|
591
|
+
"declared finder": ({ tuple, premises, describe }) => {
|
|
592
|
+
const method = String(premises[1].tuple[2]);
|
|
593
|
+
const base = String(premises[4].tuple[0]);
|
|
594
|
+
return {
|
|
595
|
+
reason: `${describe(tuple[0])} calls ${method} on ${describe(tuple[1])}, which gives back one of it`,
|
|
596
|
+
assumptions: [
|
|
597
|
+
`a pack declares that ${method} on a class extending ${base} gives back one of that class`
|
|
598
|
+
]
|
|
599
|
+
};
|
|
600
|
+
},
|
|
601
|
+
"declared argument finder": ({ tuple, premises, describe }) => {
|
|
602
|
+
const method = String(premises[1].tuple[2]);
|
|
603
|
+
const position = String(premises[2].tuple[1]);
|
|
604
|
+
const base = String(premises[3].tuple[0]);
|
|
605
|
+
return {
|
|
606
|
+
reason: `${describe(tuple[0])} calls ${method} with ${describe(tuple[1])} at argument ${position}, which gives back one of it`,
|
|
607
|
+
assumptions: [
|
|
608
|
+
`a pack declares that ${method} with a class extending ${base} at argument ${position} gives back one of that class`
|
|
609
|
+
]
|
|
610
|
+
};
|
|
611
|
+
},
|
|
612
|
+
"declared import finder": ({ tuple, premises, describe }) => {
|
|
613
|
+
const module2 = String(premises[1].tuple[1]);
|
|
614
|
+
const name = String(premises[1].tuple[2]);
|
|
615
|
+
const position = String(premises[2].tuple[2]);
|
|
616
|
+
return {
|
|
617
|
+
reason: `${describe(tuple[0])} calls ${name} from ${module2} with ${describe(tuple[1])} at argument ${position}, which gives back one of it`,
|
|
618
|
+
assumptions: [
|
|
619
|
+
`a pack declares that ${name} from ${module2} gives back one of the class at argument ${position}`
|
|
620
|
+
]
|
|
621
|
+
};
|
|
622
|
+
},
|
|
320
623
|
"call result": ({ tuple, premises, describe, inline }) => {
|
|
321
624
|
const invokes = premises[0];
|
|
322
625
|
const invoked = invokes.tuple[1];
|
|
@@ -352,7 +655,7 @@ function inlineChain(proof, state) {
|
|
|
352
655
|
return explained.steps.map((step) => step.reason);
|
|
353
656
|
}
|
|
354
657
|
function stepFrom(proof, state) {
|
|
355
|
-
const name = (0,
|
|
658
|
+
const name = (0, import_datalog2.ruleLabel)(proof.rule);
|
|
356
659
|
const phrase = state.phrases[name];
|
|
357
660
|
const from = proof.tuple[0];
|
|
358
661
|
const to = proof.tuple[1];
|
|
@@ -521,6 +824,47 @@ function pathsOf(edges, memo, childId, visiting) {
|
|
|
521
824
|
return result;
|
|
522
825
|
}
|
|
523
826
|
|
|
827
|
+
// src/nameReads.ts
|
|
828
|
+
function writesRunInOrder(scope, name, writes, rules) {
|
|
829
|
+
const last = writes[writes.length - 1];
|
|
830
|
+
if (scope === null || last === void 0) {
|
|
831
|
+
return false;
|
|
832
|
+
}
|
|
833
|
+
if (!writes.every((write) => write.direct)) {
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
return !isReadBefore(scope, name, last.at.startIndex, rules);
|
|
837
|
+
}
|
|
838
|
+
function isReadBefore(scope, name, position, rules) {
|
|
839
|
+
let found = false;
|
|
840
|
+
const visit = (node) => {
|
|
841
|
+
if (found || node.startIndex >= position) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (rules.laterBodies.has(node.type)) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
if (rules.nameTypes.has(node.type) && node.text === name) {
|
|
848
|
+
found = rules.isRead(node);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
for (const child of rules.childrenOf(node)) {
|
|
852
|
+
visit(child);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
for (const child of rules.childrenOf(scope)) {
|
|
856
|
+
visit(child);
|
|
857
|
+
}
|
|
858
|
+
return found;
|
|
859
|
+
}
|
|
860
|
+
function startsAtName(node, name, rules) {
|
|
861
|
+
if (rules.nameTypes.has(node.type)) {
|
|
862
|
+
return node.text === name;
|
|
863
|
+
}
|
|
864
|
+
const inner = rules.readFirst(node);
|
|
865
|
+
return inner !== null && startsAtName(inner, name, rules);
|
|
866
|
+
}
|
|
867
|
+
|
|
524
868
|
// src/nodeKey.ts
|
|
525
869
|
var SPAN_KEY = /^(.*):(\d+)-(\d+)$/;
|
|
526
870
|
function nodeOfKey(rootsByFile, key) {
|
|
@@ -548,10 +892,10 @@ function nodeOfKey(rootsByFile, key) {
|
|
|
548
892
|
}
|
|
549
893
|
|
|
550
894
|
// src/session.ts
|
|
551
|
-
var
|
|
895
|
+
var import_datalog3 = require("@suss/datalog");
|
|
552
896
|
function explainResolvedKey(options) {
|
|
553
897
|
const { db, rules, key, locate, displayPath } = options;
|
|
554
|
-
const proofDb = new
|
|
898
|
+
const proofDb = new import_datalog3.Database();
|
|
555
899
|
let baseFacts = 0;
|
|
556
900
|
for (const relation of db.relationNames()) {
|
|
557
901
|
for (const tuple of db.facts(relation)) {
|
|
@@ -560,7 +904,7 @@ function explainResolvedKey(options) {
|
|
|
560
904
|
}
|
|
561
905
|
}
|
|
562
906
|
const started = performance.now();
|
|
563
|
-
(0,
|
|
907
|
+
(0, import_datalog3.evaluate)(proofDb, rules, import_datalog3.witnesses);
|
|
564
908
|
const evaluateMs = performance.now() - started;
|
|
565
909
|
const derivedFacts = proofDb.relationNames().reduce((count, relation) => count + proofDb.size(relation), 0) - baseFacts;
|
|
566
910
|
const targets = new Set(
|
|
@@ -570,7 +914,7 @@ function explainResolvedKey(options) {
|
|
|
570
914
|
return null;
|
|
571
915
|
}
|
|
572
916
|
const target = [...targets][0];
|
|
573
|
-
const proof = (0,
|
|
917
|
+
const proof = (0, import_datalog3.proofOf)(
|
|
574
918
|
proofDb,
|
|
575
919
|
"resolves",
|
|
576
920
|
[key, target],
|
|
@@ -634,6 +978,35 @@ function withoutPlaceholders(answers, placeholders) {
|
|
|
634
978
|
return kept;
|
|
635
979
|
}
|
|
636
980
|
|
|
981
|
+
// src/writes.ts
|
|
982
|
+
function valueLeftByWrites(writes, ordered) {
|
|
983
|
+
const deciding = writes.filter((write) => !write.narrowsName);
|
|
984
|
+
const left = deciding.length === 0 ? writes : deciding;
|
|
985
|
+
if (left.some((write) => write.value === null)) {
|
|
986
|
+
return null;
|
|
987
|
+
}
|
|
988
|
+
if (ordered) {
|
|
989
|
+
return left[left.length - 1]?.value ?? null;
|
|
990
|
+
}
|
|
991
|
+
return sharedConstruction(left);
|
|
992
|
+
}
|
|
993
|
+
function sharedConstruction(writes) {
|
|
994
|
+
let settled = null;
|
|
995
|
+
for (const write of writes) {
|
|
996
|
+
if (write.placeholder) {
|
|
997
|
+
continue;
|
|
998
|
+
}
|
|
999
|
+
if (write.construction === null) {
|
|
1000
|
+
return null;
|
|
1001
|
+
}
|
|
1002
|
+
if (settled !== null && write.construction !== settled.construction) {
|
|
1003
|
+
return null;
|
|
1004
|
+
}
|
|
1005
|
+
settled = write;
|
|
1006
|
+
}
|
|
1007
|
+
return settled?.value ?? null;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
637
1010
|
// src/writtenValue.ts
|
|
638
1011
|
function writtenValueOf(db, key, ask) {
|
|
639
1012
|
const placeholders = placeholderValues(db);
|
|
@@ -655,336 +1028,387 @@ function writtenValueOf(db, key, ask) {
|
|
|
655
1028
|
}
|
|
656
1029
|
|
|
657
1030
|
// src/index.ts
|
|
658
|
-
var
|
|
659
|
-
var VALUE_STEP = (0,
|
|
1031
|
+
var import_datalog4 = require("@suss/datalog");
|
|
1032
|
+
var VALUE_STEP = (0, import_datalog4.constant)("value");
|
|
660
1033
|
var NAMESPACE_IMPORT_NAME = "*";
|
|
661
|
-
var NAMESPACE_IMPORT = (0,
|
|
662
|
-
var RESULT_STEP = (0,
|
|
1034
|
+
var NAMESPACE_IMPORT = (0, import_datalog4.constant)(NAMESPACE_IMPORT_NAME);
|
|
1035
|
+
var RESULT_STEP = (0, import_datalog4.constant)("result");
|
|
663
1036
|
var RESOLUTION_RULES = [
|
|
664
1037
|
// Aliasing: const x = y, or an identifier referencing a declaration.
|
|
665
1038
|
// A language with a hop of its own, like JavaScript's `.bind`, states
|
|
666
1039
|
// it as a step too, or every question but `comesTo` misses it.
|
|
667
|
-
(0,
|
|
1040
|
+
(0, import_datalog4.rule)(
|
|
668
1041
|
"stepsTo",
|
|
669
|
-
[(0,
|
|
670
|
-
[(0,
|
|
1042
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
|
|
1043
|
+
[(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
|
|
671
1044
|
"alias"
|
|
672
1045
|
),
|
|
673
1046
|
// A name written more than once has the value the last write left
|
|
674
1047
|
// there. The adapter works out which write that is and stays quiet
|
|
675
1048
|
// when control flow decides, so such a name steps nowhere at all.
|
|
676
|
-
(0,
|
|
1049
|
+
(0, import_datalog4.rule)(
|
|
677
1050
|
"stepsTo",
|
|
678
|
-
[(0,
|
|
679
|
-
[(0,
|
|
1051
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
|
|
1052
|
+
[(0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
|
|
680
1053
|
"last write"
|
|
681
1054
|
),
|
|
682
1055
|
// A fallback says the value is one of its branches, so each branch is
|
|
683
1056
|
// a step. A branch that resolves to nothing makes no claim, and two
|
|
684
1057
|
// branches resolving to different things fail the single-answer policy.
|
|
685
|
-
(0,
|
|
1058
|
+
(0, import_datalog4.rule)(
|
|
686
1059
|
"stepsTo",
|
|
687
|
-
[(0,
|
|
688
|
-
[(0,
|
|
1060
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"), VALUE_STEP],
|
|
1061
|
+
[(0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"))],
|
|
689
1062
|
"fallback"
|
|
690
1063
|
),
|
|
691
1064
|
// An import steps to what the module exports under that name.
|
|
692
|
-
(0,
|
|
1065
|
+
(0, import_datalog4.rule)(
|
|
693
1066
|
"stepsTo",
|
|
694
|
-
[(0,
|
|
1067
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("value"), VALUE_STEP],
|
|
695
1068
|
[
|
|
696
|
-
(0,
|
|
697
|
-
(0,
|
|
1069
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
1070
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value"))
|
|
698
1071
|
],
|
|
699
1072
|
"import"
|
|
700
1073
|
),
|
|
701
1074
|
// A parameter steps to what a call passes it. A function called from
|
|
702
1075
|
// several places leaves its parameter with more than one value, and a
|
|
703
1076
|
// caller that needs those apart asks `paramAt`.
|
|
704
|
-
(0,
|
|
1077
|
+
(0, import_datalog4.rule)(
|
|
705
1078
|
"stepsTo",
|
|
706
|
-
[(0,
|
|
707
|
-
[(0,
|
|
1079
|
+
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a"), VALUE_STEP],
|
|
1080
|
+
[(0, import_datalog4.lit)("passesArgument", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a"))],
|
|
708
1081
|
"argument"
|
|
709
1082
|
),
|
|
710
1083
|
// Reading a property steps to what the object contains under that
|
|
711
1084
|
// name, whichever way the object arrived: `routes.list` off a name,
|
|
712
1085
|
// or `make(body).handle` off a call.
|
|
713
|
-
(0,
|
|
1086
|
+
(0, import_datalog4.rule)(
|
|
714
1087
|
"stepsTo",
|
|
715
|
-
[(0,
|
|
1088
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("held"), VALUE_STEP],
|
|
716
1089
|
[
|
|
717
|
-
(0,
|
|
718
|
-
(0,
|
|
719
|
-
(0,
|
|
1090
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
1091
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("obj")),
|
|
1092
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
720
1093
|
],
|
|
721
1094
|
"property read"
|
|
722
1095
|
),
|
|
723
1096
|
// Calling a class makes one of it, so the call steps to the class and
|
|
724
1097
|
// a method read off the result is the one the class declares. The
|
|
725
1098
|
// caveat below is about a factory function, and a class is not one.
|
|
726
|
-
(0,
|
|
1099
|
+
(0, import_datalog4.rule)(
|
|
727
1100
|
"stepsTo",
|
|
728
|
-
[(0,
|
|
1101
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
|
|
729
1102
|
[
|
|
730
|
-
(0,
|
|
731
|
-
(0,
|
|
732
|
-
(0,
|
|
1103
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1104
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("cls")),
|
|
1105
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls"))
|
|
733
1106
|
],
|
|
734
1107
|
"class instance"
|
|
735
1108
|
),
|
|
1109
|
+
// A finder the library declares, keyed on the base a pack named so a
|
|
1110
|
+
// project class with a method of the same name on another hierarchy is
|
|
1111
|
+
// left alone. The DESIGN says what a chain of them composes into.
|
|
1112
|
+
(0, import_datalog4.rule)(
|
|
1113
|
+
"stepsTo",
|
|
1114
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
|
|
1115
|
+
[
|
|
1116
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1117
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
|
|
1118
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("cls")),
|
|
1119
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls")),
|
|
1120
|
+
// Before `libraryBase`, so the demand rewrite asks it with the base
|
|
1121
|
+
// bound and walks an ancestry only for a method a pack declared.
|
|
1122
|
+
(0, import_datalog4.lit)("givesBackOne", (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m")),
|
|
1123
|
+
(0, import_datalog4.lit)("libraryBase", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"))
|
|
1124
|
+
],
|
|
1125
|
+
"declared finder"
|
|
1126
|
+
),
|
|
1127
|
+
// The same word, for a library that takes the class as an argument
|
|
1128
|
+
// instead of as the receiver. The argument having to reach the base a
|
|
1129
|
+
// pack named is what keeps an unrelated `get` out.
|
|
1130
|
+
(0, import_datalog4.rule)(
|
|
1131
|
+
"stepsTo",
|
|
1132
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
|
|
1133
|
+
[
|
|
1134
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1135
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
|
|
1136
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a")),
|
|
1137
|
+
// Before `libraryBase`, so the demand rewrite asks it with the base
|
|
1138
|
+
// bound and walks an ancestry only for a method a pack declared.
|
|
1139
|
+
(0, import_datalog4.lit)("givesBackOneOfArgument", (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("k")),
|
|
1140
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("cls")),
|
|
1141
|
+
(0, import_datalog4.lit)("libraryBase", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"))
|
|
1142
|
+
],
|
|
1143
|
+
"declared argument finder"
|
|
1144
|
+
),
|
|
1145
|
+
// The same again for a function called on its own rather than read off
|
|
1146
|
+
// anything, keyed on the module it was imported from so a project
|
|
1147
|
+
// function spelled the same way is not mistaken for it.
|
|
1148
|
+
(0, import_datalog4.rule)(
|
|
1149
|
+
"stepsTo",
|
|
1150
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
|
|
1151
|
+
[
|
|
1152
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1153
|
+
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n")),
|
|
1154
|
+
(0, import_datalog4.lit)("givesBackOneOfImport", (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("k")),
|
|
1155
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a")),
|
|
1156
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("cls"))
|
|
1157
|
+
],
|
|
1158
|
+
"declared import finder"
|
|
1159
|
+
),
|
|
736
1160
|
// Wrapper transparency, derived: calling a factory that returns a
|
|
737
1161
|
// function which calls its parameter k steps to argument k.
|
|
738
|
-
(0,
|
|
1162
|
+
(0, import_datalog4.rule)(
|
|
739
1163
|
"stepsTo",
|
|
740
|
-
[(0,
|
|
1164
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
|
|
741
1165
|
[
|
|
742
|
-
(0,
|
|
743
|
-
(0,
|
|
744
|
-
(0,
|
|
745
|
-
(0,
|
|
1166
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1167
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f")),
|
|
1168
|
+
(0, import_datalog4.lit)("unwraps", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k")),
|
|
1169
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a"))
|
|
746
1170
|
],
|
|
747
1171
|
"factory unwrap"
|
|
748
1172
|
),
|
|
749
1173
|
// Wrapper transparency, declared: a pack says this callee wraps
|
|
750
1174
|
// argument k. The callee has to come from the library the pack said,
|
|
751
1175
|
// so a local object spelled the same way is not mistaken for it.
|
|
752
|
-
(0,
|
|
1176
|
+
(0, import_datalog4.rule)(
|
|
753
1177
|
"stepsTo",
|
|
754
|
-
[(0,
|
|
1178
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
|
|
755
1179
|
[
|
|
756
|
-
(0,
|
|
757
|
-
(0,
|
|
758
|
-
(0,
|
|
759
|
-
(0,
|
|
760
|
-
(0,
|
|
1180
|
+
(0, import_datalog4.lit)("calleeName", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n")),
|
|
1181
|
+
(0, import_datalog4.lit)("unwrapsByName", (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("k")),
|
|
1182
|
+
(0, import_datalog4.lit)("wrapperModule", (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m")),
|
|
1183
|
+
(0, import_datalog4.lit)("calleeOrigin", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("m")),
|
|
1184
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a"))
|
|
761
1185
|
],
|
|
762
1186
|
"declared wrapper"
|
|
763
1187
|
),
|
|
764
1188
|
// The one step that runs a function forwards: a call steps to what
|
|
765
1189
|
// the function it invokes returns.
|
|
766
|
-
(0,
|
|
1190
|
+
(0, import_datalog4.rule)(
|
|
767
1191
|
"stepsTo",
|
|
768
|
-
[(0,
|
|
769
|
-
[(0,
|
|
1192
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("ret"), RESULT_STEP],
|
|
1193
|
+
[(0, import_datalog4.lit)("invokes", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("ret"))],
|
|
770
1194
|
"call result"
|
|
771
1195
|
),
|
|
772
1196
|
// Where a walk gets to, and whether it ran a call on the way. The walk
|
|
773
1197
|
// so far comes first, so demand stays on the value asked about; the
|
|
774
1198
|
// README says what the other order cost.
|
|
775
|
-
(0,
|
|
1199
|
+
(0, import_datalog4.rule)(
|
|
776
1200
|
"reaches",
|
|
777
|
-
[(0,
|
|
778
|
-
[(0,
|
|
1201
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind")],
|
|
1202
|
+
[(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))]
|
|
779
1203
|
),
|
|
780
|
-
(0,
|
|
1204
|
+
(0, import_datalog4.rule)(
|
|
781
1205
|
"reaches",
|
|
782
|
-
[(0,
|
|
1206
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind")],
|
|
783
1207
|
[
|
|
784
|
-
(0,
|
|
785
|
-
(0,
|
|
1208
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP),
|
|
1209
|
+
(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))
|
|
786
1210
|
]
|
|
787
1211
|
),
|
|
788
1212
|
// Two rules rather than one leaving the next step's kind free. A free
|
|
789
1213
|
// kind is a second question about the same relation, and a
|
|
790
1214
|
// demand-driven run then derives both to answer either.
|
|
791
|
-
(0,
|
|
1215
|
+
(0, import_datalog4.rule)(
|
|
792
1216
|
"reaches",
|
|
793
|
-
[(0,
|
|
1217
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP],
|
|
794
1218
|
[
|
|
795
|
-
(0,
|
|
796
|
-
(0,
|
|
1219
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), RESULT_STEP),
|
|
1220
|
+
(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), VALUE_STEP)
|
|
797
1221
|
]
|
|
798
1222
|
),
|
|
799
|
-
(0,
|
|
1223
|
+
(0, import_datalog4.rule)(
|
|
800
1224
|
"reaches",
|
|
801
|
-
[(0,
|
|
1225
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP],
|
|
802
1226
|
[
|
|
803
|
-
(0,
|
|
804
|
-
(0,
|
|
1227
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), RESULT_STEP),
|
|
1228
|
+
(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), RESULT_STEP)
|
|
805
1229
|
]
|
|
806
1230
|
),
|
|
807
1231
|
// What a value comes down to: the walk that never ran a call, stopped
|
|
808
1232
|
// at a function or an object. Something already written out comes to
|
|
809
1233
|
// itself, and every other walk ends at one of those.
|
|
810
|
-
(0,
|
|
811
|
-
(0,
|
|
812
|
-
(0,
|
|
1234
|
+
(0, import_datalog4.rule)("comesTo", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("func", (0, import_datalog4.variable)("x"))]),
|
|
1235
|
+
(0, import_datalog4.rule)("comesTo", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]),
|
|
1236
|
+
(0, import_datalog4.rule)(
|
|
813
1237
|
"comesTo",
|
|
814
|
-
[(0,
|
|
815
|
-
[(0,
|
|
1238
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1239
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), VALUE_STEP), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
|
|
816
1240
|
),
|
|
817
|
-
(0,
|
|
1241
|
+
(0, import_datalog4.rule)(
|
|
818
1242
|
"comesTo",
|
|
819
|
-
[(0,
|
|
820
|
-
[(0,
|
|
1243
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1244
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), VALUE_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
|
|
821
1245
|
),
|
|
822
1246
|
// The same stopping condition, for the walk that ran a call. A call
|
|
823
1247
|
// gets no `comesTo` answer on purpose: coming back with what a
|
|
824
1248
|
// factory returned would fight the unwrapping answer.
|
|
825
|
-
(0,
|
|
1249
|
+
(0, import_datalog4.rule)(
|
|
826
1250
|
"givesBack",
|
|
827
|
-
[(0,
|
|
828
|
-
[(0,
|
|
1251
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1252
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
|
|
829
1253
|
),
|
|
830
|
-
(0,
|
|
1254
|
+
(0, import_datalog4.rule)(
|
|
831
1255
|
"givesBack",
|
|
832
|
-
[(0,
|
|
833
|
-
[(0,
|
|
1256
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1257
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
|
|
834
1258
|
),
|
|
835
1259
|
// Following a value to the expression it is written as, whatever kind
|
|
836
1260
|
// that is. A GraphQL document is neither a function nor an object, so
|
|
837
1261
|
// `comesTo` never reaches one.
|
|
838
|
-
(0,
|
|
839
|
-
(0,
|
|
840
|
-
(0,
|
|
1262
|
+
(0, import_datalog4.rule)("isWrittenAs", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("x"))]),
|
|
1263
|
+
(0, import_datalog4.rule)("isWrittenAs", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]),
|
|
1264
|
+
(0, import_datalog4.rule)(
|
|
841
1265
|
"isWrittenAs",
|
|
842
|
-
[(0,
|
|
843
|
-
[(0,
|
|
1266
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1267
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), VALUE_STEP), (0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("z"))]
|
|
844
1268
|
),
|
|
845
|
-
(0,
|
|
1269
|
+
(0, import_datalog4.rule)(
|
|
846
1270
|
"isWrittenAs",
|
|
847
|
-
[(0,
|
|
848
|
-
[(0,
|
|
1271
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1272
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), VALUE_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
|
|
849
1273
|
),
|
|
850
1274
|
// A call is written as whatever its callee's return value is written
|
|
851
1275
|
// as. Unlike `comesTo`, this has nothing to protect: which expression
|
|
852
1276
|
// a value was written as does not compete with unwrapping it.
|
|
853
|
-
(0,
|
|
1277
|
+
(0, import_datalog4.rule)(
|
|
854
1278
|
"isWrittenAs",
|
|
855
|
-
[(0,
|
|
1279
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
856
1280
|
[
|
|
857
|
-
(0,
|
|
858
|
-
(0,
|
|
859
|
-
(0,
|
|
1281
|
+
(0, import_datalog4.lit)("invokes", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("f")),
|
|
1282
|
+
(0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("ret")),
|
|
1283
|
+
(0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("ret"), (0, import_datalog4.variable)("z"))
|
|
860
1284
|
]
|
|
861
1285
|
),
|
|
862
1286
|
// What one call site put in a parameter, told apart from what the
|
|
863
1287
|
// other callers passed.
|
|
864
|
-
(0,
|
|
1288
|
+
(0, import_datalog4.rule)(
|
|
865
1289
|
"paramAt",
|
|
866
|
-
[(0,
|
|
1290
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("z")],
|
|
867
1291
|
[
|
|
868
|
-
(0,
|
|
869
|
-
(0,
|
|
1292
|
+
(0, import_datalog4.lit)("passesArgument", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a")),
|
|
1293
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("z"))
|
|
870
1294
|
]
|
|
871
1295
|
),
|
|
872
1296
|
// An argument arriving at the parameter it is passed to, by position
|
|
873
1297
|
// or by the name the caller wrote, keeping the call it went through
|
|
874
1298
|
// so `paramAt` can tell two call sites apart.
|
|
875
|
-
(0,
|
|
1299
|
+
(0, import_datalog4.rule)(
|
|
876
1300
|
"passesArgument",
|
|
877
|
-
[(0,
|
|
1301
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a")],
|
|
878
1302
|
[
|
|
879
|
-
(0,
|
|
880
|
-
(0,
|
|
881
|
-
(0,
|
|
1303
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("p")),
|
|
1304
|
+
(0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
|
|
1305
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a"))
|
|
882
1306
|
]
|
|
883
1307
|
),
|
|
884
|
-
(0,
|
|
1308
|
+
(0, import_datalog4.rule)(
|
|
885
1309
|
"passesArgument",
|
|
886
|
-
[(0,
|
|
1310
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a")],
|
|
887
1311
|
[
|
|
888
|
-
(0,
|
|
889
|
-
(0,
|
|
890
|
-
(0,
|
|
1312
|
+
(0, import_datalog4.lit)("paramNamed", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")),
|
|
1313
|
+
(0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
|
|
1314
|
+
(0, import_datalog4.lit)("callKeywordArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("a"))
|
|
891
1315
|
]
|
|
892
1316
|
),
|
|
893
1317
|
// Which module's export a re-exported name forwards to, however
|
|
894
1318
|
// many barrels deep the forwarding runs.
|
|
895
|
-
(0,
|
|
1319
|
+
(0, import_datalog4.rule)(
|
|
896
1320
|
"moduleForwards",
|
|
897
|
-
[(0,
|
|
898
|
-
[(0,
|
|
1321
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2")],
|
|
1322
|
+
[(0, import_datalog4.lit)("reExports", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2"))]
|
|
899
1323
|
),
|
|
900
|
-
(0,
|
|
1324
|
+
(0, import_datalog4.rule)(
|
|
901
1325
|
"moduleForwards",
|
|
902
|
-
[(0,
|
|
1326
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m3"), (0, import_datalog4.variable)("n3")],
|
|
903
1327
|
[
|
|
904
|
-
(0,
|
|
905
|
-
(0,
|
|
1328
|
+
(0, import_datalog4.lit)("reExports", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2")),
|
|
1329
|
+
(0, import_datalog4.lit)("moduleForwards", (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2"), (0, import_datalog4.variable)("m3"), (0, import_datalog4.variable)("n3"))
|
|
906
1330
|
]
|
|
907
1331
|
),
|
|
908
1332
|
// What a module exports: directly, or through re-export chains.
|
|
909
|
-
(0,
|
|
1333
|
+
(0, import_datalog4.rule)(
|
|
910
1334
|
"moduleExport",
|
|
911
|
-
[(0,
|
|
912
|
-
[(0,
|
|
1335
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value")],
|
|
1336
|
+
[(0, import_datalog4.lit)("exportsAs", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value"))],
|
|
913
1337
|
"export"
|
|
914
1338
|
),
|
|
915
|
-
(0,
|
|
1339
|
+
(0, import_datalog4.rule)(
|
|
916
1340
|
"moduleExport",
|
|
917
|
-
[(0,
|
|
1341
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value")],
|
|
918
1342
|
[
|
|
919
|
-
(0,
|
|
920
|
-
(0,
|
|
1343
|
+
(0, import_datalog4.lit)("reExports", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2")),
|
|
1344
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2"), (0, import_datalog4.variable)("value"))
|
|
921
1345
|
],
|
|
922
1346
|
"re-export"
|
|
923
1347
|
),
|
|
924
|
-
(0,
|
|
1348
|
+
(0, import_datalog4.rule)(
|
|
925
1349
|
"moduleExport",
|
|
926
|
-
[(0,
|
|
1350
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value")],
|
|
927
1351
|
[
|
|
928
|
-
(0,
|
|
929
|
-
(0,
|
|
1352
|
+
(0, import_datalog4.lit)("reExportsAll", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("m2")),
|
|
1353
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value"))
|
|
930
1354
|
],
|
|
931
1355
|
"re-export all"
|
|
932
1356
|
),
|
|
933
1357
|
// The function a call runs, written from the call's side because a
|
|
934
1358
|
// caller asking what a call gives back has the call in hand.
|
|
935
|
-
(0,
|
|
1359
|
+
(0, import_datalog4.rule)(
|
|
936
1360
|
"invokes",
|
|
937
|
-
[(0,
|
|
938
|
-
[(0,
|
|
1361
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1362
|
+
[(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f"))]
|
|
939
1363
|
),
|
|
940
1364
|
// The callee is itself a call: `daoBuilder()()`.
|
|
941
|
-
(0,
|
|
1365
|
+
(0, import_datalog4.rule)(
|
|
942
1366
|
"invokes",
|
|
943
|
-
[(0,
|
|
944
|
-
[(0,
|
|
1367
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1368
|
+
[(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("givesBack", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f"))]
|
|
945
1369
|
),
|
|
946
1370
|
// The object an expression refers to: a name through `comesTo`, a
|
|
947
1371
|
// factory call through what it gives back. Naming the step is what
|
|
948
1372
|
// makes `routes.list` and `make(body).handle` one rule.
|
|
949
|
-
(0,
|
|
1373
|
+
(0, import_datalog4.rule)(
|
|
950
1374
|
"objectOf",
|
|
951
|
-
[(0,
|
|
952
|
-
[(0,
|
|
1375
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("obj")],
|
|
1376
|
+
[(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("obj")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))]
|
|
953
1377
|
),
|
|
954
|
-
(0,
|
|
1378
|
+
(0, import_datalog4.rule)(
|
|
955
1379
|
"objectOf",
|
|
956
|
-
[(0,
|
|
957
|
-
[(0,
|
|
1380
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
|
|
1381
|
+
[(0, import_datalog4.lit)("givesBack", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))]
|
|
958
1382
|
),
|
|
959
1383
|
// Which calls a function, found by the name the call is written as
|
|
960
1384
|
// rather than by resolving every callee in the project. A caller knows
|
|
961
1385
|
// the function and wants its call sites, so both of these start from
|
|
962
1386
|
// the function. Starting from `call` instead asks what every call in
|
|
963
1387
|
// the project imports, which was 72% of everything derived.
|
|
964
|
-
(0,
|
|
1388
|
+
(0, import_datalog4.rule)(
|
|
965
1389
|
"callsFunction",
|
|
966
|
-
[(0,
|
|
967
|
-
[(0,
|
|
1390
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1391
|
+
[(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
|
|
968
1392
|
),
|
|
969
|
-
(0,
|
|
1393
|
+
(0, import_datalog4.rule)(
|
|
970
1394
|
"callsFunction",
|
|
971
|
-
[(0,
|
|
1395
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
972
1396
|
[
|
|
973
|
-
(0,
|
|
974
|
-
(0,
|
|
975
|
-
(0,
|
|
1397
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
|
|
1398
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
1399
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
|
|
976
1400
|
]
|
|
977
1401
|
),
|
|
978
1402
|
// The same, for a language whose adapter writes the import down as a
|
|
979
1403
|
// declaration and the call's callee as the name referring to it.
|
|
980
|
-
(0,
|
|
1404
|
+
(0, import_datalog4.rule)(
|
|
981
1405
|
"callsFunction",
|
|
982
|
-
[(0,
|
|
1406
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
983
1407
|
[
|
|
984
|
-
(0,
|
|
985
|
-
(0,
|
|
986
|
-
(0,
|
|
987
|
-
(0,
|
|
1408
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
|
|
1409
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("d"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
1410
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("d")),
|
|
1411
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
|
|
988
1412
|
]
|
|
989
1413
|
),
|
|
990
1414
|
// What an object contains, its base class included, so a method the base
|
|
@@ -992,47 +1416,73 @@ var RESOLUTION_RULES = [
|
|
|
992
1416
|
// declare gives two, and the caller decides. This is its own relation
|
|
993
1417
|
// rather than more `holdsProperty`, which stays something an adapter
|
|
994
1418
|
// states and the rules only read.
|
|
995
|
-
(0,
|
|
1419
|
+
(0, import_datalog4.rule)(
|
|
996
1420
|
"contains",
|
|
997
|
-
[(0,
|
|
998
|
-
[(0,
|
|
1421
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
1422
|
+
[(0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))]
|
|
999
1423
|
),
|
|
1000
|
-
(0,
|
|
1424
|
+
(0, import_datalog4.rule)(
|
|
1001
1425
|
"contains",
|
|
1002
|
-
[(0,
|
|
1426
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
1003
1427
|
[
|
|
1004
|
-
(0,
|
|
1005
|
-
(0,
|
|
1006
|
-
(0,
|
|
1428
|
+
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("base")),
|
|
1429
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("base"), (0, import_datalog4.variable)("baseCls")),
|
|
1430
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("baseCls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1431
|
+
]
|
|
1432
|
+
),
|
|
1433
|
+
// The library base a class's ancestry arrives at, however many of a
|
|
1434
|
+
// project's own classes sit in between. A base the run declares has a
|
|
1435
|
+
// node to keep walking from; one it does not has only a name.
|
|
1436
|
+
(0, import_datalog4.rule)("libraryBase", [(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n")], [(0, import_datalog4.lit)("extendsNamed", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n"))]),
|
|
1437
|
+
(0, import_datalog4.rule)(
|
|
1438
|
+
"libraryBase",
|
|
1439
|
+
[(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n")],
|
|
1440
|
+
[
|
|
1441
|
+
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")),
|
|
1442
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b")),
|
|
1443
|
+
(0, import_datalog4.lit)("libraryBase", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("n"))
|
|
1444
|
+
]
|
|
1445
|
+
),
|
|
1446
|
+
// A base a library hands back from a call rather than exporting as a
|
|
1447
|
+
// class, SQLAlchemy's `Base = declarative_base()`. The walk stops at
|
|
1448
|
+
// the call, so the function it called is the name to match on.
|
|
1449
|
+
(0, import_datalog4.rule)(
|
|
1450
|
+
"libraryBase",
|
|
1451
|
+
[(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n")],
|
|
1452
|
+
[
|
|
1453
|
+
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")),
|
|
1454
|
+
(0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")),
|
|
1455
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cc")),
|
|
1456
|
+
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("cc"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1007
1457
|
]
|
|
1008
1458
|
),
|
|
1009
1459
|
// Which function a factory returns, and which of its parameters that
|
|
1010
1460
|
// function calls: together they are what makes it a wrapper.
|
|
1011
|
-
(0,
|
|
1461
|
+
(0, import_datalog4.rule)(
|
|
1012
1462
|
"returnsFunc",
|
|
1013
|
-
[(0,
|
|
1463
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("g")],
|
|
1014
1464
|
[
|
|
1015
|
-
(0,
|
|
1016
|
-
(0,
|
|
1017
|
-
(0,
|
|
1465
|
+
(0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("value")),
|
|
1466
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("value"), (0, import_datalog4.variable)("g")),
|
|
1467
|
+
(0, import_datalog4.lit)("func", (0, import_datalog4.variable)("g"))
|
|
1018
1468
|
]
|
|
1019
1469
|
),
|
|
1020
1470
|
// A call made by a nested closure counts as made by the function
|
|
1021
1471
|
// that declares it; the closure runs as part of that function.
|
|
1022
|
-
(0,
|
|
1023
|
-
(0,
|
|
1472
|
+
(0, import_datalog4.rule)("bodyCallsDeep", [(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")], [(0, import_datalog4.lit)("bodyCalls", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"))]),
|
|
1473
|
+
(0, import_datalog4.rule)(
|
|
1024
1474
|
"bodyCallsDeep",
|
|
1025
|
-
[(0,
|
|
1026
|
-
[(0,
|
|
1475
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")],
|
|
1476
|
+
[(0, import_datalog4.lit)("containsFn", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("g")), (0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("c"))]
|
|
1027
1477
|
),
|
|
1028
|
-
(0,
|
|
1478
|
+
(0, import_datalog4.rule)(
|
|
1029
1479
|
"unwraps",
|
|
1030
|
-
[(0,
|
|
1480
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k")],
|
|
1031
1481
|
[
|
|
1032
|
-
(0,
|
|
1033
|
-
(0,
|
|
1034
|
-
(0,
|
|
1035
|
-
(0,
|
|
1482
|
+
(0, import_datalog4.lit)("returnsFunc", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("g")),
|
|
1483
|
+
(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("c")),
|
|
1484
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p")),
|
|
1485
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("p"))
|
|
1036
1486
|
]
|
|
1037
1487
|
),
|
|
1038
1488
|
// Argument flow: which parameter a value traces back to. Directly
|
|
@@ -1040,297 +1490,297 @@ var RESOLUTION_RULES = [
|
|
|
1040
1490
|
// another unwrapping factory. This is what lets
|
|
1041
1491
|
// `createProtected(h) { return service.withAuth(h); }` unwrap:
|
|
1042
1492
|
// the returned call passes h through withAuth, which unwraps.
|
|
1043
|
-
(0,
|
|
1493
|
+
(0, import_datalog4.rule)(
|
|
1044
1494
|
"flowsToParam",
|
|
1045
|
-
[(0,
|
|
1495
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("p")],
|
|
1046
1496
|
[
|
|
1047
|
-
(0,
|
|
1048
|
-
(0,
|
|
1497
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("p")),
|
|
1498
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("anyF"), (0, import_datalog4.variable)("anyK"), (0, import_datalog4.variable)("p"))
|
|
1049
1499
|
]
|
|
1050
1500
|
),
|
|
1051
|
-
(0,
|
|
1501
|
+
(0, import_datalog4.rule)(
|
|
1052
1502
|
"flowsToParam",
|
|
1053
|
-
[(0,
|
|
1503
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p")],
|
|
1054
1504
|
[
|
|
1055
|
-
(0,
|
|
1056
|
-
(0,
|
|
1057
|
-
(0,
|
|
1058
|
-
(0,
|
|
1059
|
-
(0,
|
|
1505
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1506
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f")),
|
|
1507
|
+
(0, import_datalog4.lit)("unwraps", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k")),
|
|
1508
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("a")),
|
|
1509
|
+
(0, import_datalog4.lit)("flowsToParam", (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("p"))
|
|
1060
1510
|
]
|
|
1061
1511
|
),
|
|
1062
|
-
(0,
|
|
1512
|
+
(0, import_datalog4.rule)(
|
|
1063
1513
|
"unwraps",
|
|
1064
|
-
[(0,
|
|
1514
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k")],
|
|
1065
1515
|
[
|
|
1066
|
-
(0,
|
|
1067
|
-
(0,
|
|
1068
|
-
(0,
|
|
1516
|
+
(0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("value")),
|
|
1517
|
+
(0, import_datalog4.lit)("flowsToParam", (0, import_datalog4.variable)("value"), (0, import_datalog4.variable)("p")),
|
|
1518
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("k"), (0, import_datalog4.variable)("p"))
|
|
1069
1519
|
]
|
|
1070
1520
|
),
|
|
1071
1521
|
// Where a name comes from, when what it refers to lives outside the
|
|
1072
1522
|
// source being read. A walk ends at something written out in source,
|
|
1073
1523
|
// so it never reaches a library's own function.
|
|
1074
|
-
(0,
|
|
1524
|
+
(0, import_datalog4.rule)(
|
|
1075
1525
|
"comesFrom",
|
|
1076
|
-
[(0,
|
|
1077
|
-
[(0,
|
|
1526
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1527
|
+
[(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))]
|
|
1078
1528
|
),
|
|
1079
|
-
(0,
|
|
1529
|
+
(0, import_datalog4.rule)(
|
|
1080
1530
|
"comesFrom",
|
|
1081
|
-
[(0,
|
|
1531
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1082
1532
|
[
|
|
1083
|
-
(0,
|
|
1084
|
-
(0,
|
|
1533
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP),
|
|
1534
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1085
1535
|
]
|
|
1086
1536
|
),
|
|
1087
1537
|
// Calling f ends up calling the name n that module m exports, one
|
|
1088
1538
|
// hop through f's own body or deeper through a wrapper of a wrapper.
|
|
1089
1539
|
// Several results is normal: a composed decorator applies them all.
|
|
1090
|
-
(0,
|
|
1540
|
+
(0, import_datalog4.rule)(
|
|
1091
1541
|
"callsInto",
|
|
1092
|
-
[(0,
|
|
1542
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1093
1543
|
[
|
|
1094
|
-
(0,
|
|
1095
|
-
(0,
|
|
1544
|
+
(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")),
|
|
1545
|
+
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1096
1546
|
]
|
|
1097
1547
|
),
|
|
1098
|
-
(0,
|
|
1548
|
+
(0, import_datalog4.rule)(
|
|
1099
1549
|
"callsInto",
|
|
1100
|
-
[(0,
|
|
1550
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1101
1551
|
[
|
|
1102
|
-
(0,
|
|
1103
|
-
(0,
|
|
1104
|
-
(0,
|
|
1552
|
+
(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")),
|
|
1553
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("g")),
|
|
1554
|
+
(0, import_datalog4.lit)("callsInto", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1105
1555
|
]
|
|
1106
1556
|
),
|
|
1107
1557
|
// The question callers ask: what a value comes to, narrowed to the
|
|
1108
1558
|
// functions. Objects appear in the middle of chains and never in an
|
|
1109
1559
|
// answer.
|
|
1110
|
-
(0,
|
|
1560
|
+
(0, import_datalog4.rule)(
|
|
1111
1561
|
"resolves",
|
|
1112
|
-
[(0,
|
|
1113
|
-
[(0,
|
|
1562
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1563
|
+
[(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
|
|
1114
1564
|
)
|
|
1115
1565
|
];
|
|
1116
1566
|
var RESOLUTION_QUESTIONS = [
|
|
1117
|
-
(0,
|
|
1567
|
+
(0, import_datalog4.rule)(
|
|
1118
1568
|
"wantedResolves",
|
|
1119
|
-
[(0,
|
|
1120
|
-
[(0,
|
|
1569
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1570
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("resolves", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1121
1571
|
),
|
|
1122
|
-
(0,
|
|
1572
|
+
(0, import_datalog4.rule)(
|
|
1123
1573
|
"wantedComesTo",
|
|
1124
|
-
[(0,
|
|
1125
|
-
[(0,
|
|
1574
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1575
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1126
1576
|
),
|
|
1127
|
-
(0,
|
|
1577
|
+
(0, import_datalog4.rule)(
|
|
1128
1578
|
"wantedComesTo",
|
|
1129
|
-
[(0,
|
|
1130
|
-
[(0,
|
|
1579
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1580
|
+
[(0, import_datalog4.lit)("wantedOrigin", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1131
1581
|
),
|
|
1132
|
-
(0,
|
|
1582
|
+
(0, import_datalog4.rule)(
|
|
1133
1583
|
"wantedIsWrittenAs",
|
|
1134
|
-
[(0,
|
|
1135
|
-
[(0,
|
|
1584
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1585
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1136
1586
|
),
|
|
1137
1587
|
// A call is given no `comesTo`, so this is the only way to ask what
|
|
1138
1588
|
// object one arrives at, and without it a demand-driven run derives
|
|
1139
1589
|
// `objectOf` nowhere.
|
|
1140
|
-
(0,
|
|
1590
|
+
(0, import_datalog4.rule)(
|
|
1141
1591
|
"wantedObjectOf",
|
|
1142
|
-
[(0,
|
|
1143
|
-
[(0,
|
|
1592
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1593
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1144
1594
|
),
|
|
1145
1595
|
// The same for the function a call returns: `app.use(requireCaller(config))`
|
|
1146
1596
|
// registers what the factory gives back, and `resolves` on the call
|
|
1147
1597
|
// says nothing unless the factory unwraps an argument.
|
|
1148
|
-
(0,
|
|
1598
|
+
(0, import_datalog4.rule)(
|
|
1149
1599
|
"wantedGivesBack",
|
|
1150
|
-
[(0,
|
|
1151
|
-
[(0,
|
|
1600
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1601
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("givesBack", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1152
1602
|
),
|
|
1153
1603
|
// Keyed by the parameter, since that is what a caller has in hand
|
|
1154
1604
|
// when it wants the call sites told apart.
|
|
1155
|
-
(0,
|
|
1605
|
+
(0, import_datalog4.rule)(
|
|
1156
1606
|
"wantedParamAt",
|
|
1157
|
-
[(0,
|
|
1158
|
-
[(0,
|
|
1607
|
+
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("z")],
|
|
1608
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("p")), (0, import_datalog4.lit)("paramAt", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("z"))]
|
|
1159
1609
|
),
|
|
1160
|
-
(0,
|
|
1610
|
+
(0, import_datalog4.rule)(
|
|
1161
1611
|
"wantedComesFrom",
|
|
1162
|
-
[(0,
|
|
1163
|
-
[(0,
|
|
1612
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1613
|
+
[(0, import_datalog4.lit)("wantedOrigin", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))]
|
|
1164
1614
|
),
|
|
1165
1615
|
// Call-origin questions, for attribution, in their own demand
|
|
1166
1616
|
// class. Attribution stops at the import declaration, so nothing
|
|
1167
1617
|
// here demands reaches or callsInto. The chains are closures with
|
|
1168
1618
|
// no depth bound: an alias run of any length resolves.
|
|
1169
|
-
(0,
|
|
1619
|
+
(0, import_datalog4.rule)("callOriginChain", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("wantedCallOrigin", (0, import_datalog4.variable)("x"))]),
|
|
1170
1620
|
// The chain with at least one hop taken, which is what tells a
|
|
1171
1621
|
// destructured binding apart from asking about a node directly. The
|
|
1172
1622
|
// whole chain is the seed plus those hops.
|
|
1173
|
-
(0,
|
|
1623
|
+
(0, import_datalog4.rule)(
|
|
1174
1624
|
"callOriginChain",
|
|
1175
|
-
[(0,
|
|
1176
|
-
[(0,
|
|
1625
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1626
|
+
[(0, import_datalog4.lit)("callOriginChainStepped", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
|
|
1177
1627
|
),
|
|
1178
|
-
(0,
|
|
1628
|
+
(0, import_datalog4.rule)(
|
|
1179
1629
|
"callOriginChainStepped",
|
|
1180
|
-
[(0,
|
|
1181
|
-
[(0,
|
|
1630
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1631
|
+
[(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1182
1632
|
),
|
|
1183
|
-
(0,
|
|
1633
|
+
(0, import_datalog4.rule)(
|
|
1184
1634
|
"callOriginChainStepped",
|
|
1185
|
-
[(0,
|
|
1635
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1186
1636
|
[
|
|
1187
|
-
(0,
|
|
1188
|
-
(0,
|
|
1637
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1638
|
+
(0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))
|
|
1189
1639
|
]
|
|
1190
1640
|
),
|
|
1191
|
-
(0,
|
|
1641
|
+
(0, import_datalog4.rule)(
|
|
1192
1642
|
"callOriginChainStepped",
|
|
1193
|
-
[(0,
|
|
1643
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1194
1644
|
[
|
|
1195
|
-
(0,
|
|
1196
|
-
(0,
|
|
1645
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1646
|
+
(0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))
|
|
1197
1647
|
]
|
|
1198
1648
|
),
|
|
1199
|
-
(0,
|
|
1649
|
+
(0, import_datalog4.rule)(
|
|
1200
1650
|
"wantedCallOriginPair",
|
|
1201
|
-
[(0,
|
|
1651
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1202
1652
|
[
|
|
1203
|
-
(0,
|
|
1204
|
-
(0,
|
|
1653
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1654
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1205
1655
|
]
|
|
1206
1656
|
),
|
|
1207
1657
|
// An import of a project barrel is an import of what the barrel
|
|
1208
1658
|
// forwards, so the pair surfaces the module behind the chain.
|
|
1209
|
-
(0,
|
|
1659
|
+
(0, import_datalog4.rule)(
|
|
1210
1660
|
"wantedCallOriginPair",
|
|
1211
|
-
[(0,
|
|
1661
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2")],
|
|
1212
1662
|
[
|
|
1213
|
-
(0,
|
|
1214
|
-
(0,
|
|
1215
|
-
(0,
|
|
1663
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1664
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
1665
|
+
(0, import_datalog4.lit)("moduleForwards", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("m2"), (0, import_datalog4.variable)("n2"))
|
|
1216
1666
|
]
|
|
1217
1667
|
),
|
|
1218
1668
|
// A namespace member: the module's export of the member's own name.
|
|
1219
1669
|
// The imports literal leads, since it is the smallest relation.
|
|
1220
|
-
(0,
|
|
1670
|
+
(0, import_datalog4.rule)(
|
|
1221
1671
|
"wantedCallOriginPair",
|
|
1222
|
-
[(0,
|
|
1672
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("p")],
|
|
1223
1673
|
[
|
|
1224
|
-
(0,
|
|
1225
|
-
(0,
|
|
1226
|
-
(0,
|
|
1674
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT),
|
|
1675
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("p")),
|
|
1676
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))
|
|
1227
1677
|
]
|
|
1228
1678
|
),
|
|
1229
|
-
(0,
|
|
1679
|
+
(0, import_datalog4.rule)(
|
|
1230
1680
|
"wantedCallOriginPair",
|
|
1231
|
-
[(0,
|
|
1681
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("p")],
|
|
1232
1682
|
[
|
|
1233
|
-
(0,
|
|
1234
|
-
(0,
|
|
1235
|
-
(0,
|
|
1236
|
-
(0,
|
|
1683
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("d"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT),
|
|
1684
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("d")),
|
|
1685
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("p")),
|
|
1686
|
+
(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))
|
|
1237
1687
|
]
|
|
1238
1688
|
),
|
|
1239
1689
|
// What a call made: through the call to its callee, whose own alias
|
|
1240
1690
|
// chain leads to the import.
|
|
1241
|
-
(0,
|
|
1691
|
+
(0, import_datalog4.rule)(
|
|
1242
1692
|
"callMadeChain",
|
|
1243
|
-
[(0,
|
|
1244
|
-
[(0,
|
|
1693
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("f")],
|
|
1694
|
+
[(0, import_datalog4.lit)("callOriginChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f"))]
|
|
1245
1695
|
),
|
|
1246
|
-
(0,
|
|
1696
|
+
(0, import_datalog4.rule)(
|
|
1247
1697
|
"callMadeChain",
|
|
1248
|
-
[(0,
|
|
1249
|
-
[(0,
|
|
1698
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1699
|
+
[(0, import_datalog4.lit)("callMadeChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1250
1700
|
),
|
|
1251
|
-
(0,
|
|
1701
|
+
(0, import_datalog4.rule)(
|
|
1252
1702
|
"callMadeChain",
|
|
1253
|
-
[(0,
|
|
1254
|
-
[(0,
|
|
1703
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1704
|
+
[(0, import_datalog4.lit)("callMadeChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1255
1705
|
),
|
|
1256
|
-
(0,
|
|
1706
|
+
(0, import_datalog4.rule)(
|
|
1257
1707
|
"wantedCallOriginPair",
|
|
1258
|
-
[(0,
|
|
1708
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1259
1709
|
[
|
|
1260
|
-
(0,
|
|
1261
|
-
(0,
|
|
1710
|
+
(0, import_datalog4.lit)("callMadeChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1711
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1262
1712
|
]
|
|
1263
1713
|
),
|
|
1264
1714
|
// A member destructured off what a call made keeps the member name
|
|
1265
1715
|
// as one more path segment.
|
|
1266
|
-
(0,
|
|
1716
|
+
(0, import_datalog4.rule)(
|
|
1267
1717
|
"callMemberChain",
|
|
1268
|
-
[(0,
|
|
1718
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("p")],
|
|
1269
1719
|
[
|
|
1270
|
-
(0,
|
|
1271
|
-
(0,
|
|
1272
|
-
(0,
|
|
1720
|
+
(0, import_datalog4.lit)("callOriginChainStepped", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("e")),
|
|
1721
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("e"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p")),
|
|
1722
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f"))
|
|
1273
1723
|
]
|
|
1274
1724
|
),
|
|
1275
|
-
(0,
|
|
1725
|
+
(0, import_datalog4.rule)(
|
|
1276
1726
|
"callMemberChain",
|
|
1277
|
-
[(0,
|
|
1727
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("p")],
|
|
1278
1728
|
[
|
|
1279
|
-
(0,
|
|
1280
|
-
(0,
|
|
1729
|
+
(0, import_datalog4.lit)("callMemberChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("p")),
|
|
1730
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))
|
|
1281
1731
|
]
|
|
1282
1732
|
),
|
|
1283
|
-
(0,
|
|
1733
|
+
(0, import_datalog4.rule)(
|
|
1284
1734
|
"callMemberChain",
|
|
1285
|
-
[(0,
|
|
1735
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("p")],
|
|
1286
1736
|
[
|
|
1287
|
-
(0,
|
|
1288
|
-
(0,
|
|
1737
|
+
(0, import_datalog4.lit)("callMemberChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("p")),
|
|
1738
|
+
(0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))
|
|
1289
1739
|
]
|
|
1290
1740
|
),
|
|
1291
|
-
(0,
|
|
1741
|
+
(0, import_datalog4.rule)(
|
|
1292
1742
|
"wantedCallOriginMember",
|
|
1293
|
-
[(0,
|
|
1743
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")],
|
|
1294
1744
|
[
|
|
1295
|
-
(0,
|
|
1296
|
-
(0,
|
|
1745
|
+
(0, import_datalog4.lit)("callMemberChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("p")),
|
|
1746
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1297
1747
|
]
|
|
1298
1748
|
),
|
|
1299
|
-
(0,
|
|
1749
|
+
(0, import_datalog4.rule)(
|
|
1300
1750
|
"wantedCallsInto",
|
|
1301
|
-
[(0,
|
|
1751
|
+
[(0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1302
1752
|
[
|
|
1303
|
-
(0,
|
|
1304
|
-
(0,
|
|
1305
|
-
(0,
|
|
1753
|
+
(0, import_datalog4.lit)("wantedOrigin", (0, import_datalog4.variable)("x")),
|
|
1754
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("g")),
|
|
1755
|
+
(0, import_datalog4.lit)("callsInto", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1306
1756
|
]
|
|
1307
1757
|
),
|
|
1308
1758
|
// Subject identity, its own demand class; the README's subject
|
|
1309
1759
|
// section says why the origin pair rides on the written-value walk.
|
|
1310
|
-
(0,
|
|
1760
|
+
(0, import_datalog4.rule)(
|
|
1311
1761
|
"wantedSubjectWritten",
|
|
1312
|
-
[(0,
|
|
1313
|
-
[(0,
|
|
1762
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")],
|
|
1763
|
+
[(0, import_datalog4.lit)("wantedSubject", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r"))]
|
|
1314
1764
|
),
|
|
1315
|
-
(0,
|
|
1765
|
+
(0, import_datalog4.rule)(
|
|
1316
1766
|
"wantedSubjectConstruction",
|
|
1317
|
-
[(0,
|
|
1767
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
1318
1768
|
[
|
|
1319
|
-
(0,
|
|
1320
|
-
(0,
|
|
1321
|
-
(0,
|
|
1322
|
-
(0,
|
|
1769
|
+
(0, import_datalog4.lit)("wantedSubject", (0, import_datalog4.variable)("x")),
|
|
1770
|
+
(0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")),
|
|
1771
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1772
|
+
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1323
1773
|
]
|
|
1324
1774
|
),
|
|
1325
1775
|
// The export table of one module, keyed by the module asked about.
|
|
1326
1776
|
// The moduleExport rules flatten re-export chains of any length, and
|
|
1327
1777
|
// the demand cone stays on export facts alone.
|
|
1328
|
-
(0,
|
|
1778
|
+
(0, import_datalog4.rule)(
|
|
1329
1779
|
"wantedModuleExport",
|
|
1330
|
-
[(0,
|
|
1780
|
+
[(0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value")],
|
|
1331
1781
|
[
|
|
1332
|
-
(0,
|
|
1333
|
-
(0,
|
|
1782
|
+
(0, import_datalog4.lit)("wantedExportsOf", (0, import_datalog4.variable)("m")),
|
|
1783
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("value"))
|
|
1334
1784
|
]
|
|
1335
1785
|
),
|
|
1336
1786
|
// The calls behind a receiver, for a pack that wants the anchor a
|
|
@@ -1339,63 +1789,74 @@ var RESOLUTION_QUESTIONS = [
|
|
|
1339
1789
|
// A class's ancestry, one hop per extends through the binding that
|
|
1340
1790
|
// says which class the written base is; the names on the way out
|
|
1341
1791
|
// are what a storage pack matches its library's bases against.
|
|
1342
|
-
(0,
|
|
1343
|
-
(0,
|
|
1792
|
+
(0, import_datalog4.rule)("ancestryChain", [(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c")], [(0, import_datalog4.lit)("wantedAncestry", (0, import_datalog4.variable)("c"))]),
|
|
1793
|
+
(0, import_datalog4.rule)(
|
|
1344
1794
|
"ancestryChain",
|
|
1345
|
-
[(0,
|
|
1795
|
+
[(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("b2")],
|
|
1346
1796
|
[
|
|
1347
|
-
(0,
|
|
1348
|
-
(0,
|
|
1349
|
-
(0,
|
|
1797
|
+
(0, import_datalog4.lit)("ancestryChain", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("b")),
|
|
1798
|
+
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("x")),
|
|
1799
|
+
(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b2"))
|
|
1350
1800
|
]
|
|
1351
1801
|
),
|
|
1352
|
-
(0,
|
|
1802
|
+
(0, import_datalog4.rule)(
|
|
1353
1803
|
"wantedBaseName",
|
|
1354
|
-
[(0,
|
|
1355
|
-
[(0,
|
|
1804
|
+
[(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n")],
|
|
1805
|
+
[(0, import_datalog4.lit)("ancestryChain", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("b")), (0, import_datalog4.lit)("extendsNamed", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("n"))]
|
|
1806
|
+
),
|
|
1807
|
+
// Each method the same chain declares, so a caller that settled a
|
|
1808
|
+
// receiver on a class can tell a method the project writes itself
|
|
1809
|
+
// from one only the library provides.
|
|
1810
|
+
(0, import_datalog4.rule)(
|
|
1811
|
+
"wantedDeclaredName",
|
|
1812
|
+
[(0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("n")],
|
|
1813
|
+
[
|
|
1814
|
+
(0, import_datalog4.lit)("ancestryChain", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("b")),
|
|
1815
|
+
(0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1816
|
+
]
|
|
1356
1817
|
),
|
|
1357
|
-
(0,
|
|
1358
|
-
(0,
|
|
1818
|
+
(0, import_datalog4.rule)("anchorChain", [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("x")], [(0, import_datalog4.lit)("wantedAnchor", (0, import_datalog4.variable)("x"))]),
|
|
1819
|
+
(0, import_datalog4.rule)(
|
|
1359
1820
|
"anchorChain",
|
|
1360
|
-
[(0,
|
|
1361
|
-
[(0,
|
|
1821
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1822
|
+
[(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1362
1823
|
),
|
|
1363
|
-
(0,
|
|
1824
|
+
(0, import_datalog4.rule)(
|
|
1364
1825
|
"anchorChain",
|
|
1365
|
-
[(0,
|
|
1366
|
-
[(0,
|
|
1826
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1827
|
+
[(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1367
1828
|
),
|
|
1368
|
-
(0,
|
|
1829
|
+
(0, import_datalog4.rule)(
|
|
1369
1830
|
"anchorChain",
|
|
1370
|
-
[(0,
|
|
1371
|
-
[(0,
|
|
1831
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1832
|
+
[(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"))]
|
|
1372
1833
|
),
|
|
1373
|
-
(0,
|
|
1834
|
+
(0, import_datalog4.rule)(
|
|
1374
1835
|
"anchorChain",
|
|
1375
|
-
[(0,
|
|
1836
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1376
1837
|
[
|
|
1377
|
-
(0,
|
|
1378
|
-
(0,
|
|
1379
|
-
(0,
|
|
1838
|
+
(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1839
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
1840
|
+
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("z"))
|
|
1380
1841
|
]
|
|
1381
1842
|
),
|
|
1382
|
-
(0,
|
|
1843
|
+
(0, import_datalog4.rule)(
|
|
1383
1844
|
"anchorChain",
|
|
1384
|
-
[(0,
|
|
1385
|
-
[(0,
|
|
1845
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")],
|
|
1846
|
+
[(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
|
|
1386
1847
|
),
|
|
1387
|
-
(0,
|
|
1848
|
+
(0, import_datalog4.rule)(
|
|
1388
1849
|
"anchorChain",
|
|
1389
|
-
[(0,
|
|
1850
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o")],
|
|
1390
1851
|
[
|
|
1391
|
-
(0,
|
|
1392
|
-
(0,
|
|
1852
|
+
(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")),
|
|
1853
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n"))
|
|
1393
1854
|
]
|
|
1394
1855
|
),
|
|
1395
|
-
(0,
|
|
1856
|
+
(0, import_datalog4.rule)(
|
|
1396
1857
|
"wantedAnchorCall",
|
|
1397
|
-
[(0,
|
|
1398
|
-
[(0,
|
|
1858
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")],
|
|
1859
|
+
[(0, import_datalog4.lit)("anchorChain", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("r")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
|
|
1399
1860
|
)
|
|
1400
1861
|
];
|
|
1401
1862
|
var ANSWER_RELATIONS = [
|
|
@@ -1404,6 +1865,7 @@ var ANSWER_RELATIONS = [
|
|
|
1404
1865
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1405
1866
|
0 && (module.exports = {
|
|
1406
1867
|
ANSWER_RELATIONS,
|
|
1868
|
+
ASKING_RELATIONS,
|
|
1407
1869
|
FACT_CONTRACT_CASES,
|
|
1408
1870
|
NAMESPACE_IMPORT,
|
|
1409
1871
|
NAMESPACE_IMPORT_NAME,
|
|
@@ -1412,14 +1874,24 @@ var ANSWER_RELATIONS = [
|
|
|
1412
1874
|
RESULT_STEP,
|
|
1413
1875
|
VALUE_STEP,
|
|
1414
1876
|
agreedMountPrefix,
|
|
1877
|
+
askResolution,
|
|
1878
|
+
calleeOutcomeOf,
|
|
1879
|
+
calleeOutcomes,
|
|
1415
1880
|
checkFactContract,
|
|
1881
|
+
couldBeSettled,
|
|
1416
1882
|
explainResolutionProof,
|
|
1417
1883
|
explainResolvedKey,
|
|
1418
1884
|
joinMountedPath,
|
|
1419
1885
|
mountPathsOf,
|
|
1420
1886
|
nodeOfKey,
|
|
1421
1887
|
placeholderValues,
|
|
1888
|
+
queryFacts,
|
|
1422
1889
|
renderExplanation,
|
|
1890
|
+
resolutionProgram,
|
|
1423
1891
|
singleAnswers,
|
|
1892
|
+
startsAtName,
|
|
1893
|
+
valueLeftByWrites,
|
|
1894
|
+
writesRunInOrder,
|
|
1895
|
+
writtenSourcesOf,
|
|
1424
1896
|
writtenValueOf
|
|
1425
1897
|
});
|