@suss/resolution 0.35.0 → 0.36.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 +1380 -1208
- package/dist/index.d.cts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +1366 -1204
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -27,7 +27,8 @@ var ASKING_RELATIONS = [
|
|
|
27
27
|
"wantedType",
|
|
28
28
|
"wantedUses",
|
|
29
29
|
"wantedSource",
|
|
30
|
-
"wantedInputRead"
|
|
30
|
+
"wantedInputRead",
|
|
31
|
+
"wantedMembers"
|
|
31
32
|
];
|
|
32
33
|
var NO_LANGUAGE_RULES = [];
|
|
33
34
|
var programs = /* @__PURE__ */ new WeakMap();
|
|
@@ -1952,6 +1953,155 @@ function importedFilesByFile(db, displayPathOf) {
|
|
|
1952
1953
|
return byFile;
|
|
1953
1954
|
}
|
|
1954
1955
|
|
|
1956
|
+
// src/receiverSelf.ts
|
|
1957
|
+
import { constant, lit, rule, variable as v } from "@suss/datalog";
|
|
1958
|
+
var MEMBERS_QUESTION = "wantedMembers";
|
|
1959
|
+
var SELF_AS_CLASS_NAME = "class";
|
|
1960
|
+
var SELF_AS_CLASS = constant(SELF_AS_CLASS_NAME);
|
|
1961
|
+
var SELF_AS_INSTANCE_NAME = "instance";
|
|
1962
|
+
var SELF_AS_INSTANCE = constant(SELF_AS_INSTANCE_NAME);
|
|
1963
|
+
var SELF_RULES = [
|
|
1964
|
+
rule(
|
|
1965
|
+
"selfBehind",
|
|
1966
|
+
[v("s"), v("s"), v("form")],
|
|
1967
|
+
[lit("selfReceiver", v("f"), v("s"), v("form"))],
|
|
1968
|
+
"the receiver"
|
|
1969
|
+
),
|
|
1970
|
+
// `klass = self` or `job = new(...)`. Only names, so a receiver passed
|
|
1971
|
+
// into another method is that method's parameter and never its own.
|
|
1972
|
+
rule(
|
|
1973
|
+
"selfBehind",
|
|
1974
|
+
[v("x"), v("s"), v("form")],
|
|
1975
|
+
[
|
|
1976
|
+
lit("nameHop", v("x"), v("y")),
|
|
1977
|
+
lit("selfBehind", v("y"), v("s"), v("form"))
|
|
1978
|
+
],
|
|
1979
|
+
"a name for the receiver"
|
|
1980
|
+
),
|
|
1981
|
+
// Calling the class makes one of it: Python's `cls(...)` and
|
|
1982
|
+
// TypeScript's `new this(...)`.
|
|
1983
|
+
rule(
|
|
1984
|
+
"selfBehind",
|
|
1985
|
+
[v("r"), v("s"), SELF_AS_INSTANCE],
|
|
1986
|
+
[
|
|
1987
|
+
lit("call", v("r"), v("c")),
|
|
1988
|
+
lit("selfBehind", v("c"), v("s"), SELF_AS_CLASS)
|
|
1989
|
+
],
|
|
1990
|
+
"made from the receiver's class"
|
|
1991
|
+
),
|
|
1992
|
+
// A method that returns its receiver, or one made from it, returns the
|
|
1993
|
+
// caller's: `Report.build(x)` is a Report when `build` is
|
|
1994
|
+
// `def self.build(x) = new(x)`, whichever class `build` is written in.
|
|
1995
|
+
rule(
|
|
1996
|
+
"selfResult",
|
|
1997
|
+
[v("r"), v("o"), v("form")],
|
|
1998
|
+
[
|
|
1999
|
+
lit("call", v("r"), v("c")),
|
|
2000
|
+
lit("readsProperty", v("c"), v("o"), v("n")),
|
|
2001
|
+
lit("invokes", v("r"), v("f")),
|
|
2002
|
+
lit("returnsValue", v("f"), v("ret")),
|
|
2003
|
+
lit("selfReceiver", v("f"), v("s"), v("any")),
|
|
2004
|
+
lit("selfBehind", v("ret"), v("s"), v("form"))
|
|
2005
|
+
],
|
|
2006
|
+
"returns its receiver"
|
|
2007
|
+
),
|
|
2008
|
+
rule(
|
|
2009
|
+
"selfResult",
|
|
2010
|
+
[v("x"), v("o"), v("form")],
|
|
2011
|
+
[
|
|
2012
|
+
lit("nameHop", v("x"), v("y")),
|
|
2013
|
+
lit("selfResult", v("y"), v("o"), v("form"))
|
|
2014
|
+
],
|
|
2015
|
+
"a name for what it returned"
|
|
2016
|
+
)
|
|
2017
|
+
];
|
|
2018
|
+
var SELF_QUESTIONS = [
|
|
2019
|
+
rule(
|
|
2020
|
+
"wantedSelfBehind",
|
|
2021
|
+
[v("x"), v("s"), v("form")],
|
|
2022
|
+
[lit("wanted", v("x")), lit("selfBehind", v("x"), v("s"), v("form"))]
|
|
2023
|
+
),
|
|
2024
|
+
rule(
|
|
2025
|
+
"wantedSelfResult",
|
|
2026
|
+
[v("x"), v("o"), v("form")],
|
|
2027
|
+
[lit("wanted", v("x")), lit("selfResult", v("x"), v("o"), v("form"))]
|
|
2028
|
+
),
|
|
2029
|
+
// Every member a class has, its bases' included, and the ones a nearer
|
|
2030
|
+
// member overrides, for a walk that looks a method up on a subclass.
|
|
2031
|
+
rule(
|
|
2032
|
+
"wantedMemberOf",
|
|
2033
|
+
[v("cls"), v("n"), v("held")],
|
|
2034
|
+
[
|
|
2035
|
+
lit(MEMBERS_QUESTION, v("cls")),
|
|
2036
|
+
lit("contains", v("cls"), v("n"), v("held"))
|
|
2037
|
+
]
|
|
2038
|
+
),
|
|
2039
|
+
rule(
|
|
2040
|
+
"wantedMemberOverridden",
|
|
2041
|
+
[v("cls"), v("n"), v("h")],
|
|
2042
|
+
[
|
|
2043
|
+
lit(MEMBERS_QUESTION, v("cls")),
|
|
2044
|
+
lit("contains", v("cls"), v("n"), v("m")),
|
|
2045
|
+
lit("overrides", v("m"), v("n"), v("h"))
|
|
2046
|
+
]
|
|
2047
|
+
)
|
|
2048
|
+
];
|
|
2049
|
+
function selfResultOf(db, key) {
|
|
2050
|
+
const rows = db.lookup("wantedSelfResult", 0, key);
|
|
2051
|
+
const [only] = rows;
|
|
2052
|
+
return rows.length === 1 && only !== void 0 ? { receiver: String(only[1]), form: String(only[2]) } : null;
|
|
2053
|
+
}
|
|
2054
|
+
function selfFormOf(db, key, receiver) {
|
|
2055
|
+
const forms = new Set(
|
|
2056
|
+
db.lookup("wantedSelfBehind", 0, key).filter((row) => String(row[1]) === receiver).map((row) => String(row[2]))
|
|
2057
|
+
);
|
|
2058
|
+
const [only] = forms;
|
|
2059
|
+
return forms.size === 1 && only !== void 0 ? only : null;
|
|
2060
|
+
}
|
|
2061
|
+
var ON_SUBCLASS = "#on=";
|
|
2062
|
+
function variantKey(key, subclass) {
|
|
2063
|
+
return `${key}${ON_SUBCLASS}${encodeURIComponent(subclass.name)}@${encodeURIComponent(subclass.file)}`;
|
|
2064
|
+
}
|
|
2065
|
+
function plainKeyOf(key) {
|
|
2066
|
+
const at = key.indexOf(ON_SUBCLASS);
|
|
2067
|
+
return at === -1 ? key : key.slice(0, at);
|
|
2068
|
+
}
|
|
2069
|
+
function keptVariants(variants) {
|
|
2070
|
+
const callers = /* @__PURE__ */ new Map();
|
|
2071
|
+
for (const variant of variants) {
|
|
2072
|
+
for (const callee of variant.calls) {
|
|
2073
|
+
const known = callers.get(callee) ?? [];
|
|
2074
|
+
known.push(variant.key);
|
|
2075
|
+
callers.set(callee, known);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
const kept = /* @__PURE__ */ new Set();
|
|
2079
|
+
const queue = variants.filter((variant) => variant.differs).map((variant) => variant.key);
|
|
2080
|
+
for (let key = queue.pop(); key !== void 0; key = queue.pop()) {
|
|
2081
|
+
if (kept.has(key)) {
|
|
2082
|
+
continue;
|
|
2083
|
+
}
|
|
2084
|
+
kept.add(key);
|
|
2085
|
+
queue.push(...callers.get(key) ?? []);
|
|
2086
|
+
}
|
|
2087
|
+
return kept;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
// src/members.ts
|
|
2091
|
+
function memberOf(db, classKey, name, program) {
|
|
2092
|
+
askResolution(db, [classKey], MEMBERS_QUESTION, program);
|
|
2093
|
+
const overridden = new Set(
|
|
2094
|
+
db.lookup("wantedMemberOverridden", 0, classKey).filter((row) => String(row[1]) === name).map((row) => String(row[2]))
|
|
2095
|
+
);
|
|
2096
|
+
const found = [
|
|
2097
|
+
...new Set(
|
|
2098
|
+
db.lookup("wantedMemberOf", 0, classKey).filter((row) => String(row[1]) === name).map((row) => String(row[2])).filter((held) => !overridden.has(held))
|
|
2099
|
+
)
|
|
2100
|
+
];
|
|
2101
|
+
const [only] = found;
|
|
2102
|
+
return found.length === 1 && only !== void 0 ? only : null;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
1955
2105
|
// src/mount.ts
|
|
1956
2106
|
function joinMountedPath(prefix, path) {
|
|
1957
2107
|
const trimmed = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
@@ -2121,132 +2271,132 @@ function addPackWords(db, words) {
|
|
|
2121
2271
|
}
|
|
2122
2272
|
|
|
2123
2273
|
// src/passedOn.ts
|
|
2124
|
-
import { lit, rule, variable as
|
|
2274
|
+
import { lit as lit2, rule as rule2, variable as v2 } from "@suss/datalog";
|
|
2125
2275
|
var USES_QUESTION = "wantedUses";
|
|
2126
2276
|
var PASSED_ON_RULES = [
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2277
|
+
rule2("passedOn", [v2("x")], [lit2("returnsValue", v2("f"), v2("x"))], "returned"),
|
|
2278
|
+
rule2("passedOn", [v2("x")], [lit2("yieldsValue", v2("f"), v2("x"))], "yielded"),
|
|
2279
|
+
rule2(
|
|
2130
2280
|
"passedOn",
|
|
2131
|
-
[
|
|
2132
|
-
[
|
|
2281
|
+
[v2("x")],
|
|
2282
|
+
[lit2("callArg", v2("r"), v2("k"), v2("x"))],
|
|
2133
2283
|
"an argument"
|
|
2134
2284
|
),
|
|
2135
|
-
|
|
2285
|
+
rule2(
|
|
2136
2286
|
"passedOn",
|
|
2137
|
-
[
|
|
2138
|
-
[
|
|
2287
|
+
[v2("x")],
|
|
2288
|
+
[lit2("callKeywordArg", v2("r"), v2("k"), v2("x"))],
|
|
2139
2289
|
"a keyword argument"
|
|
2140
2290
|
),
|
|
2141
|
-
|
|
2142
|
-
|
|
2291
|
+
rule2("passedOn", [v2("x")], [lit2("binds", v2("y"), v2("x"))], "another name"),
|
|
2292
|
+
rule2(
|
|
2143
2293
|
"passedOn",
|
|
2144
|
-
[
|
|
2145
|
-
[
|
|
2294
|
+
[v2("x")],
|
|
2295
|
+
[lit2("endsHolding", v2("y"), v2("x"))],
|
|
2146
2296
|
"another name's last write"
|
|
2147
2297
|
),
|
|
2148
|
-
|
|
2298
|
+
rule2(
|
|
2149
2299
|
"passedOn",
|
|
2150
|
-
[
|
|
2151
|
-
[
|
|
2300
|
+
[v2("x")],
|
|
2301
|
+
[lit2("mayHold", v2("y"), v2("x"))],
|
|
2152
2302
|
"one of another name's writes"
|
|
2153
2303
|
),
|
|
2154
|
-
|
|
2304
|
+
rule2(
|
|
2155
2305
|
"passedOn",
|
|
2156
|
-
[
|
|
2157
|
-
[
|
|
2306
|
+
[v2("x")],
|
|
2307
|
+
[lit2("holdsProperty", v2("o"), v2("n"), v2("x"))],
|
|
2158
2308
|
"held by an object"
|
|
2159
2309
|
),
|
|
2160
|
-
|
|
2310
|
+
rule2(
|
|
2161
2311
|
"passedOn",
|
|
2162
|
-
[
|
|
2163
|
-
[
|
|
2312
|
+
[v2("x")],
|
|
2313
|
+
[lit2("storesProperty", v2("o"), v2("n"), v2("x"), v2("k"))],
|
|
2164
2314
|
"stored on an object"
|
|
2165
2315
|
),
|
|
2166
|
-
|
|
2316
|
+
rule2(
|
|
2167
2317
|
"passedOn",
|
|
2168
|
-
[
|
|
2169
|
-
[
|
|
2318
|
+
[v2("x")],
|
|
2319
|
+
[lit2("holdsUnderKey", v2("o"), v2("x"))],
|
|
2170
2320
|
"stored under a key"
|
|
2171
2321
|
),
|
|
2172
|
-
|
|
2322
|
+
rule2(
|
|
2173
2323
|
"passedOn",
|
|
2174
|
-
[
|
|
2175
|
-
[
|
|
2324
|
+
[v2("x")],
|
|
2325
|
+
[lit2("readsKeyed", v2("r"), v2("o"), v2("x"))],
|
|
2176
2326
|
"used as a key"
|
|
2177
2327
|
),
|
|
2178
|
-
|
|
2179
|
-
|
|
2328
|
+
rule2("passedOn", [v2("x")], [lit2("entersValue", v2("x"))], "entered"),
|
|
2329
|
+
rule2(
|
|
2180
2330
|
"passedOn",
|
|
2181
|
-
[
|
|
2182
|
-
[
|
|
2331
|
+
[v2("x")],
|
|
2332
|
+
[lit2("entersAs", v2("y"), v2("x"))],
|
|
2183
2333
|
"entered under a name"
|
|
2184
2334
|
),
|
|
2185
|
-
|
|
2335
|
+
rule2(
|
|
2186
2336
|
"passedOn",
|
|
2187
|
-
[
|
|
2188
|
-
[
|
|
2337
|
+
[v2("x")],
|
|
2338
|
+
[lit2("paramDefault", v2("p"), v2("x"))],
|
|
2189
2339
|
"a parameter default"
|
|
2190
2340
|
),
|
|
2191
|
-
|
|
2341
|
+
rule2(
|
|
2192
2342
|
"passedOn",
|
|
2193
|
-
[
|
|
2194
|
-
[
|
|
2343
|
+
[v2("x")],
|
|
2344
|
+
[lit2("fallbackBranch", v2("e"), v2("x"))],
|
|
2195
2345
|
"a fallback branch"
|
|
2196
2346
|
),
|
|
2197
|
-
|
|
2347
|
+
rule2(
|
|
2198
2348
|
"passedOn",
|
|
2199
|
-
[
|
|
2200
|
-
[
|
|
2349
|
+
[v2("x")],
|
|
2350
|
+
[lit2("conditionalBranch", v2("e"), v2("x"))],
|
|
2201
2351
|
"a conditional branch"
|
|
2202
2352
|
),
|
|
2203
2353
|
// `app.router` and `app[key]` hand out a part of the value, so the value
|
|
2204
2354
|
// goes wherever that part goes. This rule skips a part called at once,
|
|
2205
2355
|
// `app.run()`, which `wantedCalledMethod` lists instead.
|
|
2206
|
-
|
|
2356
|
+
rule2(
|
|
2207
2357
|
"passedOn",
|
|
2208
|
-
[
|
|
2209
|
-
[
|
|
2358
|
+
[v2("x")],
|
|
2359
|
+
[lit2("readsProperty", v2("r"), v2("x"), v2("n")), lit2("passedOn", v2("r"))],
|
|
2210
2360
|
"a property passed on"
|
|
2211
2361
|
),
|
|
2212
|
-
|
|
2362
|
+
rule2(
|
|
2213
2363
|
"passedOn",
|
|
2214
|
-
[
|
|
2215
|
-
[
|
|
2364
|
+
[v2("x")],
|
|
2365
|
+
[lit2("readsKeyed", v2("r"), v2("x"), v2("k")), lit2("passedOn", v2("r"))],
|
|
2216
2366
|
"an entry passed on"
|
|
2217
2367
|
),
|
|
2218
2368
|
// A method's result can be the value itself, as a builder's is, or
|
|
2219
2369
|
// carry what was registered on it, as `s.router(contract, handlers)`
|
|
2220
2370
|
// does, so passing the result on passes the value on.
|
|
2221
|
-
|
|
2371
|
+
rule2(
|
|
2222
2372
|
"passedOn",
|
|
2223
|
-
[
|
|
2373
|
+
[v2("x")],
|
|
2224
2374
|
[
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2375
|
+
lit2("readsProperty", v2("r"), v2("x"), v2("n")),
|
|
2376
|
+
lit2("call", v2("c"), v2("r")),
|
|
2377
|
+
lit2("passedOn", v2("c"))
|
|
2228
2378
|
],
|
|
2229
2379
|
"a method result passed on"
|
|
2230
2380
|
)
|
|
2231
2381
|
];
|
|
2232
2382
|
var USES_QUESTIONS = [
|
|
2233
|
-
|
|
2383
|
+
rule2(
|
|
2234
2384
|
"wantedPassedOn",
|
|
2235
|
-
[
|
|
2236
|
-
[
|
|
2385
|
+
[v2("x")],
|
|
2386
|
+
[lit2(USES_QUESTION, v2("x")), lit2("passedOn", v2("x"))]
|
|
2237
2387
|
),
|
|
2238
|
-
|
|
2388
|
+
rule2(
|
|
2239
2389
|
"wantedPassedOn",
|
|
2240
|
-
[
|
|
2241
|
-
[
|
|
2390
|
+
[v2("x")],
|
|
2391
|
+
[lit2(USES_QUESTION, v2("x")), lit2("call", v2("r"), v2("x"))]
|
|
2242
2392
|
),
|
|
2243
|
-
|
|
2393
|
+
rule2(
|
|
2244
2394
|
"wantedCalledMethod",
|
|
2245
|
-
[
|
|
2395
|
+
[v2("x"), v2("n")],
|
|
2246
2396
|
[
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2397
|
+
lit2(USES_QUESTION, v2("x")),
|
|
2398
|
+
lit2("readsProperty", v2("r"), v2("x"), v2("n")),
|
|
2399
|
+
lit2("call", v2("c"), v2("r"))
|
|
2250
2400
|
]
|
|
2251
2401
|
)
|
|
2252
2402
|
];
|
|
@@ -2602,30 +2752,30 @@ function sharedConstruction(writes) {
|
|
|
2602
2752
|
}
|
|
2603
2753
|
|
|
2604
2754
|
// src/index.ts
|
|
2605
|
-
import { constant, lit as
|
|
2606
|
-
var VALUE_STEP =
|
|
2755
|
+
import { constant as constant2, lit as lit3, rule as rule3, variable as v3 } from "@suss/datalog";
|
|
2756
|
+
var VALUE_STEP = constant2("value");
|
|
2607
2757
|
var NAMESPACE_IMPORT_NAME = "*";
|
|
2608
|
-
var NAMESPACE_IMPORT =
|
|
2758
|
+
var NAMESPACE_IMPORT = constant2(NAMESPACE_IMPORT_NAME);
|
|
2609
2759
|
var DEFAULT_IMPORT_NAME = "default";
|
|
2610
|
-
var DEFAULT_IMPORT =
|
|
2760
|
+
var DEFAULT_IMPORT = constant2(DEFAULT_IMPORT_NAME);
|
|
2611
2761
|
var GLOBAL_MODULE = "global";
|
|
2612
2762
|
var NAMESPACE_MEMBER_RULE = "namespace member";
|
|
2613
2763
|
var BASE_CLASS_RULE = "base class";
|
|
2614
2764
|
var NAME_HOP_RULE = "name hop";
|
|
2615
|
-
var INSTANCE_STEP =
|
|
2765
|
+
var INSTANCE_STEP = constant2("instance");
|
|
2616
2766
|
var RECEIVER_STORE_NAME = "receiver";
|
|
2617
|
-
var RECEIVER_STORE =
|
|
2767
|
+
var RECEIVER_STORE = constant2(RECEIVER_STORE_NAME);
|
|
2618
2768
|
var NAMED_STORE_NAME = "name";
|
|
2619
|
-
var NAMED_STORE =
|
|
2769
|
+
var NAMED_STORE = constant2(NAMED_STORE_NAME);
|
|
2620
2770
|
var UNPLACED_STORE_NAME = "unplaced";
|
|
2621
|
-
var NO_ARGUMENTS =
|
|
2622
|
-
var FIRST_POSITION =
|
|
2623
|
-
var THEN_METHOD =
|
|
2624
|
-
var RESULT_STEP =
|
|
2771
|
+
var NO_ARGUMENTS = constant2("0");
|
|
2772
|
+
var FIRST_POSITION = constant2("0");
|
|
2773
|
+
var THEN_METHOD = constant2("then");
|
|
2774
|
+
var RESULT_STEP = constant2("result");
|
|
2625
2775
|
var NO_CONTEXT_NAME = "none";
|
|
2626
|
-
var NO_CONTEXT =
|
|
2776
|
+
var NO_CONTEXT = constant2(NO_CONTEXT_NAME);
|
|
2627
2777
|
var STEP_LATTICE = [
|
|
2628
|
-
{ soFar: VALUE_STEP, next:
|
|
2778
|
+
{ soFar: VALUE_STEP, next: v3("kind"), took: v3("kind") },
|
|
2629
2779
|
{ soFar: INSTANCE_STEP, next: VALUE_STEP, took: INSTANCE_STEP },
|
|
2630
2780
|
{ soFar: INSTANCE_STEP, next: INSTANCE_STEP, took: INSTANCE_STEP },
|
|
2631
2781
|
{ soFar: INSTANCE_STEP, next: RESULT_STEP, took: RESULT_STEP },
|
|
@@ -2634,1191 +2784,1191 @@ var STEP_LATTICE = [
|
|
|
2634
2784
|
{ soFar: RESULT_STEP, next: RESULT_STEP, took: RESULT_STEP }
|
|
2635
2785
|
];
|
|
2636
2786
|
var DISPATCH_RULES = [
|
|
2637
|
-
|
|
2787
|
+
rule3(
|
|
2638
2788
|
"entryRead",
|
|
2639
|
-
[
|
|
2640
|
-
[
|
|
2789
|
+
[v3("site"), v3("o")],
|
|
2790
|
+
[lit3("choosesEntry", v3("site"), v3("o"))]
|
|
2641
2791
|
),
|
|
2642
|
-
|
|
2792
|
+
rule3(
|
|
2643
2793
|
"entryRead",
|
|
2644
|
-
[
|
|
2645
|
-
[
|
|
2794
|
+
[v3("site"), v3("o")],
|
|
2795
|
+
[lit3("namedEntryRead", v3("site"), v3("o"), v3("n"))]
|
|
2646
2796
|
),
|
|
2647
|
-
|
|
2797
|
+
rule3(
|
|
2648
2798
|
"entryRead",
|
|
2649
|
-
[
|
|
2650
|
-
[
|
|
2799
|
+
[v3("site"), v3("o")],
|
|
2800
|
+
[lit3("choosesEntryLike", v3("site"), v3("o"), v3("p"), v3("s"))]
|
|
2651
2801
|
),
|
|
2652
2802
|
// Every entry of a read whose key is partly written out, by name. A rule
|
|
2653
2803
|
// cannot compare strings, so dispatch.ts keeps the names that match, and
|
|
2654
2804
|
// these stay out of `dispatchesTo`.
|
|
2655
|
-
|
|
2805
|
+
rule3(
|
|
2656
2806
|
"likeEntryAt",
|
|
2657
|
-
[
|
|
2807
|
+
[v3("site"), v3("n"), v3("held")],
|
|
2658
2808
|
[
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2809
|
+
lit3("choosesEntryLike", v3("site"), v3("o"), v3("p"), v3("s")),
|
|
2810
|
+
lit3("containerOf", v3("o"), v3("obj")),
|
|
2811
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
2662
2812
|
]
|
|
2663
2813
|
),
|
|
2664
|
-
|
|
2814
|
+
rule3(
|
|
2665
2815
|
"namedEntryRead",
|
|
2666
|
-
[
|
|
2667
|
-
[
|
|
2816
|
+
[v3("site"), v3("o"), v3("n")],
|
|
2817
|
+
[lit3("choosesNamedEntry", v3("site"), v3("o"), v3("n"))]
|
|
2668
2818
|
),
|
|
2669
|
-
|
|
2819
|
+
rule3(
|
|
2670
2820
|
"namedEntryRead",
|
|
2671
|
-
[
|
|
2672
|
-
[
|
|
2821
|
+
[v3("site"), v3("o"), v3("n")],
|
|
2822
|
+
[lit3("readsEntry", v3("site"), v3("o"), v3("n"))]
|
|
2673
2823
|
),
|
|
2674
2824
|
// The container a read takes its entry from: an object written out, or
|
|
2675
2825
|
// a collection the program fills through its methods.
|
|
2676
|
-
|
|
2677
|
-
|
|
2826
|
+
rule3("containerOf", [v3("o"), v3("obj")], [lit3("objectOf", v3("o"), v3("obj"))]),
|
|
2827
|
+
rule3(
|
|
2678
2828
|
"containerOf",
|
|
2679
|
-
[
|
|
2829
|
+
[v3("o"), v3("c")],
|
|
2680
2830
|
[
|
|
2681
|
-
|
|
2682
|
-
|
|
2831
|
+
lit3("reaches", v3("o"), v3("c"), VALUE_STEP),
|
|
2832
|
+
lit3("collectionValue", v3("c"))
|
|
2683
2833
|
]
|
|
2684
2834
|
),
|
|
2685
|
-
|
|
2686
|
-
|
|
2835
|
+
rule3("containerOf", [v3("c"), v3("c")], [lit3("collectionValue", v3("c"))]),
|
|
2836
|
+
rule3(
|
|
2687
2837
|
"entryAt",
|
|
2688
|
-
[
|
|
2838
|
+
[v3("site"), v3("held")],
|
|
2689
2839
|
[
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2840
|
+
lit3("choosesEntry", v3("site"), v3("o")),
|
|
2841
|
+
lit3("containerOf", v3("o"), v3("obj")),
|
|
2842
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
2693
2843
|
],
|
|
2694
2844
|
"any entry"
|
|
2695
2845
|
),
|
|
2696
|
-
|
|
2846
|
+
rule3(
|
|
2697
2847
|
"entryAt",
|
|
2698
|
-
[
|
|
2848
|
+
[v3("site"), v3("held")],
|
|
2699
2849
|
[
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2850
|
+
lit3("namedEntryRead", v3("site"), v3("o"), v3("n")),
|
|
2851
|
+
lit3("containerOf", v3("o"), v3("obj")),
|
|
2852
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
2703
2853
|
],
|
|
2704
2854
|
"named entry"
|
|
2705
2855
|
),
|
|
2706
|
-
|
|
2856
|
+
rule3(
|
|
2707
2857
|
"entryAt",
|
|
2708
|
-
[
|
|
2709
|
-
[
|
|
2858
|
+
[v3("site"), v3("held")],
|
|
2859
|
+
[lit3("computedEntryAt", v3("site"), v3("held"))]
|
|
2710
2860
|
),
|
|
2711
2861
|
// A write under a key the source computes, `T[name] = fn` or a map's
|
|
2712
2862
|
// `set`, could be under any name, so every read of the container may
|
|
2713
2863
|
// come back with it, a read narrowed to one name included.
|
|
2714
|
-
|
|
2864
|
+
rule3(
|
|
2715
2865
|
"computedEntryAt",
|
|
2716
|
-
[
|
|
2866
|
+
[v3("site"), v3("held")],
|
|
2717
2867
|
[
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2868
|
+
lit3("entryRead", v3("site"), v3("o")),
|
|
2869
|
+
lit3("containerOf", v3("o"), v3("c")),
|
|
2870
|
+
lit3("refersToObject", v3("x"), v3("c")),
|
|
2871
|
+
lit3("holdsUnderKey", v3("x"), v3("held"))
|
|
2722
2872
|
],
|
|
2723
2873
|
"entry under a computed key"
|
|
2724
2874
|
),
|
|
2725
2875
|
// The read a call takes its function from: the callee itself, a name
|
|
2726
2876
|
// for it, or the call when the call is the read, as Ruby's `send` is.
|
|
2727
|
-
|
|
2877
|
+
rule3(
|
|
2728
2878
|
"callsEntryAt",
|
|
2729
|
-
[
|
|
2730
|
-
[
|
|
2879
|
+
[v3("r"), v3("site")],
|
|
2880
|
+
[lit3("call", v3("r"), v3("site")), lit3("entryRead", v3("site"), v3("o"))]
|
|
2731
2881
|
),
|
|
2732
|
-
|
|
2882
|
+
rule3(
|
|
2733
2883
|
"callsEntryAt",
|
|
2734
|
-
[
|
|
2884
|
+
[v3("r"), v3("site")],
|
|
2735
2885
|
[
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2886
|
+
lit3("call", v3("r"), v3("c")),
|
|
2887
|
+
lit3("reaches", v3("c"), v3("site"), VALUE_STEP),
|
|
2888
|
+
lit3("entryRead", v3("site"), v3("o"))
|
|
2739
2889
|
]
|
|
2740
2890
|
),
|
|
2741
|
-
|
|
2742
|
-
|
|
2891
|
+
rule3("callsEntryAt", [v3("r"), v3("r")], [lit3("callsChosenEntry", v3("r"))]),
|
|
2892
|
+
rule3(
|
|
2743
2893
|
"callsEntryAt",
|
|
2744
|
-
[
|
|
2745
|
-
[
|
|
2894
|
+
[v3("r"), v3("site")],
|
|
2895
|
+
[lit3("callsEntryInBranch", v3("r"), v3("site"))]
|
|
2746
2896
|
),
|
|
2747
2897
|
// `c ? T[k] : undefined` is one of its branches, so a call through it
|
|
2748
2898
|
// may run what the read gives. The other branch may be some other
|
|
2749
2899
|
// function, so dispatch.ts never counts such a call as certain.
|
|
2750
|
-
|
|
2900
|
+
rule3(
|
|
2751
2901
|
"callsEntryInBranch",
|
|
2752
|
-
[
|
|
2753
|
-
[
|
|
2902
|
+
[v3("r"), v3("site")],
|
|
2903
|
+
[lit3("call", v3("r"), v3("c")), lit3("branchReadsEntry", v3("c"), v3("site"))]
|
|
2754
2904
|
),
|
|
2755
|
-
|
|
2905
|
+
rule3(
|
|
2756
2906
|
"callsEntryInBranch",
|
|
2757
|
-
[
|
|
2907
|
+
[v3("r"), v3("site")],
|
|
2758
2908
|
[
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2909
|
+
lit3("call", v3("r"), v3("c")),
|
|
2910
|
+
lit3("reaches", v3("c"), v3("x"), VALUE_STEP),
|
|
2911
|
+
lit3("branchReadsEntry", v3("x"), v3("site"))
|
|
2762
2912
|
]
|
|
2763
2913
|
),
|
|
2764
|
-
|
|
2914
|
+
rule3(
|
|
2765
2915
|
"branchReadsEntry",
|
|
2766
|
-
[
|
|
2916
|
+
[v3("x"), v3("site")],
|
|
2767
2917
|
[
|
|
2768
|
-
|
|
2769
|
-
|
|
2918
|
+
lit3("conditionalBranch", v3("x"), v3("site")),
|
|
2919
|
+
lit3("entryRead", v3("site"), v3("o"))
|
|
2770
2920
|
]
|
|
2771
2921
|
),
|
|
2772
|
-
|
|
2922
|
+
rule3(
|
|
2773
2923
|
"branchReadsEntry",
|
|
2774
|
-
[
|
|
2924
|
+
[v3("x"), v3("site")],
|
|
2775
2925
|
[
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2926
|
+
lit3("conditionalBranch", v3("x"), v3("b")),
|
|
2927
|
+
lit3("reaches", v3("b"), v3("site"), VALUE_STEP),
|
|
2928
|
+
lit3("entryRead", v3("site"), v3("o"))
|
|
2779
2929
|
]
|
|
2780
2930
|
),
|
|
2781
|
-
|
|
2931
|
+
rule3(
|
|
2782
2932
|
"dispatchesTo",
|
|
2783
|
-
[
|
|
2933
|
+
[v3("r"), v3("f")],
|
|
2784
2934
|
[
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2935
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
2936
|
+
lit3("entryAt", v3("site"), v3("held")),
|
|
2937
|
+
lit3("comesTo", v3("held"), v3("f")),
|
|
2938
|
+
lit3("func", v3("f"))
|
|
2789
2939
|
]
|
|
2790
2940
|
),
|
|
2791
2941
|
// A collection a program fills is an object the way a written one is,
|
|
2792
2942
|
// so a write through a name for it lands on it.
|
|
2793
|
-
|
|
2943
|
+
rule3("refersToObject", [v3("c"), v3("c")], [lit3("collectionValue", v3("c"))])
|
|
2794
2944
|
];
|
|
2795
2945
|
var STATED_RULES = [
|
|
2796
2946
|
// Aliasing: const x = y, or an identifier referencing a declaration.
|
|
2797
2947
|
// Every chain that follows a name takes the name hops, so a hop added
|
|
2798
2948
|
// here reaches all of them.
|
|
2799
|
-
|
|
2949
|
+
rule3("nameHop", [v3("x"), v3("y")], [lit3("binds", v3("x"), v3("y"))], "alias"),
|
|
2800
2950
|
// A name written more than once has the value the last write left
|
|
2801
2951
|
// there. The adapter works out which write that is, and stays quiet
|
|
2802
2952
|
// when control flow decides; the rule below takes that name instead.
|
|
2803
|
-
|
|
2953
|
+
rule3(
|
|
2804
2954
|
"nameHop",
|
|
2805
|
-
[
|
|
2806
|
-
[
|
|
2955
|
+
[v3("x"), v3("y")],
|
|
2956
|
+
[lit3("endsHolding", v3("x"), v3("y"))],
|
|
2807
2957
|
"last write"
|
|
2808
2958
|
),
|
|
2809
2959
|
// A name whose writes nothing orders leads to each of them, so a
|
|
2810
2960
|
// caller that can use several values gets them all and one that needs
|
|
2811
2961
|
// a single value gets none. A write stating no value stops every step.
|
|
2812
|
-
|
|
2962
|
+
rule3(
|
|
2813
2963
|
"nameHop",
|
|
2814
|
-
[
|
|
2815
|
-
[
|
|
2964
|
+
[v3("x"), v3("y")],
|
|
2965
|
+
[lit3("mayHold", v3("x"), v3("y")), lit3("writesAllStated", v3("x"))],
|
|
2816
2966
|
"one of several writes"
|
|
2817
2967
|
),
|
|
2818
2968
|
// A fallback says the value is one of its branches, so each branch is
|
|
2819
2969
|
// a step. A branch that resolves to nothing makes no claim, and two
|
|
2820
2970
|
// branches resolving to different things fail the single-answer policy.
|
|
2821
|
-
|
|
2971
|
+
rule3(
|
|
2822
2972
|
"nameHop",
|
|
2823
|
-
[
|
|
2824
|
-
[
|
|
2973
|
+
[v3("x"), v3("b")],
|
|
2974
|
+
[lit3("fallbackBranch", v3("x"), v3("b"))],
|
|
2825
2975
|
"fallback"
|
|
2826
2976
|
),
|
|
2827
2977
|
// Every name hop is a value step. A language with a hop of its own, like
|
|
2828
2978
|
// Ruby's `Const.new`, states it as a step too, or every question but
|
|
2829
2979
|
// `comesTo` misses it.
|
|
2830
|
-
|
|
2980
|
+
rule3(
|
|
2831
2981
|
"hop",
|
|
2832
|
-
[
|
|
2833
|
-
[
|
|
2982
|
+
[v3("x"), v3("y"), VALUE_STEP],
|
|
2983
|
+
[lit3("nameHop", v3("x"), v3("y"))],
|
|
2834
2984
|
NAME_HOP_RULE
|
|
2835
2985
|
),
|
|
2836
2986
|
// An import steps to what the module exports under that name. It is
|
|
2837
2987
|
// not a name hop, because the call-origin chains stop at the import.
|
|
2838
|
-
|
|
2988
|
+
rule3(
|
|
2839
2989
|
"hop",
|
|
2840
|
-
[
|
|
2990
|
+
[v3("x"), v3("value"), VALUE_STEP],
|
|
2841
2991
|
[
|
|
2842
|
-
|
|
2843
|
-
|
|
2992
|
+
lit3("imports", v3("x"), v3("m"), v3("n")),
|
|
2993
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("value"))
|
|
2844
2994
|
],
|
|
2845
2995
|
"import"
|
|
2846
2996
|
),
|
|
2847
2997
|
// A parameter steps to what a call passes it. A function called from
|
|
2848
2998
|
// several places leaves its parameter with more than one value, and a
|
|
2849
2999
|
// caller that needs those apart asks `passesArgument`, which keeps the call.
|
|
2850
|
-
|
|
3000
|
+
rule3(
|
|
2851
3001
|
"stepsTo",
|
|
2852
|
-
[
|
|
2853
|
-
[
|
|
3002
|
+
[v3("p"), v3("a"), VALUE_STEP],
|
|
3003
|
+
[lit3("passesArgument", v3("r"), v3("p"), v3("a"))],
|
|
2854
3004
|
"argument"
|
|
2855
3005
|
),
|
|
2856
3006
|
// Reading a property steps to what the object contains under that
|
|
2857
3007
|
// name, whichever way the object arrived: `routes.list` off a name,
|
|
2858
3008
|
// or `make(body).handle` off a call.
|
|
2859
|
-
|
|
3009
|
+
rule3(
|
|
2860
3010
|
"stepsTo",
|
|
2861
|
-
[
|
|
3011
|
+
[v3("x"), v3("held"), VALUE_STEP],
|
|
2862
3012
|
[
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
3013
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
3014
|
+
lit3("objectOf", v3("o"), v3("obj")),
|
|
3015
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
2866
3016
|
],
|
|
2867
3017
|
"property read"
|
|
2868
3018
|
),
|
|
2869
3019
|
// Calling a class makes one of it, so the call steps to the class and
|
|
2870
3020
|
// a method read off the result is the one the class declares. The
|
|
2871
3021
|
// caveat below is about a factory function, and a class is not one.
|
|
2872
|
-
|
|
3022
|
+
rule3(
|
|
2873
3023
|
"hop",
|
|
2874
|
-
[
|
|
3024
|
+
[v3("r"), v3("cls"), INSTANCE_STEP],
|
|
2875
3025
|
[
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3026
|
+
lit3("call", v3("r"), v3("c")),
|
|
3027
|
+
lit3("comesTo", v3("c"), v3("cls")),
|
|
3028
|
+
lit3("objectValue", v3("cls"))
|
|
2879
3029
|
],
|
|
2880
3030
|
"class instance"
|
|
2881
3031
|
),
|
|
2882
3032
|
// The receiver a method is called on. Being one of a class is the
|
|
2883
3033
|
// same hop a construction takes, so a method read off `self` finds
|
|
2884
3034
|
// what the class declares.
|
|
2885
|
-
|
|
3035
|
+
rule3(
|
|
2886
3036
|
"hop",
|
|
2887
|
-
[
|
|
2888
|
-
[
|
|
3037
|
+
[v3("x"), v3("cls"), INSTANCE_STEP],
|
|
3038
|
+
[lit3("instanceOf", v3("x"), v3("cls"))],
|
|
2889
3039
|
"receiver instance"
|
|
2890
3040
|
),
|
|
2891
3041
|
// A finder the library declares, keyed on the base a pack named so a
|
|
2892
3042
|
// project class with a method of the same name on another hierarchy is
|
|
2893
3043
|
// left alone. The DESIGN says what a chain of them composes into.
|
|
2894
|
-
|
|
3044
|
+
rule3(
|
|
2895
3045
|
"hop",
|
|
2896
|
-
[
|
|
3046
|
+
[v3("r"), v3("cls"), INSTANCE_STEP],
|
|
2897
3047
|
[
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
3048
|
+
lit3("call", v3("r"), v3("c")),
|
|
3049
|
+
lit3("readsProperty", v3("c"), v3("o"), v3("m")),
|
|
3050
|
+
lit3("objectOf", v3("o"), v3("cls")),
|
|
3051
|
+
lit3("objectValue", v3("cls")),
|
|
2902
3052
|
// Before `libraryBase`, so the demand rewrite asks it with the base
|
|
2903
3053
|
// bound and walks an ancestry only for a method a pack declared.
|
|
2904
|
-
|
|
2905
|
-
|
|
3054
|
+
lit3("givesBackOne", v3("n"), v3("m")),
|
|
3055
|
+
lit3("libraryBase", v3("cls"), v3("n"))
|
|
2906
3056
|
],
|
|
2907
3057
|
"declared finder"
|
|
2908
3058
|
),
|
|
2909
3059
|
// The same word, for a library that takes the class as an argument
|
|
2910
3060
|
// instead of as the receiver. The argument having to reach the base a
|
|
2911
3061
|
// pack named is what keeps an unrelated `get` out.
|
|
2912
|
-
|
|
3062
|
+
rule3(
|
|
2913
3063
|
"hop",
|
|
2914
|
-
[
|
|
3064
|
+
[v3("r"), v3("cls"), INSTANCE_STEP],
|
|
2915
3065
|
[
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
3066
|
+
lit3("call", v3("r"), v3("c")),
|
|
3067
|
+
lit3("readsProperty", v3("c"), v3("o"), v3("m")),
|
|
3068
|
+
lit3("callArg", v3("r"), v3("k"), v3("a")),
|
|
2919
3069
|
// Before `libraryBase`, so the demand rewrite asks it with the base
|
|
2920
3070
|
// bound and walks an ancestry only for a method a pack declared.
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
3071
|
+
lit3("givesBackOneOfArgument", v3("n"), v3("m"), v3("k")),
|
|
3072
|
+
lit3("objectOf", v3("a"), v3("cls")),
|
|
3073
|
+
lit3("libraryBase", v3("cls"), v3("n"))
|
|
2924
3074
|
],
|
|
2925
3075
|
"declared argument finder"
|
|
2926
3076
|
),
|
|
2927
3077
|
// The same again for a function called on its own rather than read off
|
|
2928
3078
|
// anything, keyed on the module it was imported from so a project
|
|
2929
3079
|
// function spelled the same way is not mistaken for it.
|
|
2930
|
-
|
|
3080
|
+
rule3(
|
|
2931
3081
|
"hop",
|
|
2932
|
-
[
|
|
3082
|
+
[v3("r"), v3("cls"), INSTANCE_STEP],
|
|
2933
3083
|
[
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
3084
|
+
lit3("call", v3("r"), v3("c")),
|
|
3085
|
+
lit3("comesFrom", v3("c"), v3("mod"), v3("n")),
|
|
3086
|
+
lit3("givesBackOneOfImport", v3("mod"), v3("n"), v3("k")),
|
|
3087
|
+
lit3("callArg", v3("r"), v3("k"), v3("a")),
|
|
3088
|
+
lit3("objectOf", v3("a"), v3("cls"))
|
|
2939
3089
|
],
|
|
2940
3090
|
"declared import finder"
|
|
2941
3091
|
),
|
|
2942
3092
|
// A block opened over a library's own constructor. The pack says
|
|
2943
3093
|
// entering one gives back the object it built, so the name the block
|
|
2944
3094
|
// opens is that call.
|
|
2945
|
-
|
|
3095
|
+
rule3(
|
|
2946
3096
|
"hop",
|
|
2947
|
-
[
|
|
3097
|
+
[v3("y"), v3("r"), VALUE_STEP],
|
|
2948
3098
|
[
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
3099
|
+
lit3("entersAs", v3("y"), v3("r")),
|
|
3100
|
+
lit3("call", v3("r"), v3("c")),
|
|
3101
|
+
lit3("comesFrom", v3("c"), v3("mod"), v3("n")),
|
|
3102
|
+
lit3("entersAsSelf", v3("mod"), v3("n"))
|
|
2953
3103
|
],
|
|
2954
3104
|
"context manager returns self"
|
|
2955
3105
|
),
|
|
2956
3106
|
// A method the language says hands back the object it was called on,
|
|
2957
3107
|
// such as JavaScript's `.bind` or Ruby's `freeze`. Each adapter lists
|
|
2958
3108
|
// its language's own in `returnsReceiver`, keyed on the method's name.
|
|
2959
|
-
|
|
3109
|
+
rule3(
|
|
2960
3110
|
"hop",
|
|
2961
|
-
[
|
|
3111
|
+
[v3("r"), v3("o"), VALUE_STEP],
|
|
2962
3112
|
[
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
3113
|
+
lit3("call", v3("r"), v3("c")),
|
|
3114
|
+
lit3("readsProperty", v3("c"), v3("o"), v3("m")),
|
|
3115
|
+
lit3("returnsReceiver", v3("m"))
|
|
2966
3116
|
],
|
|
2967
3117
|
"returns its receiver"
|
|
2968
3118
|
),
|
|
2969
3119
|
// Wrapper transparency, derived: calling a factory that returns a
|
|
2970
3120
|
// function which calls its parameter k steps to argument k.
|
|
2971
|
-
|
|
3121
|
+
rule3(
|
|
2972
3122
|
"hop",
|
|
2973
|
-
[
|
|
3123
|
+
[v3("r"), v3("a"), VALUE_STEP],
|
|
2974
3124
|
[
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
3125
|
+
lit3("call", v3("r"), v3("c")),
|
|
3126
|
+
lit3("comesTo", v3("c"), v3("f")),
|
|
3127
|
+
lit3("unwraps", v3("f"), v3("k")),
|
|
3128
|
+
lit3("callArg", v3("r"), v3("k"), v3("a"))
|
|
2979
3129
|
],
|
|
2980
3130
|
"factory unwrap"
|
|
2981
3131
|
),
|
|
2982
3132
|
// Wrapper transparency, declared: a pack says module m's n hands back
|
|
2983
3133
|
// argument k. DESIGN.md says why the argument has to describe a value.
|
|
2984
|
-
|
|
3134
|
+
rule3(
|
|
2985
3135
|
"hop",
|
|
2986
|
-
[
|
|
3136
|
+
[v3("r"), v3("a"), VALUE_STEP],
|
|
2987
3137
|
[
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3138
|
+
lit3("call", v3("r"), v3("c")),
|
|
3139
|
+
lit3("comesFrom", v3("c"), v3("m"), v3("n")),
|
|
3140
|
+
lit3("unwrapsByName", v3("m"), v3("n"), v3("k")),
|
|
3141
|
+
lit3("callArg", v3("r"), v3("k"), v3("a")),
|
|
3142
|
+
lit3("describesValue", v3("a"))
|
|
2993
3143
|
],
|
|
2994
3144
|
"declared wrapper"
|
|
2995
3145
|
),
|
|
2996
3146
|
// A container fills a parameter from the decorator a pack says
|
|
2997
3147
|
// supplies it, so the parameter is written as that decorator's call.
|
|
2998
|
-
|
|
3148
|
+
rule3(
|
|
2999
3149
|
"hop",
|
|
3000
|
-
[
|
|
3150
|
+
[v3("p"), v3("d"), VALUE_STEP],
|
|
3001
3151
|
[
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3152
|
+
lit3("decoratedWith", v3("p"), v3("d")),
|
|
3153
|
+
lit3("call", v3("d"), v3("c")),
|
|
3154
|
+
lit3("comesFrom", v3("c"), v3("m"), v3("n")),
|
|
3155
|
+
lit3("suppliesParameter", v3("m"), v3("n"))
|
|
3006
3156
|
],
|
|
3007
3157
|
"supplied by a decorator"
|
|
3008
3158
|
),
|
|
3009
3159
|
// Every value but an object written with nothing in it. The demand
|
|
3010
3160
|
// rewrite refuses negation, so each kind of value gets a rule.
|
|
3011
3161
|
...[
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
].map((kind) =>
|
|
3162
|
+
lit3("func", v3("a")),
|
|
3163
|
+
lit3("writtenValue", v3("a")),
|
|
3164
|
+
lit3("holdsProperty", v3("a"), v3("p"), v3("x")),
|
|
3165
|
+
lit3("imports", v3("a"), v3("m"), v3("n")),
|
|
3166
|
+
lit3("stepsTo", v3("a"), v3("y"), v3("kind"))
|
|
3167
|
+
].map((kind) => rule3("describesValue", [v3("a")], [kind])),
|
|
3018
3168
|
// The one step that runs a function forwards: a call steps to what
|
|
3019
3169
|
// the function it invokes returns.
|
|
3020
|
-
|
|
3170
|
+
rule3(
|
|
3021
3171
|
"hop",
|
|
3022
|
-
[
|
|
3023
|
-
[
|
|
3172
|
+
[v3("r"), v3("ret"), RESULT_STEP],
|
|
3173
|
+
[lit3("invokes", v3("r"), v3("f")), lit3("returnsValue", v3("f"), v3("ret"))],
|
|
3024
3174
|
"call result"
|
|
3025
3175
|
),
|
|
3026
3176
|
// A `.then` callback's first parameter is handed what the promise it
|
|
3027
3177
|
// was chained on settles to, so the parameter steps to that receiver.
|
|
3028
|
-
|
|
3178
|
+
rule3(
|
|
3029
3179
|
"hop",
|
|
3030
|
-
[
|
|
3180
|
+
[v3("p"), v3("r"), VALUE_STEP],
|
|
3031
3181
|
[
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3182
|
+
lit3("paramOf", v3("cb"), FIRST_POSITION, v3("p")),
|
|
3183
|
+
lit3("callArg", v3("t"), FIRST_POSITION, v3("cb")),
|
|
3184
|
+
lit3("call", v3("t"), v3("m")),
|
|
3185
|
+
lit3("readsProperty", v3("m"), v3("r"), THEN_METHOD)
|
|
3036
3186
|
],
|
|
3037
3187
|
"then gives"
|
|
3038
3188
|
),
|
|
3039
3189
|
// What a function says it gives back when its body never states a
|
|
3040
3190
|
// value. The adapter stays quiet about the annotation whenever the
|
|
3041
3191
|
// body does state one, so the two never answer the same question.
|
|
3042
|
-
|
|
3192
|
+
rule3(
|
|
3043
3193
|
"hop",
|
|
3044
|
-
[
|
|
3194
|
+
[v3("r"), v3("cls"), RESULT_STEP],
|
|
3045
3195
|
[
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3196
|
+
lit3("invokes", v3("r"), v3("f")),
|
|
3197
|
+
lit3("returnsClass", v3("f"), v3("x")),
|
|
3198
|
+
lit3("comesTo", v3("x"), v3("cls")),
|
|
3199
|
+
lit3("objectValue", v3("cls"))
|
|
3050
3200
|
],
|
|
3051
3201
|
"declared return type"
|
|
3052
3202
|
),
|
|
3053
3203
|
// Where a walk gets to, under the strongest step it took: value, then
|
|
3054
3204
|
// instance, then result. The walk so far comes first, so demand stays
|
|
3055
3205
|
// on the value asked about; the README says what the other order cost.
|
|
3056
|
-
|
|
3206
|
+
rule3(
|
|
3057
3207
|
"reaches",
|
|
3058
|
-
[
|
|
3059
|
-
[
|
|
3208
|
+
[v3("x"), v3("z"), v3("kind")],
|
|
3209
|
+
[lit3("stepsTo", v3("x"), v3("z"), v3("kind"))]
|
|
3060
3210
|
),
|
|
3061
3211
|
// A rule per pair rather than one leaving the next step's kind free. A
|
|
3062
3212
|
// free kind is a second question about the same relation, and a
|
|
3063
3213
|
// demand-driven run then derives both to answer either.
|
|
3064
3214
|
...STEP_LATTICE.map(
|
|
3065
|
-
({ soFar, next, took }) =>
|
|
3215
|
+
({ soFar, next, took }) => rule3(
|
|
3066
3216
|
"reaches",
|
|
3067
|
-
[
|
|
3217
|
+
[v3("x"), v3("z"), took],
|
|
3068
3218
|
[
|
|
3069
|
-
|
|
3070
|
-
|
|
3219
|
+
lit3("reaches", v3("x"), v3("y"), soFar),
|
|
3220
|
+
lit3("stepsTo", v3("y"), v3("z"), next)
|
|
3071
3221
|
]
|
|
3072
3222
|
)
|
|
3073
3223
|
),
|
|
3074
3224
|
// A context is an allocation site, or nothing at all for a value read
|
|
3075
3225
|
// outside every site. Both are stated, so a rule that starts a walk
|
|
3076
3226
|
// binds its context from a premise rather than from a negation.
|
|
3077
|
-
|
|
3078
|
-
|
|
3227
|
+
rule3("context", [NO_CONTEXT], [], "no context"),
|
|
3228
|
+
rule3(
|
|
3079
3229
|
"context",
|
|
3080
|
-
[
|
|
3081
|
-
[
|
|
3230
|
+
[v3("site")],
|
|
3231
|
+
[lit3("allocates", v3("site"), v3("cls"))],
|
|
3082
3232
|
"site context"
|
|
3083
3233
|
),
|
|
3084
3234
|
// The same closure, with the context the walk started under and the
|
|
3085
3235
|
// context it arrived under. It takes `hop`, because an argument and a
|
|
3086
3236
|
// property read have their own rules below.
|
|
3087
|
-
|
|
3237
|
+
rule3(
|
|
3088
3238
|
"reachesUnder",
|
|
3089
|
-
[
|
|
3090
|
-
[
|
|
3239
|
+
[v3("x"), v3("c"), v3("z"), v3("c"), v3("kind")],
|
|
3240
|
+
[lit3("context", v3("c")), lit3("hop", v3("x"), v3("z"), v3("kind"))],
|
|
3091
3241
|
"under one hop"
|
|
3092
3242
|
),
|
|
3093
3243
|
...STEP_LATTICE.map(
|
|
3094
|
-
({ soFar, next, took }) =>
|
|
3244
|
+
({ soFar, next, took }) => rule3(
|
|
3095
3245
|
"reachesUnder",
|
|
3096
|
-
[
|
|
3246
|
+
[v3("x"), v3("c"), v3("z"), v3("c2"), took],
|
|
3097
3247
|
[
|
|
3098
|
-
|
|
3099
|
-
|
|
3248
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("y"), v3("c2"), soFar),
|
|
3249
|
+
lit3("hop", v3("y"), v3("z"), next)
|
|
3100
3250
|
]
|
|
3101
3251
|
)
|
|
3102
3252
|
),
|
|
3103
3253
|
// The receiver read under a site is that site. The ordinary hop from a
|
|
3104
3254
|
// receiver to its class stays in `hop`, so `self` under any context
|
|
3105
3255
|
// still comes to the class a single-answer reader wants.
|
|
3106
|
-
|
|
3256
|
+
rule3(
|
|
3107
3257
|
"reachesUnder",
|
|
3108
|
-
[
|
|
3109
|
-
[
|
|
3258
|
+
[v3("x"), v3("c"), v3("c"), v3("c"), VALUE_STEP],
|
|
3259
|
+
[lit3("instanceOf", v3("x"), v3("cls")), lit3("allocates", v3("c"), v3("cls"))],
|
|
3110
3260
|
"receiver is the site"
|
|
3111
3261
|
),
|
|
3112
|
-
|
|
3262
|
+
rule3(
|
|
3113
3263
|
"reachesUnder",
|
|
3114
|
-
[
|
|
3264
|
+
[v3("x"), v3("c"), v3("c2"), v3("c2"), v3("kind")],
|
|
3115
3265
|
[
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3266
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("y"), v3("c2"), v3("kind")),
|
|
3267
|
+
lit3("instanceOf", v3("y"), v3("cls")),
|
|
3268
|
+
lit3("allocates", v3("c2"), v3("cls"))
|
|
3119
3269
|
],
|
|
3120
3270
|
"reached receiver is the site"
|
|
3121
3271
|
),
|
|
3122
3272
|
// The object an expression refers to under a context. A site is an
|
|
3123
3273
|
// answer here, unlike `objectOf`, and the class an instance is one of
|
|
3124
3274
|
// is an answer only under no context.
|
|
3125
|
-
|
|
3275
|
+
rule3(
|
|
3126
3276
|
"objectOfUnder",
|
|
3127
|
-
[
|
|
3128
|
-
[
|
|
3277
|
+
[v3("site"), v3("c"), v3("site")],
|
|
3278
|
+
[lit3("context", v3("c")), lit3("allocates", v3("site"), v3("cls"))],
|
|
3129
3279
|
"site is its own object"
|
|
3130
3280
|
),
|
|
3131
|
-
|
|
3281
|
+
rule3(
|
|
3132
3282
|
"objectOfUnder",
|
|
3133
|
-
[
|
|
3283
|
+
[v3("o"), v3("c"), v3("site")],
|
|
3134
3284
|
[
|
|
3135
|
-
|
|
3136
|
-
|
|
3285
|
+
lit3("reachesUnder", v3("o"), v3("c"), v3("site"), v3("c2"), VALUE_STEP),
|
|
3286
|
+
lit3("allocates", v3("site"), v3("cls"))
|
|
3137
3287
|
],
|
|
3138
3288
|
"name of a site"
|
|
3139
3289
|
),
|
|
3140
|
-
|
|
3290
|
+
rule3(
|
|
3141
3291
|
"objectOfUnder",
|
|
3142
|
-
[
|
|
3292
|
+
[v3("o"), v3("c"), v3("obj")],
|
|
3143
3293
|
[
|
|
3144
|
-
|
|
3145
|
-
|
|
3294
|
+
lit3("reachesUnder", v3("o"), v3("c"), v3("obj"), v3("c2"), VALUE_STEP),
|
|
3295
|
+
lit3("objectValue", v3("obj"))
|
|
3146
3296
|
],
|
|
3147
3297
|
"written object under a context"
|
|
3148
3298
|
),
|
|
3149
|
-
|
|
3299
|
+
rule3(
|
|
3150
3300
|
"objectOfUnder",
|
|
3151
|
-
[
|
|
3301
|
+
[v3("o"), v3("c"), v3("obj")],
|
|
3152
3302
|
[
|
|
3153
|
-
|
|
3154
|
-
|
|
3303
|
+
lit3("reachesUnder", v3("o"), v3("c"), v3("obj"), v3("c2"), RESULT_STEP),
|
|
3304
|
+
lit3("objectValue", v3("obj"))
|
|
3155
3305
|
],
|
|
3156
3306
|
"returned object under a context"
|
|
3157
3307
|
),
|
|
3158
|
-
|
|
3308
|
+
rule3(
|
|
3159
3309
|
"objectOfUnder",
|
|
3160
|
-
[
|
|
3310
|
+
[v3("o"), NO_CONTEXT, v3("cls")],
|
|
3161
3311
|
[
|
|
3162
|
-
|
|
3312
|
+
lit3(
|
|
3163
3313
|
"reachesUnder",
|
|
3164
|
-
|
|
3314
|
+
v3("o"),
|
|
3165
3315
|
NO_CONTEXT,
|
|
3166
|
-
|
|
3316
|
+
v3("cls"),
|
|
3167
3317
|
NO_CONTEXT,
|
|
3168
3318
|
INSTANCE_STEP
|
|
3169
3319
|
),
|
|
3170
|
-
|
|
3320
|
+
lit3("objectValue", v3("cls"))
|
|
3171
3321
|
],
|
|
3172
3322
|
"class reached with no context"
|
|
3173
3323
|
),
|
|
3174
|
-
|
|
3324
|
+
rule3(
|
|
3175
3325
|
"objectOfUnder",
|
|
3176
|
-
[
|
|
3177
|
-
[
|
|
3326
|
+
[v3("o"), NO_CONTEXT, v3("cls")],
|
|
3327
|
+
[lit3("instanceOf", v3("o"), v3("cls"))],
|
|
3178
3328
|
"receiver class with no context"
|
|
3179
3329
|
),
|
|
3180
|
-
|
|
3330
|
+
rule3(
|
|
3181
3331
|
"objectOfUnder",
|
|
3182
|
-
[
|
|
3183
|
-
[
|
|
3332
|
+
[v3("o"), v3("c"), v3("o")],
|
|
3333
|
+
[lit3("context", v3("c")), lit3("objectValue", v3("o"))],
|
|
3184
3334
|
"object under a context is itself"
|
|
3185
3335
|
),
|
|
3186
3336
|
// A property read goes on under the site the object was made at, so a
|
|
3187
3337
|
// field read off two constructions gives each one its own value. A
|
|
3188
3338
|
// class or a literal object keeps the context the walk was already in.
|
|
3189
|
-
|
|
3339
|
+
rule3(
|
|
3190
3340
|
"reachesUnder",
|
|
3191
|
-
[
|
|
3341
|
+
[v3("x"), v3("c"), v3("held"), v3("site"), VALUE_STEP],
|
|
3192
3342
|
[
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3343
|
+
lit3("context", v3("c")),
|
|
3344
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
3345
|
+
lit3("objectOfUnder", v3("o"), v3("c"), v3("site")),
|
|
3346
|
+
lit3("allocates", v3("site"), v3("cls")),
|
|
3347
|
+
lit3("contains", v3("site"), v3("n"), v3("held"))
|
|
3198
3348
|
],
|
|
3199
3349
|
"property read at a site"
|
|
3200
3350
|
),
|
|
3201
|
-
|
|
3351
|
+
rule3(
|
|
3202
3352
|
"reachesUnder",
|
|
3203
|
-
[
|
|
3353
|
+
[v3("x"), v3("c"), v3("held"), v3("c"), VALUE_STEP],
|
|
3204
3354
|
[
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3355
|
+
lit3("context", v3("c")),
|
|
3356
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
3357
|
+
lit3("objectOfUnder", v3("o"), v3("c"), v3("obj")),
|
|
3358
|
+
lit3("objectValue", v3("obj")),
|
|
3359
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
3210
3360
|
],
|
|
3211
3361
|
"property read off an object"
|
|
3212
3362
|
),
|
|
3213
|
-
|
|
3363
|
+
rule3(
|
|
3214
3364
|
"reachesUnder",
|
|
3215
|
-
[
|
|
3365
|
+
[v3("x"), v3("c"), v3("held"), v3("site"), v3("kind")],
|
|
3216
3366
|
[
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3367
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("y"), v3("c2"), v3("kind")),
|
|
3368
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("n")),
|
|
3369
|
+
lit3("objectOfUnder", v3("o"), v3("c2"), v3("site")),
|
|
3370
|
+
lit3("allocates", v3("site"), v3("cls")),
|
|
3371
|
+
lit3("contains", v3("site"), v3("n"), v3("held"))
|
|
3222
3372
|
],
|
|
3223
3373
|
"reached property read at a site"
|
|
3224
3374
|
),
|
|
3225
|
-
|
|
3375
|
+
rule3(
|
|
3226
3376
|
"reachesUnder",
|
|
3227
|
-
[
|
|
3377
|
+
[v3("x"), v3("c"), v3("held"), v3("c2"), v3("kind")],
|
|
3228
3378
|
[
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3379
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("y"), v3("c2"), v3("kind")),
|
|
3380
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("n")),
|
|
3381
|
+
lit3("objectOfUnder", v3("o"), v3("c2"), v3("obj")),
|
|
3382
|
+
lit3("objectValue", v3("obj")),
|
|
3383
|
+
lit3("contains", v3("obj"), v3("n"), v3("held"))
|
|
3234
3384
|
],
|
|
3235
3385
|
"reached property read off an object"
|
|
3236
3386
|
),
|
|
3237
3387
|
// A parameter goes on at the argument, under the context its caller
|
|
3238
3388
|
// was read in, and only from the calls that run the function under the
|
|
3239
3389
|
// context the walk is in. This is the one hop that changes context.
|
|
3240
|
-
|
|
3390
|
+
rule3(
|
|
3241
3391
|
"reachesUnder",
|
|
3242
|
-
[
|
|
3392
|
+
[v3("p"), v3("c"), v3("a"), v3("c3"), VALUE_STEP],
|
|
3243
3393
|
[
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3394
|
+
lit3("context", v3("c")),
|
|
3395
|
+
lit3("paramOf", v3("f"), v3("i"), v3("p")),
|
|
3396
|
+
lit3("entersUnder", v3("r"), v3("f"), v3("c"), v3("c3")),
|
|
3397
|
+
lit3("callArg", v3("r"), v3("i"), v3("a"))
|
|
3248
3398
|
],
|
|
3249
3399
|
"argument under a context"
|
|
3250
3400
|
),
|
|
3251
|
-
|
|
3401
|
+
rule3(
|
|
3252
3402
|
"reachesUnder",
|
|
3253
|
-
[
|
|
3403
|
+
[v3("p"), v3("c"), v3("a"), v3("c3"), VALUE_STEP],
|
|
3254
3404
|
[
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3405
|
+
lit3("context", v3("c")),
|
|
3406
|
+
lit3("paramNamed", v3("f"), v3("n"), v3("p")),
|
|
3407
|
+
lit3("entersUnder", v3("r"), v3("f"), v3("c"), v3("c3")),
|
|
3408
|
+
lit3("callKeywordArg", v3("r"), v3("n"), v3("a"))
|
|
3259
3409
|
],
|
|
3260
3410
|
"keyword argument under a context"
|
|
3261
3411
|
),
|
|
3262
|
-
|
|
3412
|
+
rule3(
|
|
3263
3413
|
"reachesUnder",
|
|
3264
|
-
[
|
|
3414
|
+
[v3("x"), v3("c"), v3("a"), v3("c3"), v3("kind")],
|
|
3265
3415
|
[
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3416
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("p"), v3("c2"), v3("kind")),
|
|
3417
|
+
lit3("paramOf", v3("f"), v3("i"), v3("p")),
|
|
3418
|
+
lit3("entersUnder", v3("r"), v3("f"), v3("c2"), v3("c3")),
|
|
3419
|
+
lit3("callArg", v3("r"), v3("i"), v3("a"))
|
|
3270
3420
|
],
|
|
3271
3421
|
"reached argument under a context"
|
|
3272
3422
|
),
|
|
3273
|
-
|
|
3423
|
+
rule3(
|
|
3274
3424
|
"reachesUnder",
|
|
3275
|
-
[
|
|
3425
|
+
[v3("x"), v3("c"), v3("a"), v3("c3"), v3("kind")],
|
|
3276
3426
|
[
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3427
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("p"), v3("c2"), v3("kind")),
|
|
3428
|
+
lit3("paramNamed", v3("f"), v3("n"), v3("p")),
|
|
3429
|
+
lit3("entersUnder", v3("r"), v3("f"), v3("c2"), v3("c3")),
|
|
3430
|
+
lit3("callKeywordArg", v3("r"), v3("n"), v3("a"))
|
|
3281
3431
|
],
|
|
3282
3432
|
"reached keyword argument under a context"
|
|
3283
3433
|
),
|
|
3284
3434
|
// Which call runs which function under which context. A construction
|
|
3285
3435
|
// runs its constructor under the site it makes, a method call runs
|
|
3286
3436
|
// under the site its receiver is, and anything else under no context.
|
|
3287
|
-
|
|
3437
|
+
rule3(
|
|
3288
3438
|
"entersUnder",
|
|
3289
|
-
[
|
|
3439
|
+
[v3("site"), v3("ctor"), v3("site"), v3("caller")],
|
|
3290
3440
|
[
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3441
|
+
lit3("allocates", v3("site"), v3("cls")),
|
|
3442
|
+
lit3("runsConstructor", v3("cls"), v3("ctor")),
|
|
3443
|
+
lit3("callUnder", v3("site"), v3("caller"))
|
|
3294
3444
|
],
|
|
3295
3445
|
"construction enters its constructor"
|
|
3296
3446
|
),
|
|
3297
3447
|
// When methodCallUnder and objectOfUnder bind as many columns, as they do
|
|
3298
3448
|
// once contains has run, the rewrite joins the one written first. This
|
|
3299
3449
|
// order reads the receiver under the call's own sites, not every site.
|
|
3300
|
-
|
|
3450
|
+
rule3(
|
|
3301
3451
|
"entersUnder",
|
|
3302
|
-
[
|
|
3452
|
+
[v3("r"), v3("f"), v3("site"), v3("caller")],
|
|
3303
3453
|
[
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3454
|
+
lit3("methodCallUnder", v3("r"), v3("o"), v3("m"), v3("caller")),
|
|
3455
|
+
lit3("objectOfUnder", v3("o"), v3("caller"), v3("site")),
|
|
3456
|
+
lit3("allocates", v3("site"), v3("cls")),
|
|
3457
|
+
lit3("contains", v3("site"), v3("m"), v3("f"))
|
|
3308
3458
|
],
|
|
3309
3459
|
"method call enters under its receiver"
|
|
3310
3460
|
),
|
|
3311
|
-
|
|
3461
|
+
rule3(
|
|
3312
3462
|
"methodCallUnder",
|
|
3313
|
-
[
|
|
3463
|
+
[v3("r"), v3("o"), v3("m"), v3("caller")],
|
|
3314
3464
|
[
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3465
|
+
lit3("call", v3("r"), v3("cal")),
|
|
3466
|
+
lit3("readsProperty", v3("cal"), v3("o"), v3("m")),
|
|
3467
|
+
lit3("callUnder", v3("r"), v3("caller"))
|
|
3318
3468
|
]
|
|
3319
3469
|
),
|
|
3320
3470
|
// A call written as a name runs with whatever receiver the body
|
|
3321
3471
|
// around it has, so a plain function called from a method keeps the
|
|
3322
3472
|
// site rather than taking every caller of it.
|
|
3323
|
-
|
|
3473
|
+
rule3(
|
|
3324
3474
|
"entersUnder",
|
|
3325
|
-
[
|
|
3475
|
+
[v3("r"), v3("f"), v3("c"), v3("c")],
|
|
3326
3476
|
[
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3477
|
+
lit3("context", v3("c")),
|
|
3478
|
+
lit3("callsNamed", v3("r"), v3("f")),
|
|
3479
|
+
lit3("callUnder", v3("r"), v3("c"))
|
|
3330
3480
|
],
|
|
3331
3481
|
"named call enters under the site it is made in"
|
|
3332
3482
|
),
|
|
3333
|
-
|
|
3483
|
+
rule3(
|
|
3334
3484
|
"entersUnder",
|
|
3335
|
-
[
|
|
3485
|
+
[v3("r"), v3("f"), NO_CONTEXT, v3("caller")],
|
|
3336
3486
|
[
|
|
3337
|
-
|
|
3338
|
-
|
|
3487
|
+
lit3("callsFunction", v3("r"), v3("f")),
|
|
3488
|
+
lit3("callUnder", v3("r"), v3("caller"))
|
|
3339
3489
|
],
|
|
3340
3490
|
"call enters with no context"
|
|
3341
3491
|
),
|
|
3342
3492
|
// The constructor a construction runs, the ancestry included, so a
|
|
3343
3493
|
// subclass that declares none still fills in what it inherits.
|
|
3344
|
-
|
|
3494
|
+
rule3(
|
|
3345
3495
|
"runsConstructor",
|
|
3346
|
-
[
|
|
3347
|
-
[
|
|
3496
|
+
[v3("cls"), v3("f")],
|
|
3497
|
+
[lit3("initializes", v3("cls"), v3("f"))]
|
|
3348
3498
|
),
|
|
3349
|
-
|
|
3499
|
+
rule3(
|
|
3350
3500
|
"runsConstructor",
|
|
3351
|
-
[
|
|
3501
|
+
[v3("cls"), v3("f")],
|
|
3352
3502
|
[
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3503
|
+
lit3("extends", v3("cls"), v3("b")),
|
|
3504
|
+
lit3("comesTo", v3("b"), v3("base")),
|
|
3505
|
+
lit3("runsConstructor", v3("base"), v3("f"))
|
|
3356
3506
|
]
|
|
3357
3507
|
),
|
|
3358
3508
|
// Which body a call is written in, a closure's calls included. Joining
|
|
3359
3509
|
// `bodyCalls` on the callee would put every call of a bare name in
|
|
3360
3510
|
// Python or Ruby in every body that calls that name.
|
|
3361
|
-
|
|
3362
|
-
|
|
3511
|
+
rule3("callInBody", [v3("f"), v3("r")], [lit3("makesCall", v3("f"), v3("r"))]),
|
|
3512
|
+
rule3(
|
|
3363
3513
|
"callInBody",
|
|
3364
|
-
[
|
|
3365
|
-
[
|
|
3514
|
+
[v3("f"), v3("r")],
|
|
3515
|
+
[lit3("containsFn", v3("f"), v3("g")), lit3("callInBody", v3("g"), v3("r"))]
|
|
3366
3516
|
),
|
|
3367
3517
|
// The context a call is made under: every site of the class whose
|
|
3368
3518
|
// method or constructor it is written in, and no context for a call
|
|
3369
3519
|
// outside every method body.
|
|
3370
|
-
|
|
3520
|
+
rule3(
|
|
3371
3521
|
"callUnder",
|
|
3372
|
-
[
|
|
3522
|
+
[v3("r"), v3("site")],
|
|
3373
3523
|
[
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3524
|
+
lit3("callInBody", v3("f"), v3("r")),
|
|
3525
|
+
lit3("holdsProperty", v3("cls"), v3("m"), v3("f")),
|
|
3526
|
+
lit3("allocates", v3("site"), v3("cls"))
|
|
3377
3527
|
],
|
|
3378
3528
|
"call in a method"
|
|
3379
3529
|
),
|
|
3380
|
-
|
|
3530
|
+
rule3(
|
|
3381
3531
|
"callUnder",
|
|
3382
|
-
[
|
|
3532
|
+
[v3("r"), v3("site")],
|
|
3383
3533
|
[
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3534
|
+
lit3("callInBody", v3("f"), v3("r")),
|
|
3535
|
+
lit3("initializes", v3("cls"), v3("f")),
|
|
3536
|
+
lit3("allocates", v3("site"), v3("cls"))
|
|
3387
3537
|
],
|
|
3388
3538
|
"call in a constructor"
|
|
3389
3539
|
),
|
|
3390
3540
|
// A plain function entered under a site makes its own calls under
|
|
3391
3541
|
// that site, so a chain of plain functions off one method keeps it.
|
|
3392
|
-
|
|
3542
|
+
rule3(
|
|
3393
3543
|
"callUnder",
|
|
3394
|
-
[
|
|
3544
|
+
[v3("r"), v3("c")],
|
|
3395
3545
|
[
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3546
|
+
lit3("callOutsideMethod", v3("r")),
|
|
3547
|
+
lit3("callInBody", v3("f"), v3("r")),
|
|
3548
|
+
lit3("entersUnder", v3("into"), v3("f"), v3("c"), v3("c4"))
|
|
3399
3549
|
],
|
|
3400
3550
|
"call in a function entered under a site"
|
|
3401
3551
|
),
|
|
3402
|
-
|
|
3552
|
+
rule3(
|
|
3403
3553
|
"callUnder",
|
|
3404
|
-
[
|
|
3405
|
-
[
|
|
3554
|
+
[v3("r"), NO_CONTEXT],
|
|
3555
|
+
[lit3("callOutsideMethod", v3("r"))],
|
|
3406
3556
|
"call outside every method"
|
|
3407
3557
|
),
|
|
3408
3558
|
// The two questions a caller puts under a context, stopping where
|
|
3409
3559
|
// `isWrittenAs` and `comesTo` stop, whatever context the walk ended in.
|
|
3410
|
-
|
|
3560
|
+
rule3(
|
|
3411
3561
|
"isWrittenAsUnder",
|
|
3412
|
-
[
|
|
3413
|
-
[
|
|
3562
|
+
[v3("x"), v3("c"), v3("x")],
|
|
3563
|
+
[lit3("context", v3("c")), lit3("writtenValue", v3("x"))]
|
|
3414
3564
|
),
|
|
3415
|
-
|
|
3565
|
+
rule3(
|
|
3416
3566
|
"isWrittenAsUnder",
|
|
3417
|
-
[
|
|
3418
|
-
[
|
|
3567
|
+
[v3("x"), v3("c"), v3("x")],
|
|
3568
|
+
[lit3("context", v3("c")), lit3("objectValue", v3("x"))]
|
|
3419
3569
|
),
|
|
3420
|
-
|
|
3570
|
+
rule3(
|
|
3421
3571
|
"isWrittenAsUnder",
|
|
3422
|
-
[
|
|
3572
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3423
3573
|
[
|
|
3424
|
-
|
|
3425
|
-
|
|
3574
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), VALUE_STEP),
|
|
3575
|
+
lit3("writtenValue", v3("z"))
|
|
3426
3576
|
]
|
|
3427
3577
|
),
|
|
3428
|
-
|
|
3578
|
+
rule3(
|
|
3429
3579
|
"isWrittenAsUnder",
|
|
3430
|
-
[
|
|
3580
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3431
3581
|
[
|
|
3432
|
-
|
|
3433
|
-
|
|
3582
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), VALUE_STEP),
|
|
3583
|
+
lit3("objectValue", v3("z"))
|
|
3434
3584
|
]
|
|
3435
3585
|
),
|
|
3436
3586
|
// The fallbacks a value passes under a context, so a value reader treats
|
|
3437
3587
|
// `a or b` the same way whichever path asked about it.
|
|
3438
|
-
|
|
3588
|
+
rule3(
|
|
3439
3589
|
"fallbackBehindUnder",
|
|
3440
|
-
[
|
|
3441
|
-
[
|
|
3590
|
+
[v3("x"), v3("c"), v3("x")],
|
|
3591
|
+
[lit3("context", v3("c")), lit3("fallbackBranch", v3("x"), v3("b"))]
|
|
3442
3592
|
),
|
|
3443
|
-
|
|
3593
|
+
rule3(
|
|
3444
3594
|
"fallbackBehindUnder",
|
|
3445
|
-
[
|
|
3595
|
+
[v3("x"), v3("c"), v3("f")],
|
|
3446
3596
|
[
|
|
3447
|
-
|
|
3448
|
-
|
|
3597
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("f"), v3("c2"), VALUE_STEP),
|
|
3598
|
+
lit3("fallbackBranch", v3("f"), v3("b"))
|
|
3449
3599
|
]
|
|
3450
3600
|
),
|
|
3451
|
-
|
|
3601
|
+
rule3(
|
|
3452
3602
|
"comesToUnder",
|
|
3453
|
-
[
|
|
3454
|
-
[
|
|
3603
|
+
[v3("x"), v3("c"), v3("x")],
|
|
3604
|
+
[lit3("context", v3("c")), lit3("func", v3("x"))]
|
|
3455
3605
|
),
|
|
3456
|
-
|
|
3606
|
+
rule3(
|
|
3457
3607
|
"comesToUnder",
|
|
3458
|
-
[
|
|
3459
|
-
[
|
|
3608
|
+
[v3("x"), v3("c"), v3("x")],
|
|
3609
|
+
[lit3("context", v3("c")), lit3("objectValue", v3("x"))]
|
|
3460
3610
|
),
|
|
3461
|
-
|
|
3611
|
+
rule3(
|
|
3462
3612
|
"comesToUnder",
|
|
3463
|
-
[
|
|
3613
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3464
3614
|
[
|
|
3465
|
-
|
|
3466
|
-
|
|
3615
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), VALUE_STEP),
|
|
3616
|
+
lit3("func", v3("z"))
|
|
3467
3617
|
]
|
|
3468
3618
|
),
|
|
3469
|
-
|
|
3619
|
+
rule3(
|
|
3470
3620
|
"comesToUnder",
|
|
3471
|
-
[
|
|
3621
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3472
3622
|
[
|
|
3473
|
-
|
|
3474
|
-
|
|
3623
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), VALUE_STEP),
|
|
3624
|
+
lit3("objectValue", v3("z"))
|
|
3475
3625
|
]
|
|
3476
3626
|
),
|
|
3477
|
-
|
|
3627
|
+
rule3(
|
|
3478
3628
|
"comesToUnder",
|
|
3479
|
-
[
|
|
3629
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3480
3630
|
[
|
|
3481
|
-
|
|
3482
|
-
|
|
3631
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), INSTANCE_STEP),
|
|
3632
|
+
lit3("func", v3("z"))
|
|
3483
3633
|
]
|
|
3484
3634
|
),
|
|
3485
|
-
|
|
3635
|
+
rule3(
|
|
3486
3636
|
"comesToUnder",
|
|
3487
|
-
[
|
|
3637
|
+
[v3("x"), v3("c"), v3("z")],
|
|
3488
3638
|
[
|
|
3489
|
-
|
|
3490
|
-
|
|
3639
|
+
lit3("reachesUnder", v3("x"), v3("c"), v3("z"), v3("c2"), INSTANCE_STEP),
|
|
3640
|
+
lit3("objectValue", v3("z"))
|
|
3491
3641
|
]
|
|
3492
3642
|
),
|
|
3493
3643
|
// What a value comes down to: the walk that never ran a call, stopped
|
|
3494
3644
|
// at a function or an object. Something already written out comes to
|
|
3495
3645
|
// itself, and every other walk ends at one of those.
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3646
|
+
rule3("comesTo", [v3("x"), v3("x")], [lit3("func", v3("x"))]),
|
|
3647
|
+
rule3("comesTo", [v3("x"), v3("x")], [lit3("objectValue", v3("x"))]),
|
|
3648
|
+
rule3(
|
|
3499
3649
|
"comesTo",
|
|
3500
|
-
[
|
|
3501
|
-
[
|
|
3650
|
+
[v3("x"), v3("z")],
|
|
3651
|
+
[lit3("reaches", v3("x"), v3("z"), VALUE_STEP), lit3("func", v3("z"))]
|
|
3502
3652
|
),
|
|
3503
|
-
|
|
3653
|
+
rule3(
|
|
3504
3654
|
"comesTo",
|
|
3505
|
-
[
|
|
3506
|
-
[
|
|
3655
|
+
[v3("x"), v3("z")],
|
|
3656
|
+
[lit3("reaches", v3("x"), v3("z"), VALUE_STEP), lit3("objectValue", v3("z"))]
|
|
3507
3657
|
),
|
|
3508
3658
|
// An instance walk stops the same way, so a method read off
|
|
3509
3659
|
// `new App()` still finds what the class declares.
|
|
3510
|
-
|
|
3660
|
+
rule3(
|
|
3511
3661
|
"comesTo",
|
|
3512
|
-
[
|
|
3513
|
-
[
|
|
3662
|
+
[v3("x"), v3("z")],
|
|
3663
|
+
[lit3("reaches", v3("x"), v3("z"), INSTANCE_STEP), lit3("func", v3("z"))]
|
|
3514
3664
|
),
|
|
3515
|
-
|
|
3665
|
+
rule3(
|
|
3516
3666
|
"comesTo",
|
|
3517
|
-
[
|
|
3518
|
-
[
|
|
3667
|
+
[v3("x"), v3("z")],
|
|
3668
|
+
[lit3("reaches", v3("x"), v3("z"), INSTANCE_STEP), lit3("objectValue", v3("z"))]
|
|
3519
3669
|
),
|
|
3520
3670
|
// The same stopping condition, for the walk that ran a call. A call
|
|
3521
3671
|
// gets no `comesTo` answer on purpose: coming back with what a
|
|
3522
3672
|
// factory returned would fight the unwrapping answer.
|
|
3523
|
-
|
|
3673
|
+
rule3(
|
|
3524
3674
|
"givesBack",
|
|
3525
|
-
[
|
|
3526
|
-
[
|
|
3675
|
+
[v3("x"), v3("z")],
|
|
3676
|
+
[lit3("reaches", v3("x"), v3("z"), RESULT_STEP), lit3("func", v3("z"))]
|
|
3527
3677
|
),
|
|
3528
|
-
|
|
3678
|
+
rule3(
|
|
3529
3679
|
"givesBack",
|
|
3530
|
-
[
|
|
3531
|
-
[
|
|
3680
|
+
[v3("x"), v3("z")],
|
|
3681
|
+
[lit3("reaches", v3("x"), v3("z"), RESULT_STEP), lit3("objectValue", v3("z"))]
|
|
3532
3682
|
),
|
|
3533
3683
|
// `(c) => asyncHandler(fn)` gives back the wrapper's own closure and
|
|
3534
3684
|
// the fn it unwraps. This is the unwrapped one, which a caller prefers
|
|
3535
3685
|
// for the same reason `comesTo` wins over `givesBack` on the call.
|
|
3536
|
-
|
|
3686
|
+
rule3(
|
|
3537
3687
|
"givesBackUnwrapped",
|
|
3538
|
-
[
|
|
3688
|
+
[v3("x"), v3("z")],
|
|
3539
3689
|
[
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3690
|
+
lit3("reaches", v3("x"), v3("r"), RESULT_STEP),
|
|
3691
|
+
lit3("call", v3("r"), v3("c")),
|
|
3692
|
+
lit3("comesTo", v3("r"), v3("z")),
|
|
3693
|
+
lit3("func", v3("z"))
|
|
3544
3694
|
]
|
|
3545
3695
|
),
|
|
3546
3696
|
// Following a value to the expression it is written as, whatever kind
|
|
3547
3697
|
// that is. A GraphQL document is neither a function nor an object, so
|
|
3548
3698
|
// `comesTo` never reaches one.
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3699
|
+
rule3("isWrittenAs", [v3("x"), v3("x")], [lit3("writtenValue", v3("x"))]),
|
|
3700
|
+
rule3("isWrittenAs", [v3("x"), v3("x")], [lit3("objectValue", v3("x"))]),
|
|
3701
|
+
rule3(
|
|
3552
3702
|
"isWrittenAs",
|
|
3553
|
-
[
|
|
3554
|
-
[
|
|
3703
|
+
[v3("x"), v3("z")],
|
|
3704
|
+
[lit3("reaches", v3("x"), v3("z"), VALUE_STEP), lit3("writtenValue", v3("z"))]
|
|
3555
3705
|
),
|
|
3556
|
-
|
|
3706
|
+
rule3(
|
|
3557
3707
|
"isWrittenAs",
|
|
3558
|
-
[
|
|
3559
|
-
[
|
|
3708
|
+
[v3("x"), v3("z")],
|
|
3709
|
+
[lit3("reaches", v3("x"), v3("z"), VALUE_STEP), lit3("objectValue", v3("z"))]
|
|
3560
3710
|
),
|
|
3561
3711
|
// A call is written as whatever its callee's return value is written
|
|
3562
3712
|
// as. Unlike `comesTo`, this has nothing to protect: which expression
|
|
3563
3713
|
// a value was written as does not compete with unwrapping it.
|
|
3564
|
-
|
|
3714
|
+
rule3(
|
|
3565
3715
|
"isWrittenAs",
|
|
3566
|
-
[
|
|
3716
|
+
[v3("x"), v3("z")],
|
|
3567
3717
|
[
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3718
|
+
lit3("invokes", v3("x"), v3("f")),
|
|
3719
|
+
lit3("returnsValue", v3("f"), v3("ret")),
|
|
3720
|
+
lit3("isWrittenAs", v3("ret"), v3("z"))
|
|
3571
3721
|
]
|
|
3572
3722
|
),
|
|
3573
3723
|
// The fallbacks, `a || b`, a value passes on the way to what it is
|
|
3574
3724
|
// written as. A reader of values takes one whole when every answer came
|
|
3575
3725
|
// through it, so the reader's own `||` decides which branches count.
|
|
3576
|
-
|
|
3726
|
+
rule3(
|
|
3577
3727
|
"fallbackBehind",
|
|
3578
|
-
[
|
|
3579
|
-
[
|
|
3728
|
+
[v3("x"), v3("x")],
|
|
3729
|
+
[lit3("fallbackBranch", v3("x"), v3("b"))]
|
|
3580
3730
|
),
|
|
3581
|
-
|
|
3731
|
+
rule3(
|
|
3582
3732
|
"fallbackBehind",
|
|
3583
|
-
[
|
|
3733
|
+
[v3("x"), v3("f")],
|
|
3584
3734
|
[
|
|
3585
|
-
|
|
3586
|
-
|
|
3735
|
+
lit3("reaches", v3("x"), v3("f"), VALUE_STEP),
|
|
3736
|
+
lit3("fallbackBranch", v3("f"), v3("b"))
|
|
3587
3737
|
]
|
|
3588
3738
|
),
|
|
3589
|
-
|
|
3739
|
+
rule3(
|
|
3590
3740
|
"fallbackBehind",
|
|
3591
|
-
[
|
|
3741
|
+
[v3("x"), v3("f")],
|
|
3592
3742
|
[
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3743
|
+
lit3("invokes", v3("x"), v3("g")),
|
|
3744
|
+
lit3("returnsValue", v3("g"), v3("ret")),
|
|
3745
|
+
lit3("fallbackBehind", v3("ret"), v3("f"))
|
|
3596
3746
|
]
|
|
3597
3747
|
),
|
|
3598
3748
|
// Which expression running f hands back, whether f returns it, writes
|
|
3599
3749
|
// it into a name first, or ends on it as a shorthand body.
|
|
3600
|
-
|
|
3750
|
+
rule3(
|
|
3601
3751
|
"returnsCall",
|
|
3602
|
-
[
|
|
3603
|
-
[
|
|
3752
|
+
[v3("f"), v3("c")],
|
|
3753
|
+
[lit3("returnsValue", v3("f"), v3("v")), lit3("isWrittenAs", v3("v"), v3("c"))]
|
|
3604
3754
|
),
|
|
3605
3755
|
// An argument arriving at the parameter it is passed to, by position
|
|
3606
3756
|
// or by the name the caller wrote, keeping the call it went through
|
|
3607
3757
|
// so a caller can tell two call sites apart. The callee comes before the
|
|
3608
3758
|
// parameter, so a walk that starts from the argument asks which function
|
|
3609
3759
|
// its call runs instead of trying every function with a parameter there.
|
|
3610
|
-
|
|
3760
|
+
rule3(
|
|
3611
3761
|
"passesArgument",
|
|
3612
|
-
[
|
|
3762
|
+
[v3("r"), v3("p"), v3("a")],
|
|
3613
3763
|
[
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3764
|
+
lit3("callsFunction", v3("r"), v3("f")),
|
|
3765
|
+
lit3("paramOf", v3("f"), v3("k"), v3("p")),
|
|
3766
|
+
lit3("callArg", v3("r"), v3("k"), v3("a"))
|
|
3617
3767
|
]
|
|
3618
3768
|
),
|
|
3619
|
-
|
|
3769
|
+
rule3(
|
|
3620
3770
|
"passesArgument",
|
|
3621
|
-
[
|
|
3771
|
+
[v3("r"), v3("p"), v3("a")],
|
|
3622
3772
|
[
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3773
|
+
lit3("callsFunction", v3("r"), v3("f")),
|
|
3774
|
+
lit3("paramNamed", v3("f"), v3("n"), v3("p")),
|
|
3775
|
+
lit3("callKeywordArg", v3("r"), v3("n"), v3("a"))
|
|
3626
3776
|
]
|
|
3627
3777
|
),
|
|
3628
3778
|
// The expressions that refer to a parameter under another name. An
|
|
3629
3779
|
// adapter may key a read of the parameter as the parameter itself,
|
|
3630
3780
|
// or as its own node linked by binds; both arrive here.
|
|
3631
|
-
|
|
3781
|
+
rule3(
|
|
3632
3782
|
"refersToParam",
|
|
3633
|
-
[
|
|
3634
|
-
[
|
|
3783
|
+
[v3("p"), v3("p")],
|
|
3784
|
+
[lit3("paramOf", v3("f"), v3("k"), v3("p"))]
|
|
3635
3785
|
),
|
|
3636
|
-
|
|
3786
|
+
rule3(
|
|
3637
3787
|
"refersToParam",
|
|
3638
|
-
[
|
|
3639
|
-
[
|
|
3788
|
+
[v3("p"), v3("p")],
|
|
3789
|
+
[lit3("paramNamed", v3("f"), v3("n"), v3("p"))]
|
|
3640
3790
|
),
|
|
3641
3791
|
// No import step, since no module exports a parameter.
|
|
3642
|
-
|
|
3792
|
+
rule3(
|
|
3643
3793
|
"refersToParam",
|
|
3644
|
-
[
|
|
3645
|
-
[
|
|
3794
|
+
[v3("x"), v3("p")],
|
|
3795
|
+
[lit3("refersToParam", v3("y"), v3("p")), lit3("nameHop", v3("x"), v3("y"))]
|
|
3646
3796
|
),
|
|
3647
3797
|
// An object the runtime provides and nothing declares: the process
|
|
3648
3798
|
// environment, or one of the process's output streams. Each is
|
|
3649
3799
|
// followed the same way, from the spot a pack says spells it.
|
|
3650
|
-
|
|
3651
|
-
|
|
3800
|
+
rule3("runtimeObject", [v3("w")], [lit3("environmentObject", v3("w"))]),
|
|
3801
|
+
rule3("runtimeObject", [v3("w")], [lit3("streamObject", v3("w"))]),
|
|
3652
3802
|
// An expression whose value is the runtime object w: the way a pack
|
|
3653
3803
|
// spells it, a name declared as that, or a parameter a caller handed
|
|
3654
3804
|
// one of those to, however many calls deep.
|
|
3655
|
-
|
|
3805
|
+
rule3(
|
|
3656
3806
|
"runtimeValue",
|
|
3657
|
-
[
|
|
3658
|
-
[
|
|
3807
|
+
[v3("w"), v3("o")],
|
|
3808
|
+
[lit3("runtimeObject", v3("w")), lit3("refersToObject", v3("o"), v3("w"))]
|
|
3659
3809
|
),
|
|
3660
|
-
|
|
3810
|
+
rule3(
|
|
3661
3811
|
"runtimeValue",
|
|
3662
|
-
[
|
|
3812
|
+
[v3("w"), v3("o")],
|
|
3663
3813
|
[
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3814
|
+
lit3("runtimeValue", v3("w"), v3("a")),
|
|
3815
|
+
lit3("passesArgument", v3("r"), v3("p"), v3("a")),
|
|
3816
|
+
lit3("refersToParam", v3("o"), v3("p"))
|
|
3667
3817
|
]
|
|
3668
3818
|
),
|
|
3669
3819
|
// A parameter that defaults to the environment, for the callers that
|
|
3670
3820
|
// pass nothing. `loadConfig(env = process.env)` is written that way
|
|
3671
3821
|
// so that most of the program never mentions the environment at all.
|
|
3672
|
-
|
|
3822
|
+
rule3(
|
|
3673
3823
|
"runtimeValue",
|
|
3674
|
-
[
|
|
3824
|
+
[v3("w"), v3("o")],
|
|
3675
3825
|
[
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3826
|
+
lit3("runtimeValue", v3("w"), v3("d")),
|
|
3827
|
+
lit3("paramDefault", v3("p"), v3("d")),
|
|
3828
|
+
lit3("refersToParam", v3("o"), v3("p"))
|
|
3679
3829
|
]
|
|
3680
3830
|
),
|
|
3681
3831
|
// Which environment object a keyed read takes its entry from. The
|
|
3682
3832
|
// object comes first because a project writes a handful of those and
|
|
3683
3833
|
// thousands of keyed reads, and the join starts at the small end.
|
|
3684
|
-
|
|
3834
|
+
rule3(
|
|
3685
3835
|
"environmentRead",
|
|
3686
|
-
[
|
|
3836
|
+
[v3("w"), v3("site"), v3("x")],
|
|
3687
3837
|
[
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3838
|
+
lit3("environmentObject", v3("w")),
|
|
3839
|
+
lit3("runtimeValue", v3("w"), v3("o")),
|
|
3840
|
+
lit3("readsKeyed", v3("site"), v3("o"), v3("x"))
|
|
3691
3841
|
]
|
|
3692
3842
|
),
|
|
3693
|
-
|
|
3843
|
+
rule3(
|
|
3694
3844
|
"readsEnvNamed",
|
|
3695
|
-
[
|
|
3696
|
-
[
|
|
3845
|
+
[v3("site"), v3("x")],
|
|
3846
|
+
[lit3("environmentRead", v3("w"), v3("site"), v3("x"))]
|
|
3697
3847
|
),
|
|
3698
3848
|
// A parameter whose value is an environment variable's name: a read
|
|
3699
3849
|
// site takes its name from it, or it is handed on to a parameter that
|
|
3700
3850
|
// does. Asked from the site, so the recursion runs callee to caller.
|
|
3701
|
-
|
|
3851
|
+
rule3(
|
|
3702
3852
|
"paramNamesEnv",
|
|
3703
|
-
[
|
|
3853
|
+
[v3("p"), v3("site")],
|
|
3704
3854
|
[
|
|
3705
|
-
|
|
3706
|
-
|
|
3855
|
+
lit3("readsEnvNamed", v3("site"), v3("x")),
|
|
3856
|
+
lit3("refersToParam", v3("x"), v3("p"))
|
|
3707
3857
|
]
|
|
3708
3858
|
),
|
|
3709
|
-
|
|
3859
|
+
rule3(
|
|
3710
3860
|
"paramNamesEnv",
|
|
3711
|
-
[
|
|
3861
|
+
[v3("p"), v3("site")],
|
|
3712
3862
|
[
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3863
|
+
lit3("refersToParam", v3("a"), v3("p")),
|
|
3864
|
+
lit3("passesArgument", v3("r"), v3("q"), v3("a")),
|
|
3865
|
+
lit3("paramNamesEnv", v3("q"), v3("site"))
|
|
3716
3866
|
]
|
|
3717
3867
|
),
|
|
3718
3868
|
// The class some declaration says a value is one of: its own, or that of
|
|
3719
3869
|
// anything the value steps to, a caller's argument included. Two callers
|
|
3720
3870
|
// can disagree, so the asking side decides whether it got one.
|
|
3721
|
-
|
|
3722
|
-
|
|
3871
|
+
rule3("typedAs", [v3("x"), v3("t")], [lit3("instanceOf", v3("x"), v3("t"))]),
|
|
3872
|
+
rule3(
|
|
3723
3873
|
"typedAs",
|
|
3724
|
-
[
|
|
3874
|
+
[v3("x"), v3("t")],
|
|
3725
3875
|
[
|
|
3726
|
-
|
|
3727
|
-
|
|
3876
|
+
lit3("reaches", v3("x"), v3("y"), VALUE_STEP),
|
|
3877
|
+
lit3("instanceOf", v3("y"), v3("t"))
|
|
3728
3878
|
]
|
|
3729
3879
|
),
|
|
3730
3880
|
// Which module's export a re-exported name forwards to, however
|
|
3731
3881
|
// many barrels deep the forwarding runs.
|
|
3732
|
-
|
|
3882
|
+
rule3(
|
|
3733
3883
|
"moduleForwards",
|
|
3734
|
-
[
|
|
3735
|
-
[
|
|
3884
|
+
[v3("m"), v3("n"), v3("m2"), v3("n2")],
|
|
3885
|
+
[lit3("reExports", v3("m"), v3("n"), v3("m2"), v3("n2"))]
|
|
3736
3886
|
),
|
|
3737
|
-
|
|
3887
|
+
rule3(
|
|
3738
3888
|
"moduleForwards",
|
|
3739
|
-
[
|
|
3889
|
+
[v3("m"), v3("n"), v3("m3"), v3("n3")],
|
|
3740
3890
|
[
|
|
3741
|
-
|
|
3742
|
-
|
|
3891
|
+
lit3("reExports", v3("m"), v3("n"), v3("m2"), v3("n2")),
|
|
3892
|
+
lit3("moduleForwards", v3("m2"), v3("n2"), v3("m3"), v3("n3"))
|
|
3743
3893
|
]
|
|
3744
3894
|
),
|
|
3745
3895
|
// What a module exports: directly, or through re-export chains.
|
|
3746
|
-
|
|
3896
|
+
rule3(
|
|
3747
3897
|
"moduleExport",
|
|
3748
|
-
[
|
|
3749
|
-
[
|
|
3898
|
+
[v3("m"), v3("n"), v3("value")],
|
|
3899
|
+
[lit3("exportsAs", v3("m"), v3("n"), v3("value"))],
|
|
3750
3900
|
"export"
|
|
3751
3901
|
),
|
|
3752
|
-
|
|
3902
|
+
rule3(
|
|
3753
3903
|
"moduleExport",
|
|
3754
|
-
[
|
|
3904
|
+
[v3("m"), v3("n"), v3("value")],
|
|
3755
3905
|
[
|
|
3756
|
-
|
|
3757
|
-
|
|
3906
|
+
lit3("reExports", v3("m"), v3("n"), v3("m2"), v3("n2")),
|
|
3907
|
+
lit3("moduleExport", v3("m2"), v3("n2"), v3("value"))
|
|
3758
3908
|
],
|
|
3759
3909
|
"re-export"
|
|
3760
3910
|
),
|
|
3761
|
-
|
|
3911
|
+
rule3(
|
|
3762
3912
|
"moduleExport",
|
|
3763
|
-
[
|
|
3913
|
+
[v3("m"), v3("n"), v3("value")],
|
|
3764
3914
|
[
|
|
3765
|
-
|
|
3766
|
-
|
|
3915
|
+
lit3("reExportsAll", v3("m"), v3("m2")),
|
|
3916
|
+
lit3("moduleExport", v3("m2"), v3("n"), v3("value"))
|
|
3767
3917
|
],
|
|
3768
3918
|
"re-export all"
|
|
3769
3919
|
),
|
|
3770
3920
|
// The function a call runs, written from the call's side because a
|
|
3771
3921
|
// caller asking what a call gives back has the call in hand.
|
|
3772
|
-
|
|
3922
|
+
rule3(
|
|
3773
3923
|
"invokes",
|
|
3774
|
-
[
|
|
3775
|
-
[
|
|
3924
|
+
[v3("r"), v3("f")],
|
|
3925
|
+
[lit3("call", v3("r"), v3("c")), lit3("comesTo", v3("c"), v3("f"))]
|
|
3776
3926
|
),
|
|
3777
3927
|
// The callee is itself a call: `daoBuilder()()`.
|
|
3778
|
-
|
|
3928
|
+
rule3(
|
|
3779
3929
|
"invokes",
|
|
3780
|
-
[
|
|
3781
|
-
[
|
|
3930
|
+
[v3("r"), v3("f")],
|
|
3931
|
+
[lit3("call", v3("r"), v3("c")), lit3("givesBack", v3("c"), v3("f"))]
|
|
3782
3932
|
),
|
|
3783
3933
|
// The object an expression refers to: a name through `comesTo`, a
|
|
3784
3934
|
// factory call through what it gives back. Naming the step is what
|
|
3785
3935
|
// makes `routes.list` and `make(body).handle` one rule.
|
|
3786
|
-
|
|
3936
|
+
rule3(
|
|
3787
3937
|
"objectOf",
|
|
3788
|
-
[
|
|
3789
|
-
[
|
|
3938
|
+
[v3("o"), v3("obj")],
|
|
3939
|
+
[lit3("comesTo", v3("o"), v3("obj")), lit3("objectValue", v3("obj"))]
|
|
3790
3940
|
),
|
|
3791
|
-
|
|
3941
|
+
rule3(
|
|
3792
3942
|
"objectOf",
|
|
3793
|
-
[
|
|
3794
|
-
[
|
|
3943
|
+
[v3("x"), v3("obj")],
|
|
3944
|
+
[lit3("givesBack", v3("x"), v3("obj")), lit3("objectValue", v3("obj"))]
|
|
3795
3945
|
),
|
|
3796
3946
|
// A construction is the object it made, and so is any name for it.
|
|
3797
3947
|
// The class stays an answer too, so an instance whose site is not in
|
|
3798
3948
|
// the run still reads what the class stores.
|
|
3799
|
-
|
|
3949
|
+
rule3(
|
|
3800
3950
|
"objectOf",
|
|
3801
|
-
[
|
|
3802
|
-
[
|
|
3951
|
+
[v3("site"), v3("site")],
|
|
3952
|
+
[lit3("allocates", v3("site"), v3("c"))]
|
|
3803
3953
|
),
|
|
3804
|
-
|
|
3954
|
+
rule3(
|
|
3805
3955
|
"objectOf",
|
|
3806
|
-
[
|
|
3956
|
+
[v3("o"), v3("site")],
|
|
3807
3957
|
[
|
|
3808
|
-
|
|
3809
|
-
|
|
3958
|
+
lit3("reaches", v3("o"), v3("site"), VALUE_STEP),
|
|
3959
|
+
lit3("allocates", v3("site"), v3("c"))
|
|
3810
3960
|
]
|
|
3811
3961
|
),
|
|
3812
3962
|
// So is one a call hands back when it passes no arguments, as
|
|
3813
3963
|
// `get_settings()` hands back `Settings()`, since only the construction
|
|
3814
3964
|
// contains the field defaults its class declares.
|
|
3815
|
-
|
|
3965
|
+
rule3(
|
|
3816
3966
|
"objectOf",
|
|
3817
|
-
[
|
|
3967
|
+
[v3("o"), v3("site")],
|
|
3818
3968
|
[
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3969
|
+
lit3("reaches", v3("o"), v3("site"), RESULT_STEP),
|
|
3970
|
+
lit3("callArgCount", v3("site"), NO_ARGUMENTS),
|
|
3971
|
+
lit3("allocates", v3("site"), v3("c"))
|
|
3822
3972
|
]
|
|
3823
3973
|
),
|
|
3824
3974
|
// Which calls a function, found by the name the call is written as
|
|
@@ -3826,114 +3976,114 @@ var STATED_RULES = [
|
|
|
3826
3976
|
// the function and wants its call sites, so both of these start from
|
|
3827
3977
|
// the function. Starting from `call` instead asks what every call in
|
|
3828
3978
|
// the project imports, which was 72% of everything derived.
|
|
3829
|
-
|
|
3979
|
+
rule3(
|
|
3830
3980
|
"callsNamed",
|
|
3831
|
-
[
|
|
3832
|
-
[
|
|
3981
|
+
[v3("r"), v3("f")],
|
|
3982
|
+
[lit3("binds", v3("c"), v3("f")), lit3("call", v3("r"), v3("c"))]
|
|
3833
3983
|
),
|
|
3834
|
-
|
|
3984
|
+
rule3(
|
|
3835
3985
|
"callsNamed",
|
|
3836
|
-
[
|
|
3986
|
+
[v3("r"), v3("f")],
|
|
3837
3987
|
[
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3988
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("f")),
|
|
3989
|
+
lit3("imports", v3("c"), v3("m"), v3("n")),
|
|
3990
|
+
lit3("call", v3("r"), v3("c"))
|
|
3841
3991
|
]
|
|
3842
3992
|
),
|
|
3843
3993
|
// The same, for a language whose adapter writes the import down as a
|
|
3844
3994
|
// declaration and the call's callee as the name referring to it.
|
|
3845
|
-
|
|
3995
|
+
rule3(
|
|
3846
3996
|
"callsNamed",
|
|
3847
|
-
[
|
|
3997
|
+
[v3("r"), v3("f")],
|
|
3848
3998
|
[
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3999
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("f")),
|
|
4000
|
+
lit3("imports", v3("d"), v3("m"), v3("n")),
|
|
4001
|
+
lit3("binds", v3("c"), v3("d")),
|
|
4002
|
+
lit3("call", v3("r"), v3("c"))
|
|
3853
4003
|
]
|
|
3854
4004
|
),
|
|
3855
4005
|
// `const f = (x) => ...` declares the name and puts the parameters on
|
|
3856
4006
|
// the arrow, so everything above arrives at the declaration and
|
|
3857
4007
|
// `paramOf` is about the arrow. One binds hop joins the two.
|
|
3858
|
-
|
|
4008
|
+
rule3(
|
|
3859
4009
|
"callsNamed",
|
|
3860
|
-
[
|
|
3861
|
-
[
|
|
4010
|
+
[v3("r"), v3("f")],
|
|
4011
|
+
[lit3("binds", v3("g"), v3("f")), lit3("callsNamed", v3("r"), v3("g"))]
|
|
3862
4012
|
),
|
|
3863
4013
|
// Every one of those, and the binds hop again over the whole
|
|
3864
4014
|
// relation, so a property holding a name for a function is reached
|
|
3865
4015
|
// the way it was before the two were told apart.
|
|
3866
|
-
|
|
3867
|
-
|
|
4016
|
+
rule3("callsFunction", [v3("r"), v3("f")], [lit3("callsNamed", v3("r"), v3("f"))]),
|
|
4017
|
+
rule3(
|
|
3868
4018
|
"callsFunction",
|
|
3869
|
-
[
|
|
3870
|
-
[
|
|
4019
|
+
[v3("r"), v3("f")],
|
|
4020
|
+
[lit3("binds", v3("g"), v3("f")), lit3("callsFunction", v3("r"), v3("g"))]
|
|
3871
4021
|
),
|
|
3872
4022
|
// A function written on an object, called off it: `client.get(o)`.
|
|
3873
4023
|
// The receiver comes from the object through `refersToObject`, not from
|
|
3874
4024
|
// `objectOf`: a walk from every reader of the name was most of a run.
|
|
3875
|
-
|
|
4025
|
+
rule3(
|
|
3876
4026
|
"callsFunction",
|
|
3877
|
-
[
|
|
4027
|
+
[v3("r"), v3("f")],
|
|
3878
4028
|
[
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
4029
|
+
lit3("holdsProperty", v3("obj"), v3("n"), v3("f")),
|
|
4030
|
+
lit3("refersToObject", v3("o"), v3("obj")),
|
|
4031
|
+
lit3("readsProperty", v3("c"), v3("o"), v3("n")),
|
|
4032
|
+
lit3("call", v3("r"), v3("c"))
|
|
3883
4033
|
]
|
|
3884
4034
|
),
|
|
3885
4035
|
// A name bound to a factory's result, called: `const get =
|
|
3886
4036
|
// makeReader(env)` then `get(name)`. Written from the factory's call so
|
|
3887
4037
|
// the walk starts where `callsFunction` already has an answer.
|
|
3888
|
-
|
|
4038
|
+
rule3(
|
|
3889
4039
|
"callsFunction",
|
|
3890
|
-
[
|
|
4040
|
+
[v3("r"), v3("f")],
|
|
3891
4041
|
[
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
4042
|
+
lit3("returnsValue", v3("g"), v3("f")),
|
|
4043
|
+
lit3("callsFunction", v3("r0"), v3("g")),
|
|
4044
|
+
lit3("callsNamed", v3("r"), v3("r0"))
|
|
3895
4045
|
]
|
|
3896
4046
|
),
|
|
3897
4047
|
// The same, called straight off the factory's call, as
|
|
3898
4048
|
// `register("created")(handler)` or a Python decorator written that way.
|
|
3899
|
-
|
|
4049
|
+
rule3(
|
|
3900
4050
|
"callsFunction",
|
|
3901
|
-
[
|
|
4051
|
+
[v3("r"), v3("f")],
|
|
3902
4052
|
[
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
4053
|
+
lit3("returnsValue", v3("g"), v3("f")),
|
|
4054
|
+
lit3("callsFunction", v3("r0"), v3("g")),
|
|
4055
|
+
lit3("call", v3("r"), v3("r0"))
|
|
3906
4056
|
]
|
|
3907
4057
|
),
|
|
3908
4058
|
// The expressions that refer to an object under another name, through
|
|
3909
4059
|
// a name hop or an import. Asked from the object, so it visits only
|
|
3910
4060
|
// them.
|
|
3911
|
-
|
|
4061
|
+
rule3("refersToObject", [v3("obj"), v3("obj")], [lit3("objectValue", v3("obj"))]),
|
|
3912
4062
|
// A construction is an object too, and the one a name for it refers to.
|
|
3913
|
-
|
|
4063
|
+
rule3(
|
|
3914
4064
|
"refersToObject",
|
|
3915
|
-
[
|
|
3916
|
-
[
|
|
4065
|
+
[v3("site"), v3("site")],
|
|
4066
|
+
[lit3("allocates", v3("site"), v3("c"))]
|
|
3917
4067
|
),
|
|
3918
4068
|
// The process environment and the output streams are objects nothing
|
|
3919
4069
|
// declares, so a pack saying which expression spells one is the only
|
|
3920
4070
|
// way in.
|
|
3921
|
-
|
|
4071
|
+
rule3("refersToObject", [v3("w"), v3("w")], [lit3("runtimeObject", v3("w"))]),
|
|
3922
4072
|
// The hop comes first so a check with both ends bound walks forward from
|
|
3923
4073
|
// the name, which the named store needs. With one end bound, the bound
|
|
3924
4074
|
// literal goes first whatever order the body is written in.
|
|
3925
|
-
|
|
4075
|
+
rule3(
|
|
3926
4076
|
"refersToObject",
|
|
3927
|
-
[
|
|
3928
|
-
[
|
|
4077
|
+
[v3("x"), v3("obj")],
|
|
4078
|
+
[lit3("nameHop", v3("x"), v3("y")), lit3("refersToObject", v3("y"), v3("obj"))]
|
|
3929
4079
|
),
|
|
3930
|
-
|
|
4080
|
+
rule3(
|
|
3931
4081
|
"refersToObject",
|
|
3932
|
-
[
|
|
4082
|
+
[v3("x"), v3("obj")],
|
|
3933
4083
|
[
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
4084
|
+
lit3("imports", v3("x"), v3("m"), v3("n")),
|
|
4085
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("y")),
|
|
4086
|
+
lit3("refersToObject", v3("y"), v3("obj"))
|
|
3937
4087
|
]
|
|
3938
4088
|
),
|
|
3939
4089
|
// What an object contains, its base class included, so a method the base
|
|
@@ -3941,417 +4091,418 @@ var STATED_RULES = [
|
|
|
3941
4091
|
// declare gives two, and the caller decides. This is its own relation
|
|
3942
4092
|
// rather than more `holdsProperty`, which stays something an adapter
|
|
3943
4093
|
// states and the rules only read.
|
|
3944
|
-
|
|
4094
|
+
rule3(
|
|
3945
4095
|
"contains",
|
|
3946
|
-
[
|
|
3947
|
-
[
|
|
4096
|
+
[v3("o"), v3("n"), v3("held")],
|
|
4097
|
+
[lit3("holdsProperty", v3("o"), v3("n"), v3("held"))]
|
|
3948
4098
|
),
|
|
3949
|
-
|
|
4099
|
+
rule3(
|
|
3950
4100
|
"contains",
|
|
3951
|
-
[
|
|
4101
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
3952
4102
|
[
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
4103
|
+
lit3("extends", v3("cls"), v3("base")),
|
|
4104
|
+
lit3("comesTo", v3("base"), v3("baseCls")),
|
|
4105
|
+
lit3("contains", v3("baseCls"), v3("n"), v3("held"))
|
|
3956
4106
|
],
|
|
3957
4107
|
BASE_CLASS_RULE
|
|
3958
4108
|
),
|
|
3959
4109
|
// A module a Ruby class prepends is an ancestor too. It comes before the
|
|
3960
4110
|
// class in lookup, which `overrides` says, so it has a relation of its own.
|
|
3961
|
-
|
|
4111
|
+
rule3(
|
|
3962
4112
|
"contains",
|
|
3963
|
-
[
|
|
4113
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
3964
4114
|
[
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
4115
|
+
lit3("prepends", v3("cls"), v3("mod")),
|
|
4116
|
+
lit3("comesTo", v3("mod"), v3("modObj")),
|
|
4117
|
+
lit3("contains", v3("modObj"), v3("n"), v3("held"))
|
|
3968
4118
|
],
|
|
3969
4119
|
"prepended module"
|
|
3970
4120
|
),
|
|
3971
4121
|
// An association is read off an instance as a property, and stating
|
|
3972
4122
|
// it as `contains` is what puts it on the ancestry rule, so a concern
|
|
3973
4123
|
// or a base class can be the one that declares it.
|
|
3974
|
-
|
|
4124
|
+
rule3(
|
|
3975
4125
|
"contains",
|
|
3976
|
-
[
|
|
3977
|
-
[
|
|
4126
|
+
[v3("cls"), v3("n"), v3("t")],
|
|
4127
|
+
[lit3("declaresAssociation", v3("cls"), v3("n"), v3("t"))],
|
|
3978
4128
|
"declared association"
|
|
3979
4129
|
),
|
|
3980
4130
|
// The same, for a language that buries the declaration in an ordinary
|
|
3981
4131
|
// assignment. Keying on the module the callable came from is what
|
|
3982
4132
|
// keeps a project function spelled the same way out.
|
|
3983
|
-
|
|
4133
|
+
rule3(
|
|
3984
4134
|
"contains",
|
|
3985
|
-
[
|
|
4135
|
+
[v3("cls"), v3("n"), v3("t")],
|
|
3986
4136
|
[
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
4137
|
+
lit3("fieldCall", v3("cls"), v3("n"), v3("c"), v3("t")),
|
|
4138
|
+
lit3("comesFrom", v3("c"), v3("m"), v3("name")),
|
|
4139
|
+
lit3("associationConstructor", v3("m"), v3("name"))
|
|
3990
4140
|
],
|
|
3991
4141
|
"constructed association"
|
|
3992
4142
|
),
|
|
3993
4143
|
// What the constructor put on the receiver. The class is the object
|
|
3994
4144
|
// for an instance whose own site is not in the run.
|
|
3995
|
-
|
|
4145
|
+
rule3(
|
|
3996
4146
|
"contains",
|
|
3997
|
-
[
|
|
4147
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
3998
4148
|
[
|
|
3999
|
-
|
|
4000
|
-
|
|
4149
|
+
lit3("initializes", v3("cls"), v3("f")),
|
|
4150
|
+
lit3("storesProperty", v3("f"), v3("n"), v3("held"), RECEIVER_STORE)
|
|
4001
4151
|
],
|
|
4002
4152
|
"constructor store"
|
|
4003
4153
|
),
|
|
4004
4154
|
// What any other method of the class put there. Two methods writing
|
|
4005
4155
|
// one name give two rows, since nothing here orders them.
|
|
4006
|
-
|
|
4156
|
+
rule3(
|
|
4007
4157
|
"contains",
|
|
4008
|
-
[
|
|
4158
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
4009
4159
|
[
|
|
4010
|
-
|
|
4011
|
-
|
|
4160
|
+
lit3("holdsProperty", v3("cls"), v3("m"), v3("f")),
|
|
4161
|
+
lit3("storesProperty", v3("f"), v3("n"), v3("held"), RECEIVER_STORE)
|
|
4012
4162
|
],
|
|
4013
4163
|
"method store"
|
|
4014
4164
|
),
|
|
4015
4165
|
// A write through a name, `client.timeout = 5`, lands on the object the
|
|
4016
4166
|
// name refers to. The writes to the property asked about come off an
|
|
4017
4167
|
// index, and each name is checked forward against the one object.
|
|
4018
|
-
|
|
4168
|
+
rule3(
|
|
4019
4169
|
"contains",
|
|
4020
|
-
[
|
|
4170
|
+
[v3("obj"), v3("n"), v3("held")],
|
|
4021
4171
|
[
|
|
4022
|
-
|
|
4023
|
-
|
|
4172
|
+
lit3("storesProperty", v3("x"), v3("n"), v3("held"), NAMED_STORE),
|
|
4173
|
+
lit3("refersToObject", v3("x"), v3("obj"))
|
|
4024
4174
|
],
|
|
4025
4175
|
"named store"
|
|
4026
4176
|
),
|
|
4027
4177
|
// A member a class declares itself under a name one of its bases also
|
|
4028
4178
|
// contains. `contains` keeps both, and a caller that needs one answer
|
|
4029
4179
|
// prefers the member declared nearer the object the read went through.
|
|
4030
|
-
|
|
4180
|
+
rule3(
|
|
4031
4181
|
"overrides",
|
|
4032
|
-
[
|
|
4182
|
+
[v3("m"), v3("n"), v3("h")],
|
|
4033
4183
|
[
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4184
|
+
lit3("holdsProperty", v3("c"), v3("n"), v3("m")),
|
|
4185
|
+
lit3("extends", v3("c"), v3("b")),
|
|
4186
|
+
lit3("comesTo", v3("b"), v3("base")),
|
|
4187
|
+
lit3("contains", v3("base"), v3("n"), v3("h"))
|
|
4038
4188
|
]
|
|
4039
4189
|
),
|
|
4040
4190
|
// The same for a field default, which a plain subclass contains too.
|
|
4041
|
-
|
|
4191
|
+
rule3(
|
|
4042
4192
|
"overrides",
|
|
4043
|
-
[
|
|
4193
|
+
[v3("m"), v3("n"), v3("h")],
|
|
4044
4194
|
[
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4195
|
+
lit3("declaresDefault", v3("c"), v3("n"), v3("m")),
|
|
4196
|
+
lit3("extends", v3("c"), v3("b")),
|
|
4197
|
+
lit3("comesTo", v3("b"), v3("base")),
|
|
4198
|
+
lit3("contains", v3("base"), v3("n"), v3("h"))
|
|
4049
4199
|
]
|
|
4050
4200
|
),
|
|
4051
4201
|
// A prepended module's member comes before the class's own and what the
|
|
4052
4202
|
// class inherits. The module is found by a name hop, since `comesTo`
|
|
4053
4203
|
// asked backwards from the module walks to it from every value.
|
|
4054
|
-
|
|
4204
|
+
rule3(
|
|
4055
4205
|
"overrides",
|
|
4056
|
-
[
|
|
4206
|
+
[v3("m"), v3("n"), v3("h")],
|
|
4057
4207
|
[
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4208
|
+
lit3("holdsProperty", v3("modObj"), v3("n"), v3("m")),
|
|
4209
|
+
lit3("nameHop", v3("mod"), v3("modObj")),
|
|
4210
|
+
lit3("prepends", v3("c"), v3("mod")),
|
|
4211
|
+
lit3("holdsProperty", v3("c"), v3("n"), v3("h"))
|
|
4062
4212
|
]
|
|
4063
4213
|
),
|
|
4064
|
-
|
|
4214
|
+
rule3(
|
|
4065
4215
|
"overrides",
|
|
4066
|
-
[
|
|
4067
|
-
[
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4216
|
+
[v3("m"), v3("n"), v3("h")],
|
|
4217
|
+
[
|
|
4218
|
+
lit3("holdsProperty", v3("modObj"), v3("n"), v3("m")),
|
|
4219
|
+
lit3("nameHop", v3("mod"), v3("modObj")),
|
|
4220
|
+
lit3("prepends", v3("c"), v3("mod")),
|
|
4221
|
+
lit3("extends", v3("c"), v3("b")),
|
|
4222
|
+
lit3("comesTo", v3("b"), v3("base")),
|
|
4223
|
+
lit3("contains", v3("base"), v3("n"), v3("h"))
|
|
4074
4224
|
]
|
|
4075
4225
|
),
|
|
4076
4226
|
// The objects a read reads a name off, and on each one the members the
|
|
4077
4227
|
// read finds that another member there overrides.
|
|
4078
|
-
|
|
4228
|
+
rule3(
|
|
4079
4229
|
"readsFrom",
|
|
4080
|
-
[
|
|
4230
|
+
[v3("x"), v3("obj"), v3("n")],
|
|
4081
4231
|
[
|
|
4082
|
-
|
|
4083
|
-
|
|
4232
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
4233
|
+
lit3("objectOf", v3("o"), v3("obj"))
|
|
4084
4234
|
]
|
|
4085
4235
|
),
|
|
4086
|
-
|
|
4236
|
+
rule3(
|
|
4087
4237
|
"readsOverridden",
|
|
4088
|
-
[
|
|
4238
|
+
[v3("x"), v3("obj"), v3("h")],
|
|
4089
4239
|
[
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4240
|
+
lit3("readsFrom", v3("x"), v3("obj"), v3("n")),
|
|
4241
|
+
lit3("contains", v3("obj"), v3("n"), v3("m")),
|
|
4242
|
+
lit3("overrides", v3("m"), v3("n"), v3("h"))
|
|
4093
4243
|
]
|
|
4094
4244
|
),
|
|
4095
4245
|
// Every member, for a read with an override, so `contains` is asked with
|
|
4096
4246
|
// the object and name bound, the way the property read already asks it.
|
|
4097
|
-
|
|
4247
|
+
rule3(
|
|
4098
4248
|
"readsMemberOn",
|
|
4099
|
-
[
|
|
4249
|
+
[v3("x"), v3("obj"), v3("h")],
|
|
4100
4250
|
[
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4251
|
+
lit3("readsOverridden", v3("x"), v3("shadowing"), v3("overridden")),
|
|
4252
|
+
lit3("readsFrom", v3("x"), v3("obj"), v3("n")),
|
|
4253
|
+
lit3("contains", v3("obj"), v3("n"), v3("h"))
|
|
4104
4254
|
]
|
|
4105
4255
|
),
|
|
4106
4256
|
// A call written with a class's own name, which is how most languages
|
|
4107
4257
|
// spell a construction. A language that spells one some other way
|
|
4108
4258
|
// states its own rule for this, the way Ruby does for `Const.new`.
|
|
4109
|
-
|
|
4259
|
+
rule3(
|
|
4110
4260
|
"constructsNamed",
|
|
4111
|
-
[
|
|
4112
|
-
[
|
|
4261
|
+
[v3("r"), v3("cls")],
|
|
4262
|
+
[lit3("objectValue", v3("cls")), lit3("callsNamed", v3("r"), v3("cls"))]
|
|
4113
4263
|
),
|
|
4114
4264
|
// Each construction is an object of its own containing what its
|
|
4115
4265
|
// class stores, so two sites are two objects.
|
|
4116
|
-
|
|
4266
|
+
rule3(
|
|
4117
4267
|
"contains",
|
|
4118
|
-
[
|
|
4268
|
+
[v3("site"), v3("n"), v3("held")],
|
|
4119
4269
|
[
|
|
4120
|
-
|
|
4121
|
-
|
|
4270
|
+
lit3("allocates", v3("site"), v3("cls")),
|
|
4271
|
+
lit3("contains", v3("cls"), v3("n"), v3("held"))
|
|
4122
4272
|
],
|
|
4123
4273
|
"allocated instance"
|
|
4124
4274
|
),
|
|
4125
4275
|
// A construction written with no arguments keeps every field default its
|
|
4126
4276
|
// class declares. Any argument could fill a field through a constructor
|
|
4127
4277
|
// the run cannot see, and a finder's result was built somewhere else.
|
|
4128
|
-
|
|
4278
|
+
rule3(
|
|
4129
4279
|
"contains",
|
|
4130
|
-
[
|
|
4280
|
+
[v3("site"), v3("n"), v3("held")],
|
|
4131
4281
|
[
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4282
|
+
lit3("callArgCount", v3("site"), NO_ARGUMENTS),
|
|
4283
|
+
lit3("call", v3("site"), v3("c")),
|
|
4284
|
+
lit3("comesTo", v3("c"), v3("cls")),
|
|
4285
|
+
lit3("objectValue", v3("cls")),
|
|
4286
|
+
lit3("fieldDefault", v3("cls"), v3("n"), v3("held"))
|
|
4137
4287
|
],
|
|
4138
4288
|
"construction with no arguments"
|
|
4139
4289
|
),
|
|
4140
4290
|
// On a plain class nothing generates a constructor that could replace
|
|
4141
4291
|
// an annotated attribute, so every instance shares it.
|
|
4142
|
-
|
|
4292
|
+
rule3(
|
|
4143
4293
|
"contains",
|
|
4144
|
-
[
|
|
4294
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
4145
4295
|
[
|
|
4146
|
-
|
|
4147
|
-
|
|
4296
|
+
lit3("declaresDefault", v3("cls"), v3("n"), v3("held")),
|
|
4297
|
+
lit3("plainAncestry", v3("cls"))
|
|
4148
4298
|
],
|
|
4149
4299
|
"plain class attribute"
|
|
4150
4300
|
),
|
|
4151
4301
|
// A class nothing generates a constructor for. The adapter states it
|
|
4152
4302
|
// only where the source shows it, since a rule cannot say "unless", and
|
|
4153
4303
|
// a class written over one base is plain when that base is.
|
|
4154
|
-
|
|
4155
|
-
|
|
4304
|
+
rule3("plainAncestry", [v3("c")], [lit3("plainClass", v3("c"))]),
|
|
4305
|
+
rule3(
|
|
4156
4306
|
"plainAncestry",
|
|
4157
|
-
[
|
|
4307
|
+
[v3("c")],
|
|
4158
4308
|
[
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4309
|
+
lit3("extendsOnly", v3("c"), v3("base")),
|
|
4310
|
+
lit3("comesTo", v3("base"), v3("baseCls")),
|
|
4311
|
+
lit3("plainAncestry", v3("baseCls"))
|
|
4162
4312
|
]
|
|
4163
4313
|
),
|
|
4164
4314
|
// A field default, its base class's included. It stays out of `contains`,
|
|
4165
4315
|
// which every instance reads, because a constructor may replace it.
|
|
4166
|
-
|
|
4316
|
+
rule3(
|
|
4167
4317
|
"fieldDefault",
|
|
4168
|
-
[
|
|
4169
|
-
[
|
|
4318
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
4319
|
+
[lit3("declaresDefault", v3("cls"), v3("n"), v3("held"))]
|
|
4170
4320
|
),
|
|
4171
|
-
|
|
4321
|
+
rule3(
|
|
4172
4322
|
"fieldDefault",
|
|
4173
|
-
[
|
|
4323
|
+
[v3("cls"), v3("n"), v3("held")],
|
|
4174
4324
|
[
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4325
|
+
lit3("extends", v3("cls"), v3("base")),
|
|
4326
|
+
lit3("comesTo", v3("base"), v3("baseCls")),
|
|
4327
|
+
lit3("fieldDefault", v3("baseCls"), v3("n"), v3("held"))
|
|
4178
4328
|
],
|
|
4179
4329
|
BASE_CLASS_RULE
|
|
4180
4330
|
),
|
|
4181
4331
|
// A call that makes one of a class. Every finder a pack declared is
|
|
4182
4332
|
// one too, so `User.find(1)` is a site the same way `User.new` is.
|
|
4183
|
-
|
|
4333
|
+
rule3(
|
|
4184
4334
|
"allocates",
|
|
4185
|
-
[
|
|
4335
|
+
[v3("site"), v3("cls")],
|
|
4186
4336
|
[
|
|
4187
|
-
|
|
4188
|
-
|
|
4337
|
+
lit3("call", v3("site"), v3("c")),
|
|
4338
|
+
lit3("stepsTo", v3("site"), v3("cls"), INSTANCE_STEP)
|
|
4189
4339
|
],
|
|
4190
4340
|
"allocation site"
|
|
4191
4341
|
),
|
|
4192
4342
|
// The library base a class's ancestry arrives at, however many of a
|
|
4193
4343
|
// project's own classes sit in between. A base the run declares has a
|
|
4194
4344
|
// node to keep walking from; one it does not has only a name.
|
|
4195
|
-
|
|
4196
|
-
|
|
4345
|
+
rule3("libraryBase", [v3("c"), v3("n")], [lit3("extendsNamed", v3("c"), v3("n"))]),
|
|
4346
|
+
rule3(
|
|
4197
4347
|
"libraryBase",
|
|
4198
|
-
[
|
|
4348
|
+
[v3("c"), v3("n")],
|
|
4199
4349
|
[
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4350
|
+
lit3("extends", v3("c"), v3("x")),
|
|
4351
|
+
lit3("comesTo", v3("x"), v3("b")),
|
|
4352
|
+
lit3("libraryBase", v3("b"), v3("n"))
|
|
4203
4353
|
]
|
|
4204
4354
|
),
|
|
4205
4355
|
// A base a library hands back from a call rather than exporting as a
|
|
4206
4356
|
// class, SQLAlchemy's `Base = declarative_base()`. The walk stops at
|
|
4207
4357
|
// the call, so the function it called is the name to match on.
|
|
4208
|
-
|
|
4358
|
+
rule3(
|
|
4209
4359
|
"libraryBase",
|
|
4210
|
-
[
|
|
4360
|
+
[v3("c"), v3("n")],
|
|
4211
4361
|
[
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4362
|
+
lit3("extends", v3("c"), v3("x")),
|
|
4363
|
+
lit3("isWrittenAs", v3("x"), v3("r")),
|
|
4364
|
+
lit3("call", v3("r"), v3("cc")),
|
|
4365
|
+
lit3("comesFrom", v3("cc"), v3("m"), v3("n"))
|
|
4216
4366
|
]
|
|
4217
4367
|
),
|
|
4218
4368
|
// Which function a factory returns, and which of its parameters that
|
|
4219
4369
|
// function calls: together they are what makes it a wrapper.
|
|
4220
|
-
|
|
4370
|
+
rule3(
|
|
4221
4371
|
"returnsFunc",
|
|
4222
|
-
[
|
|
4372
|
+
[v3("f"), v3("g")],
|
|
4223
4373
|
[
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4374
|
+
lit3("returnsValue", v3("f"), v3("value")),
|
|
4375
|
+
lit3("comesTo", v3("value"), v3("g")),
|
|
4376
|
+
lit3("func", v3("g"))
|
|
4227
4377
|
]
|
|
4228
4378
|
),
|
|
4229
4379
|
// A call made by a nested closure counts as made by the function
|
|
4230
4380
|
// that declares it; the closure runs as part of that function.
|
|
4231
|
-
|
|
4232
|
-
|
|
4381
|
+
rule3("bodyCallsDeep", [v3("f"), v3("c")], [lit3("bodyCalls", v3("f"), v3("c"))]),
|
|
4382
|
+
rule3(
|
|
4233
4383
|
"bodyCallsDeep",
|
|
4234
|
-
[
|
|
4235
|
-
[
|
|
4384
|
+
[v3("f"), v3("c")],
|
|
4385
|
+
[lit3("containsFn", v3("f"), v3("g")), lit3("bodyCallsDeep", v3("g"), v3("c"))]
|
|
4236
4386
|
),
|
|
4237
|
-
|
|
4387
|
+
rule3(
|
|
4238
4388
|
"unwraps",
|
|
4239
|
-
[
|
|
4389
|
+
[v3("f"), v3("k")],
|
|
4240
4390
|
[
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4391
|
+
lit3("returnsFunc", v3("f"), v3("g")),
|
|
4392
|
+
lit3("bodyCallsDeep", v3("g"), v3("c")),
|
|
4393
|
+
lit3("refersToParam", v3("c"), v3("p")),
|
|
4394
|
+
lit3("paramOf", v3("f"), v3("k"), v3("p"))
|
|
4245
4395
|
]
|
|
4246
4396
|
),
|
|
4247
4397
|
// Which parameter a value traces back to: the parameter under any name,
|
|
4248
4398
|
// or a call passing it to another factory that unwraps, which is how
|
|
4249
4399
|
// `createProtected(h) { return service.withAuth(h); }` unwraps.
|
|
4250
|
-
|
|
4400
|
+
rule3(
|
|
4251
4401
|
"flowsToParam",
|
|
4252
|
-
[
|
|
4253
|
-
[
|
|
4402
|
+
[v3("x"), v3("p")],
|
|
4403
|
+
[lit3("refersToParam", v3("x"), v3("p"))]
|
|
4254
4404
|
),
|
|
4255
|
-
|
|
4405
|
+
rule3(
|
|
4256
4406
|
"flowsToParam",
|
|
4257
|
-
[
|
|
4407
|
+
[v3("r"), v3("p")],
|
|
4258
4408
|
[
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4409
|
+
lit3("call", v3("r"), v3("c")),
|
|
4410
|
+
lit3("comesTo", v3("c"), v3("f")),
|
|
4411
|
+
lit3("unwraps", v3("f"), v3("k")),
|
|
4412
|
+
lit3("callArg", v3("r"), v3("k"), v3("a")),
|
|
4413
|
+
lit3("flowsToParam", v3("a"), v3("p"))
|
|
4264
4414
|
]
|
|
4265
4415
|
),
|
|
4266
|
-
|
|
4416
|
+
rule3(
|
|
4267
4417
|
"unwraps",
|
|
4268
|
-
[
|
|
4418
|
+
[v3("f"), v3("k")],
|
|
4269
4419
|
[
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4420
|
+
lit3("returnsValue", v3("f"), v3("value")),
|
|
4421
|
+
lit3("flowsToParam", v3("value"), v3("p")),
|
|
4422
|
+
lit3("paramOf", v3("f"), v3("k"), v3("p"))
|
|
4273
4423
|
]
|
|
4274
4424
|
),
|
|
4275
4425
|
// Where a name comes from, when what it refers to lives outside the
|
|
4276
4426
|
// source being read. A walk ends at what the source writes out, so it
|
|
4277
4427
|
// never reaches a library's own function; these rules do.
|
|
4278
|
-
|
|
4428
|
+
rule3(
|
|
4279
4429
|
"comesFrom",
|
|
4280
|
-
[
|
|
4281
|
-
[
|
|
4430
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4431
|
+
[lit3("imports", v3("x"), v3("m"), v3("n"))]
|
|
4282
4432
|
),
|
|
4283
|
-
|
|
4433
|
+
rule3(
|
|
4284
4434
|
"comesFrom",
|
|
4285
|
-
[
|
|
4435
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4286
4436
|
[
|
|
4287
|
-
|
|
4288
|
-
|
|
4437
|
+
lit3("reaches", v3("x"), v3("y"), VALUE_STEP),
|
|
4438
|
+
lit3("imports", v3("y"), v3("m"), v3("n"))
|
|
4289
4439
|
]
|
|
4290
4440
|
),
|
|
4291
4441
|
// A member read off a whole-module import: the member's own name is
|
|
4292
4442
|
// what the module exports, so `fastapi.APIRouter` comes from
|
|
4293
4443
|
// fastapi's `APIRouter`. Directly, or through a name for the module.
|
|
4294
|
-
|
|
4444
|
+
rule3(
|
|
4295
4445
|
"comesFrom",
|
|
4296
|
-
[
|
|
4446
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4297
4447
|
[
|
|
4298
|
-
|
|
4299
|
-
|
|
4448
|
+
lit3("readsProperty", v3("x"), v3("ns"), v3("n")),
|
|
4449
|
+
lit3("imports", v3("ns"), v3("m"), NAMESPACE_IMPORT)
|
|
4300
4450
|
],
|
|
4301
4451
|
NAMESPACE_MEMBER_RULE
|
|
4302
4452
|
),
|
|
4303
|
-
|
|
4453
|
+
rule3(
|
|
4304
4454
|
"comesFrom",
|
|
4305
|
-
[
|
|
4455
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4306
4456
|
[
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4457
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
4458
|
+
lit3("reaches", v3("o"), v3("ns"), VALUE_STEP),
|
|
4459
|
+
lit3("imports", v3("ns"), v3("m"), NAMESPACE_IMPORT)
|
|
4310
4460
|
],
|
|
4311
4461
|
NAMESPACE_MEMBER_RULE
|
|
4312
4462
|
),
|
|
4313
4463
|
// A CommonJS module hands its exports over as the default, so after
|
|
4314
4464
|
// `import React from "react"`, `React.memo` is react's `memo`.
|
|
4315
|
-
|
|
4465
|
+
rule3(
|
|
4316
4466
|
"comesFrom",
|
|
4317
|
-
[
|
|
4467
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4318
4468
|
[
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4469
|
+
lit3("readsProperty", v3("x"), v3("o"), v3("n")),
|
|
4470
|
+
lit3("reaches", v3("o"), v3("d"), VALUE_STEP),
|
|
4471
|
+
lit3("imports", v3("d"), v3("m"), DEFAULT_IMPORT)
|
|
4322
4472
|
],
|
|
4323
4473
|
NAMESPACE_MEMBER_RULE
|
|
4324
4474
|
),
|
|
4325
4475
|
// Calling f ends up calling the name n that module m exports, one
|
|
4326
4476
|
// hop through f's own body or deeper through a wrapper of a wrapper.
|
|
4327
4477
|
// Several results is normal: a composed decorator applies them all.
|
|
4328
|
-
|
|
4478
|
+
rule3(
|
|
4329
4479
|
"callsInto",
|
|
4330
|
-
[
|
|
4480
|
+
[v3("f"), v3("m"), v3("n")],
|
|
4331
4481
|
[
|
|
4332
|
-
|
|
4333
|
-
|
|
4482
|
+
lit3("bodyCallsDeep", v3("f"), v3("c")),
|
|
4483
|
+
lit3("comesFrom", v3("c"), v3("m"), v3("n"))
|
|
4334
4484
|
]
|
|
4335
4485
|
),
|
|
4336
|
-
|
|
4486
|
+
rule3(
|
|
4337
4487
|
"callsInto",
|
|
4338
|
-
[
|
|
4488
|
+
[v3("f"), v3("m"), v3("n")],
|
|
4339
4489
|
[
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4490
|
+
lit3("bodyCallsDeep", v3("f"), v3("c")),
|
|
4491
|
+
lit3("comesTo", v3("c"), v3("g")),
|
|
4492
|
+
lit3("callsInto", v3("g"), v3("m"), v3("n"))
|
|
4343
4493
|
]
|
|
4344
4494
|
),
|
|
4345
4495
|
// The question callers ask: what a value comes to, narrowed to the
|
|
4346
4496
|
// functions. Objects appear in the middle of chains and never in an
|
|
4347
4497
|
// answer.
|
|
4348
|
-
|
|
4498
|
+
rule3(
|
|
4349
4499
|
"resolves",
|
|
4350
|
-
[
|
|
4351
|
-
[
|
|
4500
|
+
[v3("x"), v3("z")],
|
|
4501
|
+
[lit3("comesTo", v3("x"), v3("z")), lit3("func", v3("z"))]
|
|
4352
4502
|
),
|
|
4353
4503
|
...DISPATCH_RULES,
|
|
4354
|
-
...PASSED_ON_RULES
|
|
4504
|
+
...PASSED_ON_RULES,
|
|
4505
|
+
...SELF_RULES
|
|
4355
4506
|
];
|
|
4356
4507
|
function alsoSteps(rules) {
|
|
4357
4508
|
return [
|
|
@@ -4362,52 +4513,52 @@ function alsoSteps(rules) {
|
|
|
4362
4513
|
var RESOLUTION_RULES = alsoSteps(STATED_RULES);
|
|
4363
4514
|
var SOURCE_STEPS = [VALUE_STEP, RESULT_STEP];
|
|
4364
4515
|
var WRITTEN_KEY_READS = [
|
|
4365
|
-
|
|
4366
|
-
|
|
4516
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("n")),
|
|
4517
|
+
lit3("readsEntry", v3("y"), v3("o"), v3("n"))
|
|
4367
4518
|
];
|
|
4368
4519
|
var SOURCE_READS = [
|
|
4369
4520
|
...WRITTEN_KEY_READS,
|
|
4370
|
-
|
|
4521
|
+
lit3("readsKeyed", v3("y"), v3("o"), v3("k"))
|
|
4371
4522
|
];
|
|
4372
4523
|
function writtenAnswers(asking) {
|
|
4373
4524
|
return [
|
|
4374
|
-
|
|
4525
|
+
rule3(
|
|
4375
4526
|
"wantedIsWrittenAs",
|
|
4376
|
-
[
|
|
4377
|
-
[
|
|
4527
|
+
[v3("x"), v3("z")],
|
|
4528
|
+
[lit3(asking, v3("x")), lit3("isWrittenAs", v3("x"), v3("z"))]
|
|
4378
4529
|
),
|
|
4379
|
-
|
|
4530
|
+
rule3(
|
|
4380
4531
|
"wantedFallbackBehind",
|
|
4381
|
-
[
|
|
4382
|
-
[
|
|
4532
|
+
[v3("x"), v3("f")],
|
|
4533
|
+
[lit3(asking, v3("x")), lit3("fallbackBehind", v3("x"), v3("f"))]
|
|
4383
4534
|
),
|
|
4384
|
-
|
|
4535
|
+
rule3(
|
|
4385
4536
|
"wantedReadsOverridden",
|
|
4386
|
-
[
|
|
4387
|
-
[
|
|
4537
|
+
[v3("x"), v3("obj"), v3("h")],
|
|
4538
|
+
[lit3(asking, v3("x")), lit3("readsOverridden", v3("x"), v3("obj"), v3("h"))]
|
|
4388
4539
|
),
|
|
4389
|
-
|
|
4540
|
+
rule3(
|
|
4390
4541
|
"wantedReadsMemberOn",
|
|
4391
|
-
[
|
|
4392
|
-
[
|
|
4542
|
+
[v3("x"), v3("obj"), v3("h")],
|
|
4543
|
+
[lit3(asking, v3("x")), lit3("readsMemberOn", v3("x"), v3("obj"), v3("h"))]
|
|
4393
4544
|
)
|
|
4394
4545
|
];
|
|
4395
4546
|
}
|
|
4396
4547
|
var RESOLUTION_QUESTIONS = [
|
|
4397
|
-
|
|
4548
|
+
rule3(
|
|
4398
4549
|
"wantedResolves",
|
|
4399
|
-
[
|
|
4400
|
-
[
|
|
4550
|
+
[v3("x"), v3("z")],
|
|
4551
|
+
[lit3("wanted", v3("x")), lit3("resolves", v3("x"), v3("z"))]
|
|
4401
4552
|
),
|
|
4402
|
-
|
|
4553
|
+
rule3(
|
|
4403
4554
|
"wantedComesTo",
|
|
4404
|
-
[
|
|
4405
|
-
[
|
|
4555
|
+
[v3("x"), v3("z")],
|
|
4556
|
+
[lit3("wanted", v3("x")), lit3("comesTo", v3("x"), v3("z"))]
|
|
4406
4557
|
),
|
|
4407
|
-
|
|
4558
|
+
rule3(
|
|
4408
4559
|
"wantedComesTo",
|
|
4409
|
-
[
|
|
4410
|
-
[
|
|
4560
|
+
[v3("x"), v3("z")],
|
|
4561
|
+
[lit3("wantedOrigin", v3("x")), lit3("comesTo", v3("x"), v3("z"))]
|
|
4411
4562
|
),
|
|
4412
4563
|
...writtenAnswers("wanted"),
|
|
4413
4564
|
// A caller that reads only what a value is written as asks this way,
|
|
@@ -4416,666 +4567,667 @@ var RESOLUTION_QUESTIONS = [
|
|
|
4416
4567
|
// A call is given no `comesTo`, so this is the only way to ask what
|
|
4417
4568
|
// object one arrives at, and a demand-driven run derives `objectOf`
|
|
4418
4569
|
// nowhere without it. An allocation site is not one of the answers.
|
|
4419
|
-
|
|
4570
|
+
rule3(
|
|
4420
4571
|
"wantedObjectOf",
|
|
4421
|
-
[
|
|
4572
|
+
[v3("x"), v3("z")],
|
|
4422
4573
|
[
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4574
|
+
lit3("wanted", v3("x")),
|
|
4575
|
+
lit3("objectOf", v3("x"), v3("z")),
|
|
4576
|
+
lit3("objectValue", v3("z"))
|
|
4426
4577
|
]
|
|
4427
4578
|
),
|
|
4428
4579
|
// The same three questions under one allocation site, keyed by the
|
|
4429
4580
|
// value and the site both. An allocation site is an answer here,
|
|
4430
4581
|
// unlike `wantedObjectOf`, since a site is what a context is.
|
|
4431
|
-
|
|
4582
|
+
rule3(
|
|
4432
4583
|
"wantedIsWrittenAsUnder",
|
|
4433
|
-
[
|
|
4584
|
+
[v3("x"), v3("c"), v3("z")],
|
|
4434
4585
|
[
|
|
4435
|
-
|
|
4436
|
-
|
|
4586
|
+
lit3("wantedUnder", v3("x"), v3("c")),
|
|
4587
|
+
lit3("isWrittenAsUnder", v3("x"), v3("c"), v3("z"))
|
|
4437
4588
|
]
|
|
4438
4589
|
),
|
|
4439
4590
|
// Where a class was made, for a caller about to ask a value question
|
|
4440
4591
|
// under each. Going through `constructsNamed` keeps the demand on the
|
|
4441
4592
|
// calls written with the class's name rather than on every call.
|
|
4442
|
-
|
|
4593
|
+
rule3(
|
|
4443
4594
|
"wantedAllocatedAt",
|
|
4444
|
-
[
|
|
4595
|
+
[v3("cls"), v3("site")],
|
|
4445
4596
|
[
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4597
|
+
lit3("wantedSites", v3("cls")),
|
|
4598
|
+
lit3("constructsNamed", v3("site"), v3("cls")),
|
|
4599
|
+
lit3("allocates", v3("site"), v3("cls"))
|
|
4449
4600
|
]
|
|
4450
4601
|
),
|
|
4451
|
-
|
|
4602
|
+
rule3(
|
|
4452
4603
|
"wantedComesToUnder",
|
|
4453
|
-
[
|
|
4604
|
+
[v3("x"), v3("c"), v3("z")],
|
|
4454
4605
|
[
|
|
4455
|
-
|
|
4456
|
-
|
|
4606
|
+
lit3("wantedUnder", v3("x"), v3("c")),
|
|
4607
|
+
lit3("comesToUnder", v3("x"), v3("c"), v3("z"))
|
|
4457
4608
|
]
|
|
4458
4609
|
),
|
|
4459
|
-
|
|
4610
|
+
rule3(
|
|
4460
4611
|
"wantedObjectOfUnder",
|
|
4461
|
-
[
|
|
4612
|
+
[v3("x"), v3("c"), v3("z")],
|
|
4462
4613
|
[
|
|
4463
|
-
|
|
4464
|
-
|
|
4614
|
+
lit3("wantedUnder", v3("x"), v3("c")),
|
|
4615
|
+
lit3("objectOfUnder", v3("x"), v3("c"), v3("z"))
|
|
4465
4616
|
]
|
|
4466
4617
|
),
|
|
4467
|
-
|
|
4618
|
+
rule3(
|
|
4468
4619
|
"wantedFallbackBehindUnder",
|
|
4469
|
-
[
|
|
4620
|
+
[v3("x"), v3("c"), v3("f")],
|
|
4470
4621
|
[
|
|
4471
|
-
|
|
4472
|
-
|
|
4622
|
+
lit3("wantedUnder", v3("x"), v3("c")),
|
|
4623
|
+
lit3("fallbackBehindUnder", v3("x"), v3("c"), v3("f"))
|
|
4473
4624
|
]
|
|
4474
4625
|
),
|
|
4475
4626
|
// The same for the function a call returns: `app.use(requireCaller(config))`
|
|
4476
4627
|
// registers what the factory gives back, and `resolves` on the call
|
|
4477
4628
|
// says nothing unless the factory unwraps an argument.
|
|
4478
|
-
|
|
4629
|
+
rule3(
|
|
4479
4630
|
"wantedGivesBack",
|
|
4480
|
-
[
|
|
4481
|
-
[
|
|
4631
|
+
[v3("x"), v3("z")],
|
|
4632
|
+
[lit3("wanted", v3("x")), lit3("givesBack", v3("x"), v3("z"))]
|
|
4482
4633
|
),
|
|
4483
|
-
|
|
4634
|
+
rule3(
|
|
4484
4635
|
"wantedGivesBackUnwrapped",
|
|
4485
|
-
[
|
|
4486
|
-
[
|
|
4636
|
+
[v3("x"), v3("z")],
|
|
4637
|
+
[lit3("wanted", v3("x")), lit3("givesBackUnwrapped", v3("x"), v3("z"))]
|
|
4487
4638
|
),
|
|
4488
4639
|
// The argument as the caller wrote it, keyed by the parameter, since
|
|
4489
4640
|
// that is what a caller has in hand when it wants the call sites told
|
|
4490
4641
|
// apart. The caller settles the argument however its kind of value needs.
|
|
4491
|
-
|
|
4642
|
+
rule3(
|
|
4492
4643
|
"wantedPassesArgument",
|
|
4493
|
-
[
|
|
4494
|
-
[
|
|
4644
|
+
[v3("p"), v3("r"), v3("a")],
|
|
4645
|
+
[lit3("wanted", v3("p")), lit3("passesArgument", v3("r"), v3("p"), v3("a"))]
|
|
4495
4646
|
),
|
|
4496
|
-
|
|
4647
|
+
rule3(
|
|
4497
4648
|
"wantedReturnsCall",
|
|
4498
|
-
[
|
|
4499
|
-
[
|
|
4649
|
+
[v3("f"), v3("c")],
|
|
4650
|
+
[lit3("wanted", v3("f")), lit3("returnsCall", v3("f"), v3("c"))]
|
|
4500
4651
|
),
|
|
4501
4652
|
// Seeded with the expressions that spell the environment, a handful
|
|
4502
4653
|
// per project. The reads cannot be the seed: one written through a
|
|
4503
4654
|
// parameter is nowhere a scan of the source looks.
|
|
4504
|
-
|
|
4655
|
+
rule3(
|
|
4505
4656
|
"wantedParamNamesEnv",
|
|
4506
|
-
[
|
|
4657
|
+
[v3("p"), v3("site")],
|
|
4507
4658
|
[
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4659
|
+
lit3("wantedEnvObject", v3("w")),
|
|
4660
|
+
lit3("environmentRead", v3("w"), v3("site"), v3("x")),
|
|
4661
|
+
lit3("paramNamesEnv", v3("p"), v3("site"))
|
|
4511
4662
|
]
|
|
4512
4663
|
),
|
|
4513
4664
|
// The parameters the environment object is handed to, from the same
|
|
4514
4665
|
// seed, so a question about one is a lookup rather than a read of
|
|
4515
4666
|
// every file that could call its function.
|
|
4516
|
-
|
|
4667
|
+
rule3(
|
|
4517
4668
|
"wantedEnvParameter",
|
|
4518
|
-
[
|
|
4669
|
+
[v3("p")],
|
|
4519
4670
|
[
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4671
|
+
lit3("wantedEnvObject", v3("w")),
|
|
4672
|
+
lit3("runtimeValue", v3("w"), v3("p")),
|
|
4673
|
+
lit3("paramNamed", v3("f"), v3("n"), v3("p"))
|
|
4523
4674
|
]
|
|
4524
4675
|
),
|
|
4525
4676
|
// The calls that hand it on, for an asker to resolve, since the
|
|
4526
4677
|
// parameter on the other side is in a file nothing has read yet.
|
|
4527
|
-
|
|
4678
|
+
rule3(
|
|
4528
4679
|
"wantedEnvPassingCall",
|
|
4529
|
-
[
|
|
4680
|
+
[v3("r")],
|
|
4530
4681
|
[
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4682
|
+
lit3("wantedEnvObject", v3("w")),
|
|
4683
|
+
lit3("runtimeValue", v3("w"), v3("a")),
|
|
4684
|
+
lit3("callArg", v3("r"), v3("k"), v3("a"))
|
|
4534
4685
|
]
|
|
4535
4686
|
),
|
|
4536
4687
|
// The same relation asked from one expression. Seeding from the
|
|
4537
4688
|
// objects instead would settle it for every expression in the
|
|
4538
4689
|
// project, and a caller holding an argument wants only that one.
|
|
4539
|
-
|
|
4690
|
+
rule3(
|
|
4540
4691
|
"wantedEnvironmentValue",
|
|
4541
|
-
[
|
|
4692
|
+
[v3("o"), v3("w")],
|
|
4542
4693
|
[
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4694
|
+
lit3("wanted", v3("o")),
|
|
4695
|
+
lit3("runtimeValue", v3("w"), v3("o")),
|
|
4696
|
+
lit3("environmentObject", v3("w"))
|
|
4546
4697
|
]
|
|
4547
4698
|
),
|
|
4548
4699
|
// Every expression an output stream reaches, from the spots that spell
|
|
4549
4700
|
// one, so a writer at `out.write(...)` looks its receiver up.
|
|
4550
|
-
|
|
4701
|
+
rule3(
|
|
4551
4702
|
"wantedStreamValue",
|
|
4552
|
-
[
|
|
4553
|
-
[
|
|
4703
|
+
[v3("o"), v3("w")],
|
|
4704
|
+
[lit3("wantedStreamObject", v3("w")), lit3("runtimeValue", v3("w"), v3("o"))]
|
|
4554
4705
|
),
|
|
4555
4706
|
// The functions whose return becomes the exit code: a call the value
|
|
4556
4707
|
// that ends up as the code is, or one it reaches. DESIGN.md has the seeds.
|
|
4557
|
-
|
|
4708
|
+
rule3("exitStart", [v3("x"), v3("x")], [lit3("wantedExitSink", v3("x"))]),
|
|
4558
4709
|
// `reaches` takes no step through a call that picks its function from a
|
|
4559
4710
|
// table, so the walk starts again from what each function there returns.
|
|
4560
|
-
|
|
4711
|
+
rule3(
|
|
4561
4712
|
"exitStart",
|
|
4562
|
-
[
|
|
4713
|
+
[v3("x"), v3("ret")],
|
|
4563
4714
|
[
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4715
|
+
lit3("exitReached", v3("x"), v3("y")),
|
|
4716
|
+
lit3("dispatchesTo", v3("y"), v3("f")),
|
|
4717
|
+
lit3("returnsValue", v3("f"), v3("ret"))
|
|
4567
4718
|
]
|
|
4568
4719
|
),
|
|
4569
|
-
|
|
4570
|
-
|
|
4720
|
+
rule3("exitReached", [v3("x"), v3("s")], [lit3("exitStart", v3("x"), v3("s"))]),
|
|
4721
|
+
rule3(
|
|
4571
4722
|
"exitReached",
|
|
4572
|
-
[
|
|
4723
|
+
[v3("x"), v3("y")],
|
|
4573
4724
|
[
|
|
4574
|
-
|
|
4575
|
-
|
|
4725
|
+
lit3("exitStart", v3("x"), v3("s")),
|
|
4726
|
+
lit3("reaches", v3("s"), v3("y"), v3("kind"))
|
|
4576
4727
|
]
|
|
4577
4728
|
),
|
|
4578
|
-
|
|
4729
|
+
rule3(
|
|
4579
4730
|
"wantedExitCodeFrom",
|
|
4580
|
-
[
|
|
4581
|
-
[
|
|
4731
|
+
[v3("x"), v3("f")],
|
|
4732
|
+
[lit3("exitReached", v3("x"), v3("y")), lit3("invokes", v3("y"), v3("f"))]
|
|
4582
4733
|
),
|
|
4583
|
-
|
|
4734
|
+
rule3(
|
|
4584
4735
|
"wantedExitCodeFrom",
|
|
4585
|
-
[
|
|
4586
|
-
[
|
|
4736
|
+
[v3("x"), v3("f")],
|
|
4737
|
+
[lit3("exitReached", v3("x"), v3("y")), lit3("dispatchesTo", v3("y"), v3("f"))]
|
|
4587
4738
|
),
|
|
4588
4739
|
// The functions a call may run when it takes one from a table, with the
|
|
4589
4740
|
// entry each came from, and the entries that come to no function. The
|
|
4590
4741
|
// reader in dispatch.ts decides whether the call runs exactly one.
|
|
4591
|
-
|
|
4742
|
+
rule3(
|
|
4592
4743
|
"wantedDispatchSite",
|
|
4593
|
-
[
|
|
4594
|
-
[
|
|
4744
|
+
[v3("r"), v3("site")],
|
|
4745
|
+
[lit3("wantedDispatch", v3("r")), lit3("callsEntryAt", v3("r"), v3("site"))]
|
|
4595
4746
|
),
|
|
4596
|
-
|
|
4747
|
+
rule3(
|
|
4597
4748
|
"wantedDispatchEntry",
|
|
4598
|
-
[
|
|
4749
|
+
[v3("r"), v3("held")],
|
|
4599
4750
|
[
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4751
|
+
lit3("wantedDispatch", v3("r")),
|
|
4752
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
4753
|
+
lit3("entryAt", v3("site"), v3("held"))
|
|
4603
4754
|
]
|
|
4604
4755
|
),
|
|
4605
|
-
|
|
4756
|
+
rule3(
|
|
4606
4757
|
"wantedDispatchInBranch",
|
|
4607
|
-
[
|
|
4758
|
+
[v3("r"), v3("site")],
|
|
4608
4759
|
[
|
|
4609
|
-
|
|
4610
|
-
|
|
4760
|
+
lit3("wantedDispatch", v3("r")),
|
|
4761
|
+
lit3("callsEntryInBranch", v3("r"), v3("site"))
|
|
4611
4762
|
]
|
|
4612
4763
|
),
|
|
4613
|
-
|
|
4764
|
+
rule3(
|
|
4614
4765
|
"wantedDispatchComputed",
|
|
4615
|
-
[
|
|
4766
|
+
[v3("r"), v3("held")],
|
|
4616
4767
|
[
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4768
|
+
lit3("wantedDispatch", v3("r")),
|
|
4769
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
4770
|
+
lit3("computedEntryAt", v3("site"), v3("held"))
|
|
4620
4771
|
]
|
|
4621
4772
|
),
|
|
4622
|
-
|
|
4773
|
+
rule3(
|
|
4623
4774
|
"wantedDispatchFunction",
|
|
4624
|
-
[
|
|
4775
|
+
[v3("r"), v3("held"), v3("f")],
|
|
4625
4776
|
[
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4777
|
+
lit3("wantedDispatch", v3("r")),
|
|
4778
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
4779
|
+
lit3("entryAt", v3("site"), v3("held")),
|
|
4780
|
+
lit3("comesTo", v3("held"), v3("f")),
|
|
4781
|
+
lit3("func", v3("f"))
|
|
4631
4782
|
]
|
|
4632
4783
|
),
|
|
4633
|
-
|
|
4784
|
+
rule3(
|
|
4634
4785
|
"wantedDispatchLikeEntry",
|
|
4635
|
-
[
|
|
4786
|
+
[v3("r"), v3("site"), v3("n"), v3("held")],
|
|
4636
4787
|
[
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4788
|
+
lit3("wantedDispatch", v3("r")),
|
|
4789
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
4790
|
+
lit3("likeEntryAt", v3("site"), v3("n"), v3("held"))
|
|
4640
4791
|
]
|
|
4641
4792
|
),
|
|
4642
|
-
|
|
4793
|
+
rule3(
|
|
4643
4794
|
"wantedDispatchLikeFunction",
|
|
4644
|
-
[
|
|
4795
|
+
[v3("r"), v3("held"), v3("f")],
|
|
4645
4796
|
[
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4797
|
+
lit3("wantedDispatch", v3("r")),
|
|
4798
|
+
lit3("callsEntryAt", v3("r"), v3("site")),
|
|
4799
|
+
lit3("likeEntryAt", v3("site"), v3("n"), v3("held")),
|
|
4800
|
+
lit3("comesTo", v3("held"), v3("f")),
|
|
4801
|
+
lit3("func", v3("f"))
|
|
4651
4802
|
]
|
|
4652
4803
|
),
|
|
4653
4804
|
// What a function there calls in its own body, for an entry written as
|
|
4654
4805
|
// a lambda, which no summary describes.
|
|
4655
|
-
|
|
4806
|
+
rule3(
|
|
4656
4807
|
"wantedDispatchThrough",
|
|
4657
|
-
[
|
|
4808
|
+
[v3("r"), v3("f"), v3("g")],
|
|
4658
4809
|
[
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4810
|
+
lit3("wantedDispatch", v3("r")),
|
|
4811
|
+
lit3("dispatchesTo", v3("r"), v3("f")),
|
|
4812
|
+
lit3("makesCall", v3("f"), v3("r2")),
|
|
4813
|
+
lit3("invokes", v3("r2"), v3("g"))
|
|
4663
4814
|
]
|
|
4664
4815
|
),
|
|
4665
4816
|
// The calls that hand a stream on, so the asker can read the callee's file.
|
|
4666
|
-
|
|
4817
|
+
rule3(
|
|
4667
4818
|
"wantedStreamPassingCall",
|
|
4668
|
-
[
|
|
4819
|
+
[v3("r")],
|
|
4669
4820
|
[
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4821
|
+
lit3("wantedStreamObject", v3("w")),
|
|
4822
|
+
lit3("runtimeValue", v3("w"), v3("a")),
|
|
4823
|
+
lit3("callArg", v3("r"), v3("k"), v3("a"))
|
|
4673
4824
|
]
|
|
4674
4825
|
),
|
|
4675
4826
|
// Whether an expression is a parameter under another name, for a
|
|
4676
4827
|
// caller deciding whether going and reading that parameter's callers
|
|
4677
4828
|
// could change the answer it already has.
|
|
4678
|
-
|
|
4829
|
+
rule3(
|
|
4679
4830
|
"wantedRefersToParam",
|
|
4680
|
-
[
|
|
4681
|
-
[
|
|
4831
|
+
[v3("o"), v3("p")],
|
|
4832
|
+
[lit3("wanted", v3("o")), lit3("refersToParam", v3("o"), v3("p"))]
|
|
4682
4833
|
),
|
|
4683
4834
|
// The types a value is declared as, beside each argument its own
|
|
4684
4835
|
// callers pass, so the asking side can refuse a caller passing
|
|
4685
4836
|
// something no declaration types.
|
|
4686
|
-
|
|
4837
|
+
rule3(
|
|
4687
4838
|
"wantedTypedAs",
|
|
4688
|
-
[
|
|
4689
|
-
[
|
|
4839
|
+
[v3("x"), v3("t")],
|
|
4840
|
+
[lit3("wantedType", v3("x")), lit3("typedAs", v3("x"), v3("t"))]
|
|
4690
4841
|
),
|
|
4691
|
-
|
|
4842
|
+
rule3(
|
|
4692
4843
|
"wantedTypePassed",
|
|
4693
|
-
[
|
|
4844
|
+
[v3("o"), v3("a")],
|
|
4694
4845
|
[
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4846
|
+
lit3("wantedType", v3("o")),
|
|
4847
|
+
lit3("refersToParam", v3("o"), v3("p")),
|
|
4848
|
+
lit3("passesArgument", v3("r"), v3("p"), v3("a"))
|
|
4698
4849
|
]
|
|
4699
4850
|
),
|
|
4700
|
-
|
|
4851
|
+
rule3(
|
|
4701
4852
|
"wantedPassedTypedAs",
|
|
4702
|
-
[
|
|
4853
|
+
[v3("o"), v3("a"), v3("t")],
|
|
4703
4854
|
[
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4855
|
+
lit3("wantedType", v3("o")),
|
|
4856
|
+
lit3("refersToParam", v3("o"), v3("p")),
|
|
4857
|
+
lit3("passesArgument", v3("r"), v3("p"), v3("a")),
|
|
4858
|
+
lit3("typedAs", v3("a"), v3("t"))
|
|
4708
4859
|
]
|
|
4709
4860
|
),
|
|
4710
|
-
|
|
4861
|
+
rule3(
|
|
4711
4862
|
"wantedPassedParam",
|
|
4712
|
-
[
|
|
4863
|
+
[v3("o"), v3("a")],
|
|
4713
4864
|
[
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4865
|
+
lit3("wantedType", v3("o")),
|
|
4866
|
+
lit3("refersToParam", v3("o"), v3("p")),
|
|
4867
|
+
lit3("passesArgument", v3("r"), v3("p"), v3("a")),
|
|
4868
|
+
lit3("refersToParam", v3("a"), v3("q"))
|
|
4718
4869
|
]
|
|
4719
4870
|
),
|
|
4720
|
-
|
|
4871
|
+
rule3(
|
|
4721
4872
|
"wantedComesFrom",
|
|
4722
|
-
[
|
|
4723
|
-
[
|
|
4873
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4874
|
+
[lit3("wantedOrigin", v3("x")), lit3("comesFrom", v3("x"), v3("m"), v3("n"))]
|
|
4724
4875
|
),
|
|
4725
4876
|
// Call-origin questions, for attribution, in their own demand
|
|
4726
4877
|
// class. Attribution stops at the import declaration, so nothing
|
|
4727
4878
|
// here demands reaches or callsInto. The chains are closures with
|
|
4728
4879
|
// no depth bound: an alias run of any length resolves.
|
|
4729
|
-
|
|
4880
|
+
rule3("callOriginChain", [v3("x"), v3("x")], [lit3("wantedCallOrigin", v3("x"))]),
|
|
4730
4881
|
// The chain with at least one hop taken, which is what tells a
|
|
4731
4882
|
// destructured binding apart from asking about a node directly. The
|
|
4732
4883
|
// whole chain is the seed plus those hops.
|
|
4733
|
-
|
|
4884
|
+
rule3(
|
|
4734
4885
|
"callOriginChain",
|
|
4735
|
-
[
|
|
4736
|
-
[
|
|
4886
|
+
[v3("x"), v3("z")],
|
|
4887
|
+
[lit3("callOriginChainStepped", v3("x"), v3("z"))]
|
|
4737
4888
|
),
|
|
4738
|
-
|
|
4889
|
+
rule3(
|
|
4739
4890
|
"callOriginChainStepped",
|
|
4740
|
-
[
|
|
4741
|
-
[
|
|
4891
|
+
[v3("x"), v3("z")],
|
|
4892
|
+
[lit3("callOriginChain", v3("x"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
4742
4893
|
),
|
|
4743
|
-
|
|
4894
|
+
rule3(
|
|
4744
4895
|
"wantedCallOriginPair",
|
|
4745
|
-
[
|
|
4896
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4746
4897
|
[
|
|
4747
|
-
|
|
4748
|
-
|
|
4898
|
+
lit3("callOriginChain", v3("x"), v3("y")),
|
|
4899
|
+
lit3("imports", v3("y"), v3("m"), v3("n"))
|
|
4749
4900
|
]
|
|
4750
4901
|
),
|
|
4751
4902
|
// An import of a project barrel is an import of what the barrel
|
|
4752
4903
|
// forwards, so the pair surfaces the module behind the chain.
|
|
4753
|
-
|
|
4904
|
+
rule3(
|
|
4754
4905
|
"wantedCallOriginPair",
|
|
4755
|
-
[
|
|
4906
|
+
[v3("x"), v3("m2"), v3("n2")],
|
|
4756
4907
|
[
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4908
|
+
lit3("callOriginChain", v3("x"), v3("y")),
|
|
4909
|
+
lit3("imports", v3("y"), v3("m"), v3("n")),
|
|
4910
|
+
lit3("moduleForwards", v3("m"), v3("n"), v3("m2"), v3("n2"))
|
|
4760
4911
|
]
|
|
4761
4912
|
),
|
|
4762
4913
|
// A namespace member: the module's export of the member's own name.
|
|
4763
4914
|
// The imports literal leads, since it is the smallest relation.
|
|
4764
|
-
|
|
4915
|
+
rule3(
|
|
4765
4916
|
"wantedCallOriginPair",
|
|
4766
|
-
[
|
|
4917
|
+
[v3("x"), v3("m"), v3("p")],
|
|
4767
4918
|
[
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4919
|
+
lit3("imports", v3("o"), v3("m"), NAMESPACE_IMPORT),
|
|
4920
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("p")),
|
|
4921
|
+
lit3("callOriginChain", v3("x"), v3("y"))
|
|
4771
4922
|
]
|
|
4772
4923
|
),
|
|
4773
|
-
|
|
4924
|
+
rule3(
|
|
4774
4925
|
"wantedCallOriginPair",
|
|
4775
|
-
[
|
|
4926
|
+
[v3("x"), v3("m"), v3("p")],
|
|
4776
4927
|
[
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4928
|
+
lit3("imports", v3("d"), v3("m"), NAMESPACE_IMPORT),
|
|
4929
|
+
lit3("binds", v3("o"), v3("d")),
|
|
4930
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("p")),
|
|
4931
|
+
lit3("callOriginChain", v3("x"), v3("y"))
|
|
4781
4932
|
]
|
|
4782
4933
|
),
|
|
4783
4934
|
// What a call made: through the call to its callee, whose own alias
|
|
4784
4935
|
// chain leads to the import.
|
|
4785
|
-
|
|
4936
|
+
rule3(
|
|
4786
4937
|
"callMadeChain",
|
|
4787
|
-
[
|
|
4788
|
-
[
|
|
4938
|
+
[v3("x"), v3("f")],
|
|
4939
|
+
[lit3("callOriginChain", v3("x"), v3("c")), lit3("call", v3("c"), v3("f"))]
|
|
4789
4940
|
),
|
|
4790
|
-
|
|
4941
|
+
rule3(
|
|
4791
4942
|
"callMadeChain",
|
|
4792
|
-
[
|
|
4793
|
-
[
|
|
4943
|
+
[v3("x"), v3("z")],
|
|
4944
|
+
[lit3("callMadeChain", v3("x"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
4794
4945
|
),
|
|
4795
|
-
|
|
4946
|
+
rule3(
|
|
4796
4947
|
"wantedCallOriginPair",
|
|
4797
|
-
[
|
|
4948
|
+
[v3("x"), v3("m"), v3("n")],
|
|
4798
4949
|
[
|
|
4799
|
-
|
|
4800
|
-
|
|
4950
|
+
lit3("callMadeChain", v3("x"), v3("y")),
|
|
4951
|
+
lit3("imports", v3("y"), v3("m"), v3("n"))
|
|
4801
4952
|
]
|
|
4802
4953
|
),
|
|
4803
4954
|
// A member destructured off what a call made keeps the member name
|
|
4804
4955
|
// as one more path segment.
|
|
4805
|
-
|
|
4956
|
+
rule3(
|
|
4806
4957
|
"callMemberChain",
|
|
4807
|
-
[
|
|
4958
|
+
[v3("x"), v3("f"), v3("p")],
|
|
4808
4959
|
[
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4960
|
+
lit3("callOriginChainStepped", v3("x"), v3("e")),
|
|
4961
|
+
lit3("readsProperty", v3("e"), v3("c"), v3("p")),
|
|
4962
|
+
lit3("call", v3("c"), v3("f"))
|
|
4812
4963
|
]
|
|
4813
4964
|
),
|
|
4814
|
-
|
|
4965
|
+
rule3(
|
|
4815
4966
|
"callMemberChain",
|
|
4816
|
-
[
|
|
4967
|
+
[v3("x"), v3("z"), v3("p")],
|
|
4817
4968
|
[
|
|
4818
|
-
|
|
4819
|
-
|
|
4969
|
+
lit3("callMemberChain", v3("x"), v3("y"), v3("p")),
|
|
4970
|
+
lit3("nameHop", v3("y"), v3("z"))
|
|
4820
4971
|
]
|
|
4821
4972
|
),
|
|
4822
|
-
|
|
4973
|
+
rule3(
|
|
4823
4974
|
"wantedCallOriginMember",
|
|
4824
|
-
[
|
|
4975
|
+
[v3("x"), v3("m"), v3("n"), v3("p")],
|
|
4825
4976
|
[
|
|
4826
|
-
|
|
4827
|
-
|
|
4977
|
+
lit3("callMemberChain", v3("x"), v3("y"), v3("p")),
|
|
4978
|
+
lit3("imports", v3("y"), v3("m"), v3("n"))
|
|
4828
4979
|
]
|
|
4829
4980
|
),
|
|
4830
|
-
|
|
4981
|
+
rule3(
|
|
4831
4982
|
"wantedCallsInto",
|
|
4832
|
-
[
|
|
4983
|
+
[v3("g"), v3("m"), v3("n")],
|
|
4833
4984
|
[
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4985
|
+
lit3("wantedOrigin", v3("x")),
|
|
4986
|
+
lit3("comesTo", v3("x"), v3("g")),
|
|
4987
|
+
lit3("callsInto", v3("g"), v3("m"), v3("n"))
|
|
4837
4988
|
]
|
|
4838
4989
|
),
|
|
4839
4990
|
// Subject identity, its own demand class; the README's subject
|
|
4840
4991
|
// section says why the origin pair rides on the written-value walk.
|
|
4841
|
-
|
|
4992
|
+
rule3(
|
|
4842
4993
|
"wantedSubjectWritten",
|
|
4843
|
-
[
|
|
4844
|
-
[
|
|
4994
|
+
[v3("x"), v3("r")],
|
|
4995
|
+
[lit3("wantedSubject", v3("x")), lit3("isWrittenAs", v3("x"), v3("r"))]
|
|
4845
4996
|
),
|
|
4846
|
-
|
|
4997
|
+
rule3(
|
|
4847
4998
|
"wantedSubjectConstruction",
|
|
4848
|
-
[
|
|
4999
|
+
[v3("x"), v3("r"), v3("m"), v3("n")],
|
|
4849
5000
|
[
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
5001
|
+
lit3("wantedSubject", v3("x")),
|
|
5002
|
+
lit3("isWrittenAs", v3("x"), v3("r")),
|
|
5003
|
+
lit3("call", v3("r"), v3("c")),
|
|
5004
|
+
lit3("comesFrom", v3("c"), v3("m"), v3("n"))
|
|
4854
5005
|
]
|
|
4855
5006
|
),
|
|
4856
5007
|
// The export table of one module, keyed by the module asked about.
|
|
4857
5008
|
// The moduleExport rules flatten re-export chains of any length, and
|
|
4858
5009
|
// the demand cone stays on export facts alone.
|
|
4859
|
-
|
|
5010
|
+
rule3(
|
|
4860
5011
|
"wantedModuleExport",
|
|
4861
|
-
[
|
|
5012
|
+
[v3("m"), v3("n"), v3("value")],
|
|
4862
5013
|
[
|
|
4863
|
-
|
|
4864
|
-
|
|
5014
|
+
lit3("wantedExportsOf", v3("m")),
|
|
5015
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("value"))
|
|
4865
5016
|
]
|
|
4866
5017
|
),
|
|
4867
5018
|
// A class's ancestry: each base as written, then the class that name
|
|
4868
5019
|
// comes to through the name hops. A storage pack matches its library's
|
|
4869
5020
|
// bases against the base names along the way.
|
|
4870
|
-
|
|
4871
|
-
|
|
5021
|
+
rule3("ancestryChain", [v3("c"), v3("c")], [lit3("wantedAncestry", v3("c"))]),
|
|
5022
|
+
rule3(
|
|
4872
5023
|
"ancestryChain",
|
|
4873
|
-
[
|
|
4874
|
-
[
|
|
5024
|
+
[v3("c"), v3("x")],
|
|
5025
|
+
[lit3("ancestryChain", v3("c"), v3("b")), lit3("extends", v3("b"), v3("x"))]
|
|
4875
5026
|
),
|
|
4876
|
-
|
|
5027
|
+
rule3(
|
|
4877
5028
|
"ancestryChain",
|
|
4878
|
-
[
|
|
4879
|
-
[
|
|
5029
|
+
[v3("c"), v3("x")],
|
|
5030
|
+
[lit3("ancestryChain", v3("c"), v3("b")), lit3("prepends", v3("b"), v3("x"))]
|
|
4880
5031
|
),
|
|
4881
|
-
|
|
5032
|
+
rule3(
|
|
4882
5033
|
"ancestryChain",
|
|
4883
|
-
[
|
|
4884
|
-
[
|
|
5034
|
+
[v3("c"), v3("z")],
|
|
5035
|
+
[lit3("ancestryChain", v3("c"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
4885
5036
|
),
|
|
4886
|
-
|
|
5037
|
+
rule3(
|
|
4887
5038
|
"ancestryChain",
|
|
4888
|
-
[
|
|
5039
|
+
[v3("c"), v3("z")],
|
|
4889
5040
|
[
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
5041
|
+
lit3("ancestryChain", v3("c"), v3("y")),
|
|
5042
|
+
lit3("imports", v3("y"), v3("m"), v3("n")),
|
|
5043
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("z"))
|
|
4893
5044
|
]
|
|
4894
5045
|
),
|
|
4895
|
-
|
|
5046
|
+
rule3(
|
|
4896
5047
|
"wantedBaseName",
|
|
4897
|
-
[
|
|
4898
|
-
[
|
|
5048
|
+
[v3("c"), v3("n")],
|
|
5049
|
+
[lit3("ancestryChain", v3("c"), v3("b")), lit3("extendsNamed", v3("b"), v3("n"))]
|
|
4899
5050
|
),
|
|
4900
5051
|
// Each method the same chain declares, so a caller that settled a
|
|
4901
5052
|
// receiver on a class can tell a method the project writes itself
|
|
4902
5053
|
// from one only the library provides.
|
|
4903
|
-
|
|
5054
|
+
rule3(
|
|
4904
5055
|
"wantedDeclaredName",
|
|
4905
|
-
[
|
|
5056
|
+
[v3("c"), v3("n")],
|
|
4906
5057
|
[
|
|
4907
|
-
|
|
4908
|
-
|
|
5058
|
+
lit3("ancestryChain", v3("c"), v3("b")),
|
|
5059
|
+
lit3("holdsProperty", v3("b"), v3("n"), v3("held"))
|
|
4909
5060
|
]
|
|
4910
5061
|
),
|
|
4911
5062
|
// A method the class gets under a name the source computes rather than
|
|
4912
5063
|
// writes out. The adapter settles the name against the same facts and
|
|
4913
5064
|
// says so, and the chain reports it beside the ones written out.
|
|
4914
|
-
|
|
5065
|
+
rule3(
|
|
4915
5066
|
"wantedDeclaredName",
|
|
4916
|
-
[
|
|
4917
|
-
[
|
|
5067
|
+
[v3("c"), v3("n")],
|
|
5068
|
+
[lit3("ancestryChain", v3("c"), v3("b")), lit3("declaresName", v3("b"), v3("n"))]
|
|
4918
5069
|
),
|
|
4919
5070
|
// The method behind each callback the chain registers, by the event
|
|
4920
5071
|
// that runs it. A base registering one reaches every class below it,
|
|
4921
5072
|
// and the method may be declared anywhere along the same chain.
|
|
4922
|
-
|
|
5073
|
+
rule3(
|
|
4923
5074
|
"wantedCallbackMethod",
|
|
4924
|
-
[
|
|
5075
|
+
[v3("c"), v3("event"), v3("n"), v3("held")],
|
|
4925
5076
|
[
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
5077
|
+
lit3("ancestryChain", v3("c"), v3("b")),
|
|
5078
|
+
lit3("classCallback", v3("b"), v3("event"), v3("n")),
|
|
5079
|
+
lit3("ancestryChain", v3("c"), v3("b2")),
|
|
5080
|
+
lit3("holdsProperty", v3("b2"), v3("n"), v3("held"))
|
|
4930
5081
|
]
|
|
4931
5082
|
),
|
|
4932
5083
|
// The calls behind a receiver, for a pack that wants the anchor a
|
|
4933
5084
|
// chain hangs off; the README's anchor section says which hops and
|
|
4934
5085
|
// why the asking side applies the single-answer policy.
|
|
4935
|
-
|
|
4936
|
-
|
|
5086
|
+
rule3("anchorChain", [v3("x"), v3("x")], [lit3("wantedAnchor", v3("x"))]),
|
|
5087
|
+
rule3(
|
|
4937
5088
|
"anchorChain",
|
|
4938
|
-
[
|
|
4939
|
-
[
|
|
5089
|
+
[v3("x"), v3("z")],
|
|
5090
|
+
[lit3("anchorChain", v3("x"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
4940
5091
|
),
|
|
4941
|
-
|
|
5092
|
+
rule3(
|
|
4942
5093
|
"anchorChain",
|
|
4943
|
-
[
|
|
5094
|
+
[v3("x"), v3("z")],
|
|
4944
5095
|
[
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
5096
|
+
lit3("anchorChain", v3("x"), v3("y")),
|
|
5097
|
+
lit3("imports", v3("y"), v3("m"), v3("n")),
|
|
5098
|
+
lit3("moduleExport", v3("m"), v3("n"), v3("z"))
|
|
4948
5099
|
]
|
|
4949
5100
|
),
|
|
4950
|
-
|
|
5101
|
+
rule3(
|
|
4951
5102
|
"anchorChain",
|
|
4952
|
-
[
|
|
4953
|
-
[
|
|
5103
|
+
[v3("x"), v3("c")],
|
|
5104
|
+
[lit3("anchorChain", v3("x"), v3("r")), lit3("call", v3("r"), v3("c"))]
|
|
4954
5105
|
),
|
|
4955
|
-
|
|
5106
|
+
rule3(
|
|
4956
5107
|
"anchorChain",
|
|
4957
|
-
[
|
|
5108
|
+
[v3("x"), v3("o")],
|
|
4958
5109
|
[
|
|
4959
|
-
|
|
4960
|
-
|
|
5110
|
+
lit3("anchorChain", v3("x"), v3("y")),
|
|
5111
|
+
lit3("readsProperty", v3("y"), v3("o"), v3("n"))
|
|
4961
5112
|
]
|
|
4962
5113
|
),
|
|
4963
|
-
|
|
5114
|
+
rule3(
|
|
4964
5115
|
"wantedAnchorCall",
|
|
4965
|
-
[
|
|
4966
|
-
[
|
|
5116
|
+
[v3("x"), v3("r")],
|
|
5117
|
+
[lit3("anchorChain", v3("x"), v3("r")), lit3("call", v3("r"), v3("c"))]
|
|
4967
5118
|
),
|
|
4968
5119
|
...USES_QUESTIONS,
|
|
5120
|
+
...SELF_QUESTIONS,
|
|
4969
5121
|
// Where a value came from, asked from the value. DESIGN.md says why the
|
|
4970
5122
|
// walk takes `hop`, why it descends into the object a read is off, and
|
|
4971
5123
|
// why a guard's question stops at a call.
|
|
4972
|
-
|
|
5124
|
+
rule3("sourceChain", [v3("x"), v3("x")], [lit3("wantedSource", v3("x"))]),
|
|
4973
5125
|
...SOURCE_STEPS.map(
|
|
4974
|
-
(kind) =>
|
|
5126
|
+
(kind) => rule3(
|
|
4975
5127
|
"sourceChain",
|
|
4976
|
-
[
|
|
4977
|
-
[
|
|
5128
|
+
[v3("x"), v3("z")],
|
|
5129
|
+
[lit3("sourceChain", v3("x"), v3("y")), lit3("hop", v3("y"), v3("z"), kind)]
|
|
4978
5130
|
)
|
|
4979
5131
|
),
|
|
4980
5132
|
...SOURCE_READS.map(
|
|
4981
|
-
(read) =>
|
|
5133
|
+
(read) => rule3(
|
|
4982
5134
|
"sourceChain",
|
|
4983
|
-
[
|
|
4984
|
-
[
|
|
5135
|
+
[v3("x"), v3("o")],
|
|
5136
|
+
[lit3("sourceChain", v3("x"), v3("y")), read]
|
|
4985
5137
|
)
|
|
4986
5138
|
),
|
|
4987
|
-
|
|
5139
|
+
rule3(
|
|
4988
5140
|
"sourceChain",
|
|
4989
|
-
[
|
|
5141
|
+
[v3("x"), v3("a")],
|
|
4990
5142
|
[
|
|
4991
|
-
|
|
4992
|
-
|
|
5143
|
+
lit3("sourceChain", v3("x"), v3("r")),
|
|
5144
|
+
lit3("converts", v3("r"), v3("a"), v3("n"))
|
|
4993
5145
|
]
|
|
4994
5146
|
),
|
|
4995
|
-
|
|
5147
|
+
rule3(
|
|
4996
5148
|
"wantedSourceConverts",
|
|
4997
|
-
[
|
|
5149
|
+
[v3("x"), v3("r"), v3("a"), v3("n")],
|
|
4998
5150
|
[
|
|
4999
|
-
|
|
5000
|
-
|
|
5151
|
+
lit3("sourceChain", v3("x"), v3("r")),
|
|
5152
|
+
lit3("converts", v3("r"), v3("a"), v3("n"))
|
|
5001
5153
|
]
|
|
5002
5154
|
),
|
|
5003
|
-
|
|
5004
|
-
|
|
5155
|
+
rule3("inputChain", [v3("x"), v3("x")], [lit3("wantedInputRead", v3("x"))]),
|
|
5156
|
+
rule3(
|
|
5005
5157
|
"inputChain",
|
|
5006
|
-
[
|
|
5007
|
-
[
|
|
5158
|
+
[v3("x"), v3("z")],
|
|
5159
|
+
[lit3("inputChain", v3("x"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
5008
5160
|
),
|
|
5009
5161
|
...SOURCE_READS.map(
|
|
5010
|
-
(read) =>
|
|
5162
|
+
(read) => rule3(
|
|
5011
5163
|
"inputChain",
|
|
5012
|
-
[
|
|
5013
|
-
[
|
|
5164
|
+
[v3("x"), v3("o")],
|
|
5165
|
+
[lit3("inputChain", v3("x"), v3("y")), read]
|
|
5014
5166
|
)
|
|
5015
5167
|
),
|
|
5016
|
-
|
|
5017
|
-
|
|
5168
|
+
rule3("sourceMember", [v3("x"), v3("y")], [lit3("sourceChain", v3("x"), v3("y"))]),
|
|
5169
|
+
rule3("sourceMember", [v3("x"), v3("y")], [lit3("inputChain", v3("x"), v3("y"))]),
|
|
5018
5170
|
// The chain's steps and what each member is, keyed by the value asked
|
|
5019
5171
|
// about, so the asking side can rebuild the path a leaf was read along.
|
|
5020
5172
|
...SOURCE_STEPS.map(
|
|
5021
|
-
(kind) =>
|
|
5173
|
+
(kind) => rule3(
|
|
5022
5174
|
"wantedSourceHop",
|
|
5023
|
-
[
|
|
5024
|
-
[
|
|
5175
|
+
[v3("x"), v3("y"), v3("z")],
|
|
5176
|
+
[lit3("sourceChain", v3("x"), v3("y")), lit3("hop", v3("y"), v3("z"), kind)]
|
|
5025
5177
|
)
|
|
5026
5178
|
),
|
|
5027
|
-
|
|
5179
|
+
rule3(
|
|
5028
5180
|
"wantedSourceHop",
|
|
5029
|
-
[
|
|
5030
|
-
[
|
|
5181
|
+
[v3("x"), v3("y"), v3("z")],
|
|
5182
|
+
[lit3("inputChain", v3("x"), v3("y")), lit3("nameHop", v3("y"), v3("z"))]
|
|
5031
5183
|
),
|
|
5032
5184
|
...WRITTEN_KEY_READS.map(
|
|
5033
|
-
(read) =>
|
|
5185
|
+
(read) => rule3(
|
|
5034
5186
|
"wantedSourceRead",
|
|
5035
|
-
[
|
|
5036
|
-
[
|
|
5187
|
+
[v3("x"), v3("y"), v3("o"), v3("n")],
|
|
5188
|
+
[lit3("sourceMember", v3("x"), v3("y")), read]
|
|
5037
5189
|
)
|
|
5038
5190
|
),
|
|
5039
|
-
|
|
5191
|
+
rule3(
|
|
5040
5192
|
"wantedSourceKeyed",
|
|
5041
|
-
[
|
|
5193
|
+
[v3("x"), v3("y"), v3("o")],
|
|
5042
5194
|
[
|
|
5043
|
-
|
|
5044
|
-
|
|
5195
|
+
lit3("sourceMember", v3("x"), v3("y")),
|
|
5196
|
+
lit3("readsKeyed", v3("y"), v3("o"), v3("k"))
|
|
5045
5197
|
]
|
|
5046
5198
|
),
|
|
5047
|
-
|
|
5199
|
+
rule3(
|
|
5048
5200
|
"wantedSourceParam",
|
|
5049
|
-
[
|
|
5201
|
+
[v3("x"), v3("p"), v3("f")],
|
|
5050
5202
|
[
|
|
5051
|
-
|
|
5052
|
-
|
|
5203
|
+
lit3("sourceMember", v3("x"), v3("p")),
|
|
5204
|
+
lit3("paramOf", v3("f"), v3("k"), v3("p"))
|
|
5053
5205
|
]
|
|
5054
5206
|
),
|
|
5055
|
-
|
|
5207
|
+
rule3(
|
|
5056
5208
|
"wantedSourceParam",
|
|
5057
|
-
[
|
|
5209
|
+
[v3("x"), v3("p"), v3("f")],
|
|
5058
5210
|
[
|
|
5059
|
-
|
|
5060
|
-
|
|
5211
|
+
lit3("sourceMember", v3("x"), v3("p")),
|
|
5212
|
+
lit3("paramNamed", v3("f"), v3("n"), v3("p"))
|
|
5061
5213
|
]
|
|
5062
5214
|
),
|
|
5063
|
-
|
|
5215
|
+
rule3(
|
|
5064
5216
|
"wantedSourceWritten",
|
|
5065
|
-
[
|
|
5066
|
-
[
|
|
5217
|
+
[v3("x"), v3("w")],
|
|
5218
|
+
[lit3("sourceMember", v3("x"), v3("w")), lit3("writtenValue", v3("w"))]
|
|
5067
5219
|
),
|
|
5068
|
-
|
|
5220
|
+
rule3(
|
|
5069
5221
|
"wantedSourceCall",
|
|
5070
|
-
[
|
|
5071
|
-
[
|
|
5222
|
+
[v3("x"), v3("r")],
|
|
5223
|
+
[lit3("sourceMember", v3("x"), v3("r")), lit3("call", v3("r"), v3("c"))]
|
|
5072
5224
|
),
|
|
5073
|
-
|
|
5225
|
+
rule3(
|
|
5074
5226
|
"wantedSourceImport",
|
|
5075
|
-
[
|
|
5227
|
+
[v3("x"), v3("y"), v3("m"), v3("n")],
|
|
5076
5228
|
[
|
|
5077
|
-
|
|
5078
|
-
|
|
5229
|
+
lit3("sourceMember", v3("x"), v3("y")),
|
|
5230
|
+
lit3("imports", v3("y"), v3("m"), v3("n"))
|
|
5079
5231
|
]
|
|
5080
5232
|
)
|
|
5081
5233
|
];
|
|
@@ -5111,6 +5263,10 @@ export {
|
|
|
5111
5263
|
RESOLUTION_QUESTIONS,
|
|
5112
5264
|
RESOLUTION_RULES,
|
|
5113
5265
|
RESULT_STEP,
|
|
5266
|
+
SELF_AS_CLASS,
|
|
5267
|
+
SELF_AS_CLASS_NAME,
|
|
5268
|
+
SELF_AS_INSTANCE,
|
|
5269
|
+
SELF_AS_INSTANCE_NAME,
|
|
5114
5270
|
SPREAD_ENTRY,
|
|
5115
5271
|
UNDER_ANSWER_RELATIONS,
|
|
5116
5272
|
UNDER_QUESTION_ROW_BUDGET,
|
|
@@ -5150,6 +5306,8 @@ export {
|
|
|
5150
5306
|
isObserved,
|
|
5151
5307
|
isWrittenAsUnder,
|
|
5152
5308
|
joinMountedPath,
|
|
5309
|
+
keptVariants,
|
|
5310
|
+
memberOf,
|
|
5153
5311
|
mergeStoredDependencies,
|
|
5154
5312
|
mountPathsOf,
|
|
5155
5313
|
noDependencies,
|
|
@@ -5159,6 +5317,7 @@ export {
|
|
|
5159
5317
|
objectOfUnder,
|
|
5160
5318
|
observeDemand,
|
|
5161
5319
|
packHashes,
|
|
5320
|
+
plainKeyOf,
|
|
5162
5321
|
proofRules,
|
|
5163
5322
|
queryFacts,
|
|
5164
5323
|
readDispatchOutcomes,
|
|
@@ -5168,6 +5327,8 @@ export {
|
|
|
5168
5327
|
resolutionProgram,
|
|
5169
5328
|
resolutionUnderProgram,
|
|
5170
5329
|
resolvedFunctions,
|
|
5330
|
+
selfFormOf,
|
|
5331
|
+
selfResultOf,
|
|
5171
5332
|
settledFunction,
|
|
5172
5333
|
sourceLeavesOf,
|
|
5173
5334
|
spanOfKey,
|
|
@@ -5177,6 +5338,7 @@ export {
|
|
|
5177
5338
|
underQuestionSpend,
|
|
5178
5339
|
unpackHashes,
|
|
5179
5340
|
valueLeftByWrites,
|
|
5341
|
+
variantKey,
|
|
5180
5342
|
walkRecordsByFile,
|
|
5181
5343
|
writesRunInOrder,
|
|
5182
5344
|
writtenAnswersFor,
|