Apply module bundling
[platform/framework/web/wrtjs.git] / node_modules / terser / lib / mozilla-ast.js
1 /***********************************************************************
2
3   A JavaScript tokenizer / parser / beautifier / compressor.
4   https://github.com/mishoo/UglifyJS2
5
6   -------------------------------- (C) ---------------------------------
7
8                            Author: Mihai Bazon
9                          <mihai.bazon@gmail.com>
10                        http://mihai.bazon.net/blog
11
12   Distributed under the BSD license:
13
14     Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
15
16     Redistribution and use in source and binary forms, with or without
17     modification, are permitted provided that the following conditions
18     are met:
19
20         * Redistributions of source code must retain the above
21           copyright notice, this list of conditions and the following
22           disclaimer.
23
24         * Redistributions in binary form must reproduce the above
25           copyright notice, this list of conditions and the following
26           disclaimer in the documentation and/or other materials
27           provided with the distribution.
28
29     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
30     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
33     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34     OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
39     THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40     SUCH DAMAGE.
41
42  ***********************************************************************/
43
44 import { make_node } from "./utils/index.js";
45 import {
46     AST_Accessor,
47     AST_Array,
48     AST_Arrow,
49     AST_Assign,
50     AST_Atom,
51     AST_Await,
52     AST_BigInt,
53     AST_Binary,
54     AST_Block,
55     AST_BlockStatement,
56     AST_Boolean,
57     AST_Break,
58     AST_Call,
59     AST_Case,
60     AST_Catch,
61     AST_Chain,
62     AST_Class,
63     AST_ClassExpression,
64     AST_ClassProperty,
65     AST_ClassPrivateProperty,
66     AST_ConciseMethod,
67     AST_Conditional,
68     AST_Const,
69     AST_Constant,
70     AST_Continue,
71     AST_Debugger,
72     AST_Default,
73     AST_DefaultAssign,
74     AST_DefClass,
75     AST_Definitions,
76     AST_Defun,
77     AST_Destructuring,
78     AST_Directive,
79     AST_Do,
80     AST_Dot,
81     AST_DotHash,
82     AST_EmptyStatement,
83     AST_Expansion,
84     AST_Export,
85     AST_False,
86     AST_Finally,
87     AST_For,
88     AST_ForIn,
89     AST_ForOf,
90     AST_Function,
91     AST_Hole,
92     AST_If,
93     AST_Import,
94     AST_ImportMeta,
95     AST_Label,
96     AST_LabeledStatement,
97     AST_LabelRef,
98     AST_Lambda,
99     AST_Let,
100     AST_NameMapping,
101     AST_New,
102     AST_NewTarget,
103     AST_Node,
104     AST_Null,
105     AST_Number,
106     AST_Object,
107     AST_ObjectGetter,
108     AST_ObjectKeyVal,
109     AST_ObjectProperty,
110     AST_ObjectSetter,
111     AST_PrefixedTemplateString,
112     AST_PrivateGetter,
113     AST_PrivateMethod,
114     AST_PrivateSetter,
115     AST_PropAccess,
116     AST_RegExp,
117     AST_Return,
118     AST_Sequence,
119     AST_SimpleStatement,
120     AST_Statement,
121     AST_String,
122     AST_Sub,
123     AST_Super,
124     AST_Switch,
125     AST_SwitchBranch,
126     AST_Symbol,
127     AST_SymbolCatch,
128     AST_SymbolClass,
129     AST_SymbolClassProperty,
130     AST_SymbolConst,
131     AST_SymbolDefClass,
132     AST_SymbolDefun,
133     AST_SymbolExport,
134     AST_SymbolExportForeign,
135     AST_SymbolFunarg,
136     AST_SymbolImport,
137     AST_SymbolImportForeign,
138     AST_SymbolLambda,
139     AST_SymbolLet,
140     AST_SymbolMethod,
141     AST_SymbolRef,
142     AST_SymbolVar,
143     AST_TemplateSegment,
144     AST_TemplateString,
145     AST_This,
146     AST_Throw,
147     AST_Token,
148     AST_Toplevel,
149     AST_True,
150     AST_Try,
151     AST_Unary,
152     AST_UnaryPostfix,
153     AST_UnaryPrefix,
154     AST_Var,
155     AST_VarDef,
156     AST_While,
157     AST_With,
158     AST_Yield,
159 } from "./ast.js";
160 import { is_basic_identifier_string } from "./parse.js";
161
162 (function() {
163
164     var normalize_directives = function(body) {
165         var in_directive = true;
166
167         for (var i = 0; i < body.length; i++) {
168             if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
169                 body[i] = new AST_Directive({
170                     start: body[i].start,
171                     end: body[i].end,
172                     value: body[i].body.value
173                 });
174             } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
175                 in_directive = false;
176             }
177         }
178
179         return body;
180     };
181
182     const assert_clause_from_moz = (assertions) => {
183         if (assertions && assertions.length > 0) {
184             return new AST_Object({
185                 start: my_start_token(assertions),
186                 end: my_end_token(assertions),
187                 properties: assertions.map((assertion_kv) =>
188                     new AST_ObjectKeyVal({
189                         start: my_start_token(assertion_kv),
190                         end: my_end_token(assertion_kv),
191                         key: assertion_kv.key.name || assertion_kv.key.value,
192                         value: from_moz(assertion_kv.value)
193                     })
194                 )
195             });
196         }
197         return null;
198     };
199
200     var MOZ_TO_ME = {
201         Program: function(M) {
202             return new AST_Toplevel({
203                 start: my_start_token(M),
204                 end: my_end_token(M),
205                 body: normalize_directives(M.body.map(from_moz))
206             });
207         },
208
209         ArrayPattern: function(M) {
210             return new AST_Destructuring({
211                 start: my_start_token(M),
212                 end: my_end_token(M),
213                 names: M.elements.map(function(elm) {
214                     if (elm === null) {
215                         return new AST_Hole();
216                     }
217                     return from_moz(elm);
218                 }),
219                 is_array: true
220             });
221         },
222
223         ObjectPattern: function(M) {
224             return new AST_Destructuring({
225                 start: my_start_token(M),
226                 end: my_end_token(M),
227                 names: M.properties.map(from_moz),
228                 is_array: false
229             });
230         },
231
232         AssignmentPattern: function(M) {
233             return new AST_DefaultAssign({
234                 start: my_start_token(M),
235                 end: my_end_token(M),
236                 left: from_moz(M.left),
237                 operator: "=",
238                 right: from_moz(M.right)
239             });
240         },
241
242         SpreadElement: function(M) {
243             return new AST_Expansion({
244                 start: my_start_token(M),
245                 end: my_end_token(M),
246                 expression: from_moz(M.argument)
247             });
248         },
249
250         RestElement: function(M) {
251             return new AST_Expansion({
252                 start: my_start_token(M),
253                 end: my_end_token(M),
254                 expression: from_moz(M.argument)
255             });
256         },
257
258         TemplateElement: function(M) {
259             return new AST_TemplateSegment({
260                 start: my_start_token(M),
261                 end: my_end_token(M),
262                 value: M.value.cooked,
263                 raw: M.value.raw
264             });
265         },
266
267         TemplateLiteral: function(M) {
268             var segments = [];
269             for (var i = 0; i < M.quasis.length; i++) {
270                 segments.push(from_moz(M.quasis[i]));
271                 if (M.expressions[i]) {
272                     segments.push(from_moz(M.expressions[i]));
273                 }
274             }
275             return new AST_TemplateString({
276                 start: my_start_token(M),
277                 end: my_end_token(M),
278                 segments: segments
279             });
280         },
281
282         TaggedTemplateExpression: function(M) {
283             return new AST_PrefixedTemplateString({
284                 start: my_start_token(M),
285                 end: my_end_token(M),
286                 template_string: from_moz(M.quasi),
287                 prefix: from_moz(M.tag)
288             });
289         },
290
291         FunctionDeclaration: function(M) {
292             return new AST_Defun({
293                 start: my_start_token(M),
294                 end: my_end_token(M),
295                 name: from_moz(M.id),
296                 argnames: M.params.map(from_moz),
297                 is_generator: M.generator,
298                 async: M.async,
299                 body: normalize_directives(from_moz(M.body).body)
300             });
301         },
302
303         FunctionExpression: function(M) {
304             return new AST_Function({
305                 start: my_start_token(M),
306                 end: my_end_token(M),
307                 name: from_moz(M.id),
308                 argnames: M.params.map(from_moz),
309                 is_generator: M.generator,
310                 async: M.async,
311                 body: normalize_directives(from_moz(M.body).body)
312             });
313         },
314
315         ArrowFunctionExpression: function(M) {
316             const body = M.body.type === "BlockStatement"
317                 ? from_moz(M.body).body
318                 : [make_node(AST_Return, {}, { value: from_moz(M.body) })];
319             return new AST_Arrow({
320                 start: my_start_token(M),
321                 end: my_end_token(M),
322                 argnames: M.params.map(from_moz),
323                 body,
324                 async: M.async,
325             });
326         },
327
328         ExpressionStatement: function(M) {
329             return new AST_SimpleStatement({
330                 start: my_start_token(M),
331                 end: my_end_token(M),
332                 body: from_moz(M.expression)
333             });
334         },
335
336         TryStatement: function(M) {
337             var handlers = M.handlers || [M.handler];
338             if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
339                 throw new Error("Multiple catch clauses are not supported.");
340             }
341             return new AST_Try({
342                 start    : my_start_token(M),
343                 end      : my_end_token(M),
344                 body     : from_moz(M.block).body,
345                 bcatch   : from_moz(handlers[0]),
346                 bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
347             });
348         },
349
350         Property: function(M) {
351             var key = M.key;
352             var args = {
353                 start    : my_start_token(key || M.value),
354                 end      : my_end_token(M.value),
355                 key      : key.type == "Identifier" ? key.name : key.value,
356                 value    : from_moz(M.value)
357             };
358             if (M.computed) {
359                 args.key = from_moz(M.key);
360             }
361             if (M.method) {
362                 args.is_generator = M.value.generator;
363                 args.async = M.value.async;
364                 if (!M.computed) {
365                     args.key = new AST_SymbolMethod({ name: args.key });
366                 } else {
367                     args.key = from_moz(M.key);
368                 }
369                 return new AST_ConciseMethod(args);
370             }
371             if (M.kind == "init") {
372                 if (key.type != "Identifier" && key.type != "Literal") {
373                     args.key = from_moz(key);
374                 }
375                 return new AST_ObjectKeyVal(args);
376             }
377             if (typeof args.key === "string" || typeof args.key === "number") {
378                 args.key = new AST_SymbolMethod({
379                     name: args.key
380                 });
381             }
382             args.value = new AST_Accessor(args.value);
383             if (M.kind == "get") return new AST_ObjectGetter(args);
384             if (M.kind == "set") return new AST_ObjectSetter(args);
385             if (M.kind == "method") {
386                 args.async = M.value.async;
387                 args.is_generator = M.value.generator;
388                 args.quote = M.computed ? "\"" : null;
389                 return new AST_ConciseMethod(args);
390             }
391         },
392
393         MethodDefinition: function(M) {
394             var args = {
395                 start    : my_start_token(M),
396                 end      : my_end_token(M),
397                 key      : M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || M.key.value }),
398                 value    : from_moz(M.value),
399                 static   : M.static,
400             };
401             if (M.kind == "get") {
402                 return new AST_ObjectGetter(args);
403             }
404             if (M.kind == "set") {
405                 return new AST_ObjectSetter(args);
406             }
407             args.is_generator = M.value.generator;
408             args.async = M.value.async;
409             return new AST_ConciseMethod(args);
410         },
411
412         FieldDefinition: function(M) {
413             let key;
414             if (M.computed) {
415                 key = from_moz(M.key);
416             } else {
417                 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition");
418                 key = from_moz(M.key);
419             }
420             return new AST_ClassProperty({
421                 start    : my_start_token(M),
422                 end      : my_end_token(M),
423                 key,
424                 value    : from_moz(M.value),
425                 static   : M.static,
426             });
427         },
428
429         PropertyDefinition: function(M) {
430             let key;
431             if (M.computed) {
432                 key = from_moz(M.key);
433             } else {
434                 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in PropertyDefinition");
435                 key = from_moz(M.key);
436             }
437
438             return new AST_ClassProperty({
439                 start    : my_start_token(M),
440                 end      : my_end_token(M),
441                 key,
442                 value    : from_moz(M.value),
443                 static   : M.static,
444             });
445         },
446
447         ArrayExpression: function(M) {
448             return new AST_Array({
449                 start    : my_start_token(M),
450                 end      : my_end_token(M),
451                 elements : M.elements.map(function(elem) {
452                     return elem === null ? new AST_Hole() : from_moz(elem);
453                 })
454             });
455         },
456
457         ObjectExpression: function(M) {
458             return new AST_Object({
459                 start      : my_start_token(M),
460                 end        : my_end_token(M),
461                 properties : M.properties.map(function(prop) {
462                     if (prop.type === "SpreadElement") {
463                         return from_moz(prop);
464                     }
465                     prop.type = "Property";
466                     return from_moz(prop);
467                 })
468             });
469         },
470
471         SequenceExpression: function(M) {
472             return new AST_Sequence({
473                 start      : my_start_token(M),
474                 end        : my_end_token(M),
475                 expressions: M.expressions.map(from_moz)
476             });
477         },
478
479         MemberExpression: function(M) {
480             return new (M.computed ? AST_Sub : AST_Dot)({
481                 start      : my_start_token(M),
482                 end        : my_end_token(M),
483                 property   : M.computed ? from_moz(M.property) : M.property.name,
484                 expression : from_moz(M.object),
485                 optional   : M.optional || false
486             });
487         },
488
489         ChainExpression: function(M) {
490             return new AST_Chain({
491                 start      : my_start_token(M),
492                 end        : my_end_token(M),
493                 expression : from_moz(M.expression)
494             });
495         },
496
497         SwitchCase: function(M) {
498             return new (M.test ? AST_Case : AST_Default)({
499                 start      : my_start_token(M),
500                 end        : my_end_token(M),
501                 expression : from_moz(M.test),
502                 body       : M.consequent.map(from_moz)
503             });
504         },
505
506         VariableDeclaration: function(M) {
507             return new (M.kind === "const" ? AST_Const :
508                         M.kind === "let" ? AST_Let : AST_Var)({
509                 start       : my_start_token(M),
510                 end         : my_end_token(M),
511                 definitions : M.declarations.map(from_moz)
512             });
513         },
514
515         ImportDeclaration: function(M) {
516             var imported_name = null;
517             var imported_names = null;
518             M.specifiers.forEach(function (specifier) {
519                 if (specifier.type === "ImportSpecifier") {
520                     if (!imported_names) { imported_names = []; }
521                     imported_names.push(new AST_NameMapping({
522                         start: my_start_token(specifier),
523                         end: my_end_token(specifier),
524                         foreign_name: from_moz(specifier.imported),
525                         name: from_moz(specifier.local)
526                     }));
527                 } else if (specifier.type === "ImportDefaultSpecifier") {
528                     imported_name = from_moz(specifier.local);
529                 } else if (specifier.type === "ImportNamespaceSpecifier") {
530                     if (!imported_names) { imported_names = []; }
531                     imported_names.push(new AST_NameMapping({
532                         start: my_start_token(specifier),
533                         end: my_end_token(specifier),
534                         foreign_name: new AST_SymbolImportForeign({ name: "*" }),
535                         name: from_moz(specifier.local)
536                     }));
537                 }
538             });
539             return new AST_Import({
540                 start       : my_start_token(M),
541                 end         : my_end_token(M),
542                 imported_name: imported_name,
543                 imported_names : imported_names,
544                 module_name : from_moz(M.source),
545                 assert_clause: assert_clause_from_moz(M.assertions)
546             });
547         },
548
549         ExportAllDeclaration: function(M) {
550             return new AST_Export({
551                 start: my_start_token(M),
552                 end: my_end_token(M),
553                 exported_names: [
554                     new AST_NameMapping({
555                         name: new AST_SymbolExportForeign({ name: "*" }),
556                         foreign_name: new AST_SymbolExportForeign({ name: "*" })
557                     })
558                 ],
559                 module_name: from_moz(M.source),
560                 assert_clause: assert_clause_from_moz(M.assertions)
561             });
562         },
563
564         ExportNamedDeclaration: function(M) {
565             return new AST_Export({
566                 start: my_start_token(M),
567                 end: my_end_token(M),
568                 exported_definition: from_moz(M.declaration),
569                 exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(function (specifier) {
570                     return new AST_NameMapping({
571                         foreign_name: from_moz(specifier.exported),
572                         name: from_moz(specifier.local)
573                     });
574                 }) : null,
575                 module_name: from_moz(M.source),
576                 assert_clause: assert_clause_from_moz(M.assertions)
577             });
578         },
579
580         ExportDefaultDeclaration: function(M) {
581             return new AST_Export({
582                 start: my_start_token(M),
583                 end: my_end_token(M),
584                 exported_value: from_moz(M.declaration),
585                 is_default: true
586             });
587         },
588
589         Literal: function(M) {
590             var val = M.value, args = {
591                 start  : my_start_token(M),
592                 end    : my_end_token(M)
593             };
594             var rx = M.regex;
595             if (rx && rx.pattern) {
596                 // RegExpLiteral as per ESTree AST spec
597                 args.value = {
598                     source: rx.pattern,
599                     flags: rx.flags
600                 };
601                 return new AST_RegExp(args);
602             } else if (rx) {
603                 // support legacy RegExp
604                 const rx_source = M.raw || val;
605                 const match = rx_source.match(/^\/(.*)\/(\w*)$/);
606                 if (!match) throw new Error("Invalid regex source " + rx_source);
607                 const [_, source, flags] = match;
608                 args.value = { source, flags };
609                 return new AST_RegExp(args);
610             }
611             if (val === null) return new AST_Null(args);
612             switch (typeof val) {
613               case "string":
614                 args.value = val;
615                 return new AST_String(args);
616               case "number":
617                 args.value = val;
618                 args.raw = M.raw || val.toString();
619                 return new AST_Number(args);
620               case "boolean":
621                 return new (val ? AST_True : AST_False)(args);
622             }
623         },
624
625         MetaProperty: function(M) {
626             if (M.meta.name === "new" && M.property.name === "target") {
627                 return new AST_NewTarget({
628                     start: my_start_token(M),
629                     end: my_end_token(M)
630                 });
631             } else if (M.meta.name === "import" && M.property.name === "meta") {
632                 return new AST_ImportMeta({
633                     start: my_start_token(M),
634                     end: my_end_token(M)
635                 });
636             }
637         },
638
639         Identifier: function(M) {
640             var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
641             return new (  p.type == "LabeledStatement" ? AST_Label
642                         : p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : p.kind == "let" ? AST_SymbolLet : AST_SymbolVar)
643                         : /Import.*Specifier/.test(p.type) ? (p.local === M ? AST_SymbolImport : AST_SymbolImportForeign)
644                         : p.type == "ExportSpecifier" ? (p.local === M ? AST_SymbolExport : AST_SymbolExportForeign)
645                         : p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
646                         : p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
647                         : p.type == "ArrowFunctionExpression" ? (p.params.includes(M)) ? AST_SymbolFunarg : AST_SymbolRef
648                         : p.type == "ClassExpression" ? (p.id === M ? AST_SymbolClass : AST_SymbolRef)
649                         : p.type == "Property" ? (p.key === M && p.computed || p.value === M ? AST_SymbolRef : AST_SymbolMethod)
650                         : p.type == "PropertyDefinition" || p.type === "FieldDefinition" ? (p.key === M && p.computed || p.value === M ? AST_SymbolRef : AST_SymbolClassProperty)
651                         : p.type == "ClassDeclaration" ? (p.id === M ? AST_SymbolDefClass : AST_SymbolRef)
652                         : p.type == "MethodDefinition" ? (p.computed ? AST_SymbolRef : AST_SymbolMethod)
653                         : p.type == "CatchClause" ? AST_SymbolCatch
654                         : p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
655                         : AST_SymbolRef)({
656                             start : my_start_token(M),
657                             end   : my_end_token(M),
658                             name  : M.name
659                         });
660         },
661
662         BigIntLiteral(M) {
663             return new AST_BigInt({
664                 start : my_start_token(M),
665                 end   : my_end_token(M),
666                 value : M.value
667             });
668         },
669
670         EmptyStatement: function(M) {
671             return new AST_EmptyStatement({
672                 start: my_start_token(M),
673                 end: my_end_token(M)
674             });
675         },
676
677         BlockStatement: function(M) {
678             return new AST_BlockStatement({
679                 start: my_start_token(M),
680                 end: my_end_token(M),
681                 body: M.body.map(from_moz)
682             });
683         },
684
685         IfStatement: function(M) {
686             return new AST_If({
687                 start: my_start_token(M),
688                 end: my_end_token(M),
689                 condition: from_moz(M.test),
690                 body: from_moz(M.consequent),
691                 alternative: from_moz(M.alternate)
692             });
693         },
694
695         LabeledStatement: function(M) {
696             return new AST_LabeledStatement({
697                 start: my_start_token(M),
698                 end: my_end_token(M),
699                 label: from_moz(M.label),
700                 body: from_moz(M.body)
701             });
702         },
703
704         BreakStatement: function(M) {
705             return new AST_Break({
706                 start: my_start_token(M),
707                 end: my_end_token(M),
708                 label: from_moz(M.label)
709             });
710         },
711
712         ContinueStatement: function(M) {
713             return new AST_Continue({
714                 start: my_start_token(M),
715                 end: my_end_token(M),
716                 label: from_moz(M.label)
717             });
718         },
719
720         WithStatement: function(M) {
721             return new AST_With({
722                 start: my_start_token(M),
723                 end: my_end_token(M),
724                 expression: from_moz(M.object),
725                 body: from_moz(M.body)
726             });
727         },
728
729         SwitchStatement: function(M) {
730             return new AST_Switch({
731                 start: my_start_token(M),
732                 end: my_end_token(M),
733                 expression: from_moz(M.discriminant),
734                 body: M.cases.map(from_moz)
735             });
736         },
737
738         ReturnStatement: function(M) {
739             return new AST_Return({
740                 start: my_start_token(M),
741                 end: my_end_token(M),
742                 value: from_moz(M.argument)
743             });
744         },
745
746         ThrowStatement: function(M) {
747             return new AST_Throw({
748                 start: my_start_token(M),
749                 end: my_end_token(M),
750                 value: from_moz(M.argument)
751             });
752         },
753
754         WhileStatement: function(M) {
755             return new AST_While({
756                 start: my_start_token(M),
757                 end: my_end_token(M),
758                 condition: from_moz(M.test),
759                 body: from_moz(M.body)
760             });
761         },
762
763         DoWhileStatement: function(M) {
764             return new AST_Do({
765                 start: my_start_token(M),
766                 end: my_end_token(M),
767                 condition: from_moz(M.test),
768                 body: from_moz(M.body)
769             });
770         },
771
772         ForStatement: function(M) {
773             return new AST_For({
774                 start: my_start_token(M),
775                 end: my_end_token(M),
776                 init: from_moz(M.init),
777                 condition: from_moz(M.test),
778                 step: from_moz(M.update),
779                 body: from_moz(M.body)
780             });
781         },
782
783         ForInStatement: function(M) {
784             return new AST_ForIn({
785                 start: my_start_token(M),
786                 end: my_end_token(M),
787                 init: from_moz(M.left),
788                 object: from_moz(M.right),
789                 body: from_moz(M.body)
790             });
791         },
792
793         ForOfStatement: function(M) {
794             return new AST_ForOf({
795                 start: my_start_token(M),
796                 end: my_end_token(M),
797                 init: from_moz(M.left),
798                 object: from_moz(M.right),
799                 body: from_moz(M.body),
800                 await: M.await
801             });
802         },
803
804         AwaitExpression: function(M) {
805             return new AST_Await({
806                 start: my_start_token(M),
807                 end: my_end_token(M),
808                 expression: from_moz(M.argument)
809             });
810         },
811
812         YieldExpression: function(M) {
813             return new AST_Yield({
814                 start: my_start_token(M),
815                 end: my_end_token(M),
816                 expression: from_moz(M.argument),
817                 is_star: M.delegate
818             });
819         },
820
821         DebuggerStatement: function(M) {
822             return new AST_Debugger({
823                 start: my_start_token(M),
824                 end: my_end_token(M)
825             });
826         },
827
828         VariableDeclarator: function(M) {
829             return new AST_VarDef({
830                 start: my_start_token(M),
831                 end: my_end_token(M),
832                 name: from_moz(M.id),
833                 value: from_moz(M.init)
834             });
835         },
836
837         CatchClause: function(M) {
838             return new AST_Catch({
839                 start: my_start_token(M),
840                 end: my_end_token(M),
841                 argname: from_moz(M.param),
842                 body: from_moz(M.body).body
843             });
844         },
845
846         ThisExpression: function(M) {
847             return new AST_This({
848                 start: my_start_token(M),
849                 end: my_end_token(M)
850             });
851         },
852
853         Super: function(M) {
854             return new AST_Super({
855                 start: my_start_token(M),
856                 end: my_end_token(M)
857             });
858         },
859
860         BinaryExpression: function(M) {
861             return new AST_Binary({
862                 start: my_start_token(M),
863                 end: my_end_token(M),
864                 operator: M.operator,
865                 left: from_moz(M.left),
866                 right: from_moz(M.right)
867             });
868         },
869
870         LogicalExpression: function(M) {
871             return new AST_Binary({
872                 start: my_start_token(M),
873                 end: my_end_token(M),
874                 operator: M.operator,
875                 left: from_moz(M.left),
876                 right: from_moz(M.right)
877             });
878         },
879
880         AssignmentExpression: function(M) {
881             return new AST_Assign({
882                 start: my_start_token(M),
883                 end: my_end_token(M),
884                 operator: M.operator,
885                 left: from_moz(M.left),
886                 right: from_moz(M.right)
887             });
888         },
889
890         ConditionalExpression: function(M) {
891             return new AST_Conditional({
892                 start: my_start_token(M),
893                 end: my_end_token(M),
894                 condition: from_moz(M.test),
895                 consequent: from_moz(M.consequent),
896                 alternative: from_moz(M.alternate)
897             });
898         },
899
900         NewExpression: function(M) {
901             return new AST_New({
902                 start: my_start_token(M),
903                 end: my_end_token(M),
904                 expression: from_moz(M.callee),
905                 args: M.arguments.map(from_moz)
906             });
907         },
908
909         CallExpression: function(M) {
910             return new AST_Call({
911                 start: my_start_token(M),
912                 end: my_end_token(M),
913                 expression: from_moz(M.callee),
914                 optional: M.optional,
915                 args: M.arguments.map(from_moz)
916             });
917         }
918     };
919
920     MOZ_TO_ME.UpdateExpression =
921     MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
922         var prefix = "prefix" in M ? M.prefix
923             : M.type == "UnaryExpression" ? true : false;
924         return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
925             start      : my_start_token(M),
926             end        : my_end_token(M),
927             operator   : M.operator,
928             expression : from_moz(M.argument)
929         });
930     };
931
932     MOZ_TO_ME.ClassDeclaration =
933     MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) {
934         return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({
935             start    : my_start_token(M),
936             end      : my_end_token(M),
937             name     : from_moz(M.id),
938             extends  : from_moz(M.superClass),
939             properties: M.body.body.map(from_moz)
940         });
941     };
942
943     def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() {
944         return {
945             type: "EmptyStatement"
946         };
947     });
948     def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) {
949         return {
950             type: "BlockStatement",
951             body: M.body.map(to_moz)
952         };
953     });
954     def_to_moz(AST_If, function To_Moz_IfStatement(M) {
955         return {
956             type: "IfStatement",
957             test: to_moz(M.condition),
958             consequent: to_moz(M.body),
959             alternate: to_moz(M.alternative)
960         };
961     });
962     def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) {
963         return {
964             type: "LabeledStatement",
965             label: to_moz(M.label),
966             body: to_moz(M.body)
967         };
968     });
969     def_to_moz(AST_Break, function To_Moz_BreakStatement(M) {
970         return {
971             type: "BreakStatement",
972             label: to_moz(M.label)
973         };
974     });
975     def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) {
976         return {
977             type: "ContinueStatement",
978             label: to_moz(M.label)
979         };
980     });
981     def_to_moz(AST_With, function To_Moz_WithStatement(M) {
982         return {
983             type: "WithStatement",
984             object: to_moz(M.expression),
985             body: to_moz(M.body)
986         };
987     });
988     def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) {
989         return {
990             type: "SwitchStatement",
991             discriminant: to_moz(M.expression),
992             cases: M.body.map(to_moz)
993         };
994     });
995     def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) {
996         return {
997             type: "ReturnStatement",
998             argument: to_moz(M.value)
999         };
1000     });
1001     def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) {
1002         return {
1003             type: "ThrowStatement",
1004             argument: to_moz(M.value)
1005         };
1006     });
1007     def_to_moz(AST_While, function To_Moz_WhileStatement(M) {
1008         return {
1009             type: "WhileStatement",
1010             test: to_moz(M.condition),
1011             body: to_moz(M.body)
1012         };
1013     });
1014     def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) {
1015         return {
1016             type: "DoWhileStatement",
1017             test: to_moz(M.condition),
1018             body: to_moz(M.body)
1019         };
1020     });
1021     def_to_moz(AST_For, function To_Moz_ForStatement(M) {
1022         return {
1023             type: "ForStatement",
1024             init: to_moz(M.init),
1025             test: to_moz(M.condition),
1026             update: to_moz(M.step),
1027             body: to_moz(M.body)
1028         };
1029     });
1030     def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) {
1031         return {
1032             type: "ForInStatement",
1033             left: to_moz(M.init),
1034             right: to_moz(M.object),
1035             body: to_moz(M.body)
1036         };
1037     });
1038     def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) {
1039         return {
1040             type: "ForOfStatement",
1041             left: to_moz(M.init),
1042             right: to_moz(M.object),
1043             body: to_moz(M.body),
1044             await: M.await
1045         };
1046     });
1047     def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) {
1048         return {
1049             type: "AwaitExpression",
1050             argument: to_moz(M.expression)
1051         };
1052     });
1053     def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) {
1054         return {
1055             type: "YieldExpression",
1056             argument: to_moz(M.expression),
1057             delegate: M.is_star
1058         };
1059     });
1060     def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() {
1061         return {
1062             type: "DebuggerStatement"
1063         };
1064     });
1065     def_to_moz(AST_VarDef, function To_Moz_VariableDeclarator(M) {
1066         return {
1067             type: "VariableDeclarator",
1068             id: to_moz(M.name),
1069             init: to_moz(M.value)
1070         };
1071     });
1072     def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
1073         return {
1074             type: "CatchClause",
1075             param: to_moz(M.argname),
1076             body: to_moz_block(M)
1077         };
1078     });
1079
1080     def_to_moz(AST_This, function To_Moz_ThisExpression() {
1081         return {
1082             type: "ThisExpression"
1083         };
1084     });
1085     def_to_moz(AST_Super, function To_Moz_Super() {
1086         return {
1087             type: "Super"
1088         };
1089     });
1090     def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
1091         return {
1092             type: "BinaryExpression",
1093             operator: M.operator,
1094             left: to_moz(M.left),
1095             right: to_moz(M.right)
1096         };
1097     });
1098     def_to_moz(AST_Binary, function To_Moz_LogicalExpression(M) {
1099         return {
1100             type: "LogicalExpression",
1101             operator: M.operator,
1102             left: to_moz(M.left),
1103             right: to_moz(M.right)
1104         };
1105     });
1106     def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) {
1107         return {
1108             type: "AssignmentExpression",
1109             operator: M.operator,
1110             left: to_moz(M.left),
1111             right: to_moz(M.right)
1112         };
1113     });
1114     def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) {
1115         return {
1116             type: "ConditionalExpression",
1117             test: to_moz(M.condition),
1118             consequent: to_moz(M.consequent),
1119             alternate: to_moz(M.alternative)
1120         };
1121     });
1122     def_to_moz(AST_New, function To_Moz_NewExpression(M) {
1123         return {
1124             type: "NewExpression",
1125             callee: to_moz(M.expression),
1126             arguments: M.args.map(to_moz)
1127         };
1128     });
1129     def_to_moz(AST_Call, function To_Moz_CallExpression(M) {
1130         return {
1131             type: "CallExpression",
1132             callee: to_moz(M.expression),
1133             optional: M.optional,
1134             arguments: M.args.map(to_moz)
1135         };
1136     });
1137
1138     def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
1139         return to_moz_scope("Program", M);
1140     });
1141
1142     def_to_moz(AST_Expansion, function To_Moz_Spread(M) {
1143         return {
1144             type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement",
1145             argument: to_moz(M.expression)
1146         };
1147     });
1148
1149     def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) {
1150         return {
1151             type: "TaggedTemplateExpression",
1152             tag: to_moz(M.prefix),
1153             quasi: to_moz(M.template_string)
1154         };
1155     });
1156
1157     def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) {
1158         var quasis = [];
1159         var expressions = [];
1160         for (var i = 0; i < M.segments.length; i++) {
1161             if (i % 2 !== 0) {
1162                 expressions.push(to_moz(M.segments[i]));
1163             } else {
1164                 quasis.push({
1165                     type: "TemplateElement",
1166                     value: {
1167                         raw: M.segments[i].raw,
1168                         cooked: M.segments[i].value
1169                     },
1170                     tail: i === M.segments.length - 1
1171                 });
1172             }
1173         }
1174         return {
1175             type: "TemplateLiteral",
1176             quasis: quasis,
1177             expressions: expressions
1178         };
1179     });
1180
1181     def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
1182         return {
1183             type: "FunctionDeclaration",
1184             id: to_moz(M.name),
1185             params: M.argnames.map(to_moz),
1186             generator: M.is_generator,
1187             async: M.async,
1188             body: to_moz_scope("BlockStatement", M)
1189         };
1190     });
1191
1192     def_to_moz(AST_Function, function To_Moz_FunctionExpression(M, parent) {
1193         var is_generator = parent.is_generator !== undefined ?
1194             parent.is_generator : M.is_generator;
1195         return {
1196             type: "FunctionExpression",
1197             id: to_moz(M.name),
1198             params: M.argnames.map(to_moz),
1199             generator: is_generator,
1200             async: M.async,
1201             body: to_moz_scope("BlockStatement", M)
1202         };
1203     });
1204
1205     def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) {
1206         var body = {
1207             type: "BlockStatement",
1208             body: M.body.map(to_moz)
1209         };
1210         return {
1211             type: "ArrowFunctionExpression",
1212             params: M.argnames.map(to_moz),
1213             async: M.async,
1214             body: body
1215         };
1216     });
1217
1218     def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) {
1219         if (M.is_array) {
1220             return {
1221                 type: "ArrayPattern",
1222                 elements: M.names.map(to_moz)
1223             };
1224         }
1225         return {
1226             type: "ObjectPattern",
1227             properties: M.names.map(to_moz)
1228         };
1229     });
1230
1231     def_to_moz(AST_Directive, function To_Moz_Directive(M) {
1232         return {
1233             type: "ExpressionStatement",
1234             expression: {
1235                 type: "Literal",
1236                 value: M.value,
1237                 raw: M.print_to_string()
1238             },
1239             directive: M.value
1240         };
1241     });
1242
1243     def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
1244         return {
1245             type: "ExpressionStatement",
1246             expression: to_moz(M.body)
1247         };
1248     });
1249
1250     def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
1251         return {
1252             type: "SwitchCase",
1253             test: to_moz(M.expression),
1254             consequent: M.body.map(to_moz)
1255         };
1256     });
1257
1258     def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
1259         return {
1260             type: "TryStatement",
1261             block: to_moz_block(M),
1262             handler: to_moz(M.bcatch),
1263             guardedHandlers: [],
1264             finalizer: to_moz(M.bfinally)
1265         };
1266     });
1267
1268     def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
1269         return {
1270             type: "CatchClause",
1271             param: to_moz(M.argname),
1272             guard: null,
1273             body: to_moz_block(M)
1274         };
1275     });
1276
1277     def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
1278         return {
1279             type: "VariableDeclaration",
1280             kind:
1281                 M instanceof AST_Const ? "const" :
1282                 M instanceof AST_Let ? "let" : "var",
1283             declarations: M.definitions.map(to_moz)
1284         };
1285     });
1286
1287     const assert_clause_to_moz = assert_clause => {
1288         const assertions = [];
1289         if (assert_clause) {
1290             for (const { key, value } of assert_clause.properties) {
1291                 const key_moz = is_basic_identifier_string(key)
1292                     ? { type: "Identifier", name: key }
1293                     : { type: "Literal", value: key, raw: JSON.stringify(key) };
1294                 assertions.push({
1295                     type: "ImportAttribute",
1296                     key: key_moz,
1297                     value: to_moz(value)
1298                 });
1299             }
1300         }
1301         return assertions;
1302     };
1303
1304     def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
1305         if (M.exported_names) {
1306             if (M.exported_names[0].name.name === "*") {
1307                 return {
1308                     type: "ExportAllDeclaration",
1309                     source: to_moz(M.module_name),
1310                     assertions: assert_clause_to_moz(M.assert_clause)
1311                 };
1312             }
1313             return {
1314                 type: "ExportNamedDeclaration",
1315                 specifiers: M.exported_names.map(function (name_mapping) {
1316                     return {
1317                         type: "ExportSpecifier",
1318                         exported: to_moz(name_mapping.foreign_name),
1319                         local: to_moz(name_mapping.name)
1320                     };
1321                 }),
1322                 declaration: to_moz(M.exported_definition),
1323                 source: to_moz(M.module_name),
1324                 assertions: assert_clause_to_moz(M.assert_clause)
1325             };
1326         }
1327         return {
1328             type: M.is_default ? "ExportDefaultDeclaration" : "ExportNamedDeclaration",
1329             declaration: to_moz(M.exported_value || M.exported_definition)
1330         };
1331     });
1332
1333     def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
1334         var specifiers = [];
1335         if (M.imported_name) {
1336             specifiers.push({
1337                 type: "ImportDefaultSpecifier",
1338                 local: to_moz(M.imported_name)
1339             });
1340         }
1341         if (M.imported_names && M.imported_names[0].foreign_name.name === "*") {
1342             specifiers.push({
1343                 type: "ImportNamespaceSpecifier",
1344                 local: to_moz(M.imported_names[0].name)
1345             });
1346         } else if (M.imported_names) {
1347             M.imported_names.forEach(function(name_mapping) {
1348                 specifiers.push({
1349                     type: "ImportSpecifier",
1350                     local: to_moz(name_mapping.name),
1351                     imported: to_moz(name_mapping.foreign_name)
1352                 });
1353             });
1354         }
1355         return {
1356             type: "ImportDeclaration",
1357             specifiers: specifiers,
1358             source: to_moz(M.module_name),
1359             assertions: assert_clause_to_moz(M.assert_clause)
1360         };
1361     });
1362
1363     def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
1364         return {
1365             type: "MetaProperty",
1366             meta: {
1367                 type: "Identifier",
1368                 name: "import"
1369             },
1370             property: {
1371                 type: "Identifier",
1372                 name: "meta"
1373             }
1374         };
1375     });
1376
1377     def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
1378         return {
1379             type: "SequenceExpression",
1380             expressions: M.expressions.map(to_moz)
1381         };
1382     });
1383
1384     def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) {
1385         return {
1386             type: "MemberExpression",
1387             object: to_moz(M.expression),
1388             computed: false,
1389             property: {
1390                 type: "PrivateIdentifier",
1391                 name: M.property
1392             },
1393             optional: M.optional
1394         };
1395     });
1396
1397     def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
1398         var isComputed = M instanceof AST_Sub;
1399         return {
1400             type: "MemberExpression",
1401             object: to_moz(M.expression),
1402             computed: isComputed,
1403             property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property},
1404             optional: M.optional
1405         };
1406     });
1407
1408     def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
1409         return {
1410             type: "ChainExpression",
1411             expression: to_moz(M.expression)
1412         };
1413     });
1414
1415     def_to_moz(AST_Unary, function To_Moz_Unary(M) {
1416         return {
1417             type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
1418             operator: M.operator,
1419             prefix: M instanceof AST_UnaryPrefix,
1420             argument: to_moz(M.expression)
1421         };
1422     });
1423
1424     def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
1425         if (M.operator == "=" && to_moz_in_destructuring()) {
1426             return {
1427                 type: "AssignmentPattern",
1428                 left: to_moz(M.left),
1429                 right: to_moz(M.right)
1430             };
1431         }
1432
1433         const type = M.operator == "&&" || M.operator == "||" || M.operator === "??"
1434             ? "LogicalExpression"
1435             : "BinaryExpression";
1436
1437         return {
1438             type,
1439             left: to_moz(M.left),
1440             operator: M.operator,
1441             right: to_moz(M.right)
1442         };
1443     });
1444
1445     def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
1446         return {
1447             type: "ArrayExpression",
1448             elements: M.elements.map(to_moz)
1449         };
1450     });
1451
1452     def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
1453         return {
1454             type: "ObjectExpression",
1455             properties: M.properties.map(to_moz)
1456         };
1457     });
1458
1459     def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) {
1460         var key = M.key instanceof AST_Node ? to_moz(M.key) : {
1461             type: "Identifier",
1462             value: M.key
1463         };
1464         if (typeof M.key === "number") {
1465             key = {
1466                 type: "Literal",
1467                 value: Number(M.key)
1468             };
1469         }
1470         if (typeof M.key === "string") {
1471             key = {
1472                 type: "Identifier",
1473                 name: M.key
1474             };
1475         }
1476         var kind;
1477         var string_or_num = typeof M.key === "string" || typeof M.key === "number";
1478         var computed = string_or_num ? false : !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef;
1479         if (M instanceof AST_ObjectKeyVal) {
1480             kind = "init";
1481             computed = !string_or_num;
1482         } else
1483         if (M instanceof AST_ObjectGetter) {
1484             kind = "get";
1485         } else
1486         if (M instanceof AST_ObjectSetter) {
1487             kind = "set";
1488         }
1489         if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) {
1490             const kind = M instanceof AST_PrivateGetter ? "get" : "set";
1491             return {
1492                 type: "MethodDefinition",
1493                 computed: false,
1494                 kind: kind,
1495                 static: M.static,
1496                 key: {
1497                     type: "PrivateIdentifier",
1498                     name: M.key.name
1499                 },
1500                 value: to_moz(M.value)
1501             };
1502         }
1503         if (M instanceof AST_ClassPrivateProperty) {
1504             return {
1505                 type: "PropertyDefinition",
1506                 key: {
1507                     type: "PrivateIdentifier",
1508                     name: M.key.name
1509                 },
1510                 value: to_moz(M.value),
1511                 computed: false,
1512                 static: M.static
1513             };
1514         }
1515         if (M instanceof AST_ClassProperty) {
1516             return {
1517                 type: "PropertyDefinition",
1518                 key,
1519                 value: to_moz(M.value),
1520                 computed,
1521                 static: M.static
1522             };
1523         }
1524         if (parent instanceof AST_Class) {
1525             return {
1526                 type: "MethodDefinition",
1527                 computed: computed,
1528                 kind: kind,
1529                 static: M.static,
1530                 key: to_moz(M.key),
1531                 value: to_moz(M.value)
1532             };
1533         }
1534         return {
1535             type: "Property",
1536             computed: computed,
1537             kind: kind,
1538             key: key,
1539             value: to_moz(M.value)
1540         };
1541     });
1542
1543     def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) {
1544         if (parent instanceof AST_Object) {
1545             return {
1546                 type: "Property",
1547                 computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
1548                 kind: "init",
1549                 method: true,
1550                 shorthand: false,
1551                 key: to_moz(M.key),
1552                 value: to_moz(M.value)
1553             };
1554         }
1555
1556         const key = M instanceof AST_PrivateMethod
1557             ? {
1558                 type: "PrivateIdentifier",
1559                 name: M.key.name
1560             }
1561             : to_moz(M.key);
1562
1563         return {
1564             type: "MethodDefinition",
1565             kind: M.key === "constructor" ? "constructor" : "method",
1566             key,
1567             value: to_moz(M.value),
1568             computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
1569             static: M.static,
1570         };
1571     });
1572
1573     def_to_moz(AST_Class, function To_Moz_Class(M) {
1574         var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration";
1575         return {
1576             type: type,
1577             superClass: to_moz(M.extends),
1578             id: M.name ? to_moz(M.name) : null,
1579             body: {
1580                 type: "ClassBody",
1581                 body: M.properties.map(to_moz)
1582             }
1583         };
1584     });
1585
1586     def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
1587         return {
1588             type: "MetaProperty",
1589             meta: {
1590                 type: "Identifier",
1591                 name: "new"
1592             },
1593             property: {
1594                 type: "Identifier",
1595                 name: "target"
1596             }
1597         };
1598     });
1599
1600     def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
1601         if (M instanceof AST_SymbolMethod && parent.quote) {
1602             return {
1603                 type: "Literal",
1604                 value: M.name
1605             };
1606         }
1607         var def = M.definition();
1608         return {
1609             type: "Identifier",
1610             name: def ? def.mangled_name || def.name : M.name
1611         };
1612     });
1613
1614     def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
1615         const pattern = M.value.source;
1616         const flags = M.value.flags;
1617         return {
1618             type: "Literal",
1619             value: null,
1620             raw: M.print_to_string(),
1621             regex: { pattern, flags }
1622         };
1623     });
1624
1625     def_to_moz(AST_Constant, function To_Moz_Literal(M) {
1626         var value = M.value;
1627         return {
1628             type: "Literal",
1629             value: value,
1630             raw: M.raw || M.print_to_string()
1631         };
1632     });
1633
1634     def_to_moz(AST_Atom, function To_Moz_Atom(M) {
1635         return {
1636             type: "Identifier",
1637             name: String(M.value)
1638         };
1639     });
1640
1641     def_to_moz(AST_BigInt, M => ({
1642         type: "BigIntLiteral",
1643         value: M.value
1644     }));
1645
1646     AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
1647     AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
1648     AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; });
1649
1650     AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
1651     AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast);
1652
1653     /* -----[ tools ]----- */
1654
1655     function my_start_token(moznode) {
1656         var loc = moznode.loc, start = loc && loc.start;
1657         var range = moznode.range;
1658         return new AST_Token(
1659             "",
1660             "",
1661             start && start.line || 0,
1662             start && start.column || 0,
1663             range ? range [0] : moznode.start,
1664             false,
1665             [],
1666             [],
1667             loc && loc.source,
1668         );
1669     }
1670
1671     function my_end_token(moznode) {
1672         var loc = moznode.loc, end = loc && loc.end;
1673         var range = moznode.range;
1674         return new AST_Token(
1675             "",
1676             "",
1677             end && end.line || 0,
1678             end && end.column || 0,
1679             range ? range [0] : moznode.end,
1680             false,
1681             [],
1682             [],
1683             loc && loc.source,
1684         );
1685     }
1686
1687     var FROM_MOZ_STACK = null;
1688
1689     function from_moz(node) {
1690         FROM_MOZ_STACK.push(node);
1691         var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
1692         FROM_MOZ_STACK.pop();
1693         return ret;
1694     }
1695
1696     AST_Node.from_mozilla_ast = function(node) {
1697         var save_stack = FROM_MOZ_STACK;
1698         FROM_MOZ_STACK = [];
1699         var ast = from_moz(node);
1700         FROM_MOZ_STACK = save_stack;
1701         return ast;
1702     };
1703
1704     function set_moz_loc(mynode, moznode) {
1705         var start = mynode.start;
1706         var end = mynode.end;
1707         if (!(start && end)) {
1708             return moznode;
1709         }
1710         if (start.pos != null && end.endpos != null) {
1711             moznode.range = [start.pos, end.endpos];
1712         }
1713         if (start.line) {
1714             moznode.loc = {
1715                 start: {line: start.line, column: start.col},
1716                 end: end.endline ? {line: end.endline, column: end.endcol} : null
1717             };
1718             if (start.file) {
1719                 moznode.loc.source = start.file;
1720             }
1721         }
1722         return moznode;
1723     }
1724
1725     function def_to_moz(mytype, handler) {
1726         mytype.DEFMETHOD("to_mozilla_ast", function(parent) {
1727             return set_moz_loc(this, handler(this, parent));
1728         });
1729     }
1730
1731     var TO_MOZ_STACK = null;
1732
1733     function to_moz(node) {
1734         if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; }
1735         TO_MOZ_STACK.push(node);
1736         var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null;
1737         TO_MOZ_STACK.pop();
1738         if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; }
1739         return ast;
1740     }
1741
1742     function to_moz_in_destructuring() {
1743         var i = TO_MOZ_STACK.length;
1744         while (i--) {
1745             if (TO_MOZ_STACK[i] instanceof AST_Destructuring) {
1746                 return true;
1747             }
1748         }
1749         return false;
1750     }
1751
1752     function to_moz_block(node) {
1753         return {
1754             type: "BlockStatement",
1755             body: node.body.map(to_moz)
1756         };
1757     }
1758
1759     function to_moz_scope(type, node) {
1760         var body = node.body.map(to_moz);
1761         if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
1762             body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
1763         }
1764         return {
1765             type: type,
1766             body: body
1767         };
1768     }
1769 })();