@suss/resolution 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +919 -70
- package/dist/index.d.cts +169 -21
- package/dist/index.d.ts +169 -21
- package/dist/index.js +906 -70
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -22,34 +22,52 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ANSWER_RELATIONS: () => ANSWER_RELATIONS,
|
|
24
24
|
ASKING_RELATIONS: () => ASKING_RELATIONS,
|
|
25
|
+
BASE_CLASS_RULE: () => BASE_CLASS_RULE,
|
|
25
26
|
FACT_CONTRACT_CASES: () => FACT_CONTRACT_CASES,
|
|
27
|
+
INSTANCE_STEP: () => INSTANCE_STEP,
|
|
26
28
|
NAMESPACE_IMPORT: () => NAMESPACE_IMPORT,
|
|
27
29
|
NAMESPACE_IMPORT_NAME: () => NAMESPACE_IMPORT_NAME,
|
|
30
|
+
NAMESPACE_MEMBER_RULE: () => NAMESPACE_MEMBER_RULE,
|
|
31
|
+
NO_CONTEXT: () => NO_CONTEXT,
|
|
32
|
+
NO_CONTEXT_NAME: () => NO_CONTEXT_NAME,
|
|
28
33
|
RESOLUTION_QUESTIONS: () => RESOLUTION_QUESTIONS,
|
|
29
34
|
RESOLUTION_RULES: () => RESOLUTION_RULES,
|
|
30
35
|
RESULT_STEP: () => RESULT_STEP,
|
|
36
|
+
UNDER_ANSWER_RELATIONS: () => UNDER_ANSWER_RELATIONS,
|
|
31
37
|
VALUE_STEP: () => VALUE_STEP,
|
|
38
|
+
addPackWords: () => addPackWords,
|
|
32
39
|
agreedMountPrefix: () => agreedMountPrefix,
|
|
40
|
+
allocationSitesOf: () => allocationSitesOf,
|
|
41
|
+
alsoSteps: () => alsoSteps,
|
|
42
|
+
answersByKey: () => answersByKey,
|
|
33
43
|
askResolution: () => askResolution,
|
|
44
|
+
askResolutionUnder: () => askResolutionUnder,
|
|
34
45
|
calleeOutcomeOf: () => calleeOutcomeOf,
|
|
35
46
|
calleeOutcomes: () => calleeOutcomes,
|
|
36
47
|
checkFactContract: () => checkFactContract,
|
|
48
|
+
comesToUnder: () => comesToUnder,
|
|
37
49
|
couldBeSettled: () => couldBeSettled,
|
|
38
50
|
explainResolutionProof: () => explainResolutionProof,
|
|
39
51
|
explainResolvedKey: () => explainResolvedKey,
|
|
52
|
+
isWrittenAsUnder: () => isWrittenAsUnder,
|
|
40
53
|
joinMountedPath: () => joinMountedPath,
|
|
41
54
|
mountPathsOf: () => mountPathsOf,
|
|
42
55
|
nodeOfKey: () => nodeOfKey,
|
|
56
|
+
objectOfUnder: () => objectOfUnder,
|
|
43
57
|
placeholderValues: () => placeholderValues,
|
|
44
58
|
queryFacts: () => queryFacts,
|
|
45
59
|
renderExplanation: () => renderExplanation,
|
|
46
60
|
resolutionProgram: () => resolutionProgram,
|
|
61
|
+
resolutionUnderProgram: () => resolutionUnderProgram,
|
|
47
62
|
singleAnswers: () => singleAnswers,
|
|
48
63
|
startsAtName: () => startsAtName,
|
|
49
64
|
valueLeftByWrites: () => valueLeftByWrites,
|
|
50
65
|
writesRunInOrder: () => writesRunInOrder,
|
|
51
66
|
writtenSourcesOf: () => writtenSourcesOf,
|
|
52
|
-
writtenValueOf: () => writtenValueOf
|
|
67
|
+
writtenValueOf: () => writtenValueOf,
|
|
68
|
+
writtenValueUnder: () => writtenValueUnder,
|
|
69
|
+
writtenValuesByKey: () => writtenValuesByKey,
|
|
70
|
+
writtenValuesOf: () => writtenValuesOf
|
|
53
71
|
});
|
|
54
72
|
module.exports = __toCommonJS(index_exports);
|
|
55
73
|
|
|
@@ -57,6 +75,8 @@ module.exports = __toCommonJS(index_exports);
|
|
|
57
75
|
var import_datalog = require("@suss/datalog");
|
|
58
76
|
var ASKING_RELATIONS = [
|
|
59
77
|
"wanted",
|
|
78
|
+
"wantedUnder",
|
|
79
|
+
"wantedSites",
|
|
60
80
|
"wantedOrigin",
|
|
61
81
|
"wantedCallOrigin",
|
|
62
82
|
"wantedExportsOf",
|
|
@@ -66,8 +86,12 @@ var ASKING_RELATIONS = [
|
|
|
66
86
|
];
|
|
67
87
|
var NO_LANGUAGE_RULES = [];
|
|
68
88
|
var programs = /* @__PURE__ */ new WeakMap();
|
|
69
|
-
|
|
70
|
-
|
|
89
|
+
var underPrograms = /* @__PURE__ */ new WeakMap();
|
|
90
|
+
var contextFreeAnswers = () => ANSWER_RELATIONS.filter(
|
|
91
|
+
(relation) => !UNDER_ANSWER_RELATIONS.includes(relation)
|
|
92
|
+
);
|
|
93
|
+
function builtProgram(languageRules, cache, complete) {
|
|
94
|
+
const built = cache.get(languageRules);
|
|
71
95
|
if (built !== void 0) {
|
|
72
96
|
return built;
|
|
73
97
|
}
|
|
@@ -76,10 +100,16 @@ function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
|
|
|
76
100
|
...languageRules,
|
|
77
101
|
...RESOLUTION_QUESTIONS
|
|
78
102
|
];
|
|
79
|
-
const program = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? { rules, demandDriven: [], demands: [] } : (0, import_datalog.deriveOnDemand)(rules,
|
|
80
|
-
|
|
103
|
+
const program = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? { rules, demandDriven: [], demands: [] } : (0, import_datalog.deriveOnDemand)(rules, complete);
|
|
104
|
+
cache.set(languageRules, program);
|
|
81
105
|
return program;
|
|
82
106
|
}
|
|
107
|
+
function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
|
|
108
|
+
return builtProgram(languageRules, programs, contextFreeAnswers());
|
|
109
|
+
}
|
|
110
|
+
function resolutionUnderProgram(languageRules = NO_LANGUAGE_RULES) {
|
|
111
|
+
return builtProgram(languageRules, underPrograms, ANSWER_RELATIONS);
|
|
112
|
+
}
|
|
83
113
|
function queryFacts(program) {
|
|
84
114
|
if (program.demandDriven.length === 0) {
|
|
85
115
|
return [];
|
|
@@ -116,6 +146,29 @@ function askResolution(db, keys, asking = "wanted", program = resolutionProgram(
|
|
|
116
146
|
(0, import_datalog.clearRelations)(db, program.rules, forget);
|
|
117
147
|
}
|
|
118
148
|
}
|
|
149
|
+
var askedUnderByDb = /* @__PURE__ */ new WeakMap();
|
|
150
|
+
function askResolutionUnder(db, pairs, program = resolutionUnderProgram()) {
|
|
151
|
+
let asked = askedUnderByDb.get(db);
|
|
152
|
+
if (asked === void 0) {
|
|
153
|
+
asked = /* @__PURE__ */ new Set();
|
|
154
|
+
askedUnderByDb.set(db, asked);
|
|
155
|
+
}
|
|
156
|
+
const fresh = [...pairs].filter(
|
|
157
|
+
([key, site]) => !asked.has((0, import_datalog.tupleKey)([key, site]))
|
|
158
|
+
);
|
|
159
|
+
if (fresh.length === 0) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
for (const [key, site] of fresh) {
|
|
163
|
+
asked.add((0, import_datalog.tupleKey)([key, site]));
|
|
164
|
+
db.add("wantedUnder", [key, site]);
|
|
165
|
+
}
|
|
166
|
+
(0, import_datalog.evaluate)(db, program.rules);
|
|
167
|
+
const forget = queryFacts(program);
|
|
168
|
+
if (forget.length > 0) {
|
|
169
|
+
(0, import_datalog.clearRelations)(db, program.rules, forget);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
119
172
|
|
|
120
173
|
// src/callee.ts
|
|
121
174
|
var UNDECLARED = { kind: "undeclared" };
|
|
@@ -544,6 +597,12 @@ var DEFAULT_PHRASES = {
|
|
|
544
597
|
"last write": ({ tuple, describe }) => ({
|
|
545
598
|
reason: `${describe(tuple[0])} is written more than once, and the last write leaves it as ${describe(tuple[1])}`
|
|
546
599
|
}),
|
|
600
|
+
"one of several writes": ({ tuple, describe }) => ({
|
|
601
|
+
reason: `${describe(tuple[0])} is written more than once, and one of those writes makes it ${describe(tuple[1])}`,
|
|
602
|
+
assumptions: [
|
|
603
|
+
`nothing says which write to ${describe(tuple[0])} ran last, so every write it has is a possible value`
|
|
604
|
+
]
|
|
605
|
+
}),
|
|
547
606
|
fallback: ({ tuple, describe }) => ({
|
|
548
607
|
reason: `${describe(tuple[0])} is a fallback expression, and ${describe(tuple[1])} is the branch that resolves`
|
|
549
608
|
}),
|
|
@@ -560,7 +619,7 @@ var DEFAULT_PHRASES = {
|
|
|
560
619
|
"property read": ({ tuple, premises, describe }) => {
|
|
561
620
|
const [, object, name] = premises[0].tuple;
|
|
562
621
|
const contains = premises[2];
|
|
563
|
-
const inherited = contains.kind === "derived" && contains.
|
|
622
|
+
const inherited = contains.kind === "derived" && (0, import_datalog2.ruleLabel)(contains.rule) === BASE_CLASS_RULE;
|
|
564
623
|
return {
|
|
565
624
|
reason: `${describe(tuple[0])} reads ${String(name)} off ${describe(object)}, which contains ${describe(tuple[1])}`,
|
|
566
625
|
notes: inherited ? [`${String(name)} comes from a base class`] : []
|
|
@@ -639,7 +698,8 @@ var CHAIN_RELATIONS = /* @__PURE__ */ new Set([
|
|
|
639
698
|
"isWrittenAs",
|
|
640
699
|
"comesFrom",
|
|
641
700
|
"reaches",
|
|
642
|
-
"stepsTo"
|
|
701
|
+
"stepsTo",
|
|
702
|
+
"hop"
|
|
643
703
|
]);
|
|
644
704
|
function inlineChain(proof, state) {
|
|
645
705
|
const explained = explainResolutionProof(proof, {
|
|
@@ -695,6 +755,17 @@ function importStep(proof, state) {
|
|
|
695
755
|
assumptions: []
|
|
696
756
|
};
|
|
697
757
|
}
|
|
758
|
+
function namespaceMemberStep(proof, state) {
|
|
759
|
+
const [x, module2, name] = proof.tuple;
|
|
760
|
+
return {
|
|
761
|
+
from: x,
|
|
762
|
+
to: module2,
|
|
763
|
+
rule: NAMESPACE_MEMBER_RULE,
|
|
764
|
+
reason: `${state.describe(x)} reads ${String(name)} off ${state.describe(module2)}, which is imported whole`,
|
|
765
|
+
notes: [],
|
|
766
|
+
assumptions: []
|
|
767
|
+
};
|
|
768
|
+
}
|
|
698
769
|
var flattenInto = (proof, state) => {
|
|
699
770
|
if (proof.kind === "truncated") {
|
|
700
771
|
state.truncated = true;
|
|
@@ -704,7 +775,7 @@ var flattenInto = (proof, state) => {
|
|
|
704
775
|
return;
|
|
705
776
|
}
|
|
706
777
|
const relation = proof.relation;
|
|
707
|
-
if (relation === "stepsTo") {
|
|
778
|
+
if (relation === "stepsTo" || relation === "hop") {
|
|
708
779
|
state.steps.push(stepFrom(proof, state));
|
|
709
780
|
return;
|
|
710
781
|
}
|
|
@@ -715,6 +786,10 @@ var flattenInto = (proof, state) => {
|
|
|
715
786
|
return;
|
|
716
787
|
}
|
|
717
788
|
if (relation === "comesFrom") {
|
|
789
|
+
if ((0, import_datalog2.ruleLabel)(proof.rule) === NAMESPACE_MEMBER_RULE) {
|
|
790
|
+
state.steps.push(namespaceMemberStep(proof, state));
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
718
793
|
if (proof.premises.length === 2) {
|
|
719
794
|
flattenInto(proof.premises[0], state);
|
|
720
795
|
state.steps.push(importStep(proof.premises[1], state));
|
|
@@ -891,6 +966,37 @@ function nodeOfKey(rootsByFile, key) {
|
|
|
891
966
|
return null;
|
|
892
967
|
}
|
|
893
968
|
|
|
969
|
+
// src/packWords.ts
|
|
970
|
+
function addPackWords(db, words) {
|
|
971
|
+
for (const word of words.givesBackOne ?? []) {
|
|
972
|
+
db.add("givesBackOne", [word.base, word.method]);
|
|
973
|
+
}
|
|
974
|
+
for (const word of words.givesBackOneOfArgument ?? []) {
|
|
975
|
+
db.add("givesBackOneOfArgument", [
|
|
976
|
+
word.base,
|
|
977
|
+
word.method,
|
|
978
|
+
String(word.argument)
|
|
979
|
+
]);
|
|
980
|
+
}
|
|
981
|
+
for (const word of words.givesBackOneOfImport ?? []) {
|
|
982
|
+
db.add("givesBackOneOfImport", [
|
|
983
|
+
word.module,
|
|
984
|
+
word.name,
|
|
985
|
+
String(word.argument)
|
|
986
|
+
]);
|
|
987
|
+
}
|
|
988
|
+
for (const word of words.entersAsSelf ?? []) {
|
|
989
|
+
db.add("entersAsSelf", [word.module, word.name]);
|
|
990
|
+
}
|
|
991
|
+
for (const word of words.unwrapsByName ?? []) {
|
|
992
|
+
db.add("unwrapsByName", [word.callee, String(word.argument)]);
|
|
993
|
+
db.add("wrapperModule", [word.callee, word.module]);
|
|
994
|
+
}
|
|
995
|
+
for (const word of words.associationConstructor ?? []) {
|
|
996
|
+
db.add("associationConstructor", [word.module, word.name]);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
894
1000
|
// src/session.ts
|
|
895
1001
|
var import_datalog3 = require("@suss/datalog");
|
|
896
1002
|
function explainResolvedKey(options) {
|
|
@@ -946,7 +1052,7 @@ function explainResolvedKey(options) {
|
|
|
946
1052
|
|
|
947
1053
|
// src/singleAnswer.ts
|
|
948
1054
|
var NO_PLACEHOLDERS = /* @__PURE__ */ new Set();
|
|
949
|
-
function
|
|
1055
|
+
function answersByKey(rows, placeholders = NO_PLACEHOLDERS) {
|
|
950
1056
|
const candidates = /* @__PURE__ */ new Map();
|
|
951
1057
|
for (const row of rows) {
|
|
952
1058
|
const key = String(row[0]);
|
|
@@ -958,9 +1064,15 @@ function singleAnswers(rows, placeholders = NO_PLACEHOLDERS) {
|
|
|
958
1064
|
set.add(answer);
|
|
959
1065
|
candidates.set(key, set);
|
|
960
1066
|
}
|
|
961
|
-
const
|
|
1067
|
+
const answers = /* @__PURE__ */ new Map();
|
|
962
1068
|
for (const [key, set] of candidates) {
|
|
963
|
-
|
|
1069
|
+
answers.set(key, withoutPlaceholders(set, placeholders));
|
|
1070
|
+
}
|
|
1071
|
+
return answers;
|
|
1072
|
+
}
|
|
1073
|
+
function singleAnswers(rows, placeholders = NO_PLACEHOLDERS) {
|
|
1074
|
+
const settled = /* @__PURE__ */ new Map();
|
|
1075
|
+
for (const [key, answers] of answersByKey(rows, placeholders)) {
|
|
964
1076
|
if (answers.length === 1) {
|
|
965
1077
|
settled.set(key, answers[0]);
|
|
966
1078
|
}
|
|
@@ -978,6 +1090,28 @@ function withoutPlaceholders(answers, placeholders) {
|
|
|
978
1090
|
return kept;
|
|
979
1091
|
}
|
|
980
1092
|
|
|
1093
|
+
// src/underContext.ts
|
|
1094
|
+
function answersUnder(db, relation, key, site) {
|
|
1095
|
+
return db.lookup(relation, 0, key).filter((row) => String(row[1]) === site).map((row) => String(row[2]));
|
|
1096
|
+
}
|
|
1097
|
+
function isWrittenAsUnder(db, key, site) {
|
|
1098
|
+
return answersUnder(db, "wantedIsWrittenAsUnder", key, site);
|
|
1099
|
+
}
|
|
1100
|
+
function comesToUnder(db, key, site) {
|
|
1101
|
+
return answersUnder(db, "wantedComesToUnder", key, site);
|
|
1102
|
+
}
|
|
1103
|
+
function objectOfUnder(db, key, site) {
|
|
1104
|
+
return answersUnder(db, "wantedObjectOfUnder", key, site);
|
|
1105
|
+
}
|
|
1106
|
+
function writtenValueUnder(db, key, site) {
|
|
1107
|
+
const rows = isWrittenAsUnder(db, key, site).map((answer) => [key, answer]);
|
|
1108
|
+
const answers = answersByKey(rows, placeholderValues(db)).get(key) ?? [];
|
|
1109
|
+
return answers.length === 1 ? answers[0] : null;
|
|
1110
|
+
}
|
|
1111
|
+
function allocationSitesOf(db, cls) {
|
|
1112
|
+
return db.lookup("wantedAllocatedAt", 0, cls).map((row) => String(row[1]));
|
|
1113
|
+
}
|
|
1114
|
+
|
|
981
1115
|
// src/writes.ts
|
|
982
1116
|
function valueLeftByWrites(writes, ordered) {
|
|
983
1117
|
const deciding = writes.filter((write) => !write.narrowsName);
|
|
@@ -1008,23 +1142,58 @@ function sharedConstruction(writes) {
|
|
|
1008
1142
|
}
|
|
1009
1143
|
|
|
1010
1144
|
// src/writtenValue.ts
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1145
|
+
var WRITTEN_AS = "wantedIsWrittenAs";
|
|
1146
|
+
function writtenValueOf(db, key, ask, relation = WRITTEN_AS) {
|
|
1147
|
+
const answers = settledByKey(db, [key], ask, relation).get(key) ?? [];
|
|
1148
|
+
return answers.length === 1 ? answers[0] : null;
|
|
1149
|
+
}
|
|
1150
|
+
function writtenValuesOf(db, key, ask, relation = WRITTEN_AS) {
|
|
1151
|
+
const settled = settledByKey(db, [key], ask, relation).get(key) ?? [];
|
|
1152
|
+
return settled.length > 0 ? settled : writesLeft(db, key);
|
|
1153
|
+
}
|
|
1154
|
+
function writtenValuesByKey(db, keys, ask, relation = WRITTEN_AS) {
|
|
1155
|
+
const one = /* @__PURE__ */ new Map();
|
|
1156
|
+
for (const [key, answers] of settledByKey(db, keys, ask, relation)) {
|
|
1157
|
+
if (answers.length === 1) {
|
|
1158
|
+
one.set(key, answers[0]);
|
|
1159
|
+
}
|
|
1018
1160
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1161
|
+
return one;
|
|
1162
|
+
}
|
|
1163
|
+
function settledByKey(db, keys, ask, relation) {
|
|
1164
|
+
const placeholders = placeholderValues(db);
|
|
1165
|
+
const byKey = answersByKey(db.facts(relation), placeholders);
|
|
1166
|
+
const direct = new Map(keys.map((key) => [key, byKey.get(key) ?? []]));
|
|
1167
|
+
const calls = new Set(db.facts("call").map((row) => String(row[0])));
|
|
1168
|
+
const throughCalls = [...direct.values()].flat().filter((answer) => calls.has(answer));
|
|
1169
|
+
if (throughCalls.length === 0) {
|
|
1021
1170
|
return direct;
|
|
1022
1171
|
}
|
|
1023
|
-
ask(
|
|
1024
|
-
const deeper = singleAnswers(db.facts(
|
|
1025
|
-
|
|
1172
|
+
ask(throughCalls);
|
|
1173
|
+
const deeper = singleAnswers(db.facts(relation), placeholders);
|
|
1174
|
+
return new Map(
|
|
1175
|
+
[...direct].map(([key, answers]) => [
|
|
1176
|
+
key,
|
|
1177
|
+
collapseCalls(answers, calls, deeper)
|
|
1178
|
+
])
|
|
1026
1179
|
);
|
|
1027
|
-
|
|
1180
|
+
}
|
|
1181
|
+
function collapseCalls(direct, calls, deeper) {
|
|
1182
|
+
return [
|
|
1183
|
+
...new Set(
|
|
1184
|
+
direct.map(
|
|
1185
|
+
(answer) => calls.has(answer) ? deeper.get(answer) ?? answer : answer
|
|
1186
|
+
)
|
|
1187
|
+
)
|
|
1188
|
+
];
|
|
1189
|
+
}
|
|
1190
|
+
function writesLeft(db, key) {
|
|
1191
|
+
const unstated = db.facts("writesUnstated").some((row) => String(row[0]) === key);
|
|
1192
|
+
if (unstated) {
|
|
1193
|
+
return [];
|
|
1194
|
+
}
|
|
1195
|
+
const candidates = answersByKey(db.facts("mayHold"), placeholderValues(db)).get(key) ?? [];
|
|
1196
|
+
return candidates.length > 1 ? candidates : [];
|
|
1028
1197
|
}
|
|
1029
1198
|
|
|
1030
1199
|
// src/index.ts
|
|
@@ -1032,38 +1201,61 @@ var import_datalog4 = require("@suss/datalog");
|
|
|
1032
1201
|
var VALUE_STEP = (0, import_datalog4.constant)("value");
|
|
1033
1202
|
var NAMESPACE_IMPORT_NAME = "*";
|
|
1034
1203
|
var NAMESPACE_IMPORT = (0, import_datalog4.constant)(NAMESPACE_IMPORT_NAME);
|
|
1204
|
+
var NAMESPACE_MEMBER_RULE = "namespace member";
|
|
1205
|
+
var BASE_CLASS_RULE = "base class";
|
|
1206
|
+
var INSTANCE_STEP = (0, import_datalog4.constant)("instance");
|
|
1035
1207
|
var RESULT_STEP = (0, import_datalog4.constant)("result");
|
|
1036
|
-
var
|
|
1208
|
+
var NO_CONTEXT_NAME = "none";
|
|
1209
|
+
var NO_CONTEXT = (0, import_datalog4.constant)(NO_CONTEXT_NAME);
|
|
1210
|
+
var STEP_LATTICE = [
|
|
1211
|
+
{ soFar: VALUE_STEP, next: (0, import_datalog4.variable)("kind"), took: (0, import_datalog4.variable)("kind") },
|
|
1212
|
+
{ soFar: INSTANCE_STEP, next: VALUE_STEP, took: INSTANCE_STEP },
|
|
1213
|
+
{ soFar: INSTANCE_STEP, next: INSTANCE_STEP, took: INSTANCE_STEP },
|
|
1214
|
+
{ soFar: INSTANCE_STEP, next: RESULT_STEP, took: RESULT_STEP },
|
|
1215
|
+
{ soFar: RESULT_STEP, next: VALUE_STEP, took: RESULT_STEP },
|
|
1216
|
+
{ soFar: RESULT_STEP, next: INSTANCE_STEP, took: RESULT_STEP },
|
|
1217
|
+
{ soFar: RESULT_STEP, next: RESULT_STEP, took: RESULT_STEP }
|
|
1218
|
+
];
|
|
1219
|
+
var STATED_RULES = [
|
|
1037
1220
|
// Aliasing: const x = y, or an identifier referencing a declaration.
|
|
1038
1221
|
// A language with a hop of its own, like JavaScript's `.bind`, states
|
|
1039
1222
|
// it as a step too, or every question but `comesTo` misses it.
|
|
1040
1223
|
(0, import_datalog4.rule)(
|
|
1041
|
-
"
|
|
1224
|
+
"hop",
|
|
1042
1225
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
|
|
1043
1226
|
[(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
|
|
1044
1227
|
"alias"
|
|
1045
1228
|
),
|
|
1046
1229
|
// A name written more than once has the value the last write left
|
|
1047
|
-
// there. The adapter works out which write that is and stays quiet
|
|
1048
|
-
// when control flow decides
|
|
1230
|
+
// there. The adapter works out which write that is, and stays quiet
|
|
1231
|
+
// when control flow decides; the rule below takes that name instead.
|
|
1049
1232
|
(0, import_datalog4.rule)(
|
|
1050
|
-
"
|
|
1233
|
+
"hop",
|
|
1051
1234
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
|
|
1052
1235
|
[(0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
|
|
1053
1236
|
"last write"
|
|
1054
1237
|
),
|
|
1238
|
+
// A name whose writes nothing orders leads to each of them, so a
|
|
1239
|
+
// caller that can use several values gets them all and one that needs
|
|
1240
|
+
// a single value gets none. A write stating no value stops every step.
|
|
1241
|
+
(0, import_datalog4.rule)(
|
|
1242
|
+
"hop",
|
|
1243
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
|
|
1244
|
+
[(0, import_datalog4.lit)("mayHold", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("writesAllStated", (0, import_datalog4.variable)("x"))],
|
|
1245
|
+
"one of several writes"
|
|
1246
|
+
),
|
|
1055
1247
|
// A fallback says the value is one of its branches, so each branch is
|
|
1056
1248
|
// a step. A branch that resolves to nothing makes no claim, and two
|
|
1057
1249
|
// branches resolving to different things fail the single-answer policy.
|
|
1058
1250
|
(0, import_datalog4.rule)(
|
|
1059
|
-
"
|
|
1251
|
+
"hop",
|
|
1060
1252
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"), VALUE_STEP],
|
|
1061
1253
|
[(0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"))],
|
|
1062
1254
|
"fallback"
|
|
1063
1255
|
),
|
|
1064
1256
|
// An import steps to what the module exports under that name.
|
|
1065
1257
|
(0, import_datalog4.rule)(
|
|
1066
|
-
"
|
|
1258
|
+
"hop",
|
|
1067
1259
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("value"), VALUE_STEP],
|
|
1068
1260
|
[
|
|
1069
1261
|
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
|
|
@@ -1097,8 +1289,8 @@ var RESOLUTION_RULES = [
|
|
|
1097
1289
|
// a method read off the result is the one the class declares. The
|
|
1098
1290
|
// caveat below is about a factory function, and a class is not one.
|
|
1099
1291
|
(0, import_datalog4.rule)(
|
|
1100
|
-
"
|
|
1101
|
-
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"),
|
|
1292
|
+
"hop",
|
|
1293
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
|
|
1102
1294
|
[
|
|
1103
1295
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1104
1296
|
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("cls")),
|
|
@@ -1106,12 +1298,21 @@ var RESOLUTION_RULES = [
|
|
|
1106
1298
|
],
|
|
1107
1299
|
"class instance"
|
|
1108
1300
|
),
|
|
1301
|
+
// The receiver a method is called on. Being one of a class is the
|
|
1302
|
+
// same hop a construction takes, so a method read off `self` finds
|
|
1303
|
+
// what the class declares.
|
|
1304
|
+
(0, import_datalog4.rule)(
|
|
1305
|
+
"hop",
|
|
1306
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
|
|
1307
|
+
[(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls"))],
|
|
1308
|
+
"receiver instance"
|
|
1309
|
+
),
|
|
1109
1310
|
// A finder the library declares, keyed on the base a pack named so a
|
|
1110
1311
|
// project class with a method of the same name on another hierarchy is
|
|
1111
1312
|
// left alone. The DESIGN says what a chain of them composes into.
|
|
1112
1313
|
(0, import_datalog4.rule)(
|
|
1113
|
-
"
|
|
1114
|
-
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"),
|
|
1314
|
+
"hop",
|
|
1315
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
|
|
1115
1316
|
[
|
|
1116
1317
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1117
1318
|
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
|
|
@@ -1128,8 +1329,8 @@ var RESOLUTION_RULES = [
|
|
|
1128
1329
|
// instead of as the receiver. The argument having to reach the base a
|
|
1129
1330
|
// pack named is what keeps an unrelated `get` out.
|
|
1130
1331
|
(0, import_datalog4.rule)(
|
|
1131
|
-
"
|
|
1132
|
-
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"),
|
|
1332
|
+
"hop",
|
|
1333
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
|
|
1133
1334
|
[
|
|
1134
1335
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1135
1336
|
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
|
|
@@ -1146,8 +1347,8 @@ var RESOLUTION_RULES = [
|
|
|
1146
1347
|
// anything, keyed on the module it was imported from so a project
|
|
1147
1348
|
// function spelled the same way is not mistaken for it.
|
|
1148
1349
|
(0, import_datalog4.rule)(
|
|
1149
|
-
"
|
|
1150
|
-
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"),
|
|
1350
|
+
"hop",
|
|
1351
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
|
|
1151
1352
|
[
|
|
1152
1353
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1153
1354
|
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n")),
|
|
@@ -1157,10 +1358,24 @@ var RESOLUTION_RULES = [
|
|
|
1157
1358
|
],
|
|
1158
1359
|
"declared import finder"
|
|
1159
1360
|
),
|
|
1361
|
+
// A block opened over a library's own constructor. The pack says
|
|
1362
|
+
// entering one gives back the object it built, so the name the block
|
|
1363
|
+
// opens is that call.
|
|
1364
|
+
(0, import_datalog4.rule)(
|
|
1365
|
+
"hop",
|
|
1366
|
+
[(0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("r"), VALUE_STEP],
|
|
1367
|
+
[
|
|
1368
|
+
(0, import_datalog4.lit)("entersAs", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("r")),
|
|
1369
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
1370
|
+
(0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n")),
|
|
1371
|
+
(0, import_datalog4.lit)("entersAsSelf", (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n"))
|
|
1372
|
+
],
|
|
1373
|
+
"context manager returns self"
|
|
1374
|
+
),
|
|
1160
1375
|
// Wrapper transparency, derived: calling a factory that returns a
|
|
1161
1376
|
// function which calls its parameter k steps to argument k.
|
|
1162
1377
|
(0, import_datalog4.rule)(
|
|
1163
|
-
"
|
|
1378
|
+
"hop",
|
|
1164
1379
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
|
|
1165
1380
|
[
|
|
1166
1381
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
|
|
@@ -1174,7 +1389,7 @@ var RESOLUTION_RULES = [
|
|
|
1174
1389
|
// argument k. The callee has to come from the library the pack said,
|
|
1175
1390
|
// so a local object spelled the same way is not mistaken for it.
|
|
1176
1391
|
(0, import_datalog4.rule)(
|
|
1177
|
-
"
|
|
1392
|
+
"hop",
|
|
1178
1393
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
|
|
1179
1394
|
[
|
|
1180
1395
|
(0, import_datalog4.lit)("calleeName", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n")),
|
|
@@ -1188,44 +1403,441 @@ var RESOLUTION_RULES = [
|
|
|
1188
1403
|
// The one step that runs a function forwards: a call steps to what
|
|
1189
1404
|
// the function it invokes returns.
|
|
1190
1405
|
(0, import_datalog4.rule)(
|
|
1191
|
-
"
|
|
1406
|
+
"hop",
|
|
1192
1407
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("ret"), RESULT_STEP],
|
|
1193
1408
|
[(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"))],
|
|
1194
1409
|
"call result"
|
|
1195
1410
|
),
|
|
1196
|
-
//
|
|
1197
|
-
//
|
|
1198
|
-
//
|
|
1411
|
+
// What a function says it gives back when its body never states a
|
|
1412
|
+
// value. The adapter stays quiet about the annotation whenever the
|
|
1413
|
+
// body does state one, so the two never answer the same question.
|
|
1414
|
+
(0, import_datalog4.rule)(
|
|
1415
|
+
"hop",
|
|
1416
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), RESULT_STEP],
|
|
1417
|
+
[
|
|
1418
|
+
(0, import_datalog4.lit)("invokes", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
|
|
1419
|
+
(0, import_datalog4.lit)("returnsClass", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("x")),
|
|
1420
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls")),
|
|
1421
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls"))
|
|
1422
|
+
],
|
|
1423
|
+
"declared return type"
|
|
1424
|
+
),
|
|
1425
|
+
// Where a walk gets to, under the strongest step it took: value, then
|
|
1426
|
+
// instance, then result. The walk so far comes first, so demand stays
|
|
1427
|
+
// on the value asked about; the README says what the other order cost.
|
|
1199
1428
|
(0, import_datalog4.rule)(
|
|
1200
1429
|
"reaches",
|
|
1201
1430
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind")],
|
|
1202
1431
|
[(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))]
|
|
1203
1432
|
),
|
|
1433
|
+
// A rule per pair rather than one leaving the next step's kind free. A
|
|
1434
|
+
// free kind is a second question about the same relation, and a
|
|
1435
|
+
// demand-driven run then derives both to answer either.
|
|
1436
|
+
...STEP_LATTICE.map(
|
|
1437
|
+
({ soFar, next, took }) => (0, import_datalog4.rule)(
|
|
1438
|
+
"reaches",
|
|
1439
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), took],
|
|
1440
|
+
[
|
|
1441
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), soFar),
|
|
1442
|
+
(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), next)
|
|
1443
|
+
]
|
|
1444
|
+
)
|
|
1445
|
+
),
|
|
1446
|
+
// A context is an allocation site, or nothing at all for a value read
|
|
1447
|
+
// outside every site. Both are stated, so a rule that starts a walk
|
|
1448
|
+
// binds its context from a premise rather than from a negation.
|
|
1449
|
+
(0, import_datalog4.rule)("context", [NO_CONTEXT], [], "no context"),
|
|
1450
|
+
(0, import_datalog4.rule)(
|
|
1451
|
+
"context",
|
|
1452
|
+
[(0, import_datalog4.variable)("site")],
|
|
1453
|
+
[(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))],
|
|
1454
|
+
"site context"
|
|
1455
|
+
),
|
|
1456
|
+
// The same closure, with the context the walk started under and the
|
|
1457
|
+
// context it arrived under. It takes `hop`, because an argument and a
|
|
1458
|
+
// property read have their own rules below.
|
|
1459
|
+
(0, import_datalog4.rule)(
|
|
1460
|
+
"reachesUnder",
|
|
1461
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("kind")],
|
|
1462
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("hop", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))],
|
|
1463
|
+
"under one hop"
|
|
1464
|
+
),
|
|
1465
|
+
...STEP_LATTICE.map(
|
|
1466
|
+
({ soFar, next, took }) => (0, import_datalog4.rule)(
|
|
1467
|
+
"reachesUnder",
|
|
1468
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), took],
|
|
1469
|
+
[
|
|
1470
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), soFar),
|
|
1471
|
+
(0, import_datalog4.lit)("hop", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), next)
|
|
1472
|
+
]
|
|
1473
|
+
)
|
|
1474
|
+
),
|
|
1475
|
+
// The receiver read under a site is that site. The ordinary hop from a
|
|
1476
|
+
// receiver to its class stays in `hop`, so `self` under any context
|
|
1477
|
+
// still comes to the class a single-answer reader wants.
|
|
1204
1478
|
(0, import_datalog4.rule)(
|
|
1205
|
-
"
|
|
1206
|
-
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("
|
|
1479
|
+
"reachesUnder",
|
|
1480
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c"), VALUE_STEP],
|
|
1481
|
+
[(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls")), (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("cls"))],
|
|
1482
|
+
"receiver is the site"
|
|
1483
|
+
),
|
|
1484
|
+
(0, import_datalog4.rule)(
|
|
1485
|
+
"reachesUnder",
|
|
1486
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")],
|
|
1207
1487
|
[
|
|
1208
|
-
(0, import_datalog4.lit)("
|
|
1209
|
-
(0, import_datalog4.lit)("
|
|
1488
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
|
|
1489
|
+
(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("cls")),
|
|
1490
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("cls"))
|
|
1491
|
+
],
|
|
1492
|
+
"reached receiver is the site"
|
|
1493
|
+
),
|
|
1494
|
+
// The object an expression refers to under a context. A site is an
|
|
1495
|
+
// answer here, unlike `objectOf`, and the class an instance is one of
|
|
1496
|
+
// is an answer only under no context.
|
|
1497
|
+
(0, import_datalog4.rule)(
|
|
1498
|
+
"objectOfUnder",
|
|
1499
|
+
[(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")],
|
|
1500
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))],
|
|
1501
|
+
"site is its own object"
|
|
1502
|
+
),
|
|
1503
|
+
(0, import_datalog4.rule)(
|
|
1504
|
+
"objectOfUnder",
|
|
1505
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")],
|
|
1506
|
+
[
|
|
1507
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1508
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
|
|
1509
|
+
],
|
|
1510
|
+
"name of a site"
|
|
1511
|
+
),
|
|
1512
|
+
(0, import_datalog4.rule)(
|
|
1513
|
+
"objectOfUnder",
|
|
1514
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")],
|
|
1515
|
+
[
|
|
1516
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1517
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))
|
|
1518
|
+
],
|
|
1519
|
+
"written object under a context"
|
|
1520
|
+
),
|
|
1521
|
+
(0, import_datalog4.rule)(
|
|
1522
|
+
"objectOfUnder",
|
|
1523
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")],
|
|
1524
|
+
[
|
|
1525
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("c2"), RESULT_STEP),
|
|
1526
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))
|
|
1527
|
+
],
|
|
1528
|
+
"returned object under a context"
|
|
1529
|
+
),
|
|
1530
|
+
(0, import_datalog4.rule)(
|
|
1531
|
+
"objectOfUnder",
|
|
1532
|
+
[(0, import_datalog4.variable)("o"), NO_CONTEXT, (0, import_datalog4.variable)("cls")],
|
|
1533
|
+
[
|
|
1534
|
+
(0, import_datalog4.lit)(
|
|
1535
|
+
"reachesUnder",
|
|
1536
|
+
(0, import_datalog4.variable)("o"),
|
|
1537
|
+
NO_CONTEXT,
|
|
1538
|
+
(0, import_datalog4.variable)("cls"),
|
|
1539
|
+
NO_CONTEXT,
|
|
1540
|
+
INSTANCE_STEP
|
|
1541
|
+
),
|
|
1542
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls"))
|
|
1543
|
+
],
|
|
1544
|
+
"class reached with no context"
|
|
1545
|
+
),
|
|
1546
|
+
(0, import_datalog4.rule)(
|
|
1547
|
+
"objectOfUnder",
|
|
1548
|
+
[(0, import_datalog4.variable)("o"), NO_CONTEXT, (0, import_datalog4.variable)("cls")],
|
|
1549
|
+
[(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("cls"))],
|
|
1550
|
+
"receiver class with no context"
|
|
1551
|
+
),
|
|
1552
|
+
(0, import_datalog4.rule)(
|
|
1553
|
+
"objectOfUnder",
|
|
1554
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o")],
|
|
1555
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("o"))],
|
|
1556
|
+
"object under a context is itself"
|
|
1557
|
+
),
|
|
1558
|
+
// A property read goes on under the site the object was made at, so a
|
|
1559
|
+
// field read off two constructions gives each one its own value. A
|
|
1560
|
+
// class or a literal object keeps the context the walk was already in.
|
|
1561
|
+
(0, import_datalog4.rule)(
|
|
1562
|
+
"reachesUnder",
|
|
1563
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("site"), VALUE_STEP],
|
|
1564
|
+
[
|
|
1565
|
+
(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
|
|
1566
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
1567
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")),
|
|
1568
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
1569
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1570
|
+
],
|
|
1571
|
+
"property read at a site"
|
|
1572
|
+
),
|
|
1573
|
+
(0, import_datalog4.rule)(
|
|
1574
|
+
"reachesUnder",
|
|
1575
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("c"), VALUE_STEP],
|
|
1576
|
+
[
|
|
1577
|
+
(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
|
|
1578
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
1579
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")),
|
|
1580
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj")),
|
|
1581
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1582
|
+
],
|
|
1583
|
+
"property read off an object"
|
|
1584
|
+
),
|
|
1585
|
+
(0, import_datalog4.rule)(
|
|
1586
|
+
"reachesUnder",
|
|
1587
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("kind")],
|
|
1588
|
+
[
|
|
1589
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
|
|
1590
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
1591
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("site")),
|
|
1592
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
1593
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1594
|
+
],
|
|
1595
|
+
"reached property read at a site"
|
|
1596
|
+
),
|
|
1597
|
+
(0, import_datalog4.rule)(
|
|
1598
|
+
"reachesUnder",
|
|
1599
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")],
|
|
1600
|
+
[
|
|
1601
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
|
|
1602
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
1603
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("obj")),
|
|
1604
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj")),
|
|
1605
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1606
|
+
],
|
|
1607
|
+
"reached property read off an object"
|
|
1608
|
+
),
|
|
1609
|
+
// A parameter goes on at the argument, under the context its caller
|
|
1610
|
+
// was read in, and only from the calls that run the function under the
|
|
1611
|
+
// context the walk is in. This is the one hop that changes context.
|
|
1612
|
+
(0, import_datalog4.rule)(
|
|
1613
|
+
"reachesUnder",
|
|
1614
|
+
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), VALUE_STEP],
|
|
1615
|
+
[
|
|
1616
|
+
(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
|
|
1617
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("p")),
|
|
1618
|
+
(0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c3")),
|
|
1619
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("a"))
|
|
1620
|
+
],
|
|
1621
|
+
"argument under a context"
|
|
1622
|
+
),
|
|
1623
|
+
(0, import_datalog4.rule)(
|
|
1624
|
+
"reachesUnder",
|
|
1625
|
+
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), VALUE_STEP],
|
|
1626
|
+
[
|
|
1627
|
+
(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
|
|
1628
|
+
(0, import_datalog4.lit)("paramNamed", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")),
|
|
1629
|
+
(0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c3")),
|
|
1630
|
+
(0, import_datalog4.lit)("callKeywordArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("a"))
|
|
1631
|
+
],
|
|
1632
|
+
"keyword argument under a context"
|
|
1633
|
+
),
|
|
1634
|
+
(0, import_datalog4.rule)(
|
|
1635
|
+
"reachesUnder",
|
|
1636
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), (0, import_datalog4.variable)("kind")],
|
|
1637
|
+
[
|
|
1638
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
|
|
1639
|
+
(0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("p")),
|
|
1640
|
+
(0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c3")),
|
|
1641
|
+
(0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("a"))
|
|
1642
|
+
],
|
|
1643
|
+
"reached argument under a context"
|
|
1644
|
+
),
|
|
1645
|
+
(0, import_datalog4.rule)(
|
|
1646
|
+
"reachesUnder",
|
|
1647
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), (0, import_datalog4.variable)("kind")],
|
|
1648
|
+
[
|
|
1649
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
|
|
1650
|
+
(0, import_datalog4.lit)("paramNamed", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")),
|
|
1651
|
+
(0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c3")),
|
|
1652
|
+
(0, import_datalog4.lit)("callKeywordArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("a"))
|
|
1653
|
+
],
|
|
1654
|
+
"reached keyword argument under a context"
|
|
1655
|
+
),
|
|
1656
|
+
// Which call runs which function under which context. A construction
|
|
1657
|
+
// runs its constructor under the site it makes, a method call runs
|
|
1658
|
+
// under the site its receiver is, and anything else under no context.
|
|
1659
|
+
(0, import_datalog4.rule)(
|
|
1660
|
+
"entersUnder",
|
|
1661
|
+
[(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("ctor"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller")],
|
|
1662
|
+
[
|
|
1663
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
1664
|
+
(0, import_datalog4.lit)("runsConstructor", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("ctor")),
|
|
1665
|
+
(0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller"))
|
|
1666
|
+
],
|
|
1667
|
+
"construction enters its constructor"
|
|
1668
|
+
),
|
|
1669
|
+
(0, import_datalog4.rule)(
|
|
1670
|
+
"entersUnder",
|
|
1671
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller")],
|
|
1672
|
+
[
|
|
1673
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cal")),
|
|
1674
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("cal"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
|
|
1675
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("caller"), (0, import_datalog4.variable)("site")),
|
|
1676
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
1677
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
|
|
1678
|
+
(0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("caller"))
|
|
1679
|
+
],
|
|
1680
|
+
"method call enters under its receiver"
|
|
1681
|
+
),
|
|
1682
|
+
// A call written as a name runs with whatever receiver the body
|
|
1683
|
+
// around it has, so a plain function called from a method keeps the
|
|
1684
|
+
// site rather than taking every caller of it.
|
|
1685
|
+
(0, import_datalog4.rule)(
|
|
1686
|
+
"entersUnder",
|
|
1687
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c")],
|
|
1688
|
+
[
|
|
1689
|
+
(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
|
|
1690
|
+
(0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
|
|
1691
|
+
(0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
|
|
1692
|
+
],
|
|
1693
|
+
"named call enters under the site it is made in"
|
|
1694
|
+
),
|
|
1695
|
+
(0, import_datalog4.rule)(
|
|
1696
|
+
"entersUnder",
|
|
1697
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), NO_CONTEXT, (0, import_datalog4.variable)("caller")],
|
|
1698
|
+
[
|
|
1699
|
+
(0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
|
|
1700
|
+
(0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("caller"))
|
|
1701
|
+
],
|
|
1702
|
+
"call enters with no context"
|
|
1703
|
+
),
|
|
1704
|
+
// The constructor a construction runs, the ancestry included, so a
|
|
1705
|
+
// subclass that declares none still fills in what it inherits.
|
|
1706
|
+
(0, import_datalog4.rule)(
|
|
1707
|
+
"runsConstructor",
|
|
1708
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")],
|
|
1709
|
+
[(0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f"))]
|
|
1710
|
+
),
|
|
1711
|
+
(0, import_datalog4.rule)(
|
|
1712
|
+
"runsConstructor",
|
|
1713
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")],
|
|
1714
|
+
[
|
|
1715
|
+
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("b")),
|
|
1716
|
+
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("base")),
|
|
1717
|
+
(0, import_datalog4.lit)("runsConstructor", (0, import_datalog4.variable)("base"), (0, import_datalog4.variable)("f"))
|
|
1210
1718
|
]
|
|
1211
1719
|
),
|
|
1212
|
-
//
|
|
1213
|
-
//
|
|
1214
|
-
// demand-driven run then derives both to answer either.
|
|
1720
|
+
// Which body a call is written in. One adapter states the call it
|
|
1721
|
+
// found and another states the callee, so both spellings are read.
|
|
1215
1722
|
(0, import_datalog4.rule)(
|
|
1216
|
-
"
|
|
1217
|
-
[(0, import_datalog4.variable)("
|
|
1723
|
+
"callInBody",
|
|
1724
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")],
|
|
1725
|
+
[(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
|
|
1726
|
+
),
|
|
1727
|
+
(0, import_datalog4.rule)(
|
|
1728
|
+
"callInBody",
|
|
1729
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")],
|
|
1730
|
+
[(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
|
|
1731
|
+
),
|
|
1732
|
+
// The context a call is made under: every site of the class whose
|
|
1733
|
+
// method or constructor it is written in, and no context for a call
|
|
1734
|
+
// outside every method body.
|
|
1735
|
+
(0, import_datalog4.rule)(
|
|
1736
|
+
"callUnder",
|
|
1737
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("site")],
|
|
1738
|
+
[
|
|
1739
|
+
(0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
|
|
1740
|
+
(0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
|
|
1741
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
|
|
1742
|
+
],
|
|
1743
|
+
"call in a method"
|
|
1744
|
+
),
|
|
1745
|
+
(0, import_datalog4.rule)(
|
|
1746
|
+
"callUnder",
|
|
1747
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("site")],
|
|
1218
1748
|
[
|
|
1219
|
-
(0, import_datalog4.lit)("
|
|
1220
|
-
(0, import_datalog4.lit)("
|
|
1749
|
+
(0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
|
|
1750
|
+
(0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")),
|
|
1751
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
|
|
1752
|
+
],
|
|
1753
|
+
"call in a constructor"
|
|
1754
|
+
),
|
|
1755
|
+
// A plain function entered under a site makes its own calls under
|
|
1756
|
+
// that site, so a chain of plain functions off one method keeps it.
|
|
1757
|
+
(0, import_datalog4.rule)(
|
|
1758
|
+
"callUnder",
|
|
1759
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")],
|
|
1760
|
+
[
|
|
1761
|
+
(0, import_datalog4.lit)("callOutsideMethod", (0, import_datalog4.variable)("r")),
|
|
1762
|
+
(0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
|
|
1763
|
+
(0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("into"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c4"))
|
|
1764
|
+
],
|
|
1765
|
+
"call in a function entered under a site"
|
|
1766
|
+
),
|
|
1767
|
+
(0, import_datalog4.rule)(
|
|
1768
|
+
"callUnder",
|
|
1769
|
+
[(0, import_datalog4.variable)("r"), NO_CONTEXT],
|
|
1770
|
+
[(0, import_datalog4.lit)("callOutsideMethod", (0, import_datalog4.variable)("r"))],
|
|
1771
|
+
"call outside every method"
|
|
1772
|
+
),
|
|
1773
|
+
// The two questions a caller puts under a context, stopping where
|
|
1774
|
+
// `isWrittenAs` and `comesTo` stop, whatever context the walk ended in.
|
|
1775
|
+
(0, import_datalog4.rule)(
|
|
1776
|
+
"isWrittenAsUnder",
|
|
1777
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
|
|
1778
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("x"))]
|
|
1779
|
+
),
|
|
1780
|
+
(0, import_datalog4.rule)(
|
|
1781
|
+
"isWrittenAsUnder",
|
|
1782
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
|
|
1783
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]
|
|
1784
|
+
),
|
|
1785
|
+
(0, import_datalog4.rule)(
|
|
1786
|
+
"isWrittenAsUnder",
|
|
1787
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1788
|
+
[
|
|
1789
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1790
|
+
(0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("z"))
|
|
1221
1791
|
]
|
|
1222
1792
|
),
|
|
1223
1793
|
(0, import_datalog4.rule)(
|
|
1224
|
-
"
|
|
1225
|
-
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("
|
|
1794
|
+
"isWrittenAsUnder",
|
|
1795
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1796
|
+
[
|
|
1797
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1798
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
|
|
1799
|
+
]
|
|
1800
|
+
),
|
|
1801
|
+
(0, import_datalog4.rule)(
|
|
1802
|
+
"comesToUnder",
|
|
1803
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
|
|
1804
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("x"))]
|
|
1805
|
+
),
|
|
1806
|
+
(0, import_datalog4.rule)(
|
|
1807
|
+
"comesToUnder",
|
|
1808
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
|
|
1809
|
+
[(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]
|
|
1810
|
+
),
|
|
1811
|
+
(0, import_datalog4.rule)(
|
|
1812
|
+
"comesToUnder",
|
|
1813
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1814
|
+
[
|
|
1815
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1816
|
+
(0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))
|
|
1817
|
+
]
|
|
1818
|
+
),
|
|
1819
|
+
(0, import_datalog4.rule)(
|
|
1820
|
+
"comesToUnder",
|
|
1821
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1226
1822
|
[
|
|
1227
|
-
(0, import_datalog4.lit)("
|
|
1228
|
-
(0, import_datalog4.lit)("
|
|
1823
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
|
|
1824
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
|
|
1825
|
+
]
|
|
1826
|
+
),
|
|
1827
|
+
(0, import_datalog4.rule)(
|
|
1828
|
+
"comesToUnder",
|
|
1829
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1830
|
+
[
|
|
1831
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), INSTANCE_STEP),
|
|
1832
|
+
(0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))
|
|
1833
|
+
]
|
|
1834
|
+
),
|
|
1835
|
+
(0, import_datalog4.rule)(
|
|
1836
|
+
"comesToUnder",
|
|
1837
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
1838
|
+
[
|
|
1839
|
+
(0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), INSTANCE_STEP),
|
|
1840
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
|
|
1229
1841
|
]
|
|
1230
1842
|
),
|
|
1231
1843
|
// What a value comes down to: the walk that never ran a call, stopped
|
|
@@ -1243,6 +1855,18 @@ var RESOLUTION_RULES = [
|
|
|
1243
1855
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1244
1856
|
[(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"))]
|
|
1245
1857
|
),
|
|
1858
|
+
// An instance walk stops the same way, so a method read off
|
|
1859
|
+
// `new App()` still finds what the class declares.
|
|
1860
|
+
(0, import_datalog4.rule)(
|
|
1861
|
+
"comesTo",
|
|
1862
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1863
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), INSTANCE_STEP), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
|
|
1864
|
+
),
|
|
1865
|
+
(0, import_datalog4.rule)(
|
|
1866
|
+
"comesTo",
|
|
1867
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1868
|
+
[(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), INSTANCE_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
|
|
1869
|
+
),
|
|
1246
1870
|
// The same stopping condition, for the walk that ran a call. A call
|
|
1247
1871
|
// gets no `comesTo` answer on purpose: coming back with what a
|
|
1248
1872
|
// factory returned would fight the unwrapping answer.
|
|
@@ -1283,6 +1907,13 @@ var RESOLUTION_RULES = [
|
|
|
1283
1907
|
(0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("ret"), (0, import_datalog4.variable)("z"))
|
|
1284
1908
|
]
|
|
1285
1909
|
),
|
|
1910
|
+
// Which expression running f hands back, whether f returns it, writes
|
|
1911
|
+
// it into a name first, or ends on it as a shorthand body.
|
|
1912
|
+
(0, import_datalog4.rule)(
|
|
1913
|
+
"returnsCall",
|
|
1914
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")],
|
|
1915
|
+
[(0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("v")), (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("v"), (0, import_datalog4.variable)("c"))]
|
|
1916
|
+
),
|
|
1286
1917
|
// What one call site put in a parameter, told apart from what the
|
|
1287
1918
|
// other callers passed.
|
|
1288
1919
|
(0, import_datalog4.rule)(
|
|
@@ -1380,18 +2011,34 @@ var RESOLUTION_RULES = [
|
|
|
1380
2011
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
|
|
1381
2012
|
[(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"))]
|
|
1382
2013
|
),
|
|
2014
|
+
// A construction is the object it made, and so is any name for it.
|
|
2015
|
+
// The class stays an answer too, so an instance whose site is not in
|
|
2016
|
+
// the run still reads what the class stores.
|
|
2017
|
+
(0, import_datalog4.rule)(
|
|
2018
|
+
"objectOf",
|
|
2019
|
+
[(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("site")],
|
|
2020
|
+
[(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"))]
|
|
2021
|
+
),
|
|
2022
|
+
(0, import_datalog4.rule)(
|
|
2023
|
+
"objectOf",
|
|
2024
|
+
[(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("site")],
|
|
2025
|
+
[
|
|
2026
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("site"), VALUE_STEP),
|
|
2027
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"))
|
|
2028
|
+
]
|
|
2029
|
+
),
|
|
1383
2030
|
// Which calls a function, found by the name the call is written as
|
|
1384
2031
|
// rather than by resolving every callee in the project. A caller knows
|
|
1385
2032
|
// the function and wants its call sites, so both of these start from
|
|
1386
2033
|
// the function. Starting from `call` instead asks what every call in
|
|
1387
2034
|
// the project imports, which was 72% of everything derived.
|
|
1388
2035
|
(0, import_datalog4.rule)(
|
|
1389
|
-
"
|
|
2036
|
+
"callsNamed",
|
|
1390
2037
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1391
2038
|
[(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"))]
|
|
1392
2039
|
),
|
|
1393
2040
|
(0, import_datalog4.rule)(
|
|
1394
|
-
"
|
|
2041
|
+
"callsNamed",
|
|
1395
2042
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1396
2043
|
[
|
|
1397
2044
|
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
|
|
@@ -1402,7 +2049,7 @@ var RESOLUTION_RULES = [
|
|
|
1402
2049
|
// The same, for a language whose adapter writes the import down as a
|
|
1403
2050
|
// declaration and the call's callee as the name referring to it.
|
|
1404
2051
|
(0, import_datalog4.rule)(
|
|
1405
|
-
"
|
|
2052
|
+
"callsNamed",
|
|
1406
2053
|
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
1407
2054
|
[
|
|
1408
2055
|
(0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
|
|
@@ -1411,6 +2058,36 @@ var RESOLUTION_RULES = [
|
|
|
1411
2058
|
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
|
|
1412
2059
|
]
|
|
1413
2060
|
),
|
|
2061
|
+
// `const f = (x) => ...` declares the name and puts the parameters on
|
|
2062
|
+
// the arrow, so everything above arrives at the declaration and
|
|
2063
|
+
// `paramOf` is about the arrow. One binds hop joins the two.
|
|
2064
|
+
(0, import_datalog4.rule)(
|
|
2065
|
+
"callsNamed",
|
|
2066
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
2067
|
+
[(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("g"))]
|
|
2068
|
+
),
|
|
2069
|
+
// Every one of those, and the binds hop again over the whole
|
|
2070
|
+
// relation, so a property holding a name for a function is reached
|
|
2071
|
+
// the way it was before the two were told apart.
|
|
2072
|
+
(0, import_datalog4.rule)("callsFunction", [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")], [(0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"))]),
|
|
2073
|
+
(0, import_datalog4.rule)(
|
|
2074
|
+
"callsFunction",
|
|
2075
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
2076
|
+
[(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("g"))]
|
|
2077
|
+
),
|
|
2078
|
+
// A function written on an object, called off it: `client.get(o)`.
|
|
2079
|
+
// Every rule above joins on a name the callee binds to, and a read of
|
|
2080
|
+
// a property binds to nothing.
|
|
2081
|
+
(0, import_datalog4.rule)(
|
|
2082
|
+
"callsFunction",
|
|
2083
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
|
|
2084
|
+
[
|
|
2085
|
+
(0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
|
|
2086
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
2087
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("obj")),
|
|
2088
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
|
|
2089
|
+
]
|
|
2090
|
+
),
|
|
1414
2091
|
// What an object contains, its base class included, so a method the base
|
|
1415
2092
|
// declares is found on a subclass that never overrode it. A method both
|
|
1416
2093
|
// declare gives two, and the caller decides. This is its own relation
|
|
@@ -1428,7 +2105,8 @@ var RESOLUTION_RULES = [
|
|
|
1428
2105
|
(0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("base")),
|
|
1429
2106
|
(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("base"), (0, import_datalog4.variable)("baseCls")),
|
|
1430
2107
|
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("baseCls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
1431
|
-
]
|
|
2108
|
+
],
|
|
2109
|
+
BASE_CLASS_RULE
|
|
1432
2110
|
),
|
|
1433
2111
|
// An association is read off an instance as a property, and stating
|
|
1434
2112
|
// it as `contains` is what puts it on the ancestry rule, so a concern
|
|
@@ -1452,6 +2130,69 @@ var RESOLUTION_RULES = [
|
|
|
1452
2130
|
],
|
|
1453
2131
|
"constructed association"
|
|
1454
2132
|
),
|
|
2133
|
+
// What the constructor put on the receiver. The class is the object
|
|
2134
|
+
// for an instance whose own site is not in the run.
|
|
2135
|
+
(0, import_datalog4.rule)(
|
|
2136
|
+
"contains",
|
|
2137
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
2138
|
+
[
|
|
2139
|
+
(0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")),
|
|
2140
|
+
(0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
2141
|
+
],
|
|
2142
|
+
"constructor store"
|
|
2143
|
+
),
|
|
2144
|
+
// What any other method of the class put there. Two methods writing
|
|
2145
|
+
// one name give two rows, since nothing here orders them.
|
|
2146
|
+
(0, import_datalog4.rule)(
|
|
2147
|
+
"contains",
|
|
2148
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
2149
|
+
[
|
|
2150
|
+
(0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
|
|
2151
|
+
(0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
2152
|
+
],
|
|
2153
|
+
"method store"
|
|
2154
|
+
),
|
|
2155
|
+
// A write through a name rather than through the receiver,
|
|
2156
|
+
// `client.timeout = 5`, which lands on whatever that name refers to.
|
|
2157
|
+
(0, import_datalog4.rule)(
|
|
2158
|
+
"contains",
|
|
2159
|
+
[(0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
2160
|
+
[
|
|
2161
|
+
(0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")),
|
|
2162
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("obj"))
|
|
2163
|
+
],
|
|
2164
|
+
"named receiver store"
|
|
2165
|
+
),
|
|
2166
|
+
// A call written with a class's own name, which is how most languages
|
|
2167
|
+
// spell a construction. A language that spells one some other way
|
|
2168
|
+
// states its own rule for this, the way Ruby does for `Const.new`.
|
|
2169
|
+
(0, import_datalog4.rule)(
|
|
2170
|
+
"constructsNamed",
|
|
2171
|
+
[(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls")],
|
|
2172
|
+
[(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls")), (0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"))]
|
|
2173
|
+
),
|
|
2174
|
+
// Each construction is an object of its own containing what its
|
|
2175
|
+
// class stores, so two sites are two objects.
|
|
2176
|
+
(0, import_datalog4.rule)(
|
|
2177
|
+
"contains",
|
|
2178
|
+
[(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
|
|
2179
|
+
[
|
|
2180
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
2181
|
+
(0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
|
|
2182
|
+
],
|
|
2183
|
+
"allocated instance"
|
|
2184
|
+
),
|
|
2185
|
+
// A call that makes one of a class. Every finder a pack declared is
|
|
2186
|
+
// one too, so `User.find(1)` is a site the same way `User.new` is.
|
|
2187
|
+
(0, import_datalog4.rule)(
|
|
2188
|
+
"allocates",
|
|
2189
|
+
[(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")],
|
|
2190
|
+
[
|
|
2191
|
+
(0, import_datalog4.lit)("call", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c")),
|
|
2192
|
+
(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP)
|
|
2193
|
+
],
|
|
2194
|
+
"allocation site"
|
|
2195
|
+
),
|
|
1455
2196
|
// The library base a class's ancestry arrives at, however many of a
|
|
1456
2197
|
// project's own classes sit in between. A base the run declares has a
|
|
1457
2198
|
// node to keep walking from; one it does not has only a name.
|
|
@@ -1541,8 +2282,8 @@ var RESOLUTION_RULES = [
|
|
|
1541
2282
|
]
|
|
1542
2283
|
),
|
|
1543
2284
|
// Where a name comes from, when what it refers to lives outside the
|
|
1544
|
-
// source being read. A walk ends at
|
|
1545
|
-
//
|
|
2285
|
+
// source being read. A walk ends at what the source writes out, so it
|
|
2286
|
+
// never reaches a library's own function; these rules do.
|
|
1546
2287
|
(0, import_datalog4.rule)(
|
|
1547
2288
|
"comesFrom",
|
|
1548
2289
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
@@ -1556,6 +2297,28 @@ var RESOLUTION_RULES = [
|
|
|
1556
2297
|
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
|
|
1557
2298
|
]
|
|
1558
2299
|
),
|
|
2300
|
+
// A member read off a whole-module import: the member's own name is
|
|
2301
|
+
// what the module exports, so `fastapi.APIRouter` comes from
|
|
2302
|
+
// fastapi's `APIRouter`. Directly, or through a name for the module.
|
|
2303
|
+
(0, import_datalog4.rule)(
|
|
2304
|
+
"comesFrom",
|
|
2305
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
2306
|
+
[
|
|
2307
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("n")),
|
|
2308
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT)
|
|
2309
|
+
],
|
|
2310
|
+
NAMESPACE_MEMBER_RULE
|
|
2311
|
+
),
|
|
2312
|
+
(0, import_datalog4.rule)(
|
|
2313
|
+
"comesFrom",
|
|
2314
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
2315
|
+
[
|
|
2316
|
+
(0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
|
|
2317
|
+
(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("ns"), VALUE_STEP),
|
|
2318
|
+
(0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT)
|
|
2319
|
+
],
|
|
2320
|
+
NAMESPACE_MEMBER_RULE
|
|
2321
|
+
),
|
|
1559
2322
|
// Calling f ends up calling the name n that module m exports, one
|
|
1560
2323
|
// hop through f's own body or deeper through a wrapper of a wrapper.
|
|
1561
2324
|
// Several results is normal: a composed decorator applies them all.
|
|
@@ -1585,6 +2348,13 @@ var RESOLUTION_RULES = [
|
|
|
1585
2348
|
[(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"))]
|
|
1586
2349
|
)
|
|
1587
2350
|
];
|
|
2351
|
+
function alsoSteps(rules) {
|
|
2352
|
+
return [
|
|
2353
|
+
...rules,
|
|
2354
|
+
...rules.filter((r) => r.head.relation === "hop").map((r) => ({ ...r, head: { ...r.head, relation: "stepsTo" } }))
|
|
2355
|
+
];
|
|
2356
|
+
}
|
|
2357
|
+
var RESOLUTION_RULES = alsoSteps(STATED_RULES);
|
|
1588
2358
|
var RESOLUTION_QUESTIONS = [
|
|
1589
2359
|
(0, import_datalog4.rule)(
|
|
1590
2360
|
"wantedResolves",
|
|
@@ -1607,12 +2377,55 @@ var RESOLUTION_QUESTIONS = [
|
|
|
1607
2377
|
[(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"))]
|
|
1608
2378
|
),
|
|
1609
2379
|
// A call is given no `comesTo`, so this is the only way to ask what
|
|
1610
|
-
// object one arrives at, and
|
|
1611
|
-
//
|
|
2380
|
+
// object one arrives at, and a demand-driven run derives `objectOf`
|
|
2381
|
+
// nowhere without it. An allocation site is not one of the answers.
|
|
1612
2382
|
(0, import_datalog4.rule)(
|
|
1613
2383
|
"wantedObjectOf",
|
|
1614
2384
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
|
|
1615
|
-
[
|
|
2385
|
+
[
|
|
2386
|
+
(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")),
|
|
2387
|
+
(0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")),
|
|
2388
|
+
(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
|
|
2389
|
+
]
|
|
2390
|
+
),
|
|
2391
|
+
// The same three questions under one allocation site, keyed by the
|
|
2392
|
+
// value and the site both. An allocation site is an answer here,
|
|
2393
|
+
// unlike `wantedObjectOf`, since a site is what a context is.
|
|
2394
|
+
(0, import_datalog4.rule)(
|
|
2395
|
+
"wantedIsWrittenAsUnder",
|
|
2396
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
2397
|
+
[
|
|
2398
|
+
(0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
|
|
2399
|
+
(0, import_datalog4.lit)("isWrittenAsUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
|
|
2400
|
+
]
|
|
2401
|
+
),
|
|
2402
|
+
// Where a class was made, for a caller about to ask a value question
|
|
2403
|
+
// under each. Going through `constructsNamed` keeps the demand on the
|
|
2404
|
+
// calls written with the class's name rather than on every call.
|
|
2405
|
+
(0, import_datalog4.rule)(
|
|
2406
|
+
"wantedAllocatedAt",
|
|
2407
|
+
[(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("site")],
|
|
2408
|
+
[
|
|
2409
|
+
(0, import_datalog4.lit)("wantedSites", (0, import_datalog4.variable)("cls")),
|
|
2410
|
+
(0, import_datalog4.lit)("constructsNamed", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
|
|
2411
|
+
(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
|
|
2412
|
+
]
|
|
2413
|
+
),
|
|
2414
|
+
(0, import_datalog4.rule)(
|
|
2415
|
+
"wantedComesToUnder",
|
|
2416
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
2417
|
+
[
|
|
2418
|
+
(0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
|
|
2419
|
+
(0, import_datalog4.lit)("comesToUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
|
|
2420
|
+
]
|
|
2421
|
+
),
|
|
2422
|
+
(0, import_datalog4.rule)(
|
|
2423
|
+
"wantedObjectOfUnder",
|
|
2424
|
+
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
|
|
2425
|
+
[
|
|
2426
|
+
(0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
|
|
2427
|
+
(0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
|
|
2428
|
+
]
|
|
1616
2429
|
),
|
|
1617
2430
|
// The same for the function a call returns: `app.use(requireCaller(config))`
|
|
1618
2431
|
// registers what the factory gives back, and `resolves` on the call
|
|
@@ -1629,6 +2442,19 @@ var RESOLUTION_QUESTIONS = [
|
|
|
1629
2442
|
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("z")],
|
|
1630
2443
|
[(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"))]
|
|
1631
2444
|
),
|
|
2445
|
+
// The argument as the caller wrote it. A parameter given a GraphQL
|
|
2446
|
+
// document has no `paramAt` answer, since that settles through
|
|
2447
|
+
// `comesTo`, which stops at a function or an object.
|
|
2448
|
+
(0, import_datalog4.rule)(
|
|
2449
|
+
"wantedPassesArgument",
|
|
2450
|
+
[(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a")],
|
|
2451
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("p")), (0, import_datalog4.lit)("passesArgument", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a"))]
|
|
2452
|
+
),
|
|
2453
|
+
(0, import_datalog4.rule)(
|
|
2454
|
+
"wantedReturnsCall",
|
|
2455
|
+
[(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")],
|
|
2456
|
+
[(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("returnsCall", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"))]
|
|
2457
|
+
),
|
|
1632
2458
|
(0, import_datalog4.rule)(
|
|
1633
2459
|
"wantedComesFrom",
|
|
1634
2460
|
[(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
|
|
@@ -1892,36 +2718,59 @@ var RESOLUTION_QUESTIONS = [
|
|
|
1892
2718
|
var ANSWER_RELATIONS = [
|
|
1893
2719
|
...new Set(RESOLUTION_QUESTIONS.map((r) => r.head.relation))
|
|
1894
2720
|
];
|
|
2721
|
+
var UNDER_ANSWER_RELATIONS = [
|
|
2722
|
+
"wantedIsWrittenAsUnder",
|
|
2723
|
+
"wantedComesToUnder",
|
|
2724
|
+
"wantedObjectOfUnder"
|
|
2725
|
+
];
|
|
1895
2726
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1896
2727
|
0 && (module.exports = {
|
|
1897
2728
|
ANSWER_RELATIONS,
|
|
1898
2729
|
ASKING_RELATIONS,
|
|
2730
|
+
BASE_CLASS_RULE,
|
|
1899
2731
|
FACT_CONTRACT_CASES,
|
|
2732
|
+
INSTANCE_STEP,
|
|
1900
2733
|
NAMESPACE_IMPORT,
|
|
1901
2734
|
NAMESPACE_IMPORT_NAME,
|
|
2735
|
+
NAMESPACE_MEMBER_RULE,
|
|
2736
|
+
NO_CONTEXT,
|
|
2737
|
+
NO_CONTEXT_NAME,
|
|
1902
2738
|
RESOLUTION_QUESTIONS,
|
|
1903
2739
|
RESOLUTION_RULES,
|
|
1904
2740
|
RESULT_STEP,
|
|
2741
|
+
UNDER_ANSWER_RELATIONS,
|
|
1905
2742
|
VALUE_STEP,
|
|
2743
|
+
addPackWords,
|
|
1906
2744
|
agreedMountPrefix,
|
|
2745
|
+
allocationSitesOf,
|
|
2746
|
+
alsoSteps,
|
|
2747
|
+
answersByKey,
|
|
1907
2748
|
askResolution,
|
|
2749
|
+
askResolutionUnder,
|
|
1908
2750
|
calleeOutcomeOf,
|
|
1909
2751
|
calleeOutcomes,
|
|
1910
2752
|
checkFactContract,
|
|
2753
|
+
comesToUnder,
|
|
1911
2754
|
couldBeSettled,
|
|
1912
2755
|
explainResolutionProof,
|
|
1913
2756
|
explainResolvedKey,
|
|
2757
|
+
isWrittenAsUnder,
|
|
1914
2758
|
joinMountedPath,
|
|
1915
2759
|
mountPathsOf,
|
|
1916
2760
|
nodeOfKey,
|
|
2761
|
+
objectOfUnder,
|
|
1917
2762
|
placeholderValues,
|
|
1918
2763
|
queryFacts,
|
|
1919
2764
|
renderExplanation,
|
|
1920
2765
|
resolutionProgram,
|
|
2766
|
+
resolutionUnderProgram,
|
|
1921
2767
|
singleAnswers,
|
|
1922
2768
|
startsAtName,
|
|
1923
2769
|
valueLeftByWrites,
|
|
1924
2770
|
writesRunInOrder,
|
|
1925
2771
|
writtenSourcesOf,
|
|
1926
|
-
writtenValueOf
|
|
2772
|
+
writtenValueOf,
|
|
2773
|
+
writtenValueUnder,
|
|
2774
|
+
writtenValuesByKey,
|
|
2775
|
+
writtenValuesOf
|
|
1927
2776
|
});
|