1package js
2
3import (
4	"bytes"
5	"fmt"
6	"strconv"
7)
8
9var ErrInvalidJSON = fmt.Errorf("invalid JSON")
10
11// AST is the full ECMAScript abstract syntax tree.
12type AST struct {
13	Comments  [][]byte // first comments in file
14	BlockStmt          // module
15}
16
17func (ast *AST) String() string {
18	s := ""
19	for i, item := range ast.BlockStmt.List {
20		if i != 0 {
21			s += " "
22		}
23		s += item.String()
24	}
25	return s
26}
27
28////////////////////////////////////////////////////////////////
29
30// DeclType specifies the kind of declaration.
31type DeclType uint16
32
33// DeclType values.
34const (
35	NoDecl       DeclType = iota // undeclared variables
36	VariableDecl                 // var
37	FunctionDecl                 // function
38	ArgumentDecl                 // function and method arguments
39	LexicalDecl                  // let, const, class
40	CatchDecl                    // catch statement argument
41	ExprDecl                     // function expression name or class expression name
42)
43
44func (decl DeclType) String() string {
45	switch decl {
46	case NoDecl:
47		return "NoDecl"
48	case VariableDecl:
49		return "VariableDecl"
50	case FunctionDecl:
51		return "FunctionDecl"
52	case ArgumentDecl:
53		return "ArgumentDecl"
54	case LexicalDecl:
55		return "LexicalDecl"
56	case CatchDecl:
57		return "CatchDecl"
58	case ExprDecl:
59		return "ExprDecl"
60	}
61	return "Invalid(" + strconv.Itoa(int(decl)) + ")"
62}
63
64// Var is a variable, where Decl is the type of declaration and can be var|function for function scoped variables, let|const|class for block scoped variables.
65type Var struct {
66	Data []byte
67	Link *Var // is set when merging variable uses, as in:  {a} {var a}  where the first links to the second, only used for undeclared variables
68	Uses uint16
69	Decl DeclType
70}
71
72// Name returns the variable name.
73func (v *Var) Name() []byte {
74	for v.Link != nil {
75		v = v.Link
76	}
77	return v.Data
78}
79
80func (v Var) String() string {
81	return string(v.Name())
82}
83
84// JS converts the node back to valid JavaScript
85func (v Var) JS() string {
86	return v.String()
87}
88
89// JSON converts the node back to valid JSON
90func (n Var) JSON() (string, error) {
91	return "", ErrInvalidJSON
92}
93
94// VarsByUses is sortable by uses in descending order.
95type VarsByUses VarArray
96
97func (vs VarsByUses) Len() int {
98	return len(vs)
99}
100
101func (vs VarsByUses) Swap(i, j int) {
102	vs[i], vs[j] = vs[j], vs[i]
103}
104
105func (vs VarsByUses) Less(i, j int) bool {
106	return vs[i].Uses > vs[j].Uses
107}
108
109////////////////////////////////////////////////////////////////
110
111// VarArray is a set of variables in scopes.
112type VarArray []*Var
113
114func (vs VarArray) String() string {
115	s := "["
116	for i, v := range vs {
117		if i != 0 {
118			s += ", "
119		}
120		links := 0
121		for v.Link != nil {
122			v = v.Link
123			links++
124		}
125		s += fmt.Sprintf("Var{%v %s %v %v}", v.Decl, string(v.Data), links, v.Uses)
126	}
127	return s + "]"
128}
129
130// Scope is a function or block scope with a list of variables declared and used.
131type Scope struct {
132	Parent, Func   *Scope   // Parent is nil for global scope, Parent equals Func for function scope
133	Declared       VarArray // Link in Var are always nil
134	Undeclared     VarArray
135	NumVarDecls    uint16 // number of variable declaration statements in a function scope
136	NumForInit     uint16 // offset into Declared to mark variables used in for initializer
137	NumArguments   uint16 // offset into Undeclared to mark variables used in arguments
138	IsGlobalOrFunc bool
139	HasWith        bool
140}
141
142func (s Scope) String() string {
143	return "Scope{Declared: " + s.Declared.String() + ", Undeclared: " + s.Undeclared.String() + "}"
144}
145
146// Declare declares a new variable.
147func (s *Scope) Declare(decl DeclType, name []byte) (*Var, bool) {
148	// refer to new variable for previously undeclared symbols in the current and lower scopes
149	// this happens in `{ a = 5; } var a` where both a's refer to the same variable
150	curScope := s
151	if decl == VariableDecl || decl == FunctionDecl {
152		// find function scope for var and function declarations
153		for s != s.Func {
154			// make sure that `{let i;{var i}}` is an error
155			if v := s.findDeclared(name, false); v != nil && v.Decl != decl && v.Decl != CatchDecl {
156				return nil, false
157			}
158			s = s.Parent
159		}
160	}
161
162	if v := s.findDeclared(name, true); v != nil {
163		// variable already declared, might be an error or a duplicate declaration
164		if (LexicalDecl <= v.Decl || LexicalDecl <= decl) && v.Decl != ExprDecl {
165			// redeclaration of let, const, class on an already declared name is an error, except if the declared name is a function expression name
166			return nil, false
167		}
168		if v.Decl == ExprDecl {
169			v.Decl = decl
170		}
171		v.Uses++
172		for s != curScope {
173			curScope.addUndeclared(v) // add variable declaration as used variable to the current scope
174			curScope = curScope.Parent
175		}
176		return v, true
177	}
178
179	var v *Var
180	// reuse variable if previously used, as in:  a;var a
181	if decl != ArgumentDecl { // in case of function f(a=b,b), where the first b is different from the second
182		for i, uv := range s.Undeclared[s.NumArguments:] {
183			// no need to evaluate v.Link as v.Data stays the same and Link is nil in the active scope
184			if 0 < uv.Uses && uv.Decl == NoDecl && bytes.Equal(name, uv.Data) {
185				// must be NoDecl so that it can't be a var declaration that has been added
186				v = uv
187				s.Undeclared = append(s.Undeclared[:int(s.NumArguments)+i], s.Undeclared[int(s.NumArguments)+i+1:]...)
188				break
189			}
190		}
191	}
192	if v == nil {
193		// add variable to the context list and to the scope
194		v = &Var{name, nil, 0, decl}
195	} else {
196		v.Decl = decl
197	}
198	v.Uses++
199	s.Declared = append(s.Declared, v)
200	for s != curScope {
201		curScope.addUndeclared(v) // add variable declaration as used variable to the current scope
202		curScope = curScope.Parent
203	}
204	return v, true
205}
206
207// Use increments the usage of a variable.
208func (s *Scope) Use(name []byte) *Var {
209	// check if variable is declared in the current scope
210	v := s.findDeclared(name, false)
211	if v == nil {
212		// check if variable is already used before in the current or lower scopes
213		v = s.findUndeclared(name)
214		if v == nil {
215			// add variable to the context list and to the scope's undeclared
216			v = &Var{name, nil, 0, NoDecl}
217			s.Undeclared = append(s.Undeclared, v)
218		}
219	}
220	v.Uses++
221	return v
222}
223
224// findDeclared finds a declared variable in the current scope.
225func (s *Scope) findDeclared(name []byte, skipForInit bool) *Var {
226	start := 0
227	if skipForInit {
228		// we skip the for initializer for declarations (only has effect for let/const)
229		start = int(s.NumForInit)
230	}
231	// reverse order to find the inner let first in `for(let a in []){let a; {a}}`
232	for i := len(s.Declared) - 1; start <= i; i-- {
233		v := s.Declared[i]
234		// no need to evaluate v.Link as v.Data stays the same, and Link is always nil in Declared
235		if bytes.Equal(name, v.Data) {
236			return v
237		}
238	}
239	return nil
240}
241
242// findUndeclared finds an undeclared variable in the current and contained scopes.
243func (s *Scope) findUndeclared(name []byte) *Var {
244	for _, v := range s.Undeclared {
245		// no need to evaluate v.Link as v.Data stays the same and Link is nil in the active scope
246		if 0 < v.Uses && bytes.Equal(name, v.Data) {
247			return v
248		}
249	}
250	return nil
251}
252
253// add undeclared variable to scope, this is called for the block scope when declaring a var in it
254func (s *Scope) addUndeclared(v *Var) {
255	// don't add undeclared symbol if it's already there
256	for _, vorig := range s.Undeclared {
257		if v == vorig {
258			return
259		}
260	}
261	s.Undeclared = append(s.Undeclared, v) // add variable declaration as used variable to the current scope
262}
263
264// MarkForInit marks the declared variables in current scope as for statement initializer to distinguish from declarations in body.
265func (s *Scope) MarkForInit() {
266	s.NumForInit = uint16(len(s.Declared))
267}
268
269// MarkArguments marks the undeclared variables in the current scope as function arguments. It ensures different b's in `function f(a=b){var b}`.
270func (s *Scope) MarkArguments() {
271	s.NumArguments = uint16(len(s.Undeclared))
272}
273
274// HoistUndeclared copies all undeclared variables of the current scope to the parent scope.
275func (s *Scope) HoistUndeclared() {
276	for i, vorig := range s.Undeclared {
277		// no need to evaluate vorig.Link as vorig.Data stays the same
278		if 0 < vorig.Uses && vorig.Decl == NoDecl {
279			if v := s.Parent.findDeclared(vorig.Data, false); v != nil {
280				// check if variable is declared in parent scope
281				v.Uses += vorig.Uses
282				vorig.Link = v
283				s.Undeclared[i] = v // point reference to existing var (to avoid many Link chains)
284			} else if v := s.Parent.findUndeclared(vorig.Data); v != nil {
285				// check if variable is already used before in parent scope
286				v.Uses += vorig.Uses
287				vorig.Link = v
288				s.Undeclared[i] = v // point reference to existing var (to avoid many Link chains)
289			} else {
290				// add variable to the context list and to the scope's undeclared
291				s.Parent.Undeclared = append(s.Parent.Undeclared, vorig)
292			}
293		}
294	}
295}
296
297// UndeclareScope undeclares all declared variables in the current scope and adds them to the parent scope.
298// Called when possible arrow func ends up being a parenthesized expression, scope is not further used.
299func (s *Scope) UndeclareScope() {
300	// look if the variable already exists in the parent scope, if so replace the Var pointer in original use
301	for _, vorig := range s.Declared {
302		// no need to evaluate vorig.Link as vorig.Data stays the same, and Link is always nil in Declared
303		// vorig.Uses will be atleast 1
304		if v := s.Parent.findDeclared(vorig.Data, false); v != nil {
305			// check if variable has been declared in this scope
306			v.Uses += vorig.Uses
307			vorig.Link = v
308		} else if v := s.Parent.findUndeclared(vorig.Data); v != nil {
309			// check if variable is already used before in the current or lower scopes
310			v.Uses += vorig.Uses
311			vorig.Link = v
312		} else {
313			// add variable to the context list and to the scope's undeclared
314			vorig.Decl = NoDecl
315			s.Parent.Undeclared = append(s.Parent.Undeclared, vorig)
316		}
317	}
318	s.Declared = s.Declared[:0]
319	s.Undeclared = s.Undeclared[:0]
320}
321
322// Unscope moves all declared variables of the current scope to the parent scope. Undeclared variables are already in the parent scope.
323func (s *Scope) Unscope() {
324	for _, vorig := range s.Declared {
325		// no need to evaluate vorig.Link as vorig.Data stays the same, and Link is always nil in Declared
326		// vorig.Uses will be atleast 1
327		s.Parent.Declared = append(s.Parent.Declared, vorig)
328	}
329	s.Declared = s.Declared[:0]
330	s.Undeclared = s.Undeclared[:0]
331}
332
333////////////////////////////////////////////////////////////////
334
335// INode is an interface for AST nodes
336type INode interface {
337	String() string
338	JS() string
339	JSON() (string, error)
340}
341
342// IStmt is a dummy interface for statements.
343type IStmt interface {
344	INode
345	stmtNode()
346}
347
348// IBinding is a dummy interface for bindings.
349type IBinding interface {
350	INode
351	bindingNode()
352}
353
354// IExpr is a dummy interface for expressions.
355type IExpr interface {
356	INode
357	exprNode()
358}
359
360////////////////////////////////////////////////////////////////
361
362// BlockStmt is a block statement.
363type BlockStmt struct {
364	List []IStmt
365	Scope
366}
367
368func (n BlockStmt) String() string {
369	s := "Stmt({"
370	for _, item := range n.List {
371		s += " " + item.String()
372	}
373	return s + " })"
374}
375
376// JS converts the node back to valid JavaScript
377func (n BlockStmt) JS() string {
378	s := ""
379	if n.Scope.Parent != nil {
380		s += "{ "
381	}
382	for _, item := range n.List {
383		s += item.JS() + "; "
384	}
385	if n.Scope.Parent != nil {
386		s += "}"
387	}
388	return s
389}
390
391// JSON converts the node back to valid JSON
392func (n BlockStmt) JSON() (string, error) {
393	if len(n.List) != 1 {
394		return "", ErrInvalidJSON
395	}
396	return n.List[0].JSON()
397}
398
399// EmptyStmt is an empty statement.
400type EmptyStmt struct {
401}
402
403func (n EmptyStmt) String() string {
404	return "Stmt(;)"
405}
406
407// JS converts the node back to valid JavaScript
408func (n EmptyStmt) JS() string {
409	return ";"
410}
411
412// JSON converts the node back to valid JSON
413func (n EmptyStmt) JSON() (string, error) {
414	return "", ErrInvalidJSON
415}
416
417// ExprStmt is an expression statement.
418type ExprStmt struct {
419	Value IExpr
420}
421
422func (n ExprStmt) String() string {
423	val := n.Value.String()
424	if val[0] == '(' && val[len(val)-1] == ')' {
425		return "Stmt" + n.Value.String()
426	}
427	return "Stmt(" + n.Value.String() + ")"
428}
429
430// JS converts the node back to valid JavaScript
431func (n ExprStmt) JS() string {
432	return n.Value.JS()
433}
434
435// JSON converts the node back to valid JSON
436func (n ExprStmt) JSON() (string, error) {
437	return n.Value.JSON()
438}
439
440// IfStmt is an if statement.
441type IfStmt struct {
442	Cond IExpr
443	Body IStmt
444	Else IStmt // can be nil
445}
446
447func (n IfStmt) String() string {
448	s := "Stmt(if " + n.Cond.String() + " " + n.Body.String()
449	if n.Else != nil {
450		s += " else " + n.Else.String()
451	}
452	return s + ")"
453}
454
455// JS converts the node back to valid JavaScript
456func (n IfStmt) JS() string {
457	s := "if (" + n.Cond.JS() + ") "
458	switch n.Body.(type) {
459	case *BlockStmt:
460		s += n.Body.JS()
461	default:
462		s += "{ " + n.Body.JS() + " }"
463	}
464	if n.Else != nil {
465		switch n.Else.(type) {
466		case *BlockStmt:
467			s += " else " + n.Else.JS()
468		default:
469			s += " else { " + n.Else.JS() + " }"
470		}
471	}
472	return s
473}
474
475// JSON converts the node back to valid JSON
476func (n IfStmt) JSON() (string, error) {
477	return "", ErrInvalidJSON
478}
479
480// DoWhileStmt is a do-while iteration statement.
481type DoWhileStmt struct {
482	Cond IExpr
483	Body IStmt
484}
485
486func (n DoWhileStmt) String() string {
487	return "Stmt(do " + n.Body.String() + " while " + n.Cond.String() + ")"
488}
489
490// JS converts the node back to valid JavaScript
491func (n DoWhileStmt) JS() string {
492	s := "do "
493	switch n.Body.(type) {
494	case *BlockStmt:
495		s += n.Body.JS()
496	default:
497		s += "{ " + n.Body.JS() + " }"
498	}
499	return s + " while (" + n.Cond.JS() + ")"
500}
501
502// JSON converts the node back to valid JSON
503func (n DoWhileStmt) JSON() (string, error) {
504	return "", ErrInvalidJSON
505}
506
507// WhileStmt is a while iteration statement.
508type WhileStmt struct {
509	Cond IExpr
510	Body IStmt
511}
512
513func (n WhileStmt) String() string {
514	return "Stmt(while " + n.Cond.String() + " " + n.Body.String() + ")"
515}
516
517// JS converts the node back to valid JavaScript
518func (n WhileStmt) JS() string {
519	s := "while (" + n.Cond.JS() + ") "
520	if n.Body != nil {
521		s += n.Body.JS()
522	}
523	return s
524}
525
526// JSON converts the node back to valid JSON
527func (n WhileStmt) JSON() (string, error) {
528	return "", ErrInvalidJSON
529}
530
531// ForStmt is a regular for iteration statement.
532type ForStmt struct {
533	Init IExpr // can be nil
534	Cond IExpr // can be nil
535	Post IExpr // can be nil
536	Body *BlockStmt
537}
538
539func (n ForStmt) String() string {
540	s := "Stmt(for"
541	if n.Init != nil {
542		s += " " + n.Init.String()
543	}
544	s += " ;"
545	if n.Cond != nil {
546		s += " " + n.Cond.String()
547	}
548	s += " ;"
549	if n.Post != nil {
550		s += " " + n.Post.String()
551	}
552	return s + " " + n.Body.String() + ")"
553}
554
555// JS converts the node back to valid JavaScript
556func (n ForStmt) JS() string {
557	s := "for ("
558	if n.Init != nil {
559		s += n.Init.JS()
560	} else {
561		s += " "
562	}
563	s += "; "
564	if n.Cond != nil {
565		s += n.Cond.JS()
566	}
567	s += "; "
568	if n.Post != nil {
569		s += n.Post.JS()
570	}
571	return s + ") " + n.Body.JS()
572}
573
574// JSON converts the node back to valid JSON
575func (n ForStmt) JSON() (string, error) {
576	return "", ErrInvalidJSON
577}
578
579// ForInStmt is a for-in iteration statement.
580type ForInStmt struct {
581	Init  IExpr
582	Value IExpr
583	Body  *BlockStmt
584}
585
586func (n ForInStmt) String() string {
587	return "Stmt(for " + n.Init.String() + " in " + n.Value.String() + " " + n.Body.String() + ")"
588}
589
590// JS converts the node back to valid JavaScript
591func (n ForInStmt) JS() string {
592	return "for (" + n.Init.JS() + " in " + n.Value.JS() + ") " + n.Body.JS()
593}
594
595// JSON converts the node back to valid JSON
596func (n ForInStmt) JSON() (string, error) {
597	return "", ErrInvalidJSON
598}
599
600// ForOfStmt is a for-of iteration statement.
601type ForOfStmt struct {
602	Await bool
603	Init  IExpr
604	Value IExpr
605	Body  *BlockStmt
606}
607
608func (n ForOfStmt) String() string {
609	s := "Stmt(for"
610	if n.Await {
611		s += " await"
612	}
613	return s + " " + n.Init.String() + " of " + n.Value.String() + " " + n.Body.String() + ")"
614}
615
616// JS converts the node back to valid JavaScript
617func (n ForOfStmt) JS() string {
618	s := "for"
619	if n.Await {
620		s += " await"
621	}
622	return s + " (" + n.Init.JS() + " of " + n.Value.JS() + ") " + n.Body.JS()
623}
624
625// JSON converts the node back to valid JSON
626func (n ForOfStmt) JSON() (string, error) {
627	return "", ErrInvalidJSON
628}
629
630// CaseClause is a case clause or default clause for a switch statement.
631type CaseClause struct {
632	TokenType
633	Cond IExpr // can be nil
634	List []IStmt
635}
636
637func (n CaseClause) String() string {
638	s := " Clause(" + n.TokenType.String()
639	if n.Cond != nil {
640		s += " " + n.Cond.String()
641	}
642	for _, item := range n.List {
643		s += " " + item.String()
644	}
645	return s + ")"
646}
647
648// JS converts the node back to valid JavaScript
649func (n CaseClause) JS() string {
650	s := " "
651	if n.Cond != nil {
652		s += "case " + n.Cond.JS()
653	} else {
654		s += "default"
655	}
656	s += ":"
657	for _, item := range n.List {
658		s += " " + item.JS() + ";"
659	}
660	return s
661}
662
663// JSON converts the node back to valid JSON
664func (n CaseClause) JSON() (string, error) {
665	return "", ErrInvalidJSON
666}
667
668// SwitchStmt is a switch statement.
669type SwitchStmt struct {
670	Init IExpr
671	List []CaseClause
672	Scope
673}
674
675func (n SwitchStmt) String() string {
676	s := "Stmt(switch " + n.Init.String()
677	for _, clause := range n.List {
678		s += clause.String()
679	}
680	return s + ")"
681}
682
683// JS converts the node back to valid JavaScript
684func (n SwitchStmt) JS() string {
685	s := "switch (" + n.Init.JS() + ") {"
686	for _, clause := range n.List {
687		s += clause.JS()
688	}
689	return s + " }"
690}
691
692// JSON converts the node back to valid JSON
693func (n SwitchStmt) JSON() (string, error) {
694	return "", ErrInvalidJSON
695}
696
697// BranchStmt is a continue or break statement.
698type BranchStmt struct {
699	Type  TokenType
700	Label []byte // can be nil
701}
702
703func (n BranchStmt) String() string {
704	s := "Stmt(" + n.Type.String()
705	if n.Label != nil {
706		s += " " + string(n.Label)
707	}
708	return s + ")"
709}
710
711// JS converts the node back to valid JavaScript
712func (n BranchStmt) JS() string {
713	s := n.Type.String()
714	if n.Label != nil {
715		s += " " + string(n.Label)
716	}
717	return s
718}
719
720// JSON converts the node back to valid JSON
721func (n BranchStmt) JSON() (string, error) {
722	return "", ErrInvalidJSON
723}
724
725// ReturnStmt is a return statement.
726type ReturnStmt struct {
727	Value IExpr // can be nil
728}
729
730func (n ReturnStmt) String() string {
731	s := "Stmt(return"
732	if n.Value != nil {
733		s += " " + n.Value.String()
734	}
735	return s + ")"
736}
737
738// JS converts the node back to valid JavaScript
739func (n ReturnStmt) JS() string {
740	s := "return"
741	if n.Value != nil {
742		s += " " + n.Value.JS()
743	}
744	return s
745}
746
747// JSON converts the node back to valid JSON
748func (n ReturnStmt) JSON() (string, error) {
749	return "", ErrInvalidJSON
750}
751
752// WithStmt is a with statement.
753type WithStmt struct {
754	Cond IExpr
755	Body IStmt
756}
757
758func (n WithStmt) String() string {
759	return "Stmt(with " + n.Cond.String() + " " + n.Body.String() + ")"
760}
761
762// JS converts the node back to valid JavaScript
763func (n WithStmt) JS() string {
764	return "with (" + n.Cond.JS() + ") " + n.Body.JS()
765}
766
767// JSON converts the node back to valid JSON
768func (n WithStmt) JSON() (string, error) {
769	return "", ErrInvalidJSON
770}
771
772// LabelledStmt is a labelled statement.
773type LabelledStmt struct {
774	Label []byte
775	Value IStmt
776}
777
778func (n LabelledStmt) String() string {
779	return "Stmt(" + string(n.Label) + " : " + n.Value.String() + ")"
780}
781
782// JS converts the node back to valid JavaScript
783func (n LabelledStmt) JS() string {
784	return string(n.Label) + ": " + n.Value.JS()
785}
786
787// JSON converts the node back to valid JSON
788func (n LabelledStmt) JSON() (string, error) {
789	return "", ErrInvalidJSON
790}
791
792// ThrowStmt is a throw statement.
793type ThrowStmt struct {
794	Value IExpr
795}
796
797func (n ThrowStmt) String() string {
798	return "Stmt(throw " + n.Value.String() + ")"
799}
800
801// JS converts the node back to valid JavaScript
802func (n ThrowStmt) JS() string {
803	return "throw " + n.Value.JS()
804}
805
806// JSON converts the node back to valid JSON
807func (n ThrowStmt) JSON() (string, error) {
808	return "", ErrInvalidJSON
809}
810
811// TryStmt is a try statement.
812type TryStmt struct {
813	Body    *BlockStmt
814	Binding IBinding   // can be nil
815	Catch   *BlockStmt // can be nil
816	Finally *BlockStmt // can be nil
817}
818
819func (n TryStmt) String() string {
820	s := "Stmt(try " + n.Body.String()
821	if n.Catch != nil {
822		s += " catch"
823		if n.Binding != nil {
824			s += " Binding(" + n.Binding.String() + ")"
825		}
826		s += " " + n.Catch.String()
827	}
828	if n.Finally != nil {
829		s += " finally " + n.Finally.String()
830	}
831	return s + ")"
832}
833
834// JS converts the node back to valid JavaScript
835func (n TryStmt) JS() string {
836	s := "try " + n.Body.JS()
837	if n.Catch != nil {
838		s += " catch"
839		if n.Binding != nil {
840			s += "(" + n.Binding.JS() + ")"
841		}
842		s += " " + n.Catch.JS()
843	}
844	if n.Finally != nil {
845		s += " finally " + n.Finally.JS()
846	}
847	return s
848}
849
850// JSON converts the node back to valid JSON
851func (n TryStmt) JSON() (string, error) {
852	return "", ErrInvalidJSON
853}
854
855// DebuggerStmt is a debugger statement.
856type DebuggerStmt struct {
857}
858
859func (n DebuggerStmt) String() string {
860	return "Stmt(debugger)"
861}
862
863// JS converts the node back to valid JavaScript
864func (n DebuggerStmt) JS() string {
865	return "debugger"
866}
867
868// JSON converts the node back to valid JSON
869func (n DebuggerStmt) JSON() (string, error) {
870	return "", ErrInvalidJSON
871}
872
873// Alias is a name space import or import/export specifier for import/export statements.
874type Alias struct {
875	Name    []byte // can be nil
876	Binding []byte // can be nil
877}
878
879func (alias Alias) String() string {
880	s := ""
881	if alias.Name != nil {
882		s += string(alias.Name) + " as "
883	}
884	return s + string(alias.Binding)
885}
886
887// JS converts the node back to valid JavaScript
888func (alias Alias) JS() string {
889	return alias.String()
890}
891
892// JSON converts the node back to valid JSON
893func (n Alias) JSON() (string, error) {
894	return "", ErrInvalidJSON
895}
896
897// ImportStmt is an import statement.
898type ImportStmt struct {
899	List    []Alias
900	Default []byte // can be nil
901	Module  []byte
902}
903
904func (n ImportStmt) String() string {
905	s := "Stmt(import"
906	if n.Default != nil {
907		s += " " + string(n.Default)
908		if len(n.List) != 0 {
909			s += " ,"
910		}
911	}
912	if len(n.List) == 1 && len(n.List[0].Name) == 1 && n.List[0].Name[0] == '*' {
913		s += " " + n.List[0].String()
914	} else if 0 < len(n.List) {
915		s += " {"
916		for i, item := range n.List {
917			if i != 0 {
918				s += " ,"
919			}
920			if item.Binding != nil {
921				s += " " + item.String()
922			}
923		}
924		s += " }"
925	}
926	if n.Default != nil || len(n.List) != 0 {
927		s += " from"
928	}
929	return s + " " + string(n.Module) + ")"
930}
931
932// JS converts the node back to valid JavaScript
933func (n ImportStmt) JS() string {
934	s := "import"
935	if n.Default != nil {
936		s += " " + string(n.Default)
937		if len(n.List) != 0 {
938			s += " ,"
939		}
940	}
941	if len(n.List) == 1 && len(n.List[0].Name) == 1 && n.List[0].Name[0] == '*' {
942		s += " " + n.List[0].JS()
943	} else if 0 < len(n.List) {
944		s += " {"
945		for i, item := range n.List {
946			if i != 0 {
947				s += " ,"
948			}
949			if item.Binding != nil {
950				s += " " + item.JS()
951			}
952		}
953		s += " }"
954	}
955	if n.Default != nil || len(n.List) != 0 {
956		s += " from"
957	}
958	return s + " " + string(n.Module)
959}
960
961// JSON converts the node back to valid JSON
962func (n ImportStmt) JSON() (string, error) {
963	return "", ErrInvalidJSON
964}
965
966// ExportStmt is an export statement.
967type ExportStmt struct {
968	List    []Alias
969	Module  []byte // can be nil
970	Default bool
971	Decl    IExpr
972}
973
974func (n ExportStmt) String() string {
975	s := "Stmt(export"
976	if n.Decl != nil {
977		if n.Default {
978			s += " default"
979		}
980		return s + " " + n.Decl.String() + ")"
981	} else if len(n.List) == 1 && (len(n.List[0].Name) == 1 && n.List[0].Name[0] == '*' || n.List[0].Name == nil && len(n.List[0].Binding) == 1 && n.List[0].Binding[0] == '*') {
982		s += " " + n.List[0].String()
983	} else if 0 < len(n.List) {
984		s += " {"
985		for i, item := range n.List {
986			if i != 0 {
987				s += " ,"
988			}
989			if item.Binding != nil {
990				s += " " + item.String()
991			}
992		}
993		s += " }"
994	}
995	if n.Module != nil {
996		s += " from " + string(n.Module)
997	}
998	return s + ")"
999}
1000
1001// JS converts the node back to valid JavaScript
1002func (n ExportStmt) JS() string {
1003	s := "export"
1004	if n.Decl != nil {
1005		if n.Default {
1006			s += " default"
1007		}
1008		return s + " " + n.Decl.JS()
1009	} else if len(n.List) == 1 && (len(n.List[0].Name) == 1 && n.List[0].Name[0] == '*' || n.List[0].Name == nil && len(n.List[0].Binding) == 1 && n.List[0].Binding[0] == '*') {
1010		s += " " + n.List[0].JS()
1011	} else if 0 < len(n.List) {
1012		s += " {"
1013		for i, item := range n.List {
1014			if i != 0 {
1015				s += " ,"
1016			}
1017			if item.Binding != nil {
1018				s += " " + item.JS()
1019			}
1020		}
1021		s += " }"
1022	}
1023	if n.Module != nil {
1024		s += " from " + string(n.Module)
1025	}
1026	return s
1027}
1028
1029// JSON converts the node back to valid JSON
1030func (n ExportStmt) JSON() (string, error) {
1031	return "", ErrInvalidJSON
1032}
1033
1034// DirectivePrologueStmt is a string literal at the beginning of a function or module (usually "use strict").
1035type DirectivePrologueStmt struct {
1036	Value []byte
1037}
1038
1039func (n DirectivePrologueStmt) String() string {
1040	return "Stmt(" + string(n.Value) + ")"
1041}
1042
1043// JS converts the node back to valid JavaScript
1044func (n DirectivePrologueStmt) JS() string {
1045	return string(n.Value)
1046}
1047
1048// JSON converts the node back to valid JSON
1049func (n DirectivePrologueStmt) JSON() (string, error) {
1050	return "", ErrInvalidJSON
1051}
1052
1053func (n BlockStmt) stmtNode()             {}
1054func (n EmptyStmt) stmtNode()             {}
1055func (n ExprStmt) stmtNode()              {}
1056func (n IfStmt) stmtNode()                {}
1057func (n DoWhileStmt) stmtNode()           {}
1058func (n WhileStmt) stmtNode()             {}
1059func (n ForStmt) stmtNode()               {}
1060func (n ForInStmt) stmtNode()             {}
1061func (n ForOfStmt) stmtNode()             {}
1062func (n SwitchStmt) stmtNode()            {}
1063func (n BranchStmt) stmtNode()            {}
1064func (n ReturnStmt) stmtNode()            {}
1065func (n WithStmt) stmtNode()              {}
1066func (n LabelledStmt) stmtNode()          {}
1067func (n ThrowStmt) stmtNode()             {}
1068func (n TryStmt) stmtNode()               {}
1069func (n DebuggerStmt) stmtNode()          {}
1070func (n ImportStmt) stmtNode()            {}
1071func (n ExportStmt) stmtNode()            {}
1072func (n DirectivePrologueStmt) stmtNode() {}
1073
1074////////////////////////////////////////////////////////////////
1075
1076// PropertyName is a property name for binding properties, method names, and in object literals.
1077type PropertyName struct {
1078	Literal  LiteralExpr
1079	Computed IExpr // can be nil
1080}
1081
1082// IsSet returns true is PropertyName is not nil.
1083func (n PropertyName) IsSet() bool {
1084	return n.IsComputed() || n.Literal.TokenType != ErrorToken
1085}
1086
1087// IsComputed returns true if PropertyName is computed.
1088func (n PropertyName) IsComputed() bool {
1089	return n.Computed != nil
1090}
1091
1092// IsIdent returns true if PropertyName equals the given identifier name.
1093func (n PropertyName) IsIdent(data []byte) bool {
1094	return !n.IsComputed() && n.Literal.TokenType == IdentifierToken && bytes.Equal(data, n.Literal.Data)
1095}
1096
1097func (n PropertyName) String() string {
1098	if n.Computed != nil {
1099		val := n.Computed.String()
1100		if val[0] == '(' {
1101			return "[" + val[1:len(val)-1] + "]"
1102		}
1103		return "[" + val + "]"
1104	}
1105	return string(n.Literal.Data)
1106}
1107
1108// JS converts the node back to valid JavaScript
1109func (n PropertyName) JS() string {
1110	return n.String()
1111}
1112
1113// JSON converts the node back to valid JSON
1114func (n PropertyName) JSON() (string, error) {
1115	return "", ErrInvalidJSON
1116}
1117
1118// BindingArray is an array binding pattern.
1119type BindingArray struct {
1120	List []BindingElement
1121	Rest IBinding // can be nil
1122}
1123
1124func (n BindingArray) String() string {
1125	s := "["
1126	for i, item := range n.List {
1127		if i != 0 {
1128			s += ","
1129		}
1130		s += " " + item.String()
1131	}
1132	if n.Rest != nil {
1133		if len(n.List) != 0 {
1134			s += ","
1135		}
1136		s += " ...Binding(" + n.Rest.String() + ")"
1137	}
1138	return s + " ]"
1139}
1140
1141// JS converts the node back to valid JavaScript
1142func (n BindingArray) JS() string {
1143	s := "["
1144	for i, item := range n.List {
1145		if i != 0 {
1146			s += ","
1147		}
1148		s += item.JS()
1149	}
1150	if n.Rest != nil {
1151		if len(n.List) != 0 {
1152			s += ","
1153		}
1154		s += " ..." + n.Rest.JS()
1155	}
1156	return s + "]"
1157}
1158
1159// JSON converts the node back to valid JSON
1160func (n BindingArray) JSON() (string, error) {
1161	return "", ErrInvalidJSON
1162}
1163
1164// BindingObjectItem is a binding property.
1165type BindingObjectItem struct {
1166	Key   *PropertyName // can be nil
1167	Value BindingElement
1168}
1169
1170func (n BindingObjectItem) String() string {
1171	s := ""
1172	if n.Key != nil {
1173		if v, ok := n.Value.Binding.(*Var); !ok || !n.Key.IsIdent(v.Data) {
1174			s += " " + n.Key.String() + ":"
1175		}
1176	}
1177	return " " + n.Value.String()
1178}
1179
1180// JS converts the node back to valid JavaScript
1181func (n BindingObjectItem) JS() string {
1182	s := ""
1183	if n.Key != nil {
1184		if v, ok := n.Value.Binding.(*Var); !ok || !n.Key.IsIdent(v.Data) {
1185			s += " " + n.Key.JS() + ":"
1186		}
1187	}
1188	return " " + n.Value.JS()
1189}
1190
1191// JSON converts the node back to valid JSON
1192func (n BindingObjectItem) JSON() (string, error) {
1193	return "", ErrInvalidJSON
1194}
1195
1196// BindingObject is an object binding pattern.
1197type BindingObject struct {
1198	List []BindingObjectItem
1199	Rest *Var // can be nil
1200}
1201
1202func (n BindingObject) String() string {
1203	s := "{"
1204	for i, item := range n.List {
1205		if i != 0 {
1206			s += ","
1207		}
1208		if item.Key != nil {
1209			if v, ok := item.Value.Binding.(*Var); !ok || !item.Key.IsIdent(v.Data) {
1210				s += " " + item.Key.String() + ":"
1211			}
1212		}
1213		s += " " + item.Value.String()
1214	}
1215	if n.Rest != nil {
1216		if len(n.List) != 0 {
1217			s += ","
1218		}
1219		s += " ...Binding(" + string(n.Rest.Data) + ")"
1220	}
1221	return s + " }"
1222}
1223
1224// JS converts the node back to valid JavaScript
1225func (n BindingObject) JS() string {
1226	s := "{"
1227	for i, item := range n.List {
1228		if i != 0 {
1229			s += ","
1230		}
1231		if item.Key != nil {
1232			if v, ok := item.Value.Binding.(*Var); !ok || !item.Key.IsIdent(v.Data) {
1233				s += " " + item.Key.JS() + ":"
1234			}
1235		}
1236		s += " " + item.Value.JS()
1237	}
1238	if n.Rest != nil {
1239		if len(n.List) != 0 {
1240			s += ","
1241		}
1242		s += " ..." + string(n.Rest.Data)
1243	}
1244	return s + " }"
1245}
1246
1247// JSON converts the node back to valid JSON
1248func (n BindingObject) JSON() (string, error) {
1249	return "", ErrInvalidJSON
1250}
1251
1252// BindingElement is a binding element.
1253type BindingElement struct {
1254	Binding IBinding // can be nil (in case of ellision)
1255	Default IExpr    // can be nil
1256}
1257
1258func (n BindingElement) String() string {
1259	if n.Binding == nil {
1260		return "Binding()"
1261	}
1262	s := "Binding(" + n.Binding.String()
1263	if n.Default != nil {
1264		s += " = " + n.Default.String()
1265	}
1266	return s + ")"
1267}
1268
1269// JS converts the node back to valid JavaScript
1270func (n BindingElement) JS() string {
1271	if n.Binding == nil {
1272		return ""
1273	}
1274	s := n.Binding.JS()
1275	if n.Default != nil {
1276		s += " = " + n.Default.JS()
1277	}
1278	return s
1279}
1280
1281// JSON converts the node back to valid JSON
1282func (n BindingElement) JSON() (string, error) {
1283	return "", ErrInvalidJSON
1284}
1285
1286func (v *Var) bindingNode()          {}
1287func (n BindingArray) bindingNode()  {}
1288func (n BindingObject) bindingNode() {}
1289
1290////////////////////////////////////////////////////////////////
1291
1292// VarDecl is a variable statement or lexical declaration.
1293type VarDecl struct {
1294	TokenType
1295	List []BindingElement
1296}
1297
1298func (n VarDecl) String() string {
1299	s := "Decl(" + n.TokenType.String()
1300	for _, item := range n.List {
1301		s += " " + item.String()
1302	}
1303	return s + ")"
1304}
1305
1306// JS converts the node back to valid JavaScript
1307func (n VarDecl) JS() string {
1308	s := n.TokenType.String()
1309	for i, item := range n.List {
1310		if i != 0 {
1311			s += ","
1312		}
1313		s += " " + item.JS()
1314	}
1315	return s
1316}
1317
1318// JSON converts the node back to valid JSON
1319func (n VarDecl) JSON() (string, error) {
1320	return "", ErrInvalidJSON
1321}
1322
1323// Params is a list of parameters for functions, methods, and arrow function.
1324type Params struct {
1325	List []BindingElement
1326	Rest IBinding // can be nil
1327}
1328
1329func (n Params) String() string {
1330	s := "Params("
1331	for i, item := range n.List {
1332		if i != 0 {
1333			s += ", "
1334		}
1335		s += item.String()
1336	}
1337	if n.Rest != nil {
1338		if len(n.List) != 0 {
1339			s += ", "
1340		}
1341		s += "...Binding(" + n.Rest.String() + ")"
1342	}
1343	return s + ")"
1344}
1345
1346// JS converts the node back to valid JavaScript
1347func (n Params) JS() string {
1348	s := "("
1349	for i, item := range n.List {
1350		if i != 0 {
1351			s += ", "
1352		}
1353		s += item.JS()
1354	}
1355	if n.Rest != nil {
1356		if len(n.List) != 0 {
1357			s += ", "
1358		}
1359		s += "..." + n.Rest.JS()
1360	}
1361	return s + ")"
1362}
1363
1364// JSON converts the node back to valid JSON
1365func (n Params) JSON() (string, error) {
1366	return "", ErrInvalidJSON
1367}
1368
1369// FuncDecl is an (async) (generator) function declaration or expression.
1370type FuncDecl struct {
1371	Async     bool
1372	Generator bool
1373	Name      *Var // can be nil
1374	Params    Params
1375	Body      BlockStmt
1376}
1377
1378func (n FuncDecl) String() string {
1379	s := "Decl("
1380	if n.Async {
1381		s += "async function"
1382	} else {
1383		s += "function"
1384	}
1385	if n.Generator {
1386		s += "*"
1387	}
1388	if n.Name != nil {
1389		s += " " + string(n.Name.Data)
1390	}
1391	return s + " " + n.Params.String() + " " + n.Body.String() + ")"
1392}
1393
1394// JS converts the node back to valid JavaScript
1395func (n FuncDecl) JS() string {
1396	s := ""
1397	if n.Async {
1398		s += "async function"
1399	} else {
1400		s += "function"
1401	}
1402	if n.Generator {
1403		s += "*"
1404	}
1405	if n.Name != nil {
1406		s += " " + string(n.Name.Data)
1407	}
1408	return s + " " + n.Params.JS() + " " + n.Body.JS()
1409}
1410
1411// JSON converts the node back to valid JSON
1412func (n FuncDecl) JSON() (string, error) {
1413	return "", ErrInvalidJSON
1414}
1415
1416// MethodDecl is a method definition in a class declaration.
1417type MethodDecl struct {
1418	Static    bool
1419	Async     bool
1420	Generator bool
1421	Get       bool
1422	Set       bool
1423	Name      PropertyName
1424	Params    Params
1425	Body      BlockStmt
1426}
1427
1428func (n MethodDecl) String() string {
1429	s := ""
1430	if n.Static {
1431		s += " static"
1432	}
1433	if n.Async {
1434		s += " async"
1435	}
1436	if n.Generator {
1437		s += " *"
1438	}
1439	if n.Get {
1440		s += " get"
1441	}
1442	if n.Set {
1443		s += " set"
1444	}
1445	s += " " + n.Name.String() + " " + n.Params.String() + " " + n.Body.String()
1446	return "Method(" + s[1:] + ")"
1447}
1448
1449// JS converts the node back to valid JavaScript
1450func (n MethodDecl) JS() string {
1451	s := ""
1452	if n.Static {
1453		s += " static"
1454	}
1455	if n.Async {
1456		s += " async"
1457	}
1458	if n.Generator {
1459		s += " *"
1460	}
1461	if n.Get {
1462		s += " get"
1463	}
1464	if n.Set {
1465		s += " set"
1466	}
1467	s += " " + n.Name.JS() + " " + n.Params.JS() + " " + n.Body.JS()
1468	return s[1:]
1469}
1470
1471// JSON converts the node back to valid JSON
1472func (n MethodDecl) JSON() (string, error) {
1473	return "", ErrInvalidJSON
1474}
1475
1476// FieldDefinition is a field definition in a class declaration.
1477type FieldDefinition struct {
1478	Name PropertyName
1479	Init IExpr
1480}
1481
1482func (n FieldDefinition) String() string {
1483	s := "Definition(" + n.Name.String()
1484	if n.Init != nil {
1485		s += " = " + n.Init.String()
1486	}
1487	return s + ")"
1488}
1489
1490// JS converts the node back to valid JavaScript
1491func (n FieldDefinition) JS() string {
1492	s := n.Name.String()
1493	if n.Init != nil {
1494		s += " = " + n.Init.JS()
1495	}
1496	return s
1497}
1498
1499// JSON converts the node back to valid JSON
1500func (n FieldDefinition) JSON() (string, error) {
1501	return "", ErrInvalidJSON
1502}
1503
1504// ClassDecl is a class declaration.
1505type ClassDecl struct {
1506	Name        *Var  // can be nil
1507	Extends     IExpr // can be nil
1508	Definitions []FieldDefinition
1509	Methods     []*MethodDecl
1510}
1511
1512func (n ClassDecl) String() string {
1513	s := "Decl(class"
1514	if n.Name != nil {
1515		s += " " + string(n.Name.Data)
1516	}
1517	if n.Extends != nil {
1518		s += " extends " + n.Extends.String()
1519	}
1520	for _, item := range n.Definitions {
1521		s += " " + item.String()
1522	}
1523	for _, item := range n.Methods {
1524		s += " " + item.String()
1525	}
1526	return s + ")"
1527}
1528
1529// JS converts the node back to valid JavaScript
1530func (n ClassDecl) JS() string {
1531	s := "class"
1532	if n.Name != nil {
1533		s += " " + string(n.Name.Data)
1534	}
1535	if n.Extends != nil {
1536		s += " extends " + n.Extends.JS()
1537	}
1538	s += " { "
1539	for _, item := range n.Definitions {
1540		s += item.JS() + "; "
1541	}
1542	for _, item := range n.Methods {
1543		s += item.JS() + "; "
1544	}
1545	return s + "}"
1546}
1547
1548// JSON converts the node back to valid JSON
1549func (n ClassDecl) JSON() (string, error) {
1550	return "", ErrInvalidJSON
1551}
1552
1553func (n VarDecl) stmtNode()   {}
1554func (n FuncDecl) stmtNode()  {}
1555func (n ClassDecl) stmtNode() {}
1556
1557func (n VarDecl) exprNode()    {} // not a real IExpr, used for ForInit and ExportDecl
1558func (n FuncDecl) exprNode()   {}
1559func (n ClassDecl) exprNode()  {}
1560func (n MethodDecl) exprNode() {} // not a real IExpr, used for ObjectExpression PropertyName
1561
1562////////////////////////////////////////////////////////////////
1563
1564// LiteralExpr can be this, null, boolean, numeric, string, or regular expression literals.
1565type LiteralExpr struct {
1566	TokenType
1567	Data []byte
1568}
1569
1570func (n LiteralExpr) String() string {
1571	return string(n.Data)
1572}
1573
1574// JS converts the node back to valid JavaScript
1575func (n LiteralExpr) JS() string {
1576	return string(n.Data)
1577}
1578
1579// JSON converts the node back to valid JSON
1580func (n LiteralExpr) JSON() (string, error) {
1581	if n.TokenType == TrueToken || n.TokenType == FalseToken || n.TokenType == NullToken || n.TokenType == DecimalToken {
1582		return string(n.Data), nil
1583	} else if n.TokenType == StringToken {
1584		if n.Data[0] == '\'' {
1585			n.Data[0] = '"'
1586			n.Data[len(n.Data)-1] = '"'
1587		}
1588		return string(n.Data), nil
1589	}
1590	return "", ErrInvalidJSON
1591}
1592
1593// Element is an array literal element.
1594type Element struct {
1595	Value  IExpr // can be nil
1596	Spread bool
1597}
1598
1599func (n Element) String() string {
1600	s := ""
1601	if n.Value != nil {
1602		if n.Spread {
1603			s += "..."
1604		}
1605		s += n.Value.String()
1606	}
1607	return s
1608}
1609
1610// JS converts the node back to valid JavaScript
1611func (n Element) JS() string {
1612	s := ""
1613	if n.Value != nil {
1614		if n.Spread {
1615			s += "..."
1616		}
1617		s += n.Value.JS()
1618	}
1619	return s
1620}
1621
1622// JSON converts the node back to valid JSON
1623func (n Element) JSON() (string, error) {
1624	return "", ErrInvalidJSON
1625}
1626
1627// ArrayExpr is an array literal.
1628type ArrayExpr struct {
1629	List []Element
1630}
1631
1632func (n ArrayExpr) String() string {
1633	s := "["
1634	for i, item := range n.List {
1635		if i != 0 {
1636			s += ", "
1637		}
1638		if item.Value != nil {
1639			if item.Spread {
1640				s += "..."
1641			}
1642			s += item.Value.String()
1643		}
1644	}
1645	if 0 < len(n.List) && n.List[len(n.List)-1].Value == nil {
1646		s += ","
1647	}
1648	return s + "]"
1649}
1650
1651// JS converts the node back to valid JavaScript
1652func (n ArrayExpr) JS() string {
1653	s := "["
1654	for i, item := range n.List {
1655		if i != 0 {
1656			s += ", "
1657		}
1658		if item.Value != nil {
1659			if item.Spread {
1660				s += "..."
1661			}
1662			s += item.Value.JS()
1663		}
1664	}
1665	if 0 < len(n.List) && n.List[len(n.List)-1].Value == nil {
1666		s += ","
1667	}
1668	return s + "]"
1669}
1670
1671// JSON converts the node back to valid JSON
1672func (n ArrayExpr) JSON() (string, error) {
1673	s := "["
1674	for i, item := range n.List {
1675		if i != 0 {
1676			s += ", "
1677		}
1678		if item.Value != nil {
1679			if item.Spread {
1680				return "", ErrInvalidJSON
1681			}
1682			ss, err := item.Value.JSON()
1683			if err != nil {
1684				return "", err
1685			}
1686			s += ss
1687		}
1688	}
1689	if 0 < len(n.List) && n.List[len(n.List)-1].Value == nil {
1690		return "", ErrInvalidJSON
1691	}
1692	return s + "]", nil
1693}
1694
1695// Property is a property definition in an object literal.
1696type Property struct {
1697	// either Name or Spread are set. When Spread is set then Value is AssignmentExpression
1698	// if Init is set then Value is IdentifierReference, otherwise it can also be MethodDefinition
1699	Name   *PropertyName // can be nil
1700	Spread bool
1701	Value  IExpr
1702	Init   IExpr // can be nil
1703}
1704
1705func (n Property) String() string {
1706	s := ""
1707	if n.Name != nil {
1708		if v, ok := n.Value.(*Var); !ok || !n.Name.IsIdent(v.Data) {
1709			s += n.Name.String() + ": "
1710		}
1711	} else if n.Spread {
1712		s += "..."
1713	}
1714	s += n.Value.String()
1715	if n.Init != nil {
1716		s += " = " + n.Init.String()
1717	}
1718	return s
1719}
1720
1721// JS converts the node back to valid JavaScript
1722func (n Property) JS() string {
1723	s := ""
1724	if n.Name != nil {
1725		if v, ok := n.Value.(*Var); !ok || !n.Name.IsIdent(v.Data) {
1726			s += n.Name.JS() + ": "
1727		}
1728	} else if n.Spread {
1729		s += "..."
1730	}
1731	s += n.Value.JS()
1732	if n.Init != nil {
1733		s += " = " + n.Init.JS()
1734	}
1735	return s
1736}
1737
1738// JSON converts the node back to valid JSON
1739func (n Property) JSON() (string, error) {
1740	s := ""
1741	if n.Name == nil || n.Name.Literal.TokenType != StringToken && n.Name.Literal.TokenType != IdentifierToken || n.Spread || n.Init != nil {
1742		return "", ErrInvalidJSON
1743	} else if n.Name.Literal.TokenType == IdentifierToken {
1744		n.Name.Literal.TokenType = StringToken
1745		n.Name.Literal.Data = append(append([]byte{'"'}, n.Name.Literal.Data...), '"')
1746	}
1747
1748	ss, _ := n.Name.Literal.JSON()
1749	s += ss + ": "
1750
1751	var err error
1752	ss, err = n.Value.JSON()
1753	if err != nil {
1754		fmt.Println("b")
1755		return "", err
1756	}
1757	s += ss
1758	return s, nil
1759}
1760
1761// ObjectExpr is an object literal.
1762type ObjectExpr struct {
1763	List []Property
1764}
1765
1766func (n ObjectExpr) String() string {
1767	s := "{"
1768	for i, item := range n.List {
1769		if i != 0 {
1770			s += ", "
1771		}
1772		s += item.String()
1773	}
1774	return s + "}"
1775}
1776
1777// JS converts the node back to valid JavaScript
1778func (n ObjectExpr) JS() string {
1779	s := "{"
1780	for i, item := range n.List {
1781		if i != 0 {
1782			s += ", "
1783		}
1784		s += item.JS()
1785	}
1786	return s + "}"
1787}
1788
1789// JSON converts the node back to valid JSON
1790func (n ObjectExpr) JSON() (string, error) {
1791	s := "{"
1792	for i, item := range n.List {
1793		if i != 0 {
1794			s += ", "
1795		}
1796		ss, err := item.JSON()
1797		if err != nil {
1798			return "", err
1799		}
1800		s += ss
1801	}
1802	return s + "}", nil
1803}
1804
1805// TemplatePart is a template head or middle.
1806type TemplatePart struct {
1807	Value []byte
1808	Expr  IExpr
1809}
1810
1811func (n TemplatePart) String() string {
1812	return string(n.Value) + n.Expr.String()
1813}
1814
1815// JS converts the node back to valid JavaScript
1816func (n TemplatePart) JS() string {
1817	return string(n.Value) + n.Expr.JS()
1818}
1819
1820// JSON converts the node back to valid JSON
1821func (n TemplatePart) JSON() (string, error) {
1822	return "", ErrInvalidJSON
1823}
1824
1825// TemplateExpr is a template literal or member/call expression, super property, or optional chain with template literal.
1826type TemplateExpr struct {
1827	Tag  IExpr // can be nil
1828	List []TemplatePart
1829	Tail []byte
1830	Prec OpPrec
1831}
1832
1833func (n TemplateExpr) String() string {
1834	s := ""
1835	if n.Tag != nil {
1836		s += n.Tag.String()
1837	}
1838	for _, item := range n.List {
1839		s += item.String()
1840	}
1841	return s + string(n.Tail)
1842}
1843
1844// JS converts the node back to valid JavaScript
1845func (n TemplateExpr) JS() string {
1846	s := ""
1847	if n.Tag != nil {
1848		s += n.Tag.JS()
1849	}
1850	for _, item := range n.List {
1851		s += item.JS()
1852	}
1853	return s + string(n.Tail)
1854}
1855
1856// JSON converts the node back to valid JSON
1857func (n TemplateExpr) JSON() (string, error) {
1858	return "", ErrInvalidJSON
1859}
1860
1861// GroupExpr is a parenthesized expression.
1862type GroupExpr struct {
1863	X IExpr
1864}
1865
1866func (n GroupExpr) String() string {
1867	return "(" + n.X.String() + ")"
1868}
1869
1870// JS converts the node back to valid JavaScript
1871func (n GroupExpr) JS() string {
1872	return "(" + n.X.JS() + ")"
1873}
1874
1875// JSON converts the node back to valid JSON
1876func (n GroupExpr) JSON() (string, error) {
1877	return "", ErrInvalidJSON
1878}
1879
1880// IndexExpr is a member/call expression, super property, or optional chain with an index expression.
1881type IndexExpr struct {
1882	X    IExpr
1883	Y    IExpr
1884	Prec OpPrec
1885}
1886
1887func (n IndexExpr) String() string {
1888	return "(" + n.X.String() + "[" + n.Y.String() + "])"
1889}
1890
1891// JS converts the node back to valid JavaScript
1892func (n IndexExpr) JS() string {
1893	return n.X.JS() + "[" + n.Y.JS() + "]"
1894}
1895
1896// JSON converts the node back to valid JSON
1897func (n IndexExpr) JSON() (string, error) {
1898	return "", ErrInvalidJSON
1899}
1900
1901// DotExpr is a member/call expression, super property, or optional chain with a dot expression.
1902type DotExpr struct {
1903	X    IExpr
1904	Y    LiteralExpr
1905	Prec OpPrec
1906}
1907
1908func (n DotExpr) String() string {
1909	return "(" + n.X.String() + "." + n.Y.String() + ")"
1910}
1911
1912// JS converts the node back to valid JavaScript
1913func (n DotExpr) JS() string {
1914	return n.X.JS() + "." + n.Y.JS()
1915}
1916
1917// JSON converts the node back to valid JSON
1918func (n DotExpr) JSON() (string, error) {
1919	return "", ErrInvalidJSON
1920}
1921
1922// NewTargetExpr is a new target meta property.
1923type NewTargetExpr struct {
1924}
1925
1926func (n NewTargetExpr) String() string {
1927	return "(new.target)"
1928}
1929
1930// JS converts the node back to valid JavaScript
1931func (n NewTargetExpr) JS() string {
1932	return "new.target"
1933}
1934
1935// JSON converts the node back to valid JSON
1936func (n NewTargetExpr) JSON() (string, error) {
1937	return "", ErrInvalidJSON
1938}
1939
1940// ImportMetaExpr is a import meta meta property.
1941type ImportMetaExpr struct {
1942}
1943
1944func (n ImportMetaExpr) String() string {
1945	return "(import.meta)"
1946}
1947
1948// JS converts the node back to valid JavaScript
1949func (n ImportMetaExpr) JS() string {
1950	return "import.meta"
1951}
1952
1953// JSON converts the node back to valid JSON
1954func (n ImportMetaExpr) JSON() (string, error) {
1955	return "", ErrInvalidJSON
1956}
1957
1958type Arg struct {
1959	Value IExpr
1960	Rest  bool
1961}
1962
1963func (n Arg) String() string {
1964	s := ""
1965	if n.Rest {
1966		s += "..."
1967	}
1968	return s + n.Value.String()
1969}
1970
1971// JS converts the node back to valid JavaScript
1972func (n Arg) JS() string {
1973	s := ""
1974	if n.Rest {
1975		s += "..."
1976	}
1977	return s + n.Value.JS()
1978}
1979
1980// JSON converts the node back to valid JSON
1981func (n Arg) JSON() (string, error) {
1982	return "", ErrInvalidJSON
1983}
1984
1985// Args is a list of arguments as used by new and call expressions.
1986type Args struct {
1987	List []Arg
1988}
1989
1990func (n Args) String() string {
1991	s := "("
1992	for i, item := range n.List {
1993		if i != 0 {
1994			s += ", "
1995		}
1996		s += item.String()
1997	}
1998	return s + ")"
1999}
2000
2001// JS converts the node back to valid JavaScript
2002func (n Args) JS() string {
2003	s := ""
2004	for i, item := range n.List {
2005		if i != 0 {
2006			s += ", "
2007		}
2008		s += item.JS()
2009	}
2010	return s
2011}
2012
2013// JSON converts the node back to valid JSON
2014func (n Args) JSON() (string, error) {
2015	return "", ErrInvalidJSON
2016}
2017
2018// NewExpr is a new expression or new member expression.
2019type NewExpr struct {
2020	X    IExpr
2021	Args *Args // can be nil
2022}
2023
2024func (n NewExpr) String() string {
2025	if n.Args != nil {
2026		return "(new " + n.X.String() + n.Args.String() + ")"
2027	}
2028	return "(new " + n.X.String() + ")"
2029}
2030
2031// JS converts the node back to valid JavaScript
2032func (n NewExpr) JS() string {
2033	if n.Args != nil {
2034		return "new " + n.X.JS() + "(" + n.Args.JS() + ")"
2035	}
2036
2037	// always use parentheses to prevent errors when chaining e.g. new Date().getTime()
2038	return "new " + n.X.JS() + "()"
2039}
2040
2041// JSON converts the node back to valid JSON
2042func (n NewExpr) JSON() (string, error) {
2043	return "", ErrInvalidJSON
2044}
2045
2046// CallExpr is a call expression.
2047type CallExpr struct {
2048	X    IExpr
2049	Args Args
2050}
2051
2052func (n CallExpr) String() string {
2053	return "(" + n.X.String() + n.Args.String() + ")"
2054}
2055
2056// JS converts the node back to valid JavaScript
2057func (n CallExpr) JS() string {
2058	return n.X.JS() + "(" + n.Args.JS() + ")"
2059}
2060
2061// JSON converts the node back to valid JSON
2062func (n CallExpr) JSON() (string, error) {
2063	return "", ErrInvalidJSON
2064}
2065
2066// OptChainExpr is an optional chain.
2067type OptChainExpr struct {
2068	X IExpr
2069	Y IExpr // can be CallExpr, IndexExpr, LiteralExpr, or TemplateExpr
2070}
2071
2072func (n OptChainExpr) String() string {
2073	s := "(" + n.X.String() + "?."
2074	switch y := n.Y.(type) {
2075	case *CallExpr:
2076		return s + y.Args.String() + ")"
2077	case *IndexExpr:
2078		return s + "[" + y.Y.String() + "])"
2079	default:
2080		return s + y.String() + ")"
2081	}
2082}
2083
2084// JS converts the node back to valid JavaScript
2085func (n OptChainExpr) JS() string {
2086	s := n.X.String() + "?."
2087	switch y := n.Y.(type) {
2088	case *CallExpr:
2089		return s + y.Args.JS() + ")"
2090	case *IndexExpr:
2091		return s + "[" + y.Y.JS() + "])"
2092	default:
2093		return s + y.JS()
2094	}
2095}
2096
2097// JSON converts the node back to valid JSON
2098func (n OptChainExpr) JSON() (string, error) {
2099	return "", ErrInvalidJSON
2100}
2101
2102// UnaryExpr is an update or unary expression.
2103type UnaryExpr struct {
2104	Op TokenType
2105	X  IExpr
2106}
2107
2108func (n UnaryExpr) String() string {
2109	if n.Op == PostIncrToken || n.Op == PostDecrToken {
2110		return "(" + n.X.String() + n.Op.String() + ")"
2111	} else if IsIdentifierName(n.Op) {
2112		return "(" + n.Op.String() + " " + n.X.String() + ")"
2113	}
2114	return "(" + n.Op.String() + n.X.String() + ")"
2115}
2116
2117// JS converts the node back to valid JavaScript
2118func (n UnaryExpr) JS() string {
2119	if n.Op == PostIncrToken || n.Op == PostDecrToken {
2120		return n.X.JS() + n.Op.String()
2121	} else if IsIdentifierName(n.Op) {
2122		return n.Op.String() + " " + n.X.JS()
2123	}
2124	return n.Op.String() + n.X.JS()
2125}
2126
2127// JSON converts the node back to valid JSON
2128func (n UnaryExpr) JSON() (string, error) {
2129	return "", ErrInvalidJSON
2130}
2131
2132// BinaryExpr is a binary expression.
2133type BinaryExpr struct {
2134	Op   TokenType
2135	X, Y IExpr
2136}
2137
2138func (n BinaryExpr) String() string {
2139	if IsIdentifierName(n.Op) {
2140		return "(" + n.X.String() + " " + n.Op.String() + " " + n.Y.String() + ")"
2141	}
2142	return "(" + n.X.String() + n.Op.String() + n.Y.String() + ")"
2143}
2144
2145// JS converts the node back to valid JavaScript
2146func (n BinaryExpr) JS() string {
2147	return n.X.JS() + " " + n.Op.String() + " " + n.Y.JS()
2148}
2149
2150// JSON converts the node back to valid JSON
2151func (n BinaryExpr) JSON() (string, error) {
2152	return "", ErrInvalidJSON
2153}
2154
2155// CondExpr is a conditional expression.
2156type CondExpr struct {
2157	Cond, X, Y IExpr
2158}
2159
2160func (n CondExpr) String() string {
2161	return "(" + n.Cond.String() + " ? " + n.X.String() + " : " + n.Y.String() + ")"
2162}
2163
2164// JS converts the node back to valid JavaScript
2165func (n CondExpr) JS() string {
2166	return n.Cond.JS() + " ? " + n.X.JS() + " : " + n.Y.JS()
2167}
2168
2169// JSON converts the node back to valid JSON
2170func (n CondExpr) JSON() (string, error) {
2171	return "", ErrInvalidJSON
2172}
2173
2174// YieldExpr is a yield expression.
2175type YieldExpr struct {
2176	Generator bool
2177	X         IExpr // can be nil
2178}
2179
2180func (n YieldExpr) String() string {
2181	if n.X == nil {
2182		return "(yield)"
2183	}
2184	s := "(yield"
2185	if n.Generator {
2186		s += "*"
2187	}
2188	return s + " " + n.X.String() + ")"
2189}
2190
2191// JS converts the node back to valid JavaScript
2192func (n YieldExpr) JS() string {
2193	if n.X == nil {
2194		return "yield"
2195	}
2196	s := "yield"
2197	if n.Generator {
2198		s += "*"
2199	}
2200	return s + " " + n.X.JS()
2201}
2202
2203// JSON converts the node back to valid JSON
2204func (n YieldExpr) JSON() (string, error) {
2205	return "", ErrInvalidJSON
2206}
2207
2208// ArrowFunc is an (async) arrow function.
2209type ArrowFunc struct {
2210	Async  bool
2211	Params Params
2212	Body   BlockStmt
2213}
2214
2215func (n ArrowFunc) String() string {
2216	s := "("
2217	if n.Async {
2218		s += "async "
2219	}
2220	return s + n.Params.String() + " => " + n.Body.String() + ")"
2221}
2222
2223// JS converts the node back to valid JavaScript
2224func (n ArrowFunc) JS() string {
2225	s := ""
2226	if n.Async {
2227		s += "async "
2228	}
2229	return s + n.Params.JS() + " => " + n.Body.JS()
2230}
2231
2232// JSON converts the node back to valid JSON
2233func (n ArrowFunc) JSON() (string, error) {
2234	return "", ErrInvalidJSON
2235}
2236
2237func (v *Var) exprNode()           {}
2238func (n LiteralExpr) exprNode()    {}
2239func (n ArrayExpr) exprNode()      {}
2240func (n ObjectExpr) exprNode()     {}
2241func (n TemplateExpr) exprNode()   {}
2242func (n GroupExpr) exprNode()      {}
2243func (n DotExpr) exprNode()        {}
2244func (n IndexExpr) exprNode()      {}
2245func (n NewTargetExpr) exprNode()  {}
2246func (n ImportMetaExpr) exprNode() {}
2247func (n NewExpr) exprNode()        {}
2248func (n CallExpr) exprNode()       {}
2249func (n OptChainExpr) exprNode()   {}
2250func (n UnaryExpr) exprNode()      {}
2251func (n BinaryExpr) exprNode()     {}
2252func (n CondExpr) exprNode()       {}
2253func (n YieldExpr) exprNode()      {}
2254func (n ArrowFunc) exprNode()      {}
2255