1 /***********************************************************************
3 A JavaScript tokenizer / parser / beautifier / compressor.
4 https://github.com/mishoo/UglifyJS2
6 -------------------------------- (C) ---------------------------------
9 <mihai.bazon@gmail.com>
10 http://mihai.bazon.net/blog
12 Distributed under the BSD license:
14 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions
20 * Redistributions of source code must retain the above
21 copyright notice, this list of conditions and the following
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.
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
42 ***********************************************************************/
44 import { make_node } from "./utils/index.js";
65 AST_ClassPrivateProperty,
111 AST_PrefixedTemplateString,
129 AST_SymbolClassProperty,
134 AST_SymbolExportForeign,
137 AST_SymbolImportForeign,
160 import { is_basic_identifier_string } from "./parse.js";
164 var normalize_directives = function(body) {
165 var in_directive = true;
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,
172 value: body[i].body.value
174 } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
175 in_directive = false;
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)
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))
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) {
215 return new AST_Hole();
217 return from_moz(elm);
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),
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),
238 right: from_moz(M.right)
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)
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)
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,
267 TemplateLiteral: function(M) {
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]));
275 return new AST_TemplateString({
276 start: my_start_token(M),
277 end: my_end_token(M),
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)
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,
299 body: normalize_directives(from_moz(M.body).body)
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,
311 body: normalize_directives(from_moz(M.body).body)
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),
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)
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.");
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
350 Property: function(M) {
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)
359 args.key = from_moz(M.key);
362 args.is_generator = M.value.generator;
363 args.async = M.value.async;
365 args.key = new AST_SymbolMethod({ name: args.key });
367 args.key = from_moz(M.key);
369 return new AST_ConciseMethod(args);
371 if (M.kind == "init") {
372 if (key.type != "Identifier" && key.type != "Literal") {
373 args.key = from_moz(key);
375 return new AST_ObjectKeyVal(args);
377 if (typeof args.key === "string" || typeof args.key === "number") {
378 args.key = new AST_SymbolMethod({
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);
393 MethodDefinition: function(M) {
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),
401 if (M.kind == "get") {
402 return new AST_ObjectGetter(args);
404 if (M.kind == "set") {
405 return new AST_ObjectSetter(args);
407 args.is_generator = M.value.generator;
408 args.async = M.value.async;
409 return new AST_ConciseMethod(args);
412 FieldDefinition: function(M) {
415 key = from_moz(M.key);
417 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition");
418 key = from_moz(M.key);
420 return new AST_ClassProperty({
421 start : my_start_token(M),
422 end : my_end_token(M),
424 value : from_moz(M.value),
429 PropertyDefinition: function(M) {
432 key = from_moz(M.key);
434 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in PropertyDefinition");
435 key = from_moz(M.key);
438 return new AST_ClassProperty({
439 start : my_start_token(M),
440 end : my_end_token(M),
442 value : from_moz(M.value),
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);
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);
465 prop.type = "Property";
466 return from_moz(prop);
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)
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
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)
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)
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)
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)
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)
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)
549 ExportAllDeclaration: function(M) {
550 return new AST_Export({
551 start: my_start_token(M),
552 end: my_end_token(M),
554 new AST_NameMapping({
555 name: new AST_SymbolExportForeign({ name: "*" }),
556 foreign_name: new AST_SymbolExportForeign({ name: "*" })
559 module_name: from_moz(M.source),
560 assert_clause: assert_clause_from_moz(M.assertions)
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)
575 module_name: from_moz(M.source),
576 assert_clause: assert_clause_from_moz(M.assertions)
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),
589 Literal: function(M) {
590 var val = M.value, args = {
591 start : my_start_token(M),
592 end : my_end_token(M)
595 if (rx && rx.pattern) {
596 // RegExpLiteral as per ESTree AST spec
601 return new AST_RegExp(args);
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);
611 if (val === null) return new AST_Null(args);
612 switch (typeof val) {
615 return new AST_String(args);
618 args.raw = M.raw || val.toString();
619 return new AST_Number(args);
621 return new (val ? AST_True : AST_False)(args);
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),
631 } else if (M.meta.name === "import" && M.property.name === "meta") {
632 return new AST_ImportMeta({
633 start: my_start_token(M),
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
656 start : my_start_token(M),
657 end : my_end_token(M),
663 return new AST_BigInt({
664 start : my_start_token(M),
665 end : my_end_token(M),
670 EmptyStatement: function(M) {
671 return new AST_EmptyStatement({
672 start: my_start_token(M),
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)
685 IfStatement: function(M) {
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)
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)
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)
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)
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)
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)
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)
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)
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)
763 DoWhileStatement: function(M) {
765 start: my_start_token(M),
766 end: my_end_token(M),
767 condition: from_moz(M.test),
768 body: from_moz(M.body)
772 ForStatement: function(M) {
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)
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)
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),
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)
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),
821 DebuggerStatement: function(M) {
822 return new AST_Debugger({
823 start: my_start_token(M),
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)
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
846 ThisExpression: function(M) {
847 return new AST_This({
848 start: my_start_token(M),
854 return new AST_Super({
855 start: my_start_token(M),
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)
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)
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)
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)
900 NewExpression: function(M) {
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)
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)
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)
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)
943 def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() {
945 type: "EmptyStatement"
948 def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) {
950 type: "BlockStatement",
951 body: M.body.map(to_moz)
954 def_to_moz(AST_If, function To_Moz_IfStatement(M) {
957 test: to_moz(M.condition),
958 consequent: to_moz(M.body),
959 alternate: to_moz(M.alternative)
962 def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) {
964 type: "LabeledStatement",
965 label: to_moz(M.label),
969 def_to_moz(AST_Break, function To_Moz_BreakStatement(M) {
971 type: "BreakStatement",
972 label: to_moz(M.label)
975 def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) {
977 type: "ContinueStatement",
978 label: to_moz(M.label)
981 def_to_moz(AST_With, function To_Moz_WithStatement(M) {
983 type: "WithStatement",
984 object: to_moz(M.expression),
988 def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) {
990 type: "SwitchStatement",
991 discriminant: to_moz(M.expression),
992 cases: M.body.map(to_moz)
995 def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) {
997 type: "ReturnStatement",
998 argument: to_moz(M.value)
1001 def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) {
1003 type: "ThrowStatement",
1004 argument: to_moz(M.value)
1007 def_to_moz(AST_While, function To_Moz_WhileStatement(M) {
1009 type: "WhileStatement",
1010 test: to_moz(M.condition),
1011 body: to_moz(M.body)
1014 def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) {
1016 type: "DoWhileStatement",
1017 test: to_moz(M.condition),
1018 body: to_moz(M.body)
1021 def_to_moz(AST_For, function To_Moz_ForStatement(M) {
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)
1030 def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) {
1032 type: "ForInStatement",
1033 left: to_moz(M.init),
1034 right: to_moz(M.object),
1035 body: to_moz(M.body)
1038 def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) {
1040 type: "ForOfStatement",
1041 left: to_moz(M.init),
1042 right: to_moz(M.object),
1043 body: to_moz(M.body),
1047 def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) {
1049 type: "AwaitExpression",
1050 argument: to_moz(M.expression)
1053 def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) {
1055 type: "YieldExpression",
1056 argument: to_moz(M.expression),
1060 def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() {
1062 type: "DebuggerStatement"
1065 def_to_moz(AST_VarDef, function To_Moz_VariableDeclarator(M) {
1067 type: "VariableDeclarator",
1069 init: to_moz(M.value)
1072 def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
1074 type: "CatchClause",
1075 param: to_moz(M.argname),
1076 body: to_moz_block(M)
1080 def_to_moz(AST_This, function To_Moz_ThisExpression() {
1082 type: "ThisExpression"
1085 def_to_moz(AST_Super, function To_Moz_Super() {
1090 def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
1092 type: "BinaryExpression",
1093 operator: M.operator,
1094 left: to_moz(M.left),
1095 right: to_moz(M.right)
1098 def_to_moz(AST_Binary, function To_Moz_LogicalExpression(M) {
1100 type: "LogicalExpression",
1101 operator: M.operator,
1102 left: to_moz(M.left),
1103 right: to_moz(M.right)
1106 def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) {
1108 type: "AssignmentExpression",
1109 operator: M.operator,
1110 left: to_moz(M.left),
1111 right: to_moz(M.right)
1114 def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) {
1116 type: "ConditionalExpression",
1117 test: to_moz(M.condition),
1118 consequent: to_moz(M.consequent),
1119 alternate: to_moz(M.alternative)
1122 def_to_moz(AST_New, function To_Moz_NewExpression(M) {
1124 type: "NewExpression",
1125 callee: to_moz(M.expression),
1126 arguments: M.args.map(to_moz)
1129 def_to_moz(AST_Call, function To_Moz_CallExpression(M) {
1131 type: "CallExpression",
1132 callee: to_moz(M.expression),
1133 optional: M.optional,
1134 arguments: M.args.map(to_moz)
1138 def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
1139 return to_moz_scope("Program", M);
1142 def_to_moz(AST_Expansion, function To_Moz_Spread(M) {
1144 type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement",
1145 argument: to_moz(M.expression)
1149 def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) {
1151 type: "TaggedTemplateExpression",
1152 tag: to_moz(M.prefix),
1153 quasi: to_moz(M.template_string)
1157 def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) {
1159 var expressions = [];
1160 for (var i = 0; i < M.segments.length; i++) {
1162 expressions.push(to_moz(M.segments[i]));
1165 type: "TemplateElement",
1167 raw: M.segments[i].raw,
1168 cooked: M.segments[i].value
1170 tail: i === M.segments.length - 1
1175 type: "TemplateLiteral",
1177 expressions: expressions
1181 def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
1183 type: "FunctionDeclaration",
1185 params: M.argnames.map(to_moz),
1186 generator: M.is_generator,
1188 body: to_moz_scope("BlockStatement", M)
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;
1196 type: "FunctionExpression",
1198 params: M.argnames.map(to_moz),
1199 generator: is_generator,
1201 body: to_moz_scope("BlockStatement", M)
1205 def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) {
1207 type: "BlockStatement",
1208 body: M.body.map(to_moz)
1211 type: "ArrowFunctionExpression",
1212 params: M.argnames.map(to_moz),
1218 def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) {
1221 type: "ArrayPattern",
1222 elements: M.names.map(to_moz)
1226 type: "ObjectPattern",
1227 properties: M.names.map(to_moz)
1231 def_to_moz(AST_Directive, function To_Moz_Directive(M) {
1233 type: "ExpressionStatement",
1237 raw: M.print_to_string()
1243 def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
1245 type: "ExpressionStatement",
1246 expression: to_moz(M.body)
1250 def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
1253 test: to_moz(M.expression),
1254 consequent: M.body.map(to_moz)
1258 def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
1260 type: "TryStatement",
1261 block: to_moz_block(M),
1262 handler: to_moz(M.bcatch),
1263 guardedHandlers: [],
1264 finalizer: to_moz(M.bfinally)
1268 def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
1270 type: "CatchClause",
1271 param: to_moz(M.argname),
1273 body: to_moz_block(M)
1277 def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
1279 type: "VariableDeclaration",
1281 M instanceof AST_Const ? "const" :
1282 M instanceof AST_Let ? "let" : "var",
1283 declarations: M.definitions.map(to_moz)
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) };
1295 type: "ImportAttribute",
1297 value: to_moz(value)
1304 def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
1305 if (M.exported_names) {
1306 if (M.exported_names[0].name.name === "*") {
1308 type: "ExportAllDeclaration",
1309 source: to_moz(M.module_name),
1310 assertions: assert_clause_to_moz(M.assert_clause)
1314 type: "ExportNamedDeclaration",
1315 specifiers: M.exported_names.map(function (name_mapping) {
1317 type: "ExportSpecifier",
1318 exported: to_moz(name_mapping.foreign_name),
1319 local: to_moz(name_mapping.name)
1322 declaration: to_moz(M.exported_definition),
1323 source: to_moz(M.module_name),
1324 assertions: assert_clause_to_moz(M.assert_clause)
1328 type: M.is_default ? "ExportDefaultDeclaration" : "ExportNamedDeclaration",
1329 declaration: to_moz(M.exported_value || M.exported_definition)
1333 def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
1334 var specifiers = [];
1335 if (M.imported_name) {
1337 type: "ImportDefaultSpecifier",
1338 local: to_moz(M.imported_name)
1341 if (M.imported_names && M.imported_names[0].foreign_name.name === "*") {
1343 type: "ImportNamespaceSpecifier",
1344 local: to_moz(M.imported_names[0].name)
1346 } else if (M.imported_names) {
1347 M.imported_names.forEach(function(name_mapping) {
1349 type: "ImportSpecifier",
1350 local: to_moz(name_mapping.name),
1351 imported: to_moz(name_mapping.foreign_name)
1356 type: "ImportDeclaration",
1357 specifiers: specifiers,
1358 source: to_moz(M.module_name),
1359 assertions: assert_clause_to_moz(M.assert_clause)
1363 def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
1365 type: "MetaProperty",
1377 def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
1379 type: "SequenceExpression",
1380 expressions: M.expressions.map(to_moz)
1384 def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) {
1386 type: "MemberExpression",
1387 object: to_moz(M.expression),
1390 type: "PrivateIdentifier",
1393 optional: M.optional
1397 def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
1398 var isComputed = M instanceof AST_Sub;
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
1408 def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
1410 type: "ChainExpression",
1411 expression: to_moz(M.expression)
1415 def_to_moz(AST_Unary, function To_Moz_Unary(M) {
1417 type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
1418 operator: M.operator,
1419 prefix: M instanceof AST_UnaryPrefix,
1420 argument: to_moz(M.expression)
1424 def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
1425 if (M.operator == "=" && to_moz_in_destructuring()) {
1427 type: "AssignmentPattern",
1428 left: to_moz(M.left),
1429 right: to_moz(M.right)
1433 const type = M.operator == "&&" || M.operator == "||" || M.operator === "??"
1434 ? "LogicalExpression"
1435 : "BinaryExpression";
1439 left: to_moz(M.left),
1440 operator: M.operator,
1441 right: to_moz(M.right)
1445 def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
1447 type: "ArrayExpression",
1448 elements: M.elements.map(to_moz)
1452 def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
1454 type: "ObjectExpression",
1455 properties: M.properties.map(to_moz)
1459 def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) {
1460 var key = M.key instanceof AST_Node ? to_moz(M.key) : {
1464 if (typeof M.key === "number") {
1467 value: Number(M.key)
1470 if (typeof M.key === "string") {
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) {
1481 computed = !string_or_num;
1483 if (M instanceof AST_ObjectGetter) {
1486 if (M instanceof AST_ObjectSetter) {
1489 if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) {
1490 const kind = M instanceof AST_PrivateGetter ? "get" : "set";
1492 type: "MethodDefinition",
1497 type: "PrivateIdentifier",
1500 value: to_moz(M.value)
1503 if (M instanceof AST_ClassPrivateProperty) {
1505 type: "PropertyDefinition",
1507 type: "PrivateIdentifier",
1510 value: to_moz(M.value),
1515 if (M instanceof AST_ClassProperty) {
1517 type: "PropertyDefinition",
1519 value: to_moz(M.value),
1524 if (parent instanceof AST_Class) {
1526 type: "MethodDefinition",
1531 value: to_moz(M.value)
1539 value: to_moz(M.value)
1543 def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) {
1544 if (parent instanceof AST_Object) {
1547 computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
1552 value: to_moz(M.value)
1556 const key = M instanceof AST_PrivateMethod
1558 type: "PrivateIdentifier",
1564 type: "MethodDefinition",
1565 kind: M.key === "constructor" ? "constructor" : "method",
1567 value: to_moz(M.value),
1568 computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
1573 def_to_moz(AST_Class, function To_Moz_Class(M) {
1574 var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration";
1577 superClass: to_moz(M.extends),
1578 id: M.name ? to_moz(M.name) : null,
1581 body: M.properties.map(to_moz)
1586 def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
1588 type: "MetaProperty",
1600 def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
1601 if (M instanceof AST_SymbolMethod && parent.quote) {
1607 var def = M.definition();
1610 name: def ? def.mangled_name || def.name : M.name
1614 def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
1615 const pattern = M.value.source;
1616 const flags = M.value.flags;
1620 raw: M.print_to_string(),
1621 regex: { pattern, flags }
1625 def_to_moz(AST_Constant, function To_Moz_Literal(M) {
1626 var value = M.value;
1630 raw: M.raw || M.print_to_string()
1634 def_to_moz(AST_Atom, function To_Moz_Atom(M) {
1637 name: String(M.value)
1641 def_to_moz(AST_BigInt, M => ({
1642 type: "BigIntLiteral",
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; });
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);
1653 /* -----[ tools ]----- */
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(
1661 start && start.line || 0,
1662 start && start.column || 0,
1663 range ? range [0] : moznode.start,
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(
1677 end && end.line || 0,
1678 end && end.column || 0,
1679 range ? range [0] : moznode.end,
1687 var FROM_MOZ_STACK = null;
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();
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;
1704 function set_moz_loc(mynode, moznode) {
1705 var start = mynode.start;
1706 var end = mynode.end;
1707 if (!(start && end)) {
1710 if (start.pos != null && end.endpos != null) {
1711 moznode.range = [start.pos, end.endpos];
1715 start: {line: start.line, column: start.col},
1716 end: end.endline ? {line: end.endline, column: end.endcol} : null
1719 moznode.loc.source = start.file;
1725 function def_to_moz(mytype, handler) {
1726 mytype.DEFMETHOD("to_mozilla_ast", function(parent) {
1727 return set_moz_loc(this, handler(this, parent));
1731 var TO_MOZ_STACK = null;
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;
1738 if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; }
1742 function to_moz_in_destructuring() {
1743 var i = TO_MOZ_STACK.length;
1745 if (TO_MOZ_STACK[i] instanceof AST_Destructuring) {
1752 function to_moz_block(node) {
1754 type: "BlockStatement",
1755 body: node.body.map(to_moz)
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])));