1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
(function(global) {
// Save the primordial values.
const {Array, Error, Object, Proxy, Reflect, Set} = global;
const ArrayIsArray = Array.isArray;
const ReflectApply = Reflect.apply;
const ReflectDefineProperty = Reflect.defineProperty;
const ReflectGet = Reflect.get;
const ReflectGetPrototypeOf = Reflect.getPrototypeOf;
const SetPrototype = Set.prototype;
const SetPrototypeHas = SetPrototype.has;
const SetPrototypeSize = Object.getOwnPropertyDescriptor(SetPrototype, "size").get;
const SetPrototypeKeys = SetPrototype.keys;
const SetIteratorPrototypeNext = new Set().values().next;
function assertSetContainsExactOrderedItems(actual, expected) {
assertEq(ReflectGetPrototypeOf(actual), SetPrototype, "actual is a native Set object");
assertEq(ArrayIsArray(expected), true, "expected is an Array object");
assertEq(ReflectApply(SetPrototypeSize, actual, []), expected.length);
let index = 0;
let keys = ReflectApply(SetPrototypeKeys, actual, []);
while (true) {
let {done, value: item} = ReflectApply(SetIteratorPrototypeNext, keys, []);
if (done) {
break;
}
assertEq(item, expected[index], `Element at index ${index}:`);
index++;
}
}
global.assertSetContainsExactOrderedItems = assertSetContainsExactOrderedItems;
class SetLike {
#set;
constructor(values) {
this.#set = new Set(values);
}
get size() {
return ReflectApply(SetPrototypeSize, this.#set, []);
}
has(value) {
return ReflectApply(SetPrototypeHas, this.#set, [value]);
}
keys() {
let keys = ReflectApply(SetPrototypeKeys, this.#set, []);
return new SetIteratorLike(keys);
}
}
global.SetLike = SetLike;
class SetIteratorLike {
#keys;
constructor(keys) {
this.#keys = keys;
}
next() {
return ReflectApply(SetIteratorPrototypeNext, this.#keys, []);
}
// The |return| method of the iterator protocol is never called.
return() {
throw new Error("Unexpected call to |return| method");
}
// The |throw| method of the iterator protocol is never called.
throw() {
throw new Error("Unexpected call to |throw| method");
}
}
function LoggingProxy(obj, log) {
assertEq(ArrayIsArray(log), true);
let handler = new Proxy({
get(t, pk, r) {
ReflectDefineProperty(log, log.length, {
value: pk, writable: true, enumerable: true, configurable: true,
});
return ReflectGet(t, pk, r);
}
}, {
get(t, pk, r) {
ReflectDefineProperty(log, log.length, {
value: `[[${pk}]]`, writable: true, enumerable: true, configurable: true,
});
return ReflectGet(t, pk, r);
}
});
return {obj, proxy: new Proxy(obj, handler)};
}
global.LoggingProxy = LoggingProxy;
})(this);
|