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 | "use strict";
|
45 |
|
46 | (function() {
|
47 | var MOZ_TO_ME = {
|
48 | Program: function(M) {
|
49 | return new AST_Toplevel({
|
50 | start: my_start_token(M),
|
51 | end: my_end_token(M),
|
52 | body: normalize_directives(M.body.map(from_moz)),
|
53 | });
|
54 | },
|
55 | ArrowFunctionExpression: function(M) {
|
56 | var argnames = [], rest = null;
|
57 | M.params.forEach(function(param) {
|
58 | if (param.type == "RestElement") {
|
59 | rest = from_moz(param.argument);
|
60 | } else {
|
61 | argnames.push(from_moz(param));
|
62 | }
|
63 | });
|
64 | var fn = new (M.async ? AST_AsyncArrow : AST_Arrow)({
|
65 | start: my_start_token(M),
|
66 | end: my_end_token(M),
|
67 | argnames: argnames,
|
68 | rest: rest,
|
69 | });
|
70 | var node = from_moz(M.body);
|
71 | if (node instanceof AST_BlockStatement) {
|
72 | fn.body = normalize_directives(node.body);
|
73 | fn.value = null;
|
74 | } else {
|
75 | fn.body = [];
|
76 | fn.value = node;
|
77 | }
|
78 | return fn;
|
79 | },
|
80 | FunctionDeclaration: function(M) {
|
81 | var ctor;
|
82 | if (M.async) {
|
83 | ctor = M.generator ? AST_AsyncGeneratorDefun : AST_AsyncDefun;
|
84 | } else {
|
85 | ctor = M.generator ? AST_GeneratorDefun : AST_Defun;
|
86 | }
|
87 | var argnames = [], rest = null;
|
88 | M.params.forEach(function(param) {
|
89 | if (param.type == "RestElement") {
|
90 | rest = from_moz(param.argument);
|
91 | } else {
|
92 | argnames.push(from_moz(param));
|
93 | }
|
94 | });
|
95 | return new ctor({
|
96 | start: my_start_token(M),
|
97 | end: my_end_token(M),
|
98 | name: from_moz(M.id),
|
99 | argnames: argnames,
|
100 | rest: rest,
|
101 | body: normalize_directives(from_moz(M.body).body),
|
102 | });
|
103 | },
|
104 | FunctionExpression: function(M) {
|
105 | var ctor;
|
106 | if (M.async) {
|
107 | ctor = M.generator ? AST_AsyncGeneratorFunction : AST_AsyncFunction;
|
108 | } else {
|
109 | ctor = M.generator ? AST_GeneratorFunction : AST_Function;
|
110 | }
|
111 | var argnames = [], rest = null;
|
112 | M.params.forEach(function(param) {
|
113 | if (param.type == "RestElement") {
|
114 | rest = from_moz(param.argument);
|
115 | } else {
|
116 | argnames.push(from_moz(param));
|
117 | }
|
118 | });
|
119 | return new ctor({
|
120 | start: my_start_token(M),
|
121 | end: my_end_token(M),
|
122 | name: from_moz(M.id),
|
123 | argnames: argnames,
|
124 | rest: rest,
|
125 | body: normalize_directives(from_moz(M.body).body),
|
126 | });
|
127 | },
|
128 | ClassDeclaration: function(M) {
|
129 | return new AST_DefClass({
|
130 | start: my_start_token(M),
|
131 | end: my_end_token(M),
|
132 | name: from_moz(M.id),
|
133 | extends: from_moz(M.superClass),
|
134 | properties: M.body.body.map(from_moz),
|
135 | });
|
136 | },
|
137 | ClassExpression: function(M) {
|
138 | return new AST_ClassExpression({
|
139 | start: my_start_token(M),
|
140 | end: my_end_token(M),
|
141 | name: from_moz(M.id),
|
142 | extends: from_moz(M.superClass),
|
143 | properties: M.body.body.map(from_moz),
|
144 | });
|
145 | },
|
146 | MethodDefinition: function(M) {
|
147 | var key = M.key, internal = false;
|
148 | if (M.computed) {
|
149 | key = from_moz(key);
|
150 | } else if (key.type == "PrivateIdentifier") {
|
151 | internal = true;
|
152 | key = "#" + key.name;
|
153 | } else {
|
154 | key = read_name(key);
|
155 | }
|
156 | var ctor = AST_ClassMethod, value = from_moz(M.value);
|
157 | switch (M.kind) {
|
158 | case "get":
|
159 | ctor = AST_ClassGetter;
|
160 | value = new AST_Accessor(value);
|
161 | break;
|
162 | case "set":
|
163 | ctor = AST_ClassSetter;
|
164 | value = new AST_Accessor(value);
|
165 | break;
|
166 | }
|
167 | return new ctor({
|
168 | start: my_start_token(M),
|
169 | end: my_end_token(M),
|
170 | key: key,
|
171 | private: internal,
|
172 | static: M.static,
|
173 | value: value,
|
174 | });
|
175 | },
|
176 | PropertyDefinition: function(M) {
|
177 | var key = M.key, internal = false;
|
178 | if (M.computed) {
|
179 | key = from_moz(key);
|
180 | } else if (key.type == "PrivateIdentifier") {
|
181 | internal = true;
|
182 | key = "#" + key.name;
|
183 | } else {
|
184 | key = read_name(key);
|
185 | }
|
186 | return new AST_ClassField({
|
187 | start: my_start_token(M),
|
188 | end: my_end_token(M),
|
189 | key: key,
|
190 | private: internal,
|
191 | static: M.static,
|
192 | value: from_moz(M.value),
|
193 | });
|
194 | },
|
195 | ForOfStatement: function(M) {
|
196 | return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
197 | start: my_start_token(M),
|
198 | end: my_end_token(M),
|
199 | init: from_moz(M.left),
|
200 | object: from_moz(M.right),
|
201 | body: from_moz(M.body),
|
202 | });
|
203 | },
|
204 | TryStatement: function(M) {
|
205 | var handlers = M.handlers || [M.handler];
|
206 | if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
|
207 | throw new Error("Multiple catch clauses are not supported.");
|
208 | }
|
209 | return new AST_Try({
|
210 | start : my_start_token(M),
|
211 | end : my_end_token(M),
|
212 | body : from_moz(M.block).body,
|
213 | bcatch : from_moz(handlers[0]),
|
214 | bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null,
|
215 | });
|
216 | },
|
217 | Property: function(M) {
|
218 | var key = M.computed ? from_moz(M.key) : read_name(M.key);
|
219 | var args = {
|
220 | start: my_start_token(M),
|
221 | end: my_end_token(M),
|
222 | key: key,
|
223 | value: from_moz(M.value),
|
224 | };
|
225 | if (M.kind == "init") return new (M.method ? AST_ObjectMethod : AST_ObjectKeyVal)(args);
|
226 | args.value = new AST_Accessor(args.value);
|
227 | if (M.kind == "get") return new AST_ObjectGetter(args);
|
228 | if (M.kind == "set") return new AST_ObjectSetter(args);
|
229 | },
|
230 | ArrayExpression: function(M) {
|
231 | return new AST_Array({
|
232 | start: my_start_token(M),
|
233 | end: my_end_token(M),
|
234 | elements: M.elements.map(function(elem) {
|
235 | return elem === null ? new AST_Hole() : from_moz(elem);
|
236 | }),
|
237 | });
|
238 | },
|
239 | ArrayPattern: function(M) {
|
240 | var elements = [], rest = null;
|
241 | M.elements.forEach(function(el) {
|
242 | if (el === null) {
|
243 | elements.push(new AST_Hole());
|
244 | } else if (el.type == "RestElement") {
|
245 | rest = from_moz(el.argument);
|
246 | } else {
|
247 | elements.push(from_moz(el));
|
248 | }
|
249 | });
|
250 | return new AST_DestructuredArray({
|
251 | start: my_start_token(M),
|
252 | end: my_end_token(M),
|
253 | elements: elements,
|
254 | rest: rest,
|
255 | });
|
256 | },
|
257 | ObjectPattern: function(M) {
|
258 | var props = [], rest = null;
|
259 | M.properties.forEach(function(prop) {
|
260 | if (prop.type == "RestElement") {
|
261 | rest = from_moz(prop.argument);
|
262 | } else {
|
263 | props.push(new AST_DestructuredKeyVal(from_moz(prop)));
|
264 | }
|
265 | });
|
266 | return new AST_DestructuredObject({
|
267 | start: my_start_token(M),
|
268 | end: my_end_token(M),
|
269 | properties: props,
|
270 | rest: rest,
|
271 | });
|
272 | },
|
273 | MemberExpression: function(M) {
|
274 | return new (M.computed ? AST_Sub : AST_Dot)({
|
275 | start: my_start_token(M),
|
276 | end: my_end_token(M),
|
277 | optional: M.optional,
|
278 | expression: from_moz(M.object),
|
279 | property: M.computed ? from_moz(M.property) : M.property.name,
|
280 | });
|
281 | },
|
282 | MetaProperty: function(M) {
|
283 | var expr = from_moz(M.meta);
|
284 | var prop = read_name(M.property);
|
285 | if (expr.name == "new" && prop == "target") return new AST_NewTarget({
|
286 | start: my_start_token(M),
|
287 | end: my_end_token(M),
|
288 | name: "new.target",
|
289 | });
|
290 | return new AST_Dot({
|
291 | start: my_start_token(M),
|
292 | end: my_end_token(M),
|
293 | expression: expr,
|
294 | property: prop,
|
295 | });
|
296 | },
|
297 | SwitchCase: function(M) {
|
298 | return new (M.test ? AST_Case : AST_Default)({
|
299 | start : my_start_token(M),
|
300 | end : my_end_token(M),
|
301 | expression : from_moz(M.test),
|
302 | body : M.consequent.map(from_moz),
|
303 | });
|
304 | },
|
305 | ExportAllDeclaration: function(M) {
|
306 | var alias = M.exported ? read_name(M.exported) : "*";
|
307 | return new AST_ExportForeign({
|
308 | start: my_start_token(M),
|
309 | end: my_end_token(M),
|
310 | aliases: [ alias ],
|
311 | keys: [ "*" ],
|
312 | path: M.source.value,
|
313 | });
|
314 | },
|
315 | ExportDefaultDeclaration: function(M) {
|
316 | var decl = from_moz(M.declaration);
|
317 | if (!decl.name) switch (decl.CTOR) {
|
318 | case AST_AsyncDefun:
|
319 | decl = new AST_AsyncFunction(decl);
|
320 | break;
|
321 | case AST_AsyncGeneratorDefun:
|
322 | decl = new AST_AsyncGeneratorFunction(decl);
|
323 | break;
|
324 | case AST_DefClass:
|
325 | decl = new AST_ClassExpression(decl);
|
326 | break;
|
327 | case AST_Defun:
|
328 | decl = new AST_Function(decl);
|
329 | break;
|
330 | case AST_GeneratorDefun:
|
331 | decl = new AST_GeneratorFunction(decl);
|
332 | break;
|
333 | }
|
334 | return new AST_ExportDefault({
|
335 | start: my_start_token(M),
|
336 | end: my_end_token(M),
|
337 | body: decl,
|
338 | });
|
339 | },
|
340 | ExportNamedDeclaration: function(M) {
|
341 | if (M.declaration) return new AST_ExportDeclaration({
|
342 | start: my_start_token(M),
|
343 | end: my_end_token(M),
|
344 | body: from_moz(M.declaration),
|
345 | });
|
346 | if (M.source) {
|
347 | var aliases = [], keys = [];
|
348 | M.specifiers.forEach(function(prop) {
|
349 | aliases.push(read_name(prop.exported));
|
350 | keys.push(read_name(prop.local));
|
351 | });
|
352 | return new AST_ExportForeign({
|
353 | start: my_start_token(M),
|
354 | end: my_end_token(M),
|
355 | aliases: aliases,
|
356 | keys: keys,
|
357 | path: M.source.value,
|
358 | });
|
359 | }
|
360 | return new AST_ExportReferences({
|
361 | start: my_start_token(M),
|
362 | end: my_end_token(M),
|
363 | properties: M.specifiers.map(function(prop) {
|
364 | var sym = new AST_SymbolExport(from_moz(prop.local));
|
365 | sym.alias = read_name(prop.exported);
|
366 | return sym;
|
367 | }),
|
368 | });
|
369 | },
|
370 | ImportDeclaration: function(M) {
|
371 | var all = null, def = null, props = null;
|
372 | M.specifiers.forEach(function(prop) {
|
373 | var sym = new AST_SymbolImport(from_moz(prop.local));
|
374 | switch (prop.type) {
|
375 | case "ImportDefaultSpecifier":
|
376 | def = sym;
|
377 | def.key = "";
|
378 | break;
|
379 | case "ImportNamespaceSpecifier":
|
380 | all = sym;
|
381 | all.key = "*";
|
382 | break;
|
383 | default:
|
384 | sym.key = prop.imported.name || syn.name;
|
385 | if (!props) props = [];
|
386 | props.push(sym);
|
387 | break;
|
388 | }
|
389 | });
|
390 | return new AST_Import({
|
391 | start: my_start_token(M),
|
392 | end: my_end_token(M),
|
393 | all: all,
|
394 | default: def,
|
395 | properties: props,
|
396 | path: M.source.value,
|
397 | });
|
398 | },
|
399 | ImportExpression: function(M) {
|
400 | var start = my_start_token(M);
|
401 | var arg = from_moz(M.source);
|
402 | return new AST_Call({
|
403 | start: start,
|
404 | end: my_end_token(M),
|
405 | expression: new AST_SymbolRef({
|
406 | start: start,
|
407 | end: arg.start,
|
408 | name: "import",
|
409 | }),
|
410 | args: [ arg ],
|
411 | });
|
412 | },
|
413 | VariableDeclaration: function(M) {
|
414 | return new ({
|
415 | const: AST_Const,
|
416 | let: AST_Let,
|
417 | }[M.kind] || AST_Var)({
|
418 | start: my_start_token(M),
|
419 | end: my_end_token(M),
|
420 | definitions: M.declarations.map(from_moz),
|
421 | });
|
422 | },
|
423 | Literal: function(M) {
|
424 | var args = {
|
425 | start: my_start_token(M),
|
426 | end: my_end_token(M),
|
427 | };
|
428 | if (M.bigint) {
|
429 | args.value = M.bigint.toLowerCase() + "n";
|
430 | return new AST_BigInt(args);
|
431 | }
|
432 | var val = M.value;
|
433 | if (val === null) return new AST_Null(args);
|
434 | var rx = M.regex;
|
435 | if (rx && rx.pattern) {
|
436 |
|
437 | args.value = new RegExp(rx.pattern, rx.flags);
|
438 | args.value.raw_source = rx.pattern;
|
439 | return new AST_RegExp(args);
|
440 | } else if (rx) {
|
441 |
|
442 | args.value = M.regex && M.raw ? M.raw : val;
|
443 | return new AST_RegExp(args);
|
444 | }
|
445 | switch (typeof val) {
|
446 | case "string":
|
447 | args.value = val;
|
448 | return new AST_String(args);
|
449 | case "number":
|
450 | if (isNaN(val)) return new AST_NaN(args);
|
451 | var negate, node;
|
452 | if (isFinite(val)) {
|
453 | negate = 1 / val < 0;
|
454 | args.value = negate ? -val : val;
|
455 | node = new AST_Number(args);
|
456 | } else {
|
457 | negate = val < 0;
|
458 | node = new AST_Infinity(args);
|
459 | }
|
460 | return negate ? new AST_UnaryPrefix({
|
461 | start: args.start,
|
462 | end: args.end,
|
463 | operator: "-",
|
464 | expression: node,
|
465 | }) : node;
|
466 | case "boolean":
|
467 | return new (val ? AST_True : AST_False)(args);
|
468 | }
|
469 | },
|
470 | TemplateLiteral: function(M) {
|
471 | return new AST_Template({
|
472 | start: my_start_token(M),
|
473 | end: my_end_token(M),
|
474 | expressions: M.expressions.map(from_moz),
|
475 | strings: M.quasis.map(function(el) {
|
476 | return el.value.raw;
|
477 | }),
|
478 | });
|
479 | },
|
480 | TaggedTemplateExpression: function(M) {
|
481 | var tmpl = from_moz(M.quasi);
|
482 | tmpl.start = my_start_token(M);
|
483 | tmpl.end = my_end_token(M);
|
484 | tmpl.tag = from_moz(M.tag);
|
485 | return tmpl;
|
486 | },
|
487 | Identifier: function(M) {
|
488 | var p, level = FROM_MOZ_STACK.length - 1;
|
489 | do {
|
490 | p = FROM_MOZ_STACK[--level];
|
491 | } while (p.type == "ArrayPattern"
|
492 | || p.type == "AssignmentPattern" && p.left === FROM_MOZ_STACK[level + 1]
|
493 | || p.type == "ObjectPattern"
|
494 | || p.type == "Property" && p.value === FROM_MOZ_STACK[level + 1]
|
495 | || p.type == "VariableDeclarator" && p.id === FROM_MOZ_STACK[level + 1]);
|
496 | var ctor = AST_SymbolRef;
|
497 | switch (p.type) {
|
498 | case "ArrowFunctionExpression":
|
499 | if (p.body !== FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolFunarg;
|
500 | break;
|
501 | case "BreakStatement":
|
502 | case "ContinueStatement":
|
503 | ctor = AST_LabelRef;
|
504 | break;
|
505 | case "CatchClause":
|
506 | ctor = AST_SymbolCatch;
|
507 | break;
|
508 | case "ClassDeclaration":
|
509 | if (p.id === FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolDefClass;
|
510 | break;
|
511 | case "ClassExpression":
|
512 | if (p.id === FROM_MOZ_STACK[level + 1]) ctor = AST_SymbolClass;
|
513 | break;
|
514 | case "FunctionDeclaration":
|
515 | ctor = p.id === FROM_MOZ_STACK[level + 1] ? AST_SymbolDefun : AST_SymbolFunarg;
|
516 | break;
|
517 | case "FunctionExpression":
|
518 | ctor = p.id === FROM_MOZ_STACK[level + 1] ? AST_SymbolLambda : AST_SymbolFunarg;
|
519 | break;
|
520 | case "LabeledStatement":
|
521 | ctor = AST_Label;
|
522 | break;
|
523 | case "VariableDeclaration":
|
524 | ctor = {
|
525 | const: AST_SymbolConst,
|
526 | let: AST_SymbolLet,
|
527 | }[p.kind] || AST_SymbolVar;
|
528 | break;
|
529 | }
|
530 | return new ctor({
|
531 | start: my_start_token(M),
|
532 | end: my_end_token(M),
|
533 | name: M.name,
|
534 | });
|
535 | },
|
536 | Super: function(M) {
|
537 | return new AST_Super({
|
538 | start: my_start_token(M),
|
539 | end: my_end_token(M),
|
540 | name: "super",
|
541 | });
|
542 | },
|
543 | ThisExpression: function(M) {
|
544 | return new AST_This({
|
545 | start: my_start_token(M),
|
546 | end: my_end_token(M),
|
547 | name: "this",
|
548 | });
|
549 | },
|
550 | ParenthesizedExpression: function(M) {
|
551 | var node = from_moz(M.expression);
|
552 | if (!node.start.parens) node.start.parens = [];
|
553 | node.start.parens.push(my_start_token(M));
|
554 | if (!node.end.parens) node.end.parens = [];
|
555 | node.end.parens.push(my_end_token(M));
|
556 | return node;
|
557 | },
|
558 | ChainExpression: function(M) {
|
559 | var node = from_moz(M.expression);
|
560 | node.terminal = true;
|
561 | return node;
|
562 | },
|
563 | };
|
564 |
|
565 | MOZ_TO_ME.UpdateExpression =
|
566 | MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
|
567 | var prefix = "prefix" in M ? M.prefix
|
568 | : M.type == "UnaryExpression" ? true : false;
|
569 | return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
|
570 | start : my_start_token(M),
|
571 | end : my_end_token(M),
|
572 | operator : M.operator,
|
573 | expression : from_moz(M.argument)
|
574 | });
|
575 | };
|
576 |
|
577 | map("EmptyStatement", AST_EmptyStatement);
|
578 | map("ExpressionStatement", AST_SimpleStatement, "expression>body");
|
579 | map("BlockStatement", AST_BlockStatement, "body@body");
|
580 | map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
|
581 | map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
|
582 | map("BreakStatement", AST_Break, "label>label");
|
583 | map("ContinueStatement", AST_Continue, "label>label");
|
584 | map("WithStatement", AST_With, "object>expression, body>body");
|
585 | map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
|
586 | map("ReturnStatement", AST_Return, "argument>value");
|
587 | map("ThrowStatement", AST_Throw, "argument>value");
|
588 | map("WhileStatement", AST_While, "test>condition, body>body");
|
589 | map("DoWhileStatement", AST_Do, "test>condition, body>body");
|
590 | map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
|
591 | map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
|
592 | map("DebuggerStatement", AST_Debugger);
|
593 | map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
594 | map("CatchClause", AST_Catch, "param>argname, body%body");
|
595 |
|
596 | map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
597 | map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
598 | map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
599 | map("AssignmentPattern", AST_DefaultValue, "left>name, right>value");
|
600 | map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
601 | map("NewExpression", AST_New, "callee>expression, arguments@args, pure=pure");
|
602 | map("CallExpression", AST_Call, "callee>expression, arguments@args, optional=optional, pure=pure");
|
603 | map("SequenceExpression", AST_Sequence, "expressions@expressions");
|
604 | map("SpreadElement", AST_Spread, "argument>expression");
|
605 | map("ObjectExpression", AST_Object, "properties@properties");
|
606 | map("AwaitExpression", AST_Await, "argument>expression");
|
607 | map("YieldExpression", AST_Yield, "argument>expression, delegate=nested");
|
608 |
|
609 | def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
610 | return to_moz_scope("Program", M);
|
611 | });
|
612 |
|
613 | def_to_moz(AST_LambdaDefinition, function To_Moz_FunctionDeclaration(M) {
|
614 | var params = M.argnames.map(to_moz);
|
615 | if (M.rest) params.push({
|
616 | type: "RestElement",
|
617 | argument: to_moz(M.rest),
|
618 | });
|
619 | return {
|
620 | type: "FunctionDeclaration",
|
621 | id: to_moz(M.name),
|
622 | async: is_async(M),
|
623 | generator: is_generator(M),
|
624 | params: params,
|
625 | body: to_moz_scope("BlockStatement", M),
|
626 | };
|
627 | });
|
628 |
|
629 | def_to_moz(AST_Lambda, function To_Moz_FunctionExpression(M) {
|
630 | var params = M.argnames.map(to_moz);
|
631 | if (M.rest) params.push({
|
632 | type: "RestElement",
|
633 | argument: to_moz(M.rest),
|
634 | });
|
635 | if (is_arrow(M)) return {
|
636 | type: "ArrowFunctionExpression",
|
637 | async: is_async(M),
|
638 | params: params,
|
639 | body: M.value ? to_moz(M.value) : to_moz_scope("BlockStatement", M),
|
640 | };
|
641 | return {
|
642 | type: "FunctionExpression",
|
643 | id: to_moz(M.name),
|
644 | async: is_async(M),
|
645 | generator: is_generator(M),
|
646 | params: params,
|
647 | body: to_moz_scope("BlockStatement", M),
|
648 | };
|
649 | });
|
650 |
|
651 | def_to_moz(AST_DefClass, function To_Moz_ClassDeclaration(M) {
|
652 | return {
|
653 | type: "ClassDeclaration",
|
654 | id: to_moz(M.name),
|
655 | superClass: to_moz(M.extends),
|
656 | body: {
|
657 | type: "ClassBody",
|
658 | body: M.properties.map(to_moz),
|
659 | },
|
660 | };
|
661 | });
|
662 |
|
663 | def_to_moz(AST_ClassExpression, function To_Moz_ClassExpression(M) {
|
664 | return {
|
665 | type: "ClassExpression",
|
666 | id: to_moz(M.name),
|
667 | superClass: to_moz(M.extends),
|
668 | body: {
|
669 | type: "ClassBody",
|
670 | body: M.properties.map(to_moz),
|
671 | },
|
672 | };
|
673 | });
|
674 |
|
675 | function To_Moz_MethodDefinition(kind) {
|
676 | return function(M) {
|
677 | var computed = M.key instanceof AST_Node;
|
678 | var key = computed ? to_moz(M.key) : M.private ? {
|
679 | type: "PrivateIdentifier",
|
680 | name: M.key.slice(1),
|
681 | } : {
|
682 | type: "Literal",
|
683 | value: M.key,
|
684 | };
|
685 | return {
|
686 | type: "MethodDefinition",
|
687 | kind: kind,
|
688 | computed: computed,
|
689 | key: key,
|
690 | static: M.static,
|
691 | value: to_moz(M.value),
|
692 | };
|
693 | };
|
694 | }
|
695 | def_to_moz(AST_ClassGetter, To_Moz_MethodDefinition("get"));
|
696 | def_to_moz(AST_ClassSetter, To_Moz_MethodDefinition("set"));
|
697 | def_to_moz(AST_ClassMethod, To_Moz_MethodDefinition("method"));
|
698 |
|
699 | def_to_moz(AST_ClassField, function To_Moz_PropertyDefinition(M) {
|
700 | var computed = M.key instanceof AST_Node;
|
701 | var key = computed ? to_moz(M.key) : M.private ? {
|
702 | type: "PrivateIdentifier",
|
703 | name: M.key.slice(1),
|
704 | } : {
|
705 | type: "Literal",
|
706 | value: M.key,
|
707 | };
|
708 | return {
|
709 | type: "PropertyDefinition",
|
710 | computed: computed,
|
711 | key: key,
|
712 | static: M.static,
|
713 | value: to_moz(M.value),
|
714 | };
|
715 | });
|
716 |
|
717 | function To_Moz_ForOfStatement(is_await) {
|
718 | return function(M) {
|
719 | return {
|
720 | type: "ForOfStatement",
|
721 | await: is_await,
|
722 | left: to_moz(M.init),
|
723 | right: to_moz(M.object),
|
724 | body: to_moz(M.body),
|
725 | };
|
726 | };
|
727 | }
|
728 | def_to_moz(AST_ForAwaitOf, To_Moz_ForOfStatement(true));
|
729 | def_to_moz(AST_ForOf, To_Moz_ForOfStatement(false));
|
730 |
|
731 | def_to_moz(AST_Directive, function To_Moz_Directive(M) {
|
732 | return {
|
733 | type: "ExpressionStatement",
|
734 | expression: set_moz_loc(M, {
|
735 | type: "Literal",
|
736 | value: M.value,
|
737 | }),
|
738 | };
|
739 | });
|
740 |
|
741 | def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
|
742 | return {
|
743 | type: "SwitchCase",
|
744 | test: to_moz(M.expression),
|
745 | consequent: M.body.map(to_moz),
|
746 | };
|
747 | });
|
748 |
|
749 | def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
|
750 | return {
|
751 | type: "TryStatement",
|
752 | block: to_moz_block(M),
|
753 | handler: to_moz(M.bcatch),
|
754 | guardedHandlers: [],
|
755 | finalizer: to_moz(M.bfinally),
|
756 | };
|
757 | });
|
758 |
|
759 | def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
|
760 | return {
|
761 | type: "CatchClause",
|
762 | param: to_moz(M.argname),
|
763 | guard: null,
|
764 | body: to_moz_block(M),
|
765 | };
|
766 | });
|
767 |
|
768 | def_to_moz(AST_ExportDeclaration, function To_Moz_ExportNamedDeclaration_declaration(M) {
|
769 | return {
|
770 | type: "ExportNamedDeclaration",
|
771 | declaration: to_moz(M.body),
|
772 | };
|
773 | });
|
774 |
|
775 | def_to_moz(AST_ExportDefault, function To_Moz_ExportDefaultDeclaration(M) {
|
776 | return {
|
777 | type: "ExportDefaultDeclaration",
|
778 | declaration: to_moz(M.body),
|
779 | };
|
780 | });
|
781 |
|
782 | def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
783 | if (M.keys[0] == "*") return {
|
784 | type: "ExportAllDeclaration",
|
785 | exported: M.aliases[0] == "*" ? null : {
|
786 | type: "Identifier",
|
787 | name: M.aliases[0],
|
788 | },
|
789 | source: {
|
790 | type: "Literal",
|
791 | value: M.path,
|
792 | },
|
793 | };
|
794 | var specifiers = [];
|
795 | for (var i = 0; i < M.aliases.length; i++) {
|
796 | specifiers.push({
|
797 | type: "ExportSpecifier",
|
798 | exported: {
|
799 | type: "Identifier",
|
800 | name: M.aliases[i],
|
801 | },
|
802 | local: {
|
803 | type: "Identifier",
|
804 | name: M.keys[i],
|
805 | },
|
806 | });
|
807 | }
|
808 | return {
|
809 | type: "ExportNamedDeclaration",
|
810 | specifiers: specifiers,
|
811 | source: {
|
812 | type: "Literal",
|
813 | value: M.path,
|
814 | },
|
815 | };
|
816 | });
|
817 |
|
818 | def_to_moz(AST_ExportReferences, function To_Moz_ExportNamedDeclaration_specifiers(M) {
|
819 | return {
|
820 | type: "ExportNamedDeclaration",
|
821 | specifiers: M.properties.map(function(prop) {
|
822 | return {
|
823 | type: "ExportSpecifier",
|
824 | local: to_moz(prop),
|
825 | exported: {
|
826 | type: "Identifier",
|
827 | name: prop.alias,
|
828 | },
|
829 | };
|
830 | }),
|
831 | };
|
832 | });
|
833 |
|
834 | def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
835 | var specifiers = M.properties ? M.properties.map(function(prop) {
|
836 | return {
|
837 | type: "ImportSpecifier",
|
838 | local: to_moz(prop),
|
839 | imported: {
|
840 | type: "Identifier",
|
841 | name: prop.key,
|
842 | },
|
843 | };
|
844 | }) : [];
|
845 | if (M.all) specifiers.unshift({
|
846 | type: "ImportNamespaceSpecifier",
|
847 | local: to_moz(M.all),
|
848 | });
|
849 | if (M.default) specifiers.unshift({
|
850 | type: "ImportDefaultSpecifier",
|
851 | local: to_moz(M.default),
|
852 | });
|
853 | return {
|
854 | type: "ImportDeclaration",
|
855 | specifiers: specifiers,
|
856 | source: {
|
857 | type: "Literal",
|
858 | value: M.path,
|
859 | },
|
860 | };
|
861 | });
|
862 |
|
863 | def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
864 | return {
|
865 | type: "VariableDeclaration",
|
866 | kind: M.TYPE.toLowerCase(),
|
867 | declarations: M.definitions.map(to_moz),
|
868 | };
|
869 | });
|
870 |
|
871 | def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
|
872 | var computed = M instanceof AST_Sub;
|
873 | var expr = {
|
874 | type: "MemberExpression",
|
875 | object: to_moz(M.expression),
|
876 | computed: computed,
|
877 | optional: M.optional,
|
878 | property: computed ? to_moz(M.property) : {
|
879 | type: "Identifier",
|
880 | name: M.property,
|
881 | },
|
882 | };
|
883 | return M.terminal ? {
|
884 | type: "ChainExpression",
|
885 | expression: expr,
|
886 | } : expr;
|
887 | });
|
888 |
|
889 | def_to_moz(AST_Unary, function To_Moz_Unary(M) {
|
890 | return {
|
891 | type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
|
892 | operator: M.operator,
|
893 | prefix: M instanceof AST_UnaryPrefix,
|
894 | argument: to_moz(M.expression)
|
895 | };
|
896 | });
|
897 |
|
898 | def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
|
899 | return {
|
900 | type: M.operator == "&&" || M.operator == "||" ? "LogicalExpression" : "BinaryExpression",
|
901 | left: to_moz(M.left),
|
902 | operator: M.operator,
|
903 | right: to_moz(M.right)
|
904 | };
|
905 | });
|
906 |
|
907 | def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
|
908 | return {
|
909 | type: "ArrayExpression",
|
910 | elements: M.elements.map(to_moz),
|
911 | };
|
912 | });
|
913 |
|
914 | def_to_moz(AST_DestructuredArray, function To_Moz_ArrayPattern(M) {
|
915 | var elements = M.elements.map(to_moz);
|
916 | if (M.rest) elements.push({
|
917 | type: "RestElement",
|
918 | argument: to_moz(M.rest),
|
919 | });
|
920 | return {
|
921 | type: "ArrayPattern",
|
922 | elements: elements,
|
923 | };
|
924 | });
|
925 |
|
926 | def_to_moz(AST_DestructuredKeyVal, function To_Moz_Property(M) {
|
927 | var computed = M.key instanceof AST_Node;
|
928 | var key = computed ? to_moz(M.key) : {
|
929 | type: "Literal",
|
930 | value: M.key,
|
931 | };
|
932 | return {
|
933 | type: "Property",
|
934 | kind: "init",
|
935 | computed: computed,
|
936 | key: key,
|
937 | value: to_moz(M.value),
|
938 | };
|
939 | });
|
940 |
|
941 | def_to_moz(AST_DestructuredObject, function To_Moz_ObjectPattern(M) {
|
942 | var props = M.properties.map(to_moz);
|
943 | if (M.rest) props.push({
|
944 | type: "RestElement",
|
945 | argument: to_moz(M.rest),
|
946 | });
|
947 | return {
|
948 | type: "ObjectPattern",
|
949 | properties: props,
|
950 | };
|
951 | });
|
952 |
|
953 | def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
954 | var computed = M.key instanceof AST_Node;
|
955 | var key = computed ? to_moz(M.key) : {
|
956 | type: "Literal",
|
957 | value: M.key,
|
958 | };
|
959 | var kind;
|
960 | if (M instanceof AST_ObjectKeyVal) {
|
961 | kind = "init";
|
962 | } else if (M instanceof AST_ObjectGetter) {
|
963 | kind = "get";
|
964 | } else if (M instanceof AST_ObjectSetter) {
|
965 | kind = "set";
|
966 | }
|
967 | return {
|
968 | type: "Property",
|
969 | kind: kind,
|
970 | computed: computed,
|
971 | method: M instanceof AST_ObjectMethod,
|
972 | key: key,
|
973 | value: to_moz(M.value),
|
974 | };
|
975 | });
|
976 |
|
977 | def_to_moz(AST_Symbol, function To_Moz_Identifier(M) {
|
978 | var def = M.definition();
|
979 | return {
|
980 | type: "Identifier",
|
981 | name: def && def.mangled_name || M.name,
|
982 | };
|
983 | });
|
984 |
|
985 | def_to_moz(AST_Super, function To_Moz_Super() {
|
986 | return { type: "Super" };
|
987 | });
|
988 |
|
989 | def_to_moz(AST_This, function To_Moz_ThisExpression() {
|
990 | return { type: "ThisExpression" };
|
991 | });
|
992 |
|
993 | def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
|
994 | return {
|
995 | type: "MetaProperty",
|
996 | meta: {
|
997 | type: "Identifier",
|
998 | name: "new",
|
999 | },
|
1000 | property: {
|
1001 | type: "Identifier",
|
1002 | name: "target",
|
1003 | },
|
1004 | };
|
1005 | });
|
1006 |
|
1007 | def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
1008 | var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
1009 | var value = "/" + M.value.raw_source + "/" + flags;
|
1010 | return {
|
1011 | type: "Literal",
|
1012 | value: value,
|
1013 | raw: value,
|
1014 | regex: {
|
1015 | pattern: M.value.raw_source,
|
1016 | flags: flags
|
1017 | }
|
1018 | };
|
1019 | });
|
1020 |
|
1021 | def_to_moz(AST_BigInt, function To_Moz_BigInt(M) {
|
1022 | var value = M.value;
|
1023 | return {
|
1024 | type: "Literal",
|
1025 | bigint: value.slice(0, -1),
|
1026 | raw: value,
|
1027 | };
|
1028 | });
|
1029 |
|
1030 | function To_Moz_Literal(M) {
|
1031 | var value = M.value;
|
1032 | if (typeof value === "number" && (value < 0 || (value === 0 && 1 / value < 0))) {
|
1033 | return {
|
1034 | type: "UnaryExpression",
|
1035 | operator: "-",
|
1036 | prefix: true,
|
1037 | argument: {
|
1038 | type: "Literal",
|
1039 | value: -value,
|
1040 | raw: M.start.raw,
|
1041 | },
|
1042 | };
|
1043 | }
|
1044 | return {
|
1045 | type: "Literal",
|
1046 | value: value,
|
1047 | raw: M.start.raw,
|
1048 | };
|
1049 | }
|
1050 | def_to_moz(AST_Boolean, To_Moz_Literal);
|
1051 | def_to_moz(AST_Constant, To_Moz_Literal);
|
1052 | def_to_moz(AST_Null, To_Moz_Literal);
|
1053 |
|
1054 | def_to_moz(AST_Atom, function To_Moz_Atom(M) {
|
1055 | return {
|
1056 | type: "Identifier",
|
1057 | name: String(M.value),
|
1058 | };
|
1059 | });
|
1060 |
|
1061 | def_to_moz(AST_Template, function To_Moz_TemplateLiteral_TaggedTemplateExpression(M) {
|
1062 | var last = M.strings.length - 1;
|
1063 | var tmpl = {
|
1064 | type: "TemplateLiteral",
|
1065 | expressions: M.expressions.map(to_moz),
|
1066 | quasis: M.strings.map(function(str, index) {
|
1067 | return {
|
1068 | type: "TemplateElement",
|
1069 | tail: index == last,
|
1070 | value: { raw: str },
|
1071 | };
|
1072 | }),
|
1073 | };
|
1074 | if (!M.tag) return tmpl;
|
1075 | return {
|
1076 | type: "TaggedTemplateExpression",
|
1077 | tag: to_moz(M.tag),
|
1078 | quasi: tmpl,
|
1079 | };
|
1080 | });
|
1081 |
|
1082 | AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
|
1083 | AST_Hole.DEFMETHOD("to_mozilla_ast", return_null);
|
1084 | AST_Node.DEFMETHOD("to_mozilla_ast", function() {
|
1085 | throw new Error("Cannot convert AST_" + this.TYPE);
|
1086 | });
|
1087 |
|
1088 |
|
1089 |
|
1090 | function normalize_directives(body) {
|
1091 | for (var i = 0; i < body.length; i++) {
|
1092 | var stat = body[i];
|
1093 | if (!(stat instanceof AST_SimpleStatement)) break;
|
1094 | var node = stat.body;
|
1095 | if (!(node instanceof AST_String)) break;
|
1096 | if (stat.start.pos !== node.start.pos) break;
|
1097 | body[i] = new AST_Directive(node);
|
1098 | }
|
1099 | return body;
|
1100 | }
|
1101 |
|
1102 | function raw_token(moznode) {
|
1103 | if (moznode.type == "Literal") {
|
1104 | return moznode.raw != null ? moznode.raw : moznode.value + "";
|
1105 | }
|
1106 | }
|
1107 |
|
1108 | function my_start_token(moznode) {
|
1109 | var loc = moznode.loc, start = loc && loc.start;
|
1110 | var range = moznode.range;
|
1111 | return new AST_Token({
|
1112 | file : loc && loc.source,
|
1113 | line : start && start.line,
|
1114 | col : start && start.column,
|
1115 | pos : range ? range[0] : moznode.start,
|
1116 | endline : start && start.line,
|
1117 | endcol : start && start.column,
|
1118 | endpos : range ? range[0] : moznode.start,
|
1119 | raw : raw_token(moznode),
|
1120 | });
|
1121 | }
|
1122 |
|
1123 | function my_end_token(moznode) {
|
1124 | var loc = moznode.loc, end = loc && loc.end;
|
1125 | var range = moznode.range;
|
1126 | return new AST_Token({
|
1127 | file : loc && loc.source,
|
1128 | line : end && end.line,
|
1129 | col : end && end.column,
|
1130 | pos : range ? range[1] : moznode.end,
|
1131 | endline : end && end.line,
|
1132 | endcol : end && end.column,
|
1133 | endpos : range ? range[1] : moznode.end,
|
1134 | raw : raw_token(moznode),
|
1135 | });
|
1136 | }
|
1137 |
|
1138 | function read_name(M) {
|
1139 | return "" + M[M.type == "Identifier" ? "name" : "value"];
|
1140 | }
|
1141 |
|
1142 | function map(moztype, mytype, propmap) {
|
1143 | var moz_to_me = [
|
1144 | "start: my_start_token(M)",
|
1145 | "end: my_end_token(M)",
|
1146 | ];
|
1147 | var me_to_moz = [
|
1148 | "type: " + JSON.stringify(moztype),
|
1149 | ];
|
1150 |
|
1151 | if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
|
1152 | var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
1153 | if (!m) throw new Error("Can't understand property map: " + prop);
|
1154 | var moz = m[1], how = m[2], my = m[3];
|
1155 | switch (how) {
|
1156 | case "@":
|
1157 | moz_to_me.push(my + ": M." + moz + ".map(from_moz)");
|
1158 | me_to_moz.push(moz + ": M." + my + ".map(to_moz)");
|
1159 | break;
|
1160 | case ">":
|
1161 | moz_to_me.push(my + ": from_moz(M." + moz + ")");
|
1162 | me_to_moz.push(moz + ": to_moz(M." + my + ")");
|
1163 | break;
|
1164 | case "=":
|
1165 | moz_to_me.push(my + ": M." + moz);
|
1166 | me_to_moz.push(moz + ": M." + my);
|
1167 | break;
|
1168 | case "%":
|
1169 | moz_to_me.push(my + ": from_moz(M." + moz + ").body");
|
1170 | me_to_moz.push(moz + ": to_moz_block(M)");
|
1171 | break;
|
1172 | default:
|
1173 | throw new Error("Can't understand operator in propmap: " + prop);
|
1174 | }
|
1175 | });
|
1176 |
|
1177 | MOZ_TO_ME[moztype] = new Function("U2", "my_start_token", "my_end_token", "from_moz", [
|
1178 | "return function From_Moz_" + moztype + "(M) {",
|
1179 | " return new U2.AST_" + mytype.TYPE + "({",
|
1180 | moz_to_me.join(",\n"),
|
1181 | " });",
|
1182 | "};",
|
1183 | ].join("\n"))(exports, my_start_token, my_end_token, from_moz);
|
1184 | def_to_moz(mytype, new Function("to_moz", "to_moz_block", "to_moz_scope", [
|
1185 | "return function To_Moz_" + moztype + "(M) {",
|
1186 | " return {",
|
1187 | me_to_moz.join(",\n"),
|
1188 | " };",
|
1189 | "};",
|
1190 | ].join("\n"))(to_moz, to_moz_block, to_moz_scope));
|
1191 | }
|
1192 |
|
1193 | var FROM_MOZ_STACK = null;
|
1194 |
|
1195 | function from_moz(moz) {
|
1196 | FROM_MOZ_STACK.push(moz);
|
1197 | var node = null;
|
1198 | if (moz) {
|
1199 | if (!HOP(MOZ_TO_ME, moz.type)) throw new Error("Unsupported type: " + moz.type);
|
1200 | node = MOZ_TO_ME[moz.type](moz);
|
1201 | }
|
1202 | FROM_MOZ_STACK.pop();
|
1203 | return node;
|
1204 | }
|
1205 |
|
1206 | AST_Node.from_mozilla_ast = function(node) {
|
1207 | var save_stack = FROM_MOZ_STACK;
|
1208 | FROM_MOZ_STACK = [];
|
1209 | var ast = from_moz(node);
|
1210 | FROM_MOZ_STACK = save_stack;
|
1211 | ast.walk(new TreeWalker(function(node) {
|
1212 | if (node instanceof AST_LabelRef) {
|
1213 | for (var level = 0, parent; parent = this.parent(level); level++) {
|
1214 | if (parent instanceof AST_Scope) break;
|
1215 | if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
|
1216 | node.thedef = parent.label;
|
1217 | break;
|
1218 | }
|
1219 | }
|
1220 | if (!node.thedef) {
|
1221 | var s = node.start;
|
1222 | js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos);
|
1223 | }
|
1224 | }
|
1225 | }));
|
1226 | return ast;
|
1227 | };
|
1228 |
|
1229 | function set_moz_loc(mynode, moznode) {
|
1230 | var start = mynode.start;
|
1231 | var end = mynode.end;
|
1232 | if (start.pos != null && end.endpos != null) {
|
1233 | moznode.range = [start.pos, end.endpos];
|
1234 | }
|
1235 | if (start.line) {
|
1236 | moznode.loc = {
|
1237 | start: {line: start.line, column: start.col},
|
1238 | end: end.endline ? {line: end.endline, column: end.endcol} : null,
|
1239 | };
|
1240 | if (start.file) {
|
1241 | moznode.loc.source = start.file;
|
1242 | }
|
1243 | }
|
1244 | return moznode;
|
1245 | }
|
1246 |
|
1247 | function def_to_moz(mytype, handler) {
|
1248 | mytype.DEFMETHOD("to_mozilla_ast", function() {
|
1249 | return set_moz_loc(this, handler(this));
|
1250 | });
|
1251 | }
|
1252 |
|
1253 | function to_moz(node) {
|
1254 | return node != null ? node.to_mozilla_ast() : null;
|
1255 | }
|
1256 |
|
1257 | function to_moz_block(node) {
|
1258 | return {
|
1259 | type: "BlockStatement",
|
1260 | body: node.body.map(to_moz),
|
1261 | };
|
1262 | }
|
1263 |
|
1264 | function to_moz_scope(type, node) {
|
1265 | var body = node.body.map(to_moz);
|
1266 | if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
|
1267 | body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
|
1268 | }
|
1269 | return {
|
1270 | type: type,
|
1271 | body: body,
|
1272 | };
|
1273 | }
|
1274 | })();
|