@nudojs/cli 0.3.0 → 0.4.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/evaluator-api.d.ts +162 -0
- package/dist/evaluator-api.js +27683 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +281241 -0
- package/package.json +20 -13
- package/src/abs-route.ts +0 -273
- package/src/builtins/builtin-intl.ts +0 -17
- package/src/builtins/builtin-map.ts +0 -174
- package/src/builtins/builtin-promise.ts +0 -116
- package/src/builtins/builtin-prototype.ts +0 -279
- package/src/builtins/builtin-reflect.ts +0 -30
- package/src/builtins/builtin-regexp.ts +0 -34
- package/src/builtins/builtin-set.ts +0 -131
- package/src/builtins/builtin-static.ts +0 -260
- package/src/builtins/builtin-symbol.ts +0 -16
- package/src/builtins/builtin-url.ts +0 -58
- package/src/builtins/builtin-weak.ts +0 -22
- package/src/builtins/builtin-web.ts +0 -111
- package/src/config.ts +0 -32
- package/src/env-loader.ts +0 -174
- package/src/eval-binary.ts +0 -113
- package/src/evaluator-api.ts +0 -39
- package/src/evaluator.ts +0 -5164
- package/src/index.ts +0 -1034
- package/src/narrowing.ts +0 -544
- package/src/phi-from-test.ts +0 -42
- package/src/resolve-npm.ts +0 -63
- package/src/run-test.ts +0 -92
- package/src/term-registry.ts +0 -96
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 内置类原型机制:错误类集合、可构造内置类、Object/Array/Map/Set/…/Buffer
|
|
3
|
-
* 的原型成员近似表,以及 `X.prototype` 单例与类命名空间记忆化。
|
|
4
|
-
* 求值器成员分派与补全侧成员派生共用本表的唯一真值。
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { T, simplifyUnion, type TypeValue } from "@nudojs/core";
|
|
8
|
-
import { MAP_INSTANCE_METHODS, mapEntriesIterable } from "./builtin-map.ts";
|
|
9
|
-
import { SET_INSTANCE_METHODS } from "./builtin-set.ts";
|
|
10
|
-
|
|
11
|
-
// hasOwnProp 守卫:普通 Record 表查找会从原型链泄漏原生函数(如 "constructor")。
|
|
12
|
-
// 与 evaluator 内同名 helper 同语义;独立副本避免 evaluator → 本模块循环依赖。
|
|
13
|
-
function hasOwnProp(props: Record<string, unknown>, name: string): boolean {
|
|
14
|
-
return Object.prototype.hasOwnProperty.call(props, name);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const BUILTIN_ERROR_CLASSES = new Set([
|
|
18
|
-
"Error", "TypeError", "SyntaxError", "RangeError", "ReferenceError", "URIError", "EvalError",
|
|
19
|
-
]);
|
|
20
|
-
// Constructible built-in classes. A bare reference to one of these names
|
|
21
|
-
// resolves to a namespace object (like the BUILTIN_STATIC_METHODS entries),
|
|
22
|
-
// and `X.prototype` evaluates to an instance of X instead of degrading to
|
|
23
|
-
// undefined/unknown.
|
|
24
|
-
const BUILTIN_PROTOTYPE_CLASSES = new Set([
|
|
25
|
-
...BUILTIN_ERROR_CLASSES,
|
|
26
|
-
"Date", "Object", "Map", "Set", "Promise", "RegExp", "Array", "Function",
|
|
27
|
-
"String", "Number", "Boolean", "Symbol", "WeakMap", "WeakSet", "Buffer",
|
|
28
|
-
]);
|
|
29
|
-
// Object.prototype members. Real property access reads through the
|
|
30
|
-
// prototype chain, so every object-typed receiver materializes these —
|
|
31
|
-
// destructuring `const { hasOwnProperty } = obj` yields a function (not
|
|
32
|
-
// undefined) and `Object.prototype.hasOwnProperty` types as boolean.
|
|
33
|
-
// Lookup must be own-property guarded: a plain `{}` record would otherwise
|
|
34
|
-
// leak native JS functions (e.g. for "constructor") into the type system.
|
|
35
|
-
//
|
|
36
|
-
// toString/valueOf carry impls so the receiver (thisVal) shapes the result:
|
|
37
|
-
// `Object.prototype.toString.call(x)` yields the brand literal
|
|
38
|
-
// ('[object Map]', '[object Null]', ...) that Map-based type dispatch
|
|
39
|
-
// (hoek internals.typeMap) keys on; valueOf returns its receiver.
|
|
40
|
-
const OBJECT_PROTOTYPE_METHODS: Record<string, TypeValue> = {
|
|
41
|
-
hasOwnProperty: T.fnSig([T.unknown], T.boolean),
|
|
42
|
-
isPrototypeOf: T.fnSig([T.unknown], T.boolean),
|
|
43
|
-
propertyIsEnumerable: T.fnSig([T.unknown], T.boolean),
|
|
44
|
-
toString: T.fnSig([], T.string, T.never, (_args, thisVal) => objectToStringBrand(thisVal)),
|
|
45
|
-
toLocaleString: T.fnSig([], T.string),
|
|
46
|
-
valueOf: T.fnSig([], T.unknown, T.never, (_args, thisVal) => thisVal),
|
|
47
|
-
};
|
|
48
|
-
// Common prototype members approximated as unknown-result signatures
|
|
49
|
-
// (mirrors the knownInstanceMethods fallback pattern). `X.prototype.m`
|
|
50
|
-
// stays a callable function value instead of degrading to undefined.
|
|
51
|
-
const BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS: Record<string, Record<string, TypeValue>> = {
|
|
52
|
-
Object: { ...OBJECT_PROTOTYPE_METHODS },
|
|
53
|
-
Array: {
|
|
54
|
-
push: T.fnSig([T.unknown], T.number),
|
|
55
|
-
pop: T.fnSig([], T.unknown),
|
|
56
|
-
shift: T.fnSig([], T.unknown),
|
|
57
|
-
unshift: T.fnSig([T.unknown], T.number),
|
|
58
|
-
slice: T.fnSig([T.number, T.number], T.array(T.unknown)),
|
|
59
|
-
splice: T.fnSig([T.number, T.number], T.array(T.unknown)),
|
|
60
|
-
concat: T.fnSig([T.unknown], T.array(T.unknown)),
|
|
61
|
-
join: T.fnSig([T.string], T.string),
|
|
62
|
-
indexOf: T.fnSig([T.unknown], T.number),
|
|
63
|
-
lastIndexOf: T.fnSig([T.unknown], T.number),
|
|
64
|
-
includes: T.fnSig([T.unknown], T.boolean),
|
|
65
|
-
map: T.fnSig([T.unknown], T.array(T.unknown)),
|
|
66
|
-
flatMap: T.fnSig([T.unknown], T.array(T.unknown)),
|
|
67
|
-
filter: T.fnSig([T.unknown], T.array(T.unknown)),
|
|
68
|
-
forEach: T.fnSig([T.unknown], T.undefined),
|
|
69
|
-
find: T.fnSig([T.unknown], T.unknown),
|
|
70
|
-
findIndex: T.fnSig([T.unknown], T.number),
|
|
71
|
-
some: T.fnSig([T.unknown], T.boolean),
|
|
72
|
-
every: T.fnSig([T.unknown], T.boolean),
|
|
73
|
-
reduce: T.fnSig([T.unknown, T.unknown], T.unknown),
|
|
74
|
-
sort: T.fnSig([T.unknown], T.array(T.unknown)),
|
|
75
|
-
reverse: T.fnSig([], T.array(T.unknown)),
|
|
76
|
-
toString: T.fnSig([], T.string),
|
|
77
|
-
},
|
|
78
|
-
Function: {
|
|
79
|
-
call: T.fnSig([T.unknown], T.unknown),
|
|
80
|
-
apply: T.fnSig([T.unknown, T.unknown], T.unknown),
|
|
81
|
-
bind: T.fnSig([T.unknown], T.unknown),
|
|
82
|
-
toString: T.fnSig([], T.string),
|
|
83
|
-
},
|
|
84
|
-
Map: {
|
|
85
|
-
// Impl-routed: `Map.prototype.m.call(instance)` (and direct prototype
|
|
86
|
-
// calls) consult the receiver's exact entry side table, making the
|
|
87
|
-
// hoek deepEqual reflection idioms decide literally.
|
|
88
|
-
get: T.fnSig([T.unknown], T.unknown, T.never, (args, thisVal) => MAP_INSTANCE_METHODS.get(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
89
|
-
set: T.fnSig([T.unknown, T.unknown], T.unknown, T.never, (args, thisVal) => MAP_INSTANCE_METHODS.set(args[0] ?? T.unknown, args[1] ?? T.unknown, thisVal ?? T.unknown)),
|
|
90
|
-
has: T.fnSig([T.unknown], T.boolean, T.never, (args, thisVal) => MAP_INSTANCE_METHODS.has(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
91
|
-
delete: T.fnSig([T.unknown], T.boolean, T.never, (args, thisVal) => MAP_INSTANCE_METHODS.delete(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
92
|
-
clear: T.fnSig([], T.undefined, T.never, (args, thisVal) => MAP_INSTANCE_METHODS.clear(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
93
|
-
forEach: T.fnSig([T.unknown], T.undefined),
|
|
94
|
-
keys: T.fnSig([], T.array(T.unknown), T.never, (_args, thisVal) => MAP_INSTANCE_METHODS.keys(thisVal ?? T.unknown)),
|
|
95
|
-
values: T.fnSig([], T.array(T.unknown), T.never, (_args, thisVal) => MAP_INSTANCE_METHODS.values(thisVal ?? T.unknown)),
|
|
96
|
-
entries: T.fnSig([], T.array(T.tuple([T.unknown, T.unknown])), T.never, (_args, thisVal) => mapEntriesIterable(thisVal ?? T.unknown)),
|
|
97
|
-
toString: T.fnSig([], T.string),
|
|
98
|
-
},
|
|
99
|
-
Set: {
|
|
100
|
-
// Impl-routed like Map above (Set.prototype.values.call(s) ≡ s.values()).
|
|
101
|
-
add: T.fnSig([T.unknown], T.unknown, T.never, (args, thisVal) => SET_INSTANCE_METHODS.add(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
102
|
-
has: T.fnSig([T.unknown], T.boolean, T.never, (args, thisVal) => SET_INSTANCE_METHODS.has(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
103
|
-
delete: T.fnSig([T.unknown], T.boolean, T.never, (args, thisVal) => SET_INSTANCE_METHODS.delete(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
104
|
-
clear: T.fnSig([], T.undefined, T.never, (args, thisVal) => SET_INSTANCE_METHODS.clear(args[0] ?? T.unknown, thisVal ?? T.unknown)),
|
|
105
|
-
forEach: T.fnSig([T.unknown], T.undefined),
|
|
106
|
-
keys: T.fnSig([], T.array(T.unknown), T.never, (_args, thisVal) => SET_INSTANCE_METHODS.keys(thisVal ?? T.unknown)),
|
|
107
|
-
values: T.fnSig([], T.array(T.unknown), T.never, (_args, thisVal) => SET_INSTANCE_METHODS.values(thisVal ?? T.unknown)),
|
|
108
|
-
entries: T.fnSig([], T.array(T.tuple([T.unknown, T.unknown])), T.never, (_args, thisVal) => SET_INSTANCE_METHODS.entries(thisVal ?? T.unknown)),
|
|
109
|
-
toString: T.fnSig([], T.string),
|
|
110
|
-
},
|
|
111
|
-
WeakMap: {
|
|
112
|
-
get: T.fnSig([T.unknown], T.unknown),
|
|
113
|
-
set: T.fnSig([T.unknown, T.unknown], T.unknown),
|
|
114
|
-
has: T.fnSig([T.unknown], T.boolean),
|
|
115
|
-
delete: T.fnSig([T.unknown], T.boolean),
|
|
116
|
-
toString: T.fnSig([], T.string),
|
|
117
|
-
},
|
|
118
|
-
WeakSet: {
|
|
119
|
-
add: T.fnSig([T.unknown], T.unknown),
|
|
120
|
-
has: T.fnSig([T.unknown], T.boolean),
|
|
121
|
-
delete: T.fnSig([T.unknown], T.boolean),
|
|
122
|
-
toString: T.fnSig([], T.string),
|
|
123
|
-
},
|
|
124
|
-
Promise: {
|
|
125
|
-
then: T.fnSig([T.unknown], T.promise(T.unknown)),
|
|
126
|
-
catch: T.fnSig([T.unknown], T.promise(T.unknown)),
|
|
127
|
-
finally: T.fnSig([T.unknown], T.promise(T.unknown)),
|
|
128
|
-
toString: T.fnSig([], T.string),
|
|
129
|
-
},
|
|
130
|
-
Date: {
|
|
131
|
-
getTime: T.fnSig([], T.number),
|
|
132
|
-
valueOf: T.fnSig([], T.number),
|
|
133
|
-
toISOString: T.fnSig([], T.string),
|
|
134
|
-
toJSON: T.fnSig([], T.string),
|
|
135
|
-
toLocaleString: T.fnSig([], T.string),
|
|
136
|
-
toString: T.fnSig([], T.string),
|
|
137
|
-
},
|
|
138
|
-
RegExp: {
|
|
139
|
-
test: T.fnSig([T.string], T.boolean),
|
|
140
|
-
exec: T.fnSig([T.string], T.union(T.object({}), T.null)),
|
|
141
|
-
toString: T.fnSig([], T.string),
|
|
142
|
-
},
|
|
143
|
-
String: {
|
|
144
|
-
charAt: T.fnSig([T.number], T.string),
|
|
145
|
-
charCodeAt: T.fnSig([T.number], T.number),
|
|
146
|
-
indexOf: T.fnSig([T.string], T.number),
|
|
147
|
-
lastIndexOf: T.fnSig([T.string], T.number),
|
|
148
|
-
includes: T.fnSig([T.string], T.boolean),
|
|
149
|
-
startsWith: T.fnSig([T.string], T.boolean),
|
|
150
|
-
endsWith: T.fnSig([T.string], T.boolean),
|
|
151
|
-
slice: T.fnSig([T.number, T.number], T.string),
|
|
152
|
-
substring: T.fnSig([T.number, T.number], T.string),
|
|
153
|
-
toUpperCase: T.fnSig([], T.string),
|
|
154
|
-
toLowerCase: T.fnSig([], T.string),
|
|
155
|
-
trim: T.fnSig([], T.string),
|
|
156
|
-
replace: T.fnSig([T.unknown, T.string], T.string),
|
|
157
|
-
split: T.fnSig([T.string], T.array(T.string)),
|
|
158
|
-
toString: T.fnSig([], T.string),
|
|
159
|
-
valueOf: T.fnSig([], T.string),
|
|
160
|
-
},
|
|
161
|
-
Number: {
|
|
162
|
-
toFixed: T.fnSig([T.number], T.string),
|
|
163
|
-
toPrecision: T.fnSig([T.number], T.string),
|
|
164
|
-
valueOf: T.fnSig([], T.number),
|
|
165
|
-
toString: T.fnSig([T.number], T.string),
|
|
166
|
-
},
|
|
167
|
-
Boolean: {
|
|
168
|
-
valueOf: T.fnSig([], T.boolean),
|
|
169
|
-
toString: T.fnSig([], T.string),
|
|
170
|
-
},
|
|
171
|
-
Symbol: {
|
|
172
|
-
toString: T.fnSig([], T.string),
|
|
173
|
-
valueOf: T.fnSig([], T.symbol),
|
|
174
|
-
},
|
|
175
|
-
Buffer: {
|
|
176
|
-
equals: T.fnSig([T.unknown], T.boolean),
|
|
177
|
-
compare: T.fnSig([T.unknown], T.number),
|
|
178
|
-
toString: T.fnSig([T.unknown], T.string),
|
|
179
|
-
toJSON: T.fnSig([], T.unknown),
|
|
180
|
-
},
|
|
181
|
-
Error: {
|
|
182
|
-
toString: T.fnSig([], T.string),
|
|
183
|
-
},
|
|
184
|
-
};
|
|
185
|
-
// Memoized namespace values for built-in classes. Reference-stable so
|
|
186
|
-
// `'x'.constructor === String` compares identical objects (typeValueEquals
|
|
187
|
-
// falls back to reference equality for object kinds).
|
|
188
|
-
const _builtinClassValues = new Map<string, TypeValue>();
|
|
189
|
-
function builtinClassValue(name: string): TypeValue {
|
|
190
|
-
let v = _builtinClassValues.get(name);
|
|
191
|
-
if (v === undefined) {
|
|
192
|
-
v = T.object({});
|
|
193
|
-
(v as any)._builtinName = name;
|
|
194
|
-
_builtinClassValues.set(name, v);
|
|
195
|
-
}
|
|
196
|
-
return v;
|
|
197
|
-
}
|
|
198
|
-
// Cached `X.prototype` singletons. hoek-style modules assign
|
|
199
|
-
// `exports.array = Array.prototype` and later compare
|
|
200
|
-
// `baseProto === Types.buffer`: strict-equality on instances only stays
|
|
201
|
-
// precise when every evaluation of `X.prototype` yields the same TypeValue.
|
|
202
|
-
const BUILTIN_PROTOTYPE_SINGLETONS = new Map<string, TypeValue>();
|
|
203
|
-
|
|
204
|
-
function builtinPrototype(className: string): TypeValue {
|
|
205
|
-
let proto = BUILTIN_PROTOTYPE_SINGLETONS.get(className);
|
|
206
|
-
if (!proto) {
|
|
207
|
-
const methods = hasOwnProp(BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS, className)
|
|
208
|
-
? BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS[className]
|
|
209
|
-
: BUILTIN_ERROR_CLASSES.has(className)
|
|
210
|
-
? BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS.Error
|
|
211
|
-
: {};
|
|
212
|
-
proto = T.instanceOf(className, { ...methods });
|
|
213
|
-
(proto as any)._builtinProto = className;
|
|
214
|
-
BUILTIN_PROTOTYPE_SINGLETONS.set(className, proto);
|
|
215
|
-
}
|
|
216
|
-
return proto;
|
|
217
|
-
}
|
|
218
|
-
// `Object.prototype.toString` brand string ('[object Map]', '[object Null]',
|
|
219
|
-
// ...). Returns undefined when the receiver has no representable brand, so
|
|
220
|
-
// the fnSig falls back to its plain `string` return type.
|
|
221
|
-
function objectToStringBrand(v: TypeValue | undefined): TypeValue | undefined {
|
|
222
|
-
if (!v) return undefined;
|
|
223
|
-
if (v.kind === "union") {
|
|
224
|
-
const parts = v.members.map((m) => objectToStringBrand(m));
|
|
225
|
-
if (parts.some((p) => p === undefined)) return undefined;
|
|
226
|
-
return simplifyUnion(parts as TypeValue[]);
|
|
227
|
-
}
|
|
228
|
-
let base: TypeValue = v;
|
|
229
|
-
while (base.kind === "refined") base = base.base;
|
|
230
|
-
switch (base.kind) {
|
|
231
|
-
case "object": return T.literal("[object Object]");
|
|
232
|
-
case "array":
|
|
233
|
-
case "tuple": return T.literal("[object Array]");
|
|
234
|
-
case "function": return T.literal("[object Function]");
|
|
235
|
-
case "promise": return T.literal("[object Promise]");
|
|
236
|
-
case "instance": return T.literal(`[object ${base.className}]`);
|
|
237
|
-
case "literal": {
|
|
238
|
-
if (base.value === null) return T.literal("[object Null]");
|
|
239
|
-
if (base.value === undefined) return T.literal("[object Undefined]");
|
|
240
|
-
const t = typeof base.value;
|
|
241
|
-
return T.literal(`[object ${t === "number" ? "Number" : t === "string" ? "String" : "Boolean"}]`);
|
|
242
|
-
}
|
|
243
|
-
case "primitive": {
|
|
244
|
-
const brands: Record<string, string> = {
|
|
245
|
-
number: "Number", string: "String", boolean: "Boolean", bigint: "BigInt", symbol: "Symbol",
|
|
246
|
-
};
|
|
247
|
-
return T.literal(`[object ${brands[base.type] ?? "Object"}]`);
|
|
248
|
-
}
|
|
249
|
-
default: return undefined;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
// Object.getPrototypeOf: map a receiver onto its class's cached prototype
|
|
253
|
-
// singleton (plain objects → Object.prototype, arrays → Array.prototype,
|
|
254
|
-
// instances → their class's prototype). Unrepresentable receivers degrade
|
|
255
|
-
// to unknown.
|
|
256
|
-
function protoOfValue(v: TypeValue | undefined): TypeValue {
|
|
257
|
-
if (!v) return T.unknown;
|
|
258
|
-
if (v.kind === "union") return simplifyUnion(v.members.map((m) => protoOfValue(m)));
|
|
259
|
-
let base: TypeValue = v;
|
|
260
|
-
while (base.kind === "refined") base = base.base;
|
|
261
|
-
switch (base.kind) {
|
|
262
|
-
case "object": return builtinPrototype("Object");
|
|
263
|
-
case "array":
|
|
264
|
-
case "tuple": return builtinPrototype("Array");
|
|
265
|
-
case "function": return builtinPrototype("Function");
|
|
266
|
-
case "promise": return builtinPrototype("Promise");
|
|
267
|
-
case "instance": return builtinPrototype(base.className);
|
|
268
|
-
default: return T.unknown;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
export {
|
|
272
|
-
BUILTIN_ERROR_CLASSES,
|
|
273
|
-
BUILTIN_PROTOTYPE_CLASSES,
|
|
274
|
-
OBJECT_PROTOTYPE_METHODS,
|
|
275
|
-
BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS,
|
|
276
|
-
builtinClassValue,
|
|
277
|
-
builtinPrototype,
|
|
278
|
-
protoOfValue,
|
|
279
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { type TypeValue, T } from "@nudojs/core";
|
|
2
|
-
|
|
3
|
-
export const REFLECT_METHODS: Record<string, (...args: TypeValue[]) => TypeValue> = {
|
|
4
|
-
has: () => T.boolean,
|
|
5
|
-
get: () => T.unknown,
|
|
6
|
-
set: () => T.boolean,
|
|
7
|
-
deleteProperty: () => T.boolean,
|
|
8
|
-
apply: () => T.unknown,
|
|
9
|
-
construct: () => T.object({}),
|
|
10
|
-
// Shape-aware like Object.keys: known receivers list their declared
|
|
11
|
-
// own-property names (hoek's Utils.keys → clone/flatten key loops then
|
|
12
|
-
// iterate concrete keys instead of a symbolic string), arrays add the
|
|
13
|
-
// non-enumerable "length" own key. Unknown shapes keep the approximation.
|
|
14
|
-
ownKeys: (target?: TypeValue) => {
|
|
15
|
-
let base = target;
|
|
16
|
-
while (base?.kind === "refined") base = base.base;
|
|
17
|
-
if (base && (base.kind === "object" || base.kind === "instance")) {
|
|
18
|
-
return T.tuple(Object.keys(base.properties).map((k) => T.literal(k)));
|
|
19
|
-
}
|
|
20
|
-
if (base?.kind === "tuple") {
|
|
21
|
-
return T.tuple([
|
|
22
|
-
...base.elements.map((_, i) => T.literal(String(i))),
|
|
23
|
-
T.literal("length"),
|
|
24
|
-
]);
|
|
25
|
-
}
|
|
26
|
-
return T.array(T.string);
|
|
27
|
-
},
|
|
28
|
-
getPrototypeOf: () => T.union(T.object({}), T.null),
|
|
29
|
-
getOwnPropertyDescriptor: () => T.union(T.object({}), T.undefined),
|
|
30
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { type TypeValue, T } from "@nudojs/core";
|
|
2
|
-
|
|
3
|
-
export const REGEXP_INSTANCE_METHODS: Record<string, (...args: TypeValue[]) => TypeValue> = {
|
|
4
|
-
test: () => T.boolean,
|
|
5
|
-
exec: () => T.union(T.null, T.object({})),
|
|
6
|
-
toString: () => T.string,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const REGEXP_PROPS: Record<string, TypeValue> = {
|
|
10
|
-
source: T.string,
|
|
11
|
-
flags: T.string,
|
|
12
|
-
global: T.boolean,
|
|
13
|
-
ignoreCase: T.boolean,
|
|
14
|
-
multiline: T.boolean,
|
|
15
|
-
dotAll: T.boolean,
|
|
16
|
-
unicode: T.boolean,
|
|
17
|
-
sticky: T.boolean,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export function createRegExpType(): TypeValue {
|
|
21
|
-
return T.instanceOf("RegExp", {
|
|
22
|
-
source: T.string,
|
|
23
|
-
flags: T.string,
|
|
24
|
-
global: T.boolean,
|
|
25
|
-
ignoreCase: T.boolean,
|
|
26
|
-
multiline: T.boolean,
|
|
27
|
-
dotAll: T.boolean,
|
|
28
|
-
unicode: T.boolean,
|
|
29
|
-
sticky: T.boolean,
|
|
30
|
-
test: T.fn(["...args"], { type: "BlockStatement", body: [] } as any, undefined as any),
|
|
31
|
-
exec: T.fn(["...args"], { type: "BlockStatement", body: [] } as any, undefined as any),
|
|
32
|
-
toString: T.fn(["...args"], { type: "BlockStatement", body: [] } as any, undefined as any),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { type TypeValue, T, simplifyUnion, typeValueEquals } from "@nudojs/core";
|
|
2
|
-
|
|
3
|
-
// Literal/instance values recorded at construction (`new Set([a, b])`) or
|
|
4
|
-
// via add() — precise enough for typeValueEquals lookup in has(). Symbolic
|
|
5
|
-
// values are skipped and has() falls back to boolean.
|
|
6
|
-
function valueTrackable(v: TypeValue | undefined): boolean {
|
|
7
|
-
return v?.kind === "literal" || v?.kind === "instance";
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// Union values distribute: every member present → true, none present →
|
|
11
|
-
// false, mixed/not comparable → null (symbolic boolean fallback).
|
|
12
|
-
function lookupValues(values: TypeValue[], value: TypeValue): boolean | null {
|
|
13
|
-
if (value.kind === "union") {
|
|
14
|
-
const results = value.members.map((m) => lookupValues(values, m));
|
|
15
|
-
if (results.some((r) => r === null)) return null;
|
|
16
|
-
return results.some((r) => r === true) && results.every((r) => r === true);
|
|
17
|
-
}
|
|
18
|
-
if (!valueTrackable(value)) return null;
|
|
19
|
-
return values.some((v) => typeValueEquals(v, value));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const SET_INSTANCE_METHODS: Record<string, (...args: TypeValue[]) => TypeValue> = {
|
|
23
|
-
add: (value: TypeValue, set?: TypeValue) => {
|
|
24
|
-
if (set) {
|
|
25
|
-
const typeArgs = (set as any)._typeArgs || { T: T.unknown };
|
|
26
|
-
(set as any)._typeArgs = {
|
|
27
|
-
T: typeArgs.T.kind === "unknown" ? value : simplifyUnion([typeArgs.T, value]),
|
|
28
|
-
};
|
|
29
|
-
if (valueTrackable(value)) {
|
|
30
|
-
// An exact list can start on the first trackable add (nothing
|
|
31
|
-
// untracked came before); once partial it stays partial.
|
|
32
|
-
if ((set as any)._values === undefined && (set as any)._valuesExact !== false) {
|
|
33
|
-
(set as any)._values = [];
|
|
34
|
-
(set as any)._valuesExact = true;
|
|
35
|
-
}
|
|
36
|
-
if ((set as any)._valuesExact) {
|
|
37
|
-
const values = (set as any)._values as TypeValue[];
|
|
38
|
-
if (!values.some((v) => typeValueEquals(v, value))) values.push(value);
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
(set as any)._valuesExact = false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return set ?? T.unknown;
|
|
45
|
-
},
|
|
46
|
-
has: (value: TypeValue, set?: TypeValue) => {
|
|
47
|
-
const values = exactSetValues(set);
|
|
48
|
-
if (values) {
|
|
49
|
-
const looked = lookupValues(values, value);
|
|
50
|
-
if (looked !== null) return T.literal(looked);
|
|
51
|
-
}
|
|
52
|
-
return T.boolean;
|
|
53
|
-
},
|
|
54
|
-
delete: (value: TypeValue, set?: TypeValue) => {
|
|
55
|
-
const values = exactSetValues(set);
|
|
56
|
-
if (values && valueTrackable(value)) {
|
|
57
|
-
const idx = values.findIndex((v) => typeValueEquals(v, value));
|
|
58
|
-
if (idx >= 0) {
|
|
59
|
-
values.splice(idx, 1);
|
|
60
|
-
return T.literal(true);
|
|
61
|
-
}
|
|
62
|
-
return T.literal(false);
|
|
63
|
-
}
|
|
64
|
-
return T.boolean;
|
|
65
|
-
},
|
|
66
|
-
clear: (value?: TypeValue, set?: TypeValue) => {
|
|
67
|
-
// s.clear() arrives as clear(receiver): the set sits in the first
|
|
68
|
-
// param slot when the call has no arguments.
|
|
69
|
-
const target = set ?? value;
|
|
70
|
-
if (target && (target as any)._valuesExact) {
|
|
71
|
-
(target as any)._values = [];
|
|
72
|
-
}
|
|
73
|
-
return T.undefined;
|
|
74
|
-
},
|
|
75
|
-
forEach: () => T.undefined,
|
|
76
|
-
values: (set?: TypeValue) => setValuesIterable(set),
|
|
77
|
-
// For Set, keys() is the same as values()
|
|
78
|
-
keys: (set?: TypeValue) => setValuesIterable(set),
|
|
79
|
-
entries: (set?: TypeValue) => {
|
|
80
|
-
const values = exactSetValues(set);
|
|
81
|
-
if (values) return T.tuple(values.map((v) => T.tuple([v, v])));
|
|
82
|
-
const typeArgs = (set as any)?._typeArgs;
|
|
83
|
-
if (typeArgs?.T) return T.array(T.tuple([typeArgs.T, typeArgs.T]));
|
|
84
|
-
return T.array(T.tuple([T.unknown, T.unknown]));
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// Exact membership side table: present only when every member seen so far
|
|
89
|
-
// (construction elements + adds) was trackable. Partial tables must not
|
|
90
|
-
// decide has()/delete()/iteration — an untracked member could be anything.
|
|
91
|
-
export function exactSetValues(set: TypeValue | undefined): TypeValue[] | undefined {
|
|
92
|
-
if (!set || (set as any)._valuesExact !== true) return undefined;
|
|
93
|
-
return (set as any)._values as TypeValue[] | undefined;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// values()/keys() keep feeding `new Set(...)`-style consumers: a tuple of
|
|
97
|
-
// the exact members when the side table is complete, else array<T>.
|
|
98
|
-
export function setValuesIterable(set: TypeValue | undefined): TypeValue {
|
|
99
|
-
const values = exactSetValues(set);
|
|
100
|
-
if (values) return T.tuple([...values]);
|
|
101
|
-
const typeArgs = (set as any)?._typeArgs;
|
|
102
|
-
if (typeArgs?.T) return T.array(typeArgs.T);
|
|
103
|
-
return T.array(T.unknown);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function createSetType(args?: TypeValue[]): TypeValue {
|
|
107
|
-
const obj = T.instanceOf("Set", {});
|
|
108
|
-
|
|
109
|
-
if (args && args.length > 0) {
|
|
110
|
-
const arg = args[0];
|
|
111
|
-
if (arg.kind === "tuple" || arg.kind === "array") {
|
|
112
|
-
const elements = arg.kind === "tuple" ? arg.elements : [arg.element];
|
|
113
|
-
(obj as any)._typeArgs = { T: simplifyUnion(elements) };
|
|
114
|
-
// Only a fully trackable element list is exact: symbolic elements
|
|
115
|
-
// mean the recorded values are a subset of the real membership.
|
|
116
|
-
const exact = elements.every(valueTrackable);
|
|
117
|
-
if (exact && elements.length > 0) {
|
|
118
|
-
(obj as any)._values = elements;
|
|
119
|
-
(obj as any)._valuesExact = true;
|
|
120
|
-
} else if (!exact) {
|
|
121
|
-
(obj as any)._valuesExact = false;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (!(obj as any)._typeArgs) {
|
|
127
|
-
(obj as any)._typeArgs = { T: T.unknown };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return obj;
|
|
131
|
-
}
|