@typescript-guy/fn-monitor 1.0.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/ACKNOWLEDGEMENTS.md +10 -0
- package/LICENSE.md +10 -0
- package/README.md +201 -0
- package/dist/custom-types.d.ts +239 -0
- package/dist/custom-types.js +341 -0
- package/dist/evaluate/declaration.d.ts +27 -0
- package/dist/evaluate/declaration.js +289 -0
- package/dist/evaluate/expression.d.ts +40 -0
- package/dist/evaluate/expression.js +604 -0
- package/dist/evaluate/helper.d.ts +18 -0
- package/dist/evaluate/helper.js +270 -0
- package/dist/evaluate/identifier.d.ts +7 -0
- package/dist/evaluate/identifier.js +27 -0
- package/dist/evaluate/index.d.ts +3 -0
- package/dist/evaluate/index.js +112 -0
- package/dist/evaluate/literal.d.ts +3 -0
- package/dist/evaluate/literal.js +8 -0
- package/dist/evaluate/pattern.d.ts +13 -0
- package/dist/evaluate/pattern.js +118 -0
- package/dist/evaluate/program.d.ts +3 -0
- package/dist/evaluate/program.js +20 -0
- package/dist/evaluate/statement.d.ts +35 -0
- package/dist/evaluate/statement.js +323 -0
- package/dist/evaluate_n/declaration.d.ts +27 -0
- package/dist/evaluate_n/declaration.js +289 -0
- package/dist/evaluate_n/expression.d.ts +38 -0
- package/dist/evaluate_n/expression.js +596 -0
- package/dist/evaluate_n/helper.d.ts +18 -0
- package/dist/evaluate_n/helper.js +238 -0
- package/dist/evaluate_n/identifier.d.ts +7 -0
- package/dist/evaluate_n/identifier.js +27 -0
- package/dist/evaluate_n/index.d.ts +3 -0
- package/dist/evaluate_n/index.js +76 -0
- package/dist/evaluate_n/literal.d.ts +3 -0
- package/dist/evaluate_n/literal.js +8 -0
- package/dist/evaluate_n/pattern.d.ts +13 -0
- package/dist/evaluate_n/pattern.js +118 -0
- package/dist/evaluate_n/program.d.ts +3 -0
- package/dist/evaluate_n/program.js +20 -0
- package/dist/evaluate_n/statement.d.ts +35 -0
- package/dist/evaluate_n/statement.js +301 -0
- package/dist/examples/example-2.d.ts +1 -0
- package/dist/examples/example.d.ts +1 -0
- package/dist/helper-functions.d.ts +15 -0
- package/dist/helper-functions.js +104 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +312 -0
- package/dist/q-list.d.ts +39 -0
- package/dist/q-list.js +146 -0
- package/dist/scope/index.d.ts +81 -0
- package/dist/scope/index.js +168 -0
- package/dist/scope/variable.d.ts +20 -0
- package/dist/scope/variable.js +38 -0
- package/dist/share/async.d.ts +7 -0
- package/dist/share/async.js +43 -0
- package/dist/share/const.d.ts +25 -0
- package/dist/share/const.js +21 -0
- package/dist/share/util.d.ts +33 -0
- package/dist/share/util.js +379 -0
- package/dist/sval.d.ts +15 -0
- package/dist/sval.js +104 -0
- package/package.json +54 -0
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
import { callSuper, WINDOW, getSetter, createSymbol, define, getGetter, assign, freeze, getDptor } from '../share/util.js';
|
|
2
|
+
import { STRICT, AWAIT, PRIVATE, OPTCHAIN, CLSCTOR, STRICT_FN, SUPERCALL, IMPORT, NEWTARGET, NOCTOR, SUPER } from '../share/const.js';
|
|
3
|
+
import { createFunc, pattern, createClass } from './helper.js';
|
|
4
|
+
import { Prop } from '../scope/variable.js';
|
|
5
|
+
import { Identifier } from './identifier.js';
|
|
6
|
+
import { Literal } from './literal.js';
|
|
7
|
+
import Scope from '../scope/index.js';
|
|
8
|
+
import evaluate from './index.js';
|
|
9
|
+
|
|
10
|
+
function* ThisExpression(node, scope) {
|
|
11
|
+
const superCall = scope.find(SUPERCALL);
|
|
12
|
+
if (superCall && superCall.get() !== true) {
|
|
13
|
+
throw new ReferenceError("Must call super constructor in derived class before accessing 'this' or returning from derived constructor");
|
|
14
|
+
} else {
|
|
15
|
+
return scope.find("this").get();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function* ArrayExpression(node, scope) {
|
|
19
|
+
let results = [];
|
|
20
|
+
for (let i = 0; i < node.elements.length; i++) {
|
|
21
|
+
const item = node.elements[i];
|
|
22
|
+
if (item === null) {
|
|
23
|
+
results.length++;
|
|
24
|
+
} else if (item.type === "SpreadElement") {
|
|
25
|
+
results = results.concat(yield* SpreadElement(item, scope));
|
|
26
|
+
} else {
|
|
27
|
+
results.push(yield* evaluate(item, scope));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return results;
|
|
31
|
+
}
|
|
32
|
+
function* ObjectExpression(node, scope) {
|
|
33
|
+
const object = {};
|
|
34
|
+
for (let i = 0; i < node.properties.length; i++) {
|
|
35
|
+
const property = node.properties[i];
|
|
36
|
+
if (property.type === "SpreadElement") {
|
|
37
|
+
assign(object, yield* SpreadElement(property, scope, { spreadProps: true }));
|
|
38
|
+
} else {
|
|
39
|
+
let key;
|
|
40
|
+
const propKey = property.key;
|
|
41
|
+
if (property.computed) {
|
|
42
|
+
key = yield* evaluate(propKey, scope);
|
|
43
|
+
} else {
|
|
44
|
+
if (propKey.type === "Identifier") {
|
|
45
|
+
key = propKey.name;
|
|
46
|
+
} else {
|
|
47
|
+
key = "" + (yield* Literal(propKey));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const value = yield* evaluate(property.value, scope);
|
|
51
|
+
const propKind = property.kind;
|
|
52
|
+
if (propKind === "init") {
|
|
53
|
+
object[key] = value;
|
|
54
|
+
} else if (propKind === "get") {
|
|
55
|
+
const oriDptor = getDptor(object, key);
|
|
56
|
+
define(object, key, {
|
|
57
|
+
get: value,
|
|
58
|
+
set: oriDptor && oriDptor.set,
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true
|
|
61
|
+
});
|
|
62
|
+
} else {
|
|
63
|
+
const oriDptor = getDptor(object, key);
|
|
64
|
+
define(object, key, {
|
|
65
|
+
get: oriDptor && oriDptor.get,
|
|
66
|
+
set: value,
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return object;
|
|
74
|
+
}
|
|
75
|
+
function* FunctionExpression(node, scope) {
|
|
76
|
+
if (node.id && node.id.name) {
|
|
77
|
+
const tmpScope = new Scope(scope);
|
|
78
|
+
const func = createFunc(node, tmpScope);
|
|
79
|
+
tmpScope.const(node.id.name, func);
|
|
80
|
+
return func;
|
|
81
|
+
} else {
|
|
82
|
+
return createFunc(node, scope);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function* UnaryExpression(node, scope) {
|
|
86
|
+
const arg = node.argument;
|
|
87
|
+
switch (node.operator) {
|
|
88
|
+
case "+":
|
|
89
|
+
return +(yield* evaluate(arg, scope));
|
|
90
|
+
case "-":
|
|
91
|
+
return -(yield* evaluate(arg, scope));
|
|
92
|
+
case "!":
|
|
93
|
+
return !(yield* evaluate(arg, scope));
|
|
94
|
+
case "~":
|
|
95
|
+
return ~(yield* evaluate(arg, scope));
|
|
96
|
+
case "void":
|
|
97
|
+
return void (yield* evaluate(arg, scope));
|
|
98
|
+
case "typeof":
|
|
99
|
+
if (arg.type === "Identifier") {
|
|
100
|
+
return typeof (yield* Identifier(arg, scope, { throwErr: false }));
|
|
101
|
+
} else {
|
|
102
|
+
return typeof (yield* evaluate(arg, scope));
|
|
103
|
+
}
|
|
104
|
+
case "delete":
|
|
105
|
+
if (arg.type === "MemberExpression") {
|
|
106
|
+
const variable = yield* MemberExpression(arg, scope, { getVar: true });
|
|
107
|
+
return variable.del();
|
|
108
|
+
} else if (arg.type === "Identifier") {
|
|
109
|
+
throw new SyntaxError("Delete of an unqualified identifier in strict mode");
|
|
110
|
+
} else {
|
|
111
|
+
yield* evaluate(arg, scope);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/* istanbul ignore next */
|
|
115
|
+
default:
|
|
116
|
+
throw new SyntaxError(`Unexpected token ${node.operator}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function* UpdateExpression(node, scope) {
|
|
120
|
+
const arg = node.argument;
|
|
121
|
+
let variable;
|
|
122
|
+
if (arg.type === "Identifier") {
|
|
123
|
+
variable = yield* Identifier(arg, scope, { getVar: true });
|
|
124
|
+
} else if (arg.type === "MemberExpression") {
|
|
125
|
+
variable = yield* MemberExpression(arg, scope, { getVar: true });
|
|
126
|
+
} else {
|
|
127
|
+
throw new SyntaxError("Unexpected token");
|
|
128
|
+
}
|
|
129
|
+
const value = variable.get();
|
|
130
|
+
if (node.operator === "++") {
|
|
131
|
+
variable.set(value + 1);
|
|
132
|
+
return node.prefix ? variable.get() : value;
|
|
133
|
+
} else if (node.operator === "--") {
|
|
134
|
+
variable.set(value - 1);
|
|
135
|
+
return node.prefix ? variable.get() : value;
|
|
136
|
+
} else {
|
|
137
|
+
throw new SyntaxError(`Unexpected token ${node.operator}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function* BinaryExpression(node, scope) {
|
|
141
|
+
let left;
|
|
142
|
+
let right;
|
|
143
|
+
if (node.left.type === "PrivateIdentifier") {
|
|
144
|
+
left = node.left.name;
|
|
145
|
+
right = yield* evaluate(node.right, scope);
|
|
146
|
+
right = right[PRIVATE] || {};
|
|
147
|
+
} else {
|
|
148
|
+
left = yield* evaluate(node.left, scope);
|
|
149
|
+
right = yield* evaluate(node.right, scope);
|
|
150
|
+
}
|
|
151
|
+
switch (node.operator) {
|
|
152
|
+
case "==":
|
|
153
|
+
return left == right;
|
|
154
|
+
case "!=":
|
|
155
|
+
return left != right;
|
|
156
|
+
case "===":
|
|
157
|
+
return left === right;
|
|
158
|
+
case "!==":
|
|
159
|
+
return left !== right;
|
|
160
|
+
case "<":
|
|
161
|
+
return left < right;
|
|
162
|
+
case "<=":
|
|
163
|
+
return left <= right;
|
|
164
|
+
case ">":
|
|
165
|
+
return left > right;
|
|
166
|
+
case ">=":
|
|
167
|
+
return left >= right;
|
|
168
|
+
case "<<":
|
|
169
|
+
return left << right;
|
|
170
|
+
case ">>":
|
|
171
|
+
return left >> right;
|
|
172
|
+
case ">>>":
|
|
173
|
+
return left >>> right;
|
|
174
|
+
case "+":
|
|
175
|
+
return left + right;
|
|
176
|
+
case "-":
|
|
177
|
+
return left - right;
|
|
178
|
+
case "*":
|
|
179
|
+
return left * right;
|
|
180
|
+
case "**":
|
|
181
|
+
return left ** right;
|
|
182
|
+
case "/":
|
|
183
|
+
return left / right;
|
|
184
|
+
case "%":
|
|
185
|
+
return left % right;
|
|
186
|
+
case "|":
|
|
187
|
+
return left | right;
|
|
188
|
+
case "^":
|
|
189
|
+
return left ^ right;
|
|
190
|
+
case "&":
|
|
191
|
+
return left & right;
|
|
192
|
+
case "in":
|
|
193
|
+
return left in right;
|
|
194
|
+
case "instanceof":
|
|
195
|
+
return left instanceof right;
|
|
196
|
+
/* istanbul ignore next */
|
|
197
|
+
default:
|
|
198
|
+
throw new SyntaxError(`Unexpected token ${node.operator}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function* AssignmentExpression(node, scope) {
|
|
202
|
+
const left = node.left;
|
|
203
|
+
let variable;
|
|
204
|
+
if (left.type === "Identifier") {
|
|
205
|
+
variable = yield* Identifier(left, scope, { getVar: true, throwErr: false });
|
|
206
|
+
if (!variable) {
|
|
207
|
+
const strictMode = scope.find(STRICT);
|
|
208
|
+
if (strictMode && strictMode.get()) {
|
|
209
|
+
throw new ReferenceError(`${left.name} is not defined`);
|
|
210
|
+
}
|
|
211
|
+
const win = scope.global().find("window").get();
|
|
212
|
+
variable = new Prop(win, left.name);
|
|
213
|
+
}
|
|
214
|
+
} else if (left.type === "MemberExpression") {
|
|
215
|
+
variable = yield* MemberExpression(left, scope, { getVar: true });
|
|
216
|
+
} else {
|
|
217
|
+
const value2 = yield* evaluate(node.right, scope);
|
|
218
|
+
return yield* pattern(left, scope, { feed: value2 });
|
|
219
|
+
}
|
|
220
|
+
const value = yield* evaluate(node.right, scope);
|
|
221
|
+
switch (node.operator) {
|
|
222
|
+
case "=":
|
|
223
|
+
variable.set(value);
|
|
224
|
+
return variable.get();
|
|
225
|
+
case "+=":
|
|
226
|
+
variable.set(variable.get() + value);
|
|
227
|
+
return variable.get();
|
|
228
|
+
case "-=":
|
|
229
|
+
variable.set(variable.get() - value);
|
|
230
|
+
return variable.get();
|
|
231
|
+
case "*=":
|
|
232
|
+
variable.set(variable.get() * value);
|
|
233
|
+
return variable.get();
|
|
234
|
+
case "/=":
|
|
235
|
+
variable.set(variable.get() / value);
|
|
236
|
+
return variable.get();
|
|
237
|
+
case "%=":
|
|
238
|
+
variable.set(variable.get() % value);
|
|
239
|
+
return variable.get();
|
|
240
|
+
case "**=":
|
|
241
|
+
variable.set(variable.get() ** value);
|
|
242
|
+
return variable.get();
|
|
243
|
+
case "<<=":
|
|
244
|
+
variable.set(variable.get() << value);
|
|
245
|
+
return variable.get();
|
|
246
|
+
case ">>=":
|
|
247
|
+
variable.set(variable.get() >> value);
|
|
248
|
+
return variable.get();
|
|
249
|
+
case ">>>=":
|
|
250
|
+
variable.set(variable.get() >>> value);
|
|
251
|
+
return variable.get();
|
|
252
|
+
case "|=":
|
|
253
|
+
variable.set(variable.get() | value);
|
|
254
|
+
return variable.get();
|
|
255
|
+
case "^=":
|
|
256
|
+
variable.set(variable.get() ^ value);
|
|
257
|
+
return variable.get();
|
|
258
|
+
case "&=":
|
|
259
|
+
variable.set(variable.get() & value);
|
|
260
|
+
return variable.get();
|
|
261
|
+
case "??=":
|
|
262
|
+
variable.set(variable.get() ?? value);
|
|
263
|
+
return variable.get();
|
|
264
|
+
case "&&=":
|
|
265
|
+
variable.set(variable.get() && value);
|
|
266
|
+
return variable.get();
|
|
267
|
+
case "||=":
|
|
268
|
+
variable.set(variable.get() || value);
|
|
269
|
+
return variable.get();
|
|
270
|
+
/* istanbul ignore next */
|
|
271
|
+
default:
|
|
272
|
+
throw new SyntaxError(`Unexpected token ${node.operator}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function* LogicalExpression(node, scope) {
|
|
276
|
+
switch (node.operator) {
|
|
277
|
+
case "||":
|
|
278
|
+
return (yield* evaluate(node.left, scope)) || (yield* evaluate(node.right, scope));
|
|
279
|
+
case "&&":
|
|
280
|
+
return (yield* evaluate(node.left, scope)) && (yield* evaluate(node.right, scope));
|
|
281
|
+
case "??":
|
|
282
|
+
return (yield* evaluate(node.left, scope)) ?? (yield* evaluate(node.right, scope));
|
|
283
|
+
default:
|
|
284
|
+
throw new SyntaxError(`Unexpected token ${node.operator}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function* MemberExpression(node, scope, options = {}) {
|
|
288
|
+
const { getObj = false, getVar = false } = options;
|
|
289
|
+
let object;
|
|
290
|
+
if (node.object.type === "Super") {
|
|
291
|
+
object = yield* Super(node.object, scope, { getProto: true });
|
|
292
|
+
} else {
|
|
293
|
+
object = yield* evaluate(node.object, scope);
|
|
294
|
+
}
|
|
295
|
+
if (object === OPTCHAIN) return OPTCHAIN;
|
|
296
|
+
if (getObj) return object;
|
|
297
|
+
let key;
|
|
298
|
+
let priv = false;
|
|
299
|
+
if (node.computed) {
|
|
300
|
+
key = yield* evaluate(node.property, scope);
|
|
301
|
+
} else if (node.property.type === "PrivateIdentifier") {
|
|
302
|
+
key = node.property.name;
|
|
303
|
+
priv = true;
|
|
304
|
+
} else {
|
|
305
|
+
key = node.property.name;
|
|
306
|
+
}
|
|
307
|
+
if (priv) {
|
|
308
|
+
object = object[PRIVATE];
|
|
309
|
+
}
|
|
310
|
+
if (getVar) {
|
|
311
|
+
const setter = getSetter(object, key);
|
|
312
|
+
if (node.object.type === "Super" && setter) {
|
|
313
|
+
const thisObject = scope.find("this").get();
|
|
314
|
+
const privateKey = createSymbol(key);
|
|
315
|
+
define(thisObject, privateKey, { set: setter });
|
|
316
|
+
return new Prop(thisObject, privateKey);
|
|
317
|
+
} else {
|
|
318
|
+
return new Prop(object, key);
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
const getter = getGetter(object, key);
|
|
322
|
+
if (node.object.type === "Super" && getter) {
|
|
323
|
+
const thisObject = scope.find("this").get();
|
|
324
|
+
if (node.optional && thisObject == null) {
|
|
325
|
+
return OPTCHAIN;
|
|
326
|
+
}
|
|
327
|
+
return getter.call(thisObject);
|
|
328
|
+
} else {
|
|
329
|
+
if (node.optional && object == null) {
|
|
330
|
+
return OPTCHAIN;
|
|
331
|
+
}
|
|
332
|
+
return object[key];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function* ConditionalExpression(node, scope) {
|
|
337
|
+
return (yield* evaluate(node.test, scope)) ? yield* evaluate(node.consequent, scope) : yield* evaluate(node.alternate, scope);
|
|
338
|
+
}
|
|
339
|
+
function getCalleeDesc(node) {
|
|
340
|
+
if (node.type === "Identifier") {
|
|
341
|
+
return node.name;
|
|
342
|
+
} else if (node.type === "MemberExpression") {
|
|
343
|
+
const memberNode = node;
|
|
344
|
+
const objDesc = getCalleeDesc(memberNode.object);
|
|
345
|
+
if (!memberNode.computed) {
|
|
346
|
+
if (memberNode.property.type === "PrivateIdentifier") {
|
|
347
|
+
return `${objDesc}.#${memberNode.property.name}`;
|
|
348
|
+
}
|
|
349
|
+
return `${objDesc}.${memberNode.property.name}`;
|
|
350
|
+
}
|
|
351
|
+
const prop = memberNode.property;
|
|
352
|
+
if (prop.type === "Literal") {
|
|
353
|
+
return `${objDesc}[${prop.raw}]`;
|
|
354
|
+
}
|
|
355
|
+
if (prop.type === "Identifier") {
|
|
356
|
+
return `${objDesc}[${prop.name}]`;
|
|
357
|
+
}
|
|
358
|
+
return objDesc;
|
|
359
|
+
} else if (node.type === "Super") {
|
|
360
|
+
return "super";
|
|
361
|
+
}
|
|
362
|
+
return "(intermediate value)";
|
|
363
|
+
}
|
|
364
|
+
function* CallExpression(node, scope) {
|
|
365
|
+
let func;
|
|
366
|
+
let object;
|
|
367
|
+
if (node.callee.type === "MemberExpression") {
|
|
368
|
+
object = yield* MemberExpression(node.callee, scope, { getObj: true });
|
|
369
|
+
if (object === OPTCHAIN) return OPTCHAIN;
|
|
370
|
+
if (node.callee.optional && object == null) {
|
|
371
|
+
return OPTCHAIN;
|
|
372
|
+
}
|
|
373
|
+
let key;
|
|
374
|
+
let priv = false;
|
|
375
|
+
if (node.callee.computed) {
|
|
376
|
+
key = yield* evaluate(node.callee.property, scope);
|
|
377
|
+
} else if (node.callee.property.type === "PrivateIdentifier") {
|
|
378
|
+
key = node.callee.property.name;
|
|
379
|
+
priv = true;
|
|
380
|
+
} else {
|
|
381
|
+
key = node.callee.property.name;
|
|
382
|
+
}
|
|
383
|
+
let obj = object;
|
|
384
|
+
if (priv) {
|
|
385
|
+
obj = obj[PRIVATE];
|
|
386
|
+
}
|
|
387
|
+
if (node.callee.object.type === "Super") {
|
|
388
|
+
const thisObject = scope.find("this").get();
|
|
389
|
+
func = obj[key].bind(thisObject);
|
|
390
|
+
} else {
|
|
391
|
+
func = obj[key];
|
|
392
|
+
}
|
|
393
|
+
if (node.optional && func == null) {
|
|
394
|
+
return OPTCHAIN;
|
|
395
|
+
}
|
|
396
|
+
if (typeof func !== "function") {
|
|
397
|
+
const calleeDesc = getCalleeDesc(node.callee);
|
|
398
|
+
throw new TypeError(`${calleeDesc} is not a function`);
|
|
399
|
+
} else if (CLSCTOR in func) {
|
|
400
|
+
const calleeDesc = getCalleeDesc(node.callee);
|
|
401
|
+
throw new TypeError(`Class constructor ${calleeDesc} cannot be invoked without 'new'`);
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
func = yield* evaluate(node.callee, scope);
|
|
405
|
+
if (func === OPTCHAIN) return OPTCHAIN;
|
|
406
|
+
if (node.optional && func == null) {
|
|
407
|
+
return OPTCHAIN;
|
|
408
|
+
}
|
|
409
|
+
if (typeof func !== "function" || node.callee.type !== "Super" && CLSCTOR in func) {
|
|
410
|
+
let name;
|
|
411
|
+
if (node.callee.type === "Identifier") {
|
|
412
|
+
name = node.callee.name;
|
|
413
|
+
} else {
|
|
414
|
+
try {
|
|
415
|
+
name = JSON.stringify(func);
|
|
416
|
+
} catch (err) {
|
|
417
|
+
name = "" + func;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (typeof func !== "function") {
|
|
421
|
+
throw new TypeError(`${name} is not a function`);
|
|
422
|
+
} else {
|
|
423
|
+
throw new TypeError(`Class constructor ${name} cannot be invoked without 'new'`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (node.callee.type === "Super") {
|
|
427
|
+
object = scope.find("this").get();
|
|
428
|
+
} else {
|
|
429
|
+
const isStrictCall = !!scope.find(STRICT)?.get() || !!(func && func[STRICT_FN]);
|
|
430
|
+
object = isStrictCall ? void 0 : scope.find("this").get();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
let args = [];
|
|
434
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
435
|
+
const arg = node.arguments[i];
|
|
436
|
+
if (arg.type === "SpreadElement") {
|
|
437
|
+
args = args.concat(yield* SpreadElement(arg, scope));
|
|
438
|
+
} else {
|
|
439
|
+
args.push(yield* evaluate(arg, scope));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (node.callee.type === "Super") {
|
|
443
|
+
const superCall = scope.find(SUPERCALL);
|
|
444
|
+
const construct = superCall.get();
|
|
445
|
+
if (construct === true) {
|
|
446
|
+
throw new ReferenceError("Super constructor may only be called once");
|
|
447
|
+
}
|
|
448
|
+
const inst = callSuper(object, func, args);
|
|
449
|
+
yield* construct(inst);
|
|
450
|
+
scope.find("this").set(inst);
|
|
451
|
+
scope.find(SUPERCALL).set(true);
|
|
452
|
+
return inst;
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
return func.apply(object, args);
|
|
456
|
+
} catch (err) {
|
|
457
|
+
if (err instanceof TypeError && err.message === "Illegal invocation" && func.toString().indexOf("[native code]") !== -1) {
|
|
458
|
+
const win = scope.global().find("window").get();
|
|
459
|
+
if (win && win[WINDOW]) {
|
|
460
|
+
return func.apply(win[WINDOW], args);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
throw err;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function* NewExpression(node, scope) {
|
|
467
|
+
const constructor = yield* evaluate(node.callee, scope);
|
|
468
|
+
if (typeof constructor !== "function") {
|
|
469
|
+
let name;
|
|
470
|
+
if (node.callee.type === "Identifier") {
|
|
471
|
+
name = node.callee.name;
|
|
472
|
+
} else {
|
|
473
|
+
try {
|
|
474
|
+
name = JSON.stringify(constructor);
|
|
475
|
+
} catch (err) {
|
|
476
|
+
name = "" + constructor;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
throw new TypeError(`${name} is not a constructor`);
|
|
480
|
+
} else if (constructor[NOCTOR]) {
|
|
481
|
+
throw new TypeError(`${constructor.name || "(intermediate value)"} is not a constructor`);
|
|
482
|
+
}
|
|
483
|
+
let args = [];
|
|
484
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
485
|
+
const arg = node.arguments[i];
|
|
486
|
+
if (arg.type === "SpreadElement") {
|
|
487
|
+
args = args.concat(yield* SpreadElement(arg, scope));
|
|
488
|
+
} else {
|
|
489
|
+
args.push(yield* evaluate(arg, scope));
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return new constructor(...args);
|
|
493
|
+
}
|
|
494
|
+
function* MetaProperty(node, scope) {
|
|
495
|
+
if (node.meta.name === "new" && node.property.name === "target") {
|
|
496
|
+
return scope.find(NEWTARGET).get();
|
|
497
|
+
} else if (node.meta.name === "import" && node.property.name === "meta") {
|
|
498
|
+
return { url: "" };
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function* SequenceExpression(node, scope) {
|
|
502
|
+
let result;
|
|
503
|
+
for (let i = 0; i < node.expressions.length; i++) {
|
|
504
|
+
result = yield* evaluate(node.expressions[i], scope);
|
|
505
|
+
}
|
|
506
|
+
return result;
|
|
507
|
+
}
|
|
508
|
+
function* ArrowFunctionExpression(node, scope) {
|
|
509
|
+
return createFunc(node, scope);
|
|
510
|
+
}
|
|
511
|
+
function* TemplateLiteral(node, scope) {
|
|
512
|
+
const quasis = node.quasis.slice();
|
|
513
|
+
const expressions = node.expressions.slice();
|
|
514
|
+
let result = "";
|
|
515
|
+
let temEl;
|
|
516
|
+
let expr;
|
|
517
|
+
while (temEl = quasis.shift()) {
|
|
518
|
+
result += yield* TemplateElement(temEl);
|
|
519
|
+
expr = expressions.shift();
|
|
520
|
+
if (expr) {
|
|
521
|
+
result += yield* evaluate(expr, scope);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return result;
|
|
525
|
+
}
|
|
526
|
+
function* TaggedTemplateExpression(node, scope) {
|
|
527
|
+
const tagFunc = yield* evaluate(node.tag, scope);
|
|
528
|
+
const quasis = node.quasi.quasis;
|
|
529
|
+
const str = quasis.map((v) => v.value.cooked);
|
|
530
|
+
const raw = quasis.map((v) => v.value.raw);
|
|
531
|
+
define(str, "raw", {
|
|
532
|
+
value: freeze(raw)
|
|
533
|
+
});
|
|
534
|
+
const expressions = node.quasi.expressions;
|
|
535
|
+
const args = [];
|
|
536
|
+
if (expressions) {
|
|
537
|
+
for (let i = 0; i < expressions.length; i++) {
|
|
538
|
+
args.push(yield* evaluate(expressions[i], scope));
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return tagFunc(freeze(str), ...args);
|
|
542
|
+
}
|
|
543
|
+
function* TemplateElement(node, scope) {
|
|
544
|
+
return node.value.raw;
|
|
545
|
+
}
|
|
546
|
+
function* ClassExpression(node, scope) {
|
|
547
|
+
if (node.id && node.id.name) {
|
|
548
|
+
const tmpScope = new Scope(scope);
|
|
549
|
+
const klass = yield* createClass(node, tmpScope);
|
|
550
|
+
tmpScope.const(node.id.name, klass);
|
|
551
|
+
return klass;
|
|
552
|
+
} else {
|
|
553
|
+
return yield* createClass(node, scope);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function* Super(node, scope, options = {}) {
|
|
557
|
+
const { getProto = false } = options;
|
|
558
|
+
const superClass = scope.find(SUPER).get();
|
|
559
|
+
return getProto ? superClass.prototype : superClass;
|
|
560
|
+
}
|
|
561
|
+
function* SpreadElement(node, scope, options = {}) {
|
|
562
|
+
const result = yield* evaluate(node.argument, scope);
|
|
563
|
+
if (options.spreadProps) {
|
|
564
|
+
return result;
|
|
565
|
+
}
|
|
566
|
+
if (typeof Symbol === "function" && typeof result[Symbol.iterator] !== "function") {
|
|
567
|
+
throw new TypeError("Spread syntax requires ...iterable[Symbol.iterator] to be a function");
|
|
568
|
+
}
|
|
569
|
+
return [...result];
|
|
570
|
+
}
|
|
571
|
+
function* ChainExpression(node, scope) {
|
|
572
|
+
const result = yield* evaluate(node.expression, scope);
|
|
573
|
+
return result === OPTCHAIN ? void 0 : result;
|
|
574
|
+
}
|
|
575
|
+
function* ImportExpression(node, scope) {
|
|
576
|
+
const globalScope = scope.global();
|
|
577
|
+
const source = yield* evaluate(node.source, scope);
|
|
578
|
+
const module = globalScope.find(IMPORT + source);
|
|
579
|
+
let value;
|
|
580
|
+
if (module) {
|
|
581
|
+
const result = module.get();
|
|
582
|
+
if (result) {
|
|
583
|
+
if (typeof result === "function") {
|
|
584
|
+
value = result();
|
|
585
|
+
} else if (typeof result === "object") {
|
|
586
|
+
value = result;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (!value || typeof value !== "object") {
|
|
591
|
+
return Promise.reject(new TypeError(`Failed to resolve module specifier "${source}"`));
|
|
592
|
+
}
|
|
593
|
+
return Promise.resolve(value);
|
|
594
|
+
}
|
|
595
|
+
function* YieldExpression(node, scope) {
|
|
596
|
+
const res = yield* evaluate(node.argument, scope);
|
|
597
|
+
return node.delegate ? yield* res : yield res;
|
|
598
|
+
}
|
|
599
|
+
function* AwaitExpression(node, scope) {
|
|
600
|
+
AWAIT.RES = yield* evaluate(node.argument, scope);
|
|
601
|
+
return yield AWAIT;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
export { ArrayExpression, ArrowFunctionExpression, AssignmentExpression, AwaitExpression, BinaryExpression, CallExpression, ChainExpression, ClassExpression, ConditionalExpression, FunctionExpression, ImportExpression, LogicalExpression, MemberExpression, MetaProperty, NewExpression, ObjectExpression, SequenceExpression, SpreadElement, Super, TaggedTemplateExpression, TemplateElement, TemplateLiteral, ThisExpression, UnaryExpression, UpdateExpression, YieldExpression };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as Scope } from '../scope/index.ts';
|
|
2
|
+
import { PatternOptions } from './pattern.ts';
|
|
3
|
+
import * as acorn from 'acorn';
|
|
4
|
+
export interface hoistOptions {
|
|
5
|
+
onlyBlock?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function hoist(block: acorn.Program | acorn.BlockStatement | acorn.StaticBlock, scope: Scope, options?: hoistOptions): Generator<any, void, any>;
|
|
8
|
+
export declare function pattern(node: acorn.Pattern, scope: Scope, options?: PatternOptions): IterableIterator<any>;
|
|
9
|
+
export interface CtorOptions {
|
|
10
|
+
construct?: (object: any) => Generator | void;
|
|
11
|
+
superClass?: (...args: any[]) => any;
|
|
12
|
+
}
|
|
13
|
+
export declare function createFunc(node: acorn.FunctionDeclaration | acorn.FunctionExpression | acorn.ArrowFunctionExpression, scope: Scope, options?: CtorOptions): any;
|
|
14
|
+
export declare function createClass(node: acorn.ClassDeclaration | acorn.ClassExpression, scope: Scope): Generator<any, () => Generator<any, any, any>, any>;
|
|
15
|
+
export interface ForXHandlerOptions {
|
|
16
|
+
value: any;
|
|
17
|
+
}
|
|
18
|
+
export declare function ForXHandler(node: acorn.ForInStatement | acorn.ForOfStatement, scope: Scope, options: ForXHandlerOptions): Generator<any, any, any>;
|