1 package minify 2 3 import ( 4 "errors" 5 "io" 6 "unicode/utf8" 7 8 "vimagination.zapto.org/javascript" 9 "vimagination.zapto.org/javascript/internal" 10 ) 11 12 type writer struct { 13 io.Writer 14 count int64 15 err error 16 lastChar rune 17 } 18 19 func (w *writer) WriteString(str string) { 20 if w.err == nil { 21 var n int 22 if internal.IsIDContinue(w.lastChar) { 23 r, _ := utf8.DecodeRuneInString(str) 24 if internal.IsIDContinue(r) { 25 n, w.err = io.WriteString(w.Writer, " ") 26 w.count += int64(n) 27 } 28 } 29 n, w.err = io.WriteString(w.Writer, str) 30 w.count += int64(n) 31 if len(str) > 0 { 32 w.lastChar, _ = utf8.DecodeLastRuneInString(str) 33 } 34 } 35 } 36 37 func (w *writer) WriteEOS() { 38 if w.err == nil && w.lastChar != '}' { 39 w.WriteString(";") 40 } 41 } 42 43 func Print(w io.Writer, m *javascript.Module) (int64, error) { 44 wr := writer{Writer: w} 45 for n := range m.ModuleListItems { 46 if n > 0 { 47 wr.WriteEOS() 48 } 49 wr.WriteModuleListItem(&m.ModuleListItems[n]) 50 } 51 return wr.count, wr.err 52 } 53 54 func (w *writer) WriteModuleListItem(mi *javascript.ModuleItem) { 55 if mi.ExportDeclaration != nil { 56 w.WriteExportDeclaration(mi.ExportDeclaration) 57 } else if mi.ImportDeclaration != nil { 58 w.WriteImportDeclaration(mi.ImportDeclaration) 59 } else if mi.StatementListItem != nil { 60 w.WriteStatementListItem(mi.StatementListItem) 61 } 62 } 63 64 func (w *writer) WriteExportDeclaration(ed *javascript.ExportDeclaration) { 65 w.WriteString("export") 66 if ed.FromClause != nil { 67 if ed.ExportClause != nil { 68 w.WriteExportClause(ed.ExportClause) 69 } else { 70 w.WriteString("*") 71 if ed.ExportFromClause != nil { 72 w.WriteString("as") 73 w.WriteString(ed.ExportFromClause.Data) 74 } 75 } 76 w.WriteFromClause(ed.FromClause) 77 } else if ed.ExportClause != nil { 78 w.WriteExportClause(ed.ExportClause) 79 } else if ed.VariableStatement != nil { 80 w.WriteVariableStatement(ed.VariableStatement) 81 } else if ed.Declaration != nil { 82 w.WriteDeclaration(ed.Declaration) 83 } else if ed.DefaultFunction != nil { 84 w.WriteString("default") 85 w.WriteFunctionDeclaration(ed.DefaultFunction) 86 } else if ed.DefaultClass != nil { 87 w.WriteString("default") 88 w.WriteClassDeclaration(ed.DefaultClass) 89 } else if ed.DefaultAssignmentExpression != nil { 90 w.WriteString("default") 91 w.WriteAssignmentExpression(ed.DefaultAssignmentExpression) 92 } 93 } 94 95 func (w *writer) WriteExportClause(ec *javascript.ExportClause) { 96 w.WriteString("{") 97 for n := range ec.ExportList { 98 if n > 0 { 99 w.WriteString(",") 100 } 101 w.WriteExportSpecifier(&ec.ExportList[n]) 102 } 103 w.WriteString("}") 104 } 105 106 func (w *writer) WriteExportSpecifier(es *javascript.ExportSpecifier) { 107 if es.IdentifierName == nil { 108 w.err = ErrInvalidAST 109 return 110 } 111 w.WriteString(es.IdentifierName.Data) 112 if es.EIdentifierName != nil && es.EIdentifierName.Data != es.IdentifierName.Data { 113 w.WriteString("as") 114 w.WriteString(es.EIdentifierName.Data) 115 } 116 } 117 118 func (w *writer) WriteFromClause(fc *javascript.FromClause) { 119 w.WriteString("from") 120 w.WriteString(fc.ModuleSpecifier.Data) 121 } 122 123 func (w *writer) WriteImportDeclaration(id *javascript.ImportDeclaration) { 124 if id.ImportClause == nil && id.FromClause.ModuleSpecifier == nil { 125 w.err = ErrInvalidAST 126 return 127 } 128 w.WriteString("import") 129 if id.ImportClause != nil { 130 w.WriteImportClause(id.ImportClause) 131 w.WriteFromClause(&id.FromClause) 132 } else if id.FromClause.ModuleSpecifier != nil { 133 w.WriteString(id.FromClause.ModuleSpecifier.Data) 134 } 135 } 136 137 func (w *writer) WriteImportClause(ic *javascript.ImportClause) { 138 if ic.ImportedDefaultBinding != nil { 139 w.WriteString(ic.ImportedDefaultBinding.Data) 140 if ic.NameSpaceImport != nil || ic.NamedImports != nil { 141 w.WriteString(",") 142 } 143 } 144 if ic.NameSpaceImport != nil { 145 w.WriteString("*as") 146 w.WriteString(ic.NameSpaceImport.Data) 147 } else if ic.NamedImports != nil { 148 w.WriteNamedImports(ic.NamedImports) 149 } 150 } 151 152 func (w *writer) WriteNamedImports(ni *javascript.NamedImports) { 153 w.WriteString("{") 154 for n := range ni.ImportList { 155 if n > 0 { 156 w.WriteString(",") 157 } 158 w.WriteImportSpecifier(&ni.ImportList[n]) 159 } 160 w.WriteString("}") 161 } 162 163 func (w *writer) WriteImportSpecifier(is *javascript.ImportSpecifier) { 164 if is.IdentifierName == nil { 165 w.err = ErrInvalidAST 166 return 167 } 168 if is.IdentifierName != nil && is.IdentifierName.Data != is.ImportedBinding.Data { 169 w.WriteString(is.IdentifierName.Data) 170 w.WriteString("as") 171 } 172 w.WriteString(is.ImportedBinding.Data) 173 } 174 175 func (w *writer) WriteStatementListItem(si *javascript.StatementListItem) { 176 if si.Statement != nil { 177 w.WriteStatement(si.Statement) 178 } else if si.Declaration != nil { 179 w.WriteDeclaration(si.Declaration) 180 } 181 } 182 183 func (w *writer) WriteStatement(s *javascript.Statement) { 184 switch s.Type { 185 case javascript.StatementNormal: 186 if s.BlockStatement != nil { 187 w.WriteBlock(s.BlockStatement) 188 } else if s.VariableStatement != nil { 189 w.WriteVariableStatement(s.VariableStatement) 190 } else if s.ExpressionStatement != nil { 191 w.WriteExpressionStatement(s.ExpressionStatement) 192 } else if s.IfStatement != nil { 193 w.WriteIfStatement(s.IfStatement) 194 } else if s.IterationStatementDo != nil { 195 w.WriteIterationStatementDo(s.IterationStatementDo) 196 } else if s.IterationStatementWhile != nil { 197 w.WriteIterationStatementWhile(s.IterationStatementWhile) 198 } else if s.IterationStatementFor != nil { 199 w.WriteIterationStatementFor(s.IterationStatementFor) 200 } else if s.SwitchStatement != nil { 201 w.WriteSwitchStatement(s.SwitchStatement) 202 } else if s.WithStatement != nil { 203 w.WriteWithStatement(s.WithStatement) 204 } else if s.LabelIdentifier != nil { 205 w.WriteString(s.LabelIdentifier.Data) 206 w.WriteString(":") 207 if s.LabelledItemFunction != nil { 208 w.WriteFunctionDeclaration(s.LabelledItemFunction) 209 } else if s.LabelledItemStatement != nil { 210 w.WriteStatement(s.LabelledItemStatement) 211 } 212 } else if s.TryStatement != nil { 213 w.WriteTryStatement(s.TryStatement) 214 } 215 case javascript.StatementContinue: 216 w.WriteString("continue") 217 if s.LabelIdentifier != nil { 218 w.WriteString(s.LabelIdentifier.Data) 219 } 220 case javascript.StatementBreak: 221 w.WriteString("break") 222 if s.LabelIdentifier != nil { 223 w.WriteString(s.LabelIdentifier.Data) 224 } 225 case javascript.StatementReturn: 226 w.WriteString("return") 227 if s.ExpressionStatement != nil { 228 w.WriteExpressionStatement(s.ExpressionStatement) 229 } 230 case javascript.StatementThrow: 231 if s.ExpressionStatement != nil { 232 w.WriteString("throw") 233 w.WriteExpressionStatement(s.ExpressionStatement) 234 } 235 case javascript.StatementDebugger: 236 w.WriteString("debugger") 237 } 238 } 239 240 func (w *writer) WriteExpressionStatement(e *javascript.Expression) { 241 for n := range e.Expressions { 242 if n > 0 { 243 w.WriteString(",") 244 } 245 w.WriteAssignmentExpression(&e.Expressions[n]) 246 } 247 } 248 249 func (w *writer) WriteIfStatement(i *javascript.IfStatement) { 250 w.WriteString("if(") 251 w.WriteExpressionStatement(&i.Expression) 252 w.WriteString(")") 253 w.WriteStatement(&i.Statement) 254 if i.ElseStatement != nil { 255 w.WriteEOS() 256 w.WriteString("else") 257 w.WriteStatement(i.ElseStatement) 258 } 259 } 260 261 func (w *writer) WriteIterationStatementDo(i *javascript.IterationStatementDo) { 262 w.WriteString("do") 263 w.WriteStatement(&i.Statement) 264 w.WriteEOS() 265 w.WriteString("while(") 266 w.WriteExpressionStatement(&i.Expression) 267 w.WriteString(")") 268 } 269 270 func (w *writer) WriteIterationStatementWhile(i *javascript.IterationStatementWhile) { 271 w.WriteString("while(") 272 w.WriteExpressionStatement(&i.Expression) 273 w.WriteString(")") 274 w.WriteStatement(&i.Statement) 275 } 276 277 func (w *writer) WriteIterationStatementFor(i *javascript.IterationStatementFor) { 278 switch i.Type { 279 case javascript.ForNormal: 280 if i.InitVar != nil || i.InitLexical != nil || i.InitExpression != nil { 281 w.err = ErrInvalidAST 282 return 283 } 284 case javascript.ForNormalVar: 285 if len(i.InitVar) == 0 { 286 w.err = ErrInvalidAST 287 return 288 } 289 case javascript.ForNormalLexicalDeclaration: 290 if i.InitLexical == nil { 291 w.err = ErrInvalidAST 292 return 293 } 294 case javascript.ForNormalExpression: 295 if i.InitExpression == nil { 296 w.err = ErrInvalidAST 297 return 298 } 299 case javascript.ForInLeftHandSide, javascript.ForOfLeftHandSide, javascript.ForAwaitOfLeftHandSide: 300 if i.LeftHandSideExpression == nil { 301 w.err = ErrInvalidAST 302 return 303 } 304 case javascript.ForInVar, javascript.ForOfVar, javascript.ForAwaitOfVar, javascript.ForInLet, javascript.ForOfLet, javascript.ForAwaitOfLet, javascript.ForInConst, javascript.ForOfConst, javascript.ForAwaitOfConst: 305 if i.ForBindingIdentifier == nil && i.ForBindingPatternObject == nil && i.ForBindingPatternArray == nil { 306 w.err = ErrInvalidAST 307 return 308 } 309 default: 310 w.err = ErrInvalidAST 311 return 312 } 313 switch i.Type { 314 case javascript.ForInLeftHandSide, javascript.ForInVar, javascript.ForInLet, javascript.ForInConst: 315 if i.In == nil { 316 w.err = ErrInvalidAST 317 return 318 } 319 case javascript.ForOfLeftHandSide, javascript.ForOfVar, javascript.ForOfLet, javascript.ForOfConst, javascript.ForAwaitOfLeftHandSide, javascript.ForAwaitOfVar, javascript.ForAwaitOfLet, javascript.ForAwaitOfConst: 320 if i.Of == nil { 321 w.err = ErrInvalidAST 322 return 323 } 324 } 325 switch i.Type { 326 case javascript.ForAwaitOfLeftHandSide, javascript.ForAwaitOfVar, javascript.ForAwaitOfLet, javascript.ForAwaitOfConst: 327 w.WriteString("for await(") 328 default: 329 w.WriteString("for(") 330 } 331 switch i.Type { 332 case javascript.ForNormal: 333 w.WriteString(";") 334 case javascript.ForNormalVar: 335 w.WriteString("var") 336 for n := range i.InitVar { 337 if n > 0 { 338 w.WriteString(",") 339 } 340 w.WriteLexicalBinding((*javascript.LexicalBinding)(&i.InitVar[n])) 341 } 342 w.WriteString(";") 343 case javascript.ForNormalLexicalDeclaration: 344 w.WriteLexicalDeclaration(i.InitLexical) 345 w.WriteString(";") 346 case javascript.ForNormalExpression: 347 w.WriteExpressionStatement(i.InitExpression) 348 w.WriteString(";") 349 case javascript.ForInLeftHandSide, javascript.ForOfLeftHandSide, javascript.ForAwaitOfLeftHandSide: 350 w.WriteLeftHandSideExpression(i.LeftHandSideExpression) 351 default: 352 switch i.Type { 353 case javascript.ForInVar, javascript.ForOfVar, javascript.ForAwaitOfVar: 354 w.WriteString("var") 355 case javascript.ForInLet, javascript.ForOfLet, javascript.ForAwaitOfLet: 356 w.WriteString("let") 357 case javascript.ForInConst, javascript.ForOfConst, javascript.ForAwaitOfConst: 358 w.WriteString("const") 359 } 360 if i.ForBindingIdentifier != nil { 361 w.WriteString(i.ForBindingIdentifier.Data) 362 } else if i.ForBindingPatternObject != nil { 363 w.WriteObjectBindingPattern(i.ForBindingPatternObject) 364 } else { 365 w.WriteArrayBindingPattern(i.ForBindingPatternArray) 366 } 367 } 368 switch i.Type { 369 case javascript.ForNormal, javascript.ForNormalVar, javascript.ForNormalLexicalDeclaration, javascript.ForNormalExpression: 370 if i.Conditional != nil { 371 w.WriteExpressionStatement(i.Conditional) 372 } 373 w.WriteString(";") 374 if i.Afterthought != nil { 375 w.WriteExpressionStatement(i.Afterthought) 376 } 377 case javascript.ForInLeftHandSide, javascript.ForInVar, javascript.ForInLet, javascript.ForInConst: 378 w.WriteString("in") 379 w.WriteExpressionStatement(i.In) 380 case javascript.ForOfLeftHandSide, javascript.ForOfVar, javascript.ForOfLet, javascript.ForOfConst, javascript.ForAwaitOfLeftHandSide, javascript.ForAwaitOfVar, javascript.ForAwaitOfLet, javascript.ForAwaitOfConst: 381 w.WriteString("of") 382 w.WriteAssignmentExpression(i.Of) 383 } 384 w.WriteString(")") 385 w.WriteStatement(&i.Statement) 386 } 387 388 func (w *writer) WriteLexicalBinding(lb *javascript.LexicalBinding) { 389 if lb.BindingIdentifier != nil { 390 w.WriteString(lb.BindingIdentifier.Data) 391 } else if lb.ArrayBindingPattern != nil { 392 w.WriteArrayBindingPattern(lb.ArrayBindingPattern) 393 } else if lb.ObjectBindingPattern != nil { 394 w.WriteObjectBindingPattern(lb.ObjectBindingPattern) 395 } else { 396 w.err = ErrInvalidAST 397 return 398 } 399 if lb.Initializer != nil { 400 w.WriteString("=") 401 w.WriteAssignmentExpression(lb.Initializer) 402 } 403 } 404 405 func (w *writer) WriteLexicalDeclaration(ld *javascript.LexicalDeclaration) { 406 if len(ld.BindingList) == 0 { 407 w.err = ErrInvalidAST 408 return 409 } 410 if ld.LetOrConst == javascript.Let { 411 w.WriteString("let") 412 } else { 413 w.WriteString("const") 414 } 415 for n := range ld.BindingList { 416 if n > 0 { 417 w.WriteString(",") 418 } 419 w.WriteLexicalBinding(&ld.BindingList[n]) 420 } 421 } 422 423 func (w *writer) WriteLeftHandSideExpression(lhs *javascript.LeftHandSideExpression) { 424 if lhs.NewExpression != nil { 425 w.WriteNewExpression(lhs.NewExpression) 426 } else if lhs.CallExpression != nil { 427 w.WriteCallExpression(lhs.CallExpression) 428 } else if lhs.OptionalExpression != nil { 429 w.WriteOptionalExpression(lhs.OptionalExpression) 430 } 431 } 432 433 func (w *writer) WriteNewExpression(ne *javascript.NewExpression) { 434 for i := uint(0); i < ne.News; i++ { 435 w.WriteString("new") 436 } 437 w.WriteMemberExpression(&ne.MemberExpression) 438 } 439 440 func (w *writer) WriteMemberExpression(me *javascript.MemberExpression) { 441 if me.MemberExpression != nil { 442 if me.Arguments != nil { 443 w.WriteString("new") 444 w.WriteMemberExpression(me.MemberExpression) 445 w.WriteArguments(me.Arguments) 446 } else if me.Expression != nil { 447 w.WriteMemberExpression(me.MemberExpression) 448 w.WriteString("[") 449 w.WriteExpressionStatement(me.Expression) 450 w.WriteString("]") 451 } else if me.IdentifierName != nil { 452 w.WriteMemberExpression(me.MemberExpression) 453 w.WriteString(".") 454 w.WriteString(me.IdentifierName.Data) 455 } else if me.PrivateIdentifier != nil { 456 w.WriteMemberExpression(me.MemberExpression) 457 w.WriteString(".") 458 w.WriteString(me.PrivateIdentifier.Data) 459 } else if me.TemplateLiteral != nil { 460 w.WriteMemberExpression(me.MemberExpression) 461 w.WriteTemplateLiteral(me.TemplateLiteral) 462 } 463 } else if me.PrimaryExpression != nil { 464 w.WritePrimaryExpression(me.PrimaryExpression) 465 } else if me.SuperProperty { 466 if me.Expression != nil { 467 w.WriteString("super[") 468 w.WriteExpressionStatement(me.Expression) 469 w.WriteString("]") 470 } else if me.IdentifierName != nil { 471 w.WriteString("super.") 472 w.WriteString(me.IdentifierName.Data) 473 } 474 } else if me.NewTarget { 475 w.WriteString("new.target") 476 } else if me.ImportMeta { 477 w.WriteString("import.meta") 478 } 479 } 480 481 func (w *writer) WriteArguments(a *javascript.Arguments) { 482 w.WriteString("(") 483 for n := range a.ArgumentList { 484 if n > 0 { 485 w.WriteString(",") 486 } 487 w.WriteArgument(&a.ArgumentList[n]) 488 } 489 w.WriteString(")") 490 } 491 492 func (w *writer) WriteArgument(a *javascript.Argument) { 493 if a.Spread { 494 w.WriteString("...") 495 } 496 w.WriteAssignmentExpression(&a.AssignmentExpression) 497 } 498 499 func (w *writer) WriteTemplateLiteral(tl *javascript.TemplateLiteral) { 500 if tl.NoSubstitutionTemplate != nil { 501 w.WriteString(tl.NoSubstitutionTemplate.Data) 502 } else if tl.TemplateHead != nil && tl.TemplateTail != nil && len(tl.Expressions) == len(tl.TemplateMiddleList)+1 { 503 w.WriteString(tl.TemplateHead.Data) 504 w.WriteExpressionStatement(&tl.Expressions[0]) 505 for n := range tl.TemplateMiddleList { 506 w.WriteString(tl.TemplateMiddleList[n].Data) 507 w.WriteExpressionStatement(&tl.Expressions[n+1]) 508 } 509 w.WriteString(tl.TemplateTail.Data) 510 } 511 } 512 513 func (w *writer) WritePrimaryExpression(pe *javascript.PrimaryExpression) { 514 if pe.This != nil { 515 w.WriteString("this") 516 } else if pe.IdentifierReference != nil { 517 w.WriteString(pe.IdentifierReference.Data) 518 } else if pe.Literal != nil { 519 w.WriteString(pe.Literal.Data) 520 } else if pe.ArrayLiteral != nil { 521 w.WriteArrayLiteral(pe.ArrayLiteral) 522 } else if pe.ObjectLiteral != nil { 523 w.WriteObjectLiteral(pe.ObjectLiteral) 524 } else if pe.FunctionExpression != nil { 525 w.WriteFunctionDeclaration(pe.FunctionExpression) 526 } else if pe.ClassExpression != nil { 527 w.WriteClassDeclaration(pe.ClassExpression) 528 } else if pe.TemplateLiteral != nil { 529 w.WriteTemplateLiteral(pe.TemplateLiteral) 530 } else if pe.ParenthesizedExpression != nil { 531 w.WriteParenthesizedExpression(pe.ParenthesizedExpression) 532 } 533 } 534 535 func (w *writer) WriteArrayLiteral(al *javascript.ArrayLiteral) { 536 w.WriteString("[") 537 for n := range al.ElementList { 538 if n > 0 { 539 w.WriteString(",") 540 } 541 w.WriteArrayElement(&al.ElementList[n]) 542 } 543 w.WriteString("]") 544 } 545 546 func (w *writer) WriteArrayElement(ae *javascript.ArrayElement) { 547 if ae.Spread { 548 w.WriteString("...") 549 } 550 w.WriteAssignmentExpression(&ae.AssignmentExpression) 551 } 552 553 func (w *writer) WriteObjectLiteral(ol *javascript.ObjectLiteral) { 554 w.WriteString("{") 555 for n := range ol.PropertyDefinitionList { 556 if n > 0 { 557 w.WriteString(",") 558 } 559 w.WritePropertyDefinition(&ol.PropertyDefinitionList[n]) 560 } 561 w.WriteString("}") 562 } 563 564 func (w *writer) WritePropertyDefinition(pd *javascript.PropertyDefinition) { 565 if pd.AssignmentExpression != nil { 566 if pd.PropertyName != nil { 567 w.WritePropertyName(pd.PropertyName) 568 var done bool 569 if !pd.IsCoverInitializedName && pd.PropertyName.LiteralPropertyName != nil && pd.AssignmentExpression.ConditionalExpression != nil { 570 c := javascript.UnwrapConditional(pd.AssignmentExpression.ConditionalExpression) 571 if pe, ok := c.(*javascript.PrimaryExpression); ok && pe.IdentifierReference != nil { 572 done = pe.IdentifierReference.Type == pd.PropertyName.LiteralPropertyName.Type && pe.IdentifierReference.Data == pd.PropertyName.LiteralPropertyName.Data 573 } 574 } 575 if !done { 576 if pd.IsCoverInitializedName { 577 w.WriteString("=") 578 } else { 579 w.WriteString(":") 580 } 581 w.WriteAssignmentExpression(pd.AssignmentExpression) 582 } 583 } else { 584 w.WriteString("...") 585 w.WriteAssignmentExpression(pd.AssignmentExpression) 586 } 587 } else if pd.MethodDefinition != nil { 588 w.WriteMethodDefinition(pd.MethodDefinition) 589 } 590 } 591 592 func (w *writer) WritePropertyName(pn *javascript.PropertyName) { 593 if pn.LiteralPropertyName != nil { 594 w.WriteString(pn.LiteralPropertyName.Data) 595 } else if pn.ComputedPropertyName != nil { 596 w.WriteString("[") 597 w.WriteAssignmentExpression(pn.ComputedPropertyName) 598 w.WriteString("]") 599 } 600 } 601 602 func (w *writer) WriteMethodDefinition(md *javascript.MethodDefinition) { 603 switch md.Type { 604 case javascript.MethodNormal: 605 case javascript.MethodGenerator: 606 w.WriteString("*") 607 case javascript.MethodAsync: 608 w.WriteString("async") 609 case javascript.MethodAsyncGenerator: 610 w.WriteString("async*") 611 case javascript.MethodGetter: 612 w.WriteString("get") 613 case javascript.MethodSetter: 614 w.WriteString("set") 615 default: 616 w.err = ErrInvalidAST 617 return 618 } 619 w.WriteClassElementName(&md.ClassElementName) 620 w.WriteFormalParameters(&md.Params) 621 w.WriteBlock(&md.FunctionBody) 622 } 623 624 func (w *writer) WriteClassElementName(cem *javascript.ClassElementName) { 625 if cem.PropertyName != nil { 626 w.WritePropertyName(cem.PropertyName) 627 } else if cem.PrivateIdentifier != nil { 628 w.WriteString(cem.PrivateIdentifier.Data) 629 } 630 } 631 632 func (w *writer) WriteFormalParameters(fp *javascript.FormalParameters) { 633 w.WriteString("(") 634 for n := range fp.FormalParameterList { 635 if n > 0 { 636 w.WriteString(",") 637 } 638 w.WriteBindingElement(&fp.FormalParameterList[n]) 639 } 640 if fp.BindingIdentifier != nil || fp.ArrayBindingPattern != nil || fp.ObjectBindingPattern != nil { 641 if len(fp.FormalParameterList) > 0 { 642 w.WriteString(",") 643 } 644 if fp.BindingIdentifier != nil { 645 w.WriteString("...") 646 w.WriteString(fp.BindingIdentifier.Data) 647 } else if fp.ArrayBindingPattern != nil { 648 w.WriteString("...") 649 w.WriteArrayBindingPattern(fp.ArrayBindingPattern) 650 } else if fp.ObjectBindingPattern != nil { 651 w.WriteString("...") 652 w.WriteObjectBindingPattern(fp.ObjectBindingPattern) 653 } 654 } 655 w.WriteString(")") 656 } 657 658 func (w *writer) WriteBindingElement(be *javascript.BindingElement) { 659 if be.SingleNameBinding != nil { 660 w.WriteString(be.SingleNameBinding.Data) 661 } else if be.ArrayBindingPattern != nil { 662 w.WriteArrayBindingPattern(be.ArrayBindingPattern) 663 } else if be.ObjectBindingPattern != nil { 664 w.WriteObjectBindingPattern(be.ObjectBindingPattern) 665 } else { 666 w.err = ErrInvalidAST 667 return 668 } 669 if be.Initializer != nil { 670 w.WriteString("=") 671 w.WriteAssignmentExpression(be.Initializer) 672 } 673 } 674 675 func (w *writer) WriteBlock(b *javascript.Block) { 676 w.WriteString("{") 677 for n := range b.StatementList { 678 if n > 0 { 679 w.WriteEOS() 680 } 681 w.WriteStatementListItem(&b.StatementList[n]) 682 } 683 w.WriteString("}") 684 } 685 686 func (w *writer) WriteParenthesizedExpression(pe *javascript.ParenthesizedExpression) { 687 w.WriteString("(") 688 for n := range pe.Expressions { 689 if n > 0 { 690 w.WriteString(",") 691 } 692 w.WriteAssignmentExpression(&pe.Expressions[n]) 693 } 694 w.WriteString(")") 695 } 696 697 func (w *writer) WriteCallExpression(ce *javascript.CallExpression) { 698 if ce.SuperCall && ce.Arguments != nil { 699 w.WriteString("super") 700 w.WriteArguments(ce.Arguments) 701 } else if ce.ImportCall != nil { 702 w.WriteString("import(") 703 w.WriteAssignmentExpression(ce.ImportCall) 704 w.WriteString(")") 705 } else if ce.MemberExpression != nil && ce.Arguments != nil { 706 w.WriteMemberExpression(ce.MemberExpression) 707 w.WriteArguments(ce.Arguments) 708 } else if ce.CallExpression != nil { 709 w.WriteCallExpression(ce.CallExpression) 710 if ce.Arguments != nil { 711 w.WriteArguments(ce.Arguments) 712 } else if ce.Expression != nil { 713 w.WriteString("[") 714 w.WriteExpressionStatement(ce.Expression) 715 w.WriteString("]") 716 } else if ce.IdentifierName != nil { 717 w.WriteString(".") 718 w.WriteString(ce.IdentifierName.Data) 719 } else if ce.TemplateLiteral != nil { 720 w.WriteTemplateLiteral(ce.TemplateLiteral) 721 } else if ce.PrivateIdentifier != nil { 722 w.WriteString(".") 723 w.WriteString(ce.PrivateIdentifier.Data) 724 } 725 } 726 } 727 728 func (w *writer) WriteOptionalExpression(oe *javascript.OptionalExpression) { 729 if oe.MemberExpression != nil { 730 w.WriteMemberExpression(oe.MemberExpression) 731 } else if oe.CallExpression != nil { 732 w.WriteCallExpression(oe.CallExpression) 733 } else if oe.OptionalExpression != nil { 734 w.WriteOptionalExpression(oe.OptionalExpression) 735 } 736 w.WriteOptionalChain(&oe.OptionalChain) 737 } 738 739 func (w *writer) WriteOptionalChain(oc *javascript.OptionalChain) { 740 if oc.OptionalChain != nil { 741 w.WriteOptionalChain(oc.OptionalChain) 742 } else { 743 w.WriteString("?.") 744 } 745 if oc.Arguments != nil { 746 w.WriteArguments(oc.Arguments) 747 } else if oc.Expression != nil { 748 w.WriteString("[") 749 w.WriteExpressionStatement(oc.Expression) 750 w.WriteString("]") 751 } else if oc.IdentifierName != nil { 752 if oc.OptionalChain != nil { 753 w.WriteString(".") 754 } 755 w.WriteString(oc.IdentifierName.Data) 756 } else if oc.TemplateLiteral != nil { 757 w.WriteTemplateLiteral(oc.TemplateLiteral) 758 } else if oc.PrivateIdentifier != nil { 759 if oc.OptionalChain != nil { 760 w.WriteString(".") 761 } 762 w.WriteString(oc.PrivateIdentifier.Data) 763 } 764 } 765 766 func (w *writer) WriteObjectBindingPattern(ob *javascript.ObjectBindingPattern) { 767 w.WriteString("{") 768 for n := range ob.BindingPropertyList { 769 if n > 0 { 770 w.WriteString(",") 771 } 772 w.WriteBindingProperty(&ob.BindingPropertyList[n]) 773 } 774 if ob.BindingRestProperty != nil { 775 if len(ob.BindingPropertyList) > 0 { 776 w.WriteString(",") 777 } 778 w.WriteString("...") 779 w.WriteString(ob.BindingRestProperty.Data) 780 } 781 w.WriteString("}") 782 } 783 784 func (w *writer) WriteBindingProperty(bp *javascript.BindingProperty) { 785 if bp.PropertyName.LiteralPropertyName != nil && bp.BindingElement.SingleNameBinding != nil && bp.PropertyName.LiteralPropertyName.Data == bp.BindingElement.SingleNameBinding.Data { 786 w.WriteBindingElement(&bp.BindingElement) 787 } else { 788 w.WritePropertyName(&bp.PropertyName) 789 w.WriteString(":") 790 w.WriteBindingElement(&bp.BindingElement) 791 } 792 } 793 794 func (w *writer) WriteArrayBindingPattern(ab *javascript.ArrayBindingPattern) { 795 w.WriteString("[") 796 for n := range ab.BindingElementList { 797 if n > 0 { 798 w.WriteString(",") 799 } 800 w.WriteBindingElement(&ab.BindingElementList[n]) 801 } 802 if ab.BindingRestElement != nil { 803 if len(ab.BindingElementList) > 0 { 804 w.WriteString(",") 805 } 806 w.WriteString("...") 807 w.WriteBindingElement(ab.BindingRestElement) 808 } 809 w.WriteString("]") 810 } 811 812 func (w *writer) WriteSwitchStatement(s *javascript.SwitchStatement) { 813 w.WriteString("switch(") 814 w.WriteExpressionStatement(&s.Expression) 815 w.WriteString("){") 816 for n := range s.CaseClauses { 817 if n > 0 { 818 w.WriteEOS() 819 } 820 w.WriteCaseClause(&s.CaseClauses[n]) 821 } 822 if len(s.DefaultClause) > 0 { 823 if len(s.CaseClauses) > 0 { 824 w.WriteEOS() 825 } 826 w.WriteString("default:") 827 for n := range s.DefaultClause { 828 if n > 0 { 829 w.WriteEOS() 830 } 831 w.WriteStatementListItem(&s.DefaultClause[n]) 832 } 833 } 834 for n := range s.PostDefaultCaseClauses { 835 if n > 0 || len(s.CaseClauses) > 0 || len(s.DefaultClause) > 0 { 836 w.WriteEOS() 837 } 838 w.WriteCaseClause(&s.PostDefaultCaseClauses[n]) 839 } 840 w.WriteString("}") 841 } 842 843 func (w *writer) WriteCaseClause(cc *javascript.CaseClause) { 844 w.WriteString("case") 845 w.WriteExpressionStatement(&cc.Expression) 846 w.WriteString(":") 847 for n := range cc.StatementList { 848 if n > 0 { 849 w.WriteEOS() 850 } 851 w.WriteStatementListItem(&cc.StatementList[n]) 852 } 853 } 854 855 func (w *writer) WriteWithStatement(ws *javascript.WithStatement) { 856 w.WriteString("with(") 857 w.WriteExpressionStatement(&ws.Expression) 858 w.WriteString(")") 859 w.WriteStatement(&ws.Statement) 860 } 861 862 func (w *writer) WriteTryStatement(t *javascript.TryStatement) { 863 w.WriteString("try") 864 w.WriteBlock(&t.TryBlock) 865 if t.CatchBlock != nil { 866 w.WriteString("catch(") 867 if t.CatchParameterBindingIdentifier != nil { 868 w.WriteString(t.CatchParameterBindingIdentifier.Data) 869 } else if t.CatchParameterArrayBindingPattern != nil { 870 w.WriteArrayBindingPattern(t.CatchParameterArrayBindingPattern) 871 } else if t.CatchParameterObjectBindingPattern != nil { 872 w.WriteObjectBindingPattern(t.CatchParameterObjectBindingPattern) 873 } 874 w.WriteString(")") 875 w.WriteBlock(t.CatchBlock) 876 } 877 if t.FinallyBlock != nil { 878 w.WriteString("finally") 879 w.WriteBlock(t.FinallyBlock) 880 } 881 } 882 883 func (w *writer) WriteVariableStatement(vs *javascript.VariableStatement) { 884 if len(vs.VariableDeclarationList) > 0 { 885 w.WriteString("var") 886 for n := range vs.VariableDeclarationList { 887 if n > 0 { 888 w.WriteString(",") 889 } 890 w.WriteLexicalBinding((*javascript.LexicalBinding)(&vs.VariableDeclarationList[n])) 891 } 892 } 893 } 894 895 func (w *writer) WriteDeclaration(d *javascript.Declaration) { 896 if d.ClassDeclaration != nil { 897 w.WriteClassDeclaration(d.ClassDeclaration) 898 } else if d.FunctionDeclaration != nil { 899 w.WriteFunctionDeclaration(d.FunctionDeclaration) 900 } else if d.LexicalDeclaration != nil { 901 w.WriteLexicalDeclaration(d.LexicalDeclaration) 902 } 903 } 904 905 func (w *writer) WriteFunctionDeclaration(f *javascript.FunctionDeclaration) { 906 if f.Type == javascript.FunctionAsync || f.Type == javascript.FunctionAsyncGenerator { 907 w.WriteString("async") 908 } 909 w.WriteString("function") 910 if f.Type == javascript.FunctionGenerator || f.Type == javascript.FunctionAsyncGenerator { 911 w.WriteString("*") 912 } 913 if f.BindingIdentifier != nil { 914 w.WriteString(f.BindingIdentifier.Data) 915 } 916 w.WriteFormalParameters(&f.FormalParameters) 917 w.WriteBlock(&f.FunctionBody) 918 } 919 920 func (w *writer) WriteClassDeclaration(cd *javascript.ClassDeclaration) { 921 w.WriteString("class") 922 if cd.BindingIdentifier != nil { 923 w.WriteString(cd.BindingIdentifier.Data) 924 } 925 if cd.ClassHeritage != nil { 926 w.WriteString("extends") 927 w.WriteLeftHandSideExpression(cd.ClassHeritage) 928 } 929 w.WriteString("{") 930 for n := range cd.ClassBody { 931 if n > 0 { 932 w.WriteEOS() 933 } 934 w.WriteClassElement(&cd.ClassBody[n]) 935 } 936 w.WriteString("}") 937 } 938 939 func (w *writer) WriteClassElement(ce *javascript.ClassElement) { 940 if ce.Static { 941 w.WriteString("static") 942 } 943 if ce.MethodDefinition != nil { 944 w.WriteMethodDefinition(ce.MethodDefinition) 945 } else if ce.FieldDefinition != nil { 946 w.WriteFieldDefinition(ce.FieldDefinition) 947 } else if ce.ClassStaticBlock != nil { 948 w.WriteBlock(ce.ClassStaticBlock) 949 } 950 } 951 952 func (w *writer) WriteFieldDefinition(fd *javascript.FieldDefinition) { 953 w.WriteClassElementName(&fd.ClassElementName) 954 if fd.Initializer != nil { 955 w.WriteString("=") 956 w.WriteAssignmentExpression(fd.Initializer) 957 } 958 } 959 960 func (w *writer) WriteAssignmentExpression(ae *javascript.AssignmentExpression) { 961 if ae.Yield && ae.AssignmentExpression != nil { 962 w.WriteString("yield") 963 if ae.Delegate { 964 w.WriteString("*") 965 } 966 w.WriteAssignmentExpression(ae.AssignmentExpression) 967 } else if ae.ArrowFunction != nil { 968 w.WriteArrowFunction(ae.ArrowFunction) 969 } else if ae.LeftHandSideExpression != nil && ae.AssignmentExpression != nil { 970 var ao string 971 switch ae.AssignmentOperator { 972 case javascript.AssignmentAssign: 973 ao = "=" 974 case javascript.AssignmentMultiply: 975 ao = "*=" 976 case javascript.AssignmentDivide: 977 ao = "/=" 978 case javascript.AssignmentRemainder: 979 ao = "%=" 980 case javascript.AssignmentAdd: 981 ao = "+=" 982 case javascript.AssignmentSubtract: 983 ao = "-=" 984 case javascript.AssignmentLeftShift: 985 ao = "<<=" 986 case javascript.AssignmentSignPropagatingRightShift: 987 ao = ">>=" 988 case javascript.AssignmentZeroFillRightShift: 989 ao = ">>>=" 990 case javascript.AssignmentBitwiseAND: 991 ao = "&=" 992 case javascript.AssignmentBitwiseXOR: 993 ao = "^=" 994 case javascript.AssignmentBitwiseOR: 995 ao = "|=" 996 case javascript.AssignmentExponentiation: 997 ao = "**=" 998 case javascript.AssignmentLogicalAnd: 999 ao = "&&=" 1000 case javascript.AssignmentLogicalOr: 1001 ao = "||=" 1002 case javascript.AssignmentNullish: 1003 ao = "??=" 1004 default: 1005 w.err = ErrInvalidAST 1006 return 1007 } 1008 w.WriteLeftHandSideExpression(ae.LeftHandSideExpression) 1009 w.WriteString(ao) 1010 w.WriteAssignmentExpression(ae.AssignmentExpression) 1011 } else if ae.AssignmentPattern != nil && ae.AssignmentExpression != nil && ae.AssignmentOperator == javascript.AssignmentAssign { 1012 w.WriteAssignmentPattern(ae.AssignmentPattern) 1013 w.WriteString("=") 1014 w.WriteAssignmentExpression(ae.AssignmentExpression) 1015 } else if ae.ConditionalExpression != nil { 1016 w.WriteConditionalExpression(ae.ConditionalExpression) 1017 } 1018 } 1019 1020 func (w *writer) WriteArrowFunction(af *javascript.ArrowFunction) { 1021 if af.FunctionBody == nil && af.AssignmentExpression == nil || (af.BindingIdentifier == nil && af.FormalParameters == nil) { 1022 w.err = ErrInvalidAST 1023 return 1024 } 1025 if af.Async { 1026 w.WriteString("async") 1027 } 1028 if af.BindingIdentifier != nil { 1029 w.WriteString(af.BindingIdentifier.Data) 1030 } else if af.FormalParameters != nil { 1031 w.WriteFormalParameters(af.FormalParameters) 1032 } 1033 w.WriteString("=>") 1034 if af.FunctionBody != nil { 1035 w.WriteBlock(af.FunctionBody) 1036 } else { 1037 w.WriteAssignmentExpression(af.AssignmentExpression) 1038 } 1039 } 1040 1041 func (w *writer) WriteAssignmentPattern(ap *javascript.AssignmentPattern) { 1042 if ap.ArrayAssignmentPattern != nil { 1043 w.WriteArrayAssignmentPattern(ap.ArrayAssignmentPattern) 1044 } else if ap.ObjectAssignmentPattern != nil { 1045 w.WriteObjectAssignmentPattern(ap.ObjectAssignmentPattern) 1046 } 1047 } 1048 1049 func (w *writer) WriteArrayAssignmentPattern(aa *javascript.ArrayAssignmentPattern) { 1050 w.WriteString("[") 1051 ae := aa.AssignmentElements 1052 for len(ae) > 0 && ae[len(ae)-1].DestructuringAssignmentTarget.AssignmentPattern == nil && ae[len(ae)-1].DestructuringAssignmentTarget.LeftHandSideExpression == nil { 1053 ae = ae[:len(ae)-1] 1054 } 1055 for n := range ae { 1056 if n > 0 { 1057 w.WriteString(",") 1058 } 1059 w.WriteAssignmentElement(&aa.AssignmentElements[n]) 1060 } 1061 if aa.AssignmentRestElement != nil { 1062 if len(aa.AssignmentElements) > 0 { 1063 w.WriteString(",") 1064 } 1065 w.WriteString("...") 1066 w.WriteLeftHandSideExpression(aa.AssignmentRestElement) 1067 } 1068 w.WriteString("]") 1069 } 1070 1071 func (w *writer) WriteAssignmentElement(ae *javascript.AssignmentElement) { 1072 w.WriteDestructuringAssignmentTarget(&ae.DestructuringAssignmentTarget) 1073 if ae.Initializer != nil { 1074 w.WriteString("=") 1075 w.WriteAssignmentExpression(ae.Initializer) 1076 } 1077 } 1078 1079 func (w *writer) WriteDestructuringAssignmentTarget(da *javascript.DestructuringAssignmentTarget) { 1080 if da.LeftHandSideExpression != nil { 1081 w.WriteLeftHandSideExpression(da.LeftHandSideExpression) 1082 } else if da.AssignmentPattern != nil { 1083 w.WriteAssignmentPattern(da.AssignmentPattern) 1084 } 1085 } 1086 1087 func (w *writer) WriteObjectAssignmentPattern(oa *javascript.ObjectAssignmentPattern) { 1088 w.WriteString("{") 1089 for n := range oa.AssignmentPropertyList { 1090 if n > 0 { 1091 w.WriteString(",") 1092 } 1093 w.WriteAssignmentProperty(&oa.AssignmentPropertyList[n]) 1094 } 1095 if oa.AssignmentRestElement != nil { 1096 if len(oa.AssignmentPropertyList) > 0 { 1097 w.WriteString(",") 1098 } 1099 w.WriteString("...") 1100 w.WriteLeftHandSideExpression(oa.AssignmentRestElement) 1101 } 1102 w.WriteString("}") 1103 } 1104 1105 func (w *writer) WriteAssignmentProperty(ap *javascript.AssignmentProperty) { 1106 w.WritePropertyName(&ap.PropertyName) 1107 if ap.DestructuringAssignmentTarget != nil { 1108 if ap.PropertyName.LiteralPropertyName != nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression != nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.CallExpression == nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.OptionalExpression == nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression != nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.News == 0 && ap.DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression != nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference != nil && ap.DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference.Data == ap.PropertyName.LiteralPropertyName.Data { 1109 return 1110 } 1111 w.WriteString(":") 1112 w.WriteDestructuringAssignmentTarget(ap.DestructuringAssignmentTarget) 1113 } 1114 if ap.Initializer != nil { 1115 w.WriteString("=") 1116 w.WriteAssignmentExpression(ap.Initializer) 1117 } 1118 } 1119 1120 func (w *writer) WriteConditionalExpression(ce *javascript.ConditionalExpression) { 1121 if ce.LogicalORExpression != nil { 1122 w.WriteLogicalORExpression(ce.LogicalORExpression) 1123 } else if ce.CoalesceExpression != nil { 1124 w.WriteCoalesceExpression(ce.CoalesceExpression) 1125 } else { 1126 w.err = ErrInvalidAST 1127 return 1128 } 1129 if ce.True != nil && ce.False != nil { 1130 w.WriteString("?") 1131 w.WriteAssignmentExpression(ce.True) 1132 w.WriteString(":") 1133 w.WriteAssignmentExpression(ce.False) 1134 } 1135 } 1136 1137 func (w *writer) WriteLogicalORExpression(lo *javascript.LogicalORExpression) { 1138 if lo.LogicalORExpression != nil { 1139 w.WriteLogicalORExpression(lo.LogicalORExpression) 1140 w.WriteString("||") 1141 } 1142 w.WriteLogicalANDExpression(&lo.LogicalANDExpression) 1143 } 1144 1145 func (w *writer) WriteLogicalANDExpression(la *javascript.LogicalANDExpression) { 1146 if la.LogicalANDExpression != nil { 1147 w.WriteLogicalANDExpression(la.LogicalANDExpression) 1148 w.WriteString("&&") 1149 } 1150 w.WriteBitwiseORExpression(&la.BitwiseORExpression) 1151 } 1152 1153 func (w *writer) WriteBitwiseORExpression(bo *javascript.BitwiseORExpression) { 1154 if bo.BitwiseORExpression != nil { 1155 w.WriteBitwiseORExpression(bo.BitwiseORExpression) 1156 w.WriteString("|") 1157 } 1158 w.WriteBitwiseXORExpression(&bo.BitwiseXORExpression) 1159 } 1160 1161 func (w *writer) WriteBitwiseXORExpression(bx *javascript.BitwiseXORExpression) { 1162 if bx.BitwiseXORExpression != nil { 1163 w.WriteBitwiseXORExpression(bx.BitwiseXORExpression) 1164 w.WriteString("^") 1165 } 1166 w.WriteBitwiseANDExpression(&bx.BitwiseANDExpression) 1167 } 1168 1169 func (w *writer) WriteBitwiseANDExpression(ba *javascript.BitwiseANDExpression) { 1170 if ba.BitwiseANDExpression != nil { 1171 w.WriteBitwiseANDExpression(ba.BitwiseANDExpression) 1172 w.WriteString("&") 1173 } 1174 w.WriteEqualityExpression(&ba.EqualityExpression) 1175 } 1176 1177 func (w *writer) WriteEqualityExpression(ee *javascript.EqualityExpression) { 1178 if ee.EqualityExpression != nil { 1179 var eo string 1180 switch ee.EqualityOperator { 1181 case javascript.EqualityEqual: 1182 eo = "==" 1183 case javascript.EqualityNotEqual: 1184 eo = "!=" 1185 case javascript.EqualityStrictEqual: 1186 eo = "===" 1187 case javascript.EqualityStrictNotEqual: 1188 eo = "!==" 1189 default: 1190 w.err = ErrInvalidAST 1191 return 1192 } 1193 w.WriteEqualityExpression(ee.EqualityExpression) 1194 w.WriteString(eo) 1195 } 1196 w.WriteRelationalExpression(&ee.RelationalExpression) 1197 } 1198 1199 func (w *writer) WriteRelationalExpression(re *javascript.RelationalExpression) { 1200 if re.PrivateIdentifier != nil { 1201 w.WriteString(re.PrivateIdentifier.Data) 1202 w.WriteString("in") 1203 } else if re.RelationalExpression != nil { 1204 var ro string 1205 switch re.RelationshipOperator { 1206 case javascript.RelationshipLessThan: 1207 ro = "<" 1208 case javascript.RelationshipGreaterThan: 1209 ro = ">" 1210 case javascript.RelationshipLessThanEqual: 1211 ro = "<=" 1212 case javascript.RelationshipGreaterThanEqual: 1213 ro = ">=" 1214 case javascript.RelationshipInstanceOf: 1215 ro = "instanceof" 1216 case javascript.RelationshipIn: 1217 ro = "in" 1218 default: 1219 w.err = ErrInvalidAST 1220 return 1221 } 1222 w.WriteRelationalExpression(re.RelationalExpression) 1223 w.WriteString(ro) 1224 } 1225 w.WriteShiftExpression(&re.ShiftExpression) 1226 } 1227 1228 func (w *writer) WriteShiftExpression(se *javascript.ShiftExpression) { 1229 if se.ShiftExpression != nil { 1230 var so string 1231 switch se.ShiftOperator { 1232 case javascript.ShiftLeft: 1233 so = "<<" 1234 case javascript.ShiftRight: 1235 so = ">>" 1236 case javascript.ShiftUnsignedRight: 1237 so = ">>>" 1238 default: 1239 w.err = ErrInvalidAST 1240 return 1241 } 1242 w.WriteShiftExpression(se.ShiftExpression) 1243 w.WriteString(so) 1244 } 1245 w.WriteAdditiveExpression(&se.AdditiveExpression) 1246 } 1247 1248 func (w *writer) WriteAdditiveExpression(ae *javascript.AdditiveExpression) { 1249 if ae.AdditiveExpression != nil { 1250 var ao string 1251 switch ae.AdditiveOperator { 1252 case javascript.AdditiveAdd: 1253 ao = "+" 1254 case javascript.AdditiveMinus: 1255 ao = "-" 1256 default: 1257 w.err = ErrInvalidAST 1258 return 1259 } 1260 w.WriteAdditiveExpression(ae.AdditiveExpression) 1261 w.WriteString(ao) 1262 } 1263 w.WriteMultiplicativeExpression(&ae.MultiplicativeExpression) 1264 } 1265 1266 func (w *writer) WriteMultiplicativeExpression(me *javascript.MultiplicativeExpression) { 1267 if me.MultiplicativeExpression != nil { 1268 var mo string 1269 switch me.MultiplicativeOperator { 1270 case javascript.MultiplicativeMultiply: 1271 mo = "*" 1272 case javascript.MultiplicativeDivide: 1273 mo = "/" 1274 case javascript.MultiplicativeRemainder: 1275 mo = "%" 1276 default: 1277 w.err = ErrInvalidAST 1278 return 1279 } 1280 w.WriteMultiplicativeExpression(me.MultiplicativeExpression) 1281 w.WriteString(mo) 1282 } 1283 w.WriteExponentiationExpression(&me.ExponentiationExpression) 1284 } 1285 1286 func (w *writer) WriteExponentiationExpression(ee *javascript.ExponentiationExpression) { 1287 if ee.ExponentiationExpression != nil { 1288 w.WriteExponentiationExpression(ee.ExponentiationExpression) 1289 w.WriteString("**") 1290 } 1291 w.WriteUnaryExpression(&ee.UnaryExpression) 1292 } 1293 1294 func (w *writer) WriteUnaryExpression(ue *javascript.UnaryExpression) { 1295 for _, uo := range ue.UnaryOperators { 1296 switch uo { 1297 case javascript.UnaryDelete: 1298 w.WriteString("delete") 1299 case javascript.UnaryVoid: 1300 w.WriteString("void") 1301 case javascript.UnaryTypeOf: 1302 w.WriteString("typeof") 1303 case javascript.UnaryAdd: 1304 w.WriteString("+") 1305 case javascript.UnaryMinus: 1306 w.WriteString("-") 1307 case javascript.UnaryBitwiseNot: 1308 w.WriteString("~") 1309 case javascript.UnaryLogicalNot: 1310 w.WriteString("!") 1311 case javascript.UnaryAwait: 1312 w.WriteString("await") 1313 } 1314 } 1315 w.WriteUpdateExpression(&ue.UpdateExpression) 1316 } 1317 1318 func (w *writer) WriteUpdateExpression(ue *javascript.UpdateExpression) { 1319 if ue.LeftHandSideExpression != nil { 1320 var uo string 1321 switch ue.UpdateOperator { 1322 case javascript.UpdatePostIncrement: 1323 uo = "++" 1324 case javascript.UpdatePostDecrement: 1325 uo = "--" 1326 case javascript.UpdatePreIncrement, javascript.UpdatePreDecrement: 1327 w.err = ErrInvalidAST 1328 return 1329 default: 1330 } 1331 w.WriteLeftHandSideExpression(ue.LeftHandSideExpression) 1332 if len(uo) > 0 { 1333 w.WriteString(uo) 1334 } 1335 } else if ue.UnaryExpression != nil { 1336 switch ue.UpdateOperator { 1337 case javascript.UpdatePreIncrement: 1338 w.WriteString("++") 1339 case javascript.UpdatePreDecrement: 1340 w.WriteString("--") 1341 default: 1342 w.err = ErrInvalidAST 1343 return 1344 } 1345 w.WriteUnaryExpression(ue.UnaryExpression) 1346 } 1347 } 1348 1349 func (w *writer) WriteCoalesceExpression(ce *javascript.CoalesceExpression) { 1350 if ce.CoalesceExpressionHead != nil { 1351 w.WriteCoalesceExpression(ce.CoalesceExpressionHead) 1352 w.WriteString("??") 1353 } 1354 w.WriteBitwiseORExpression(&ce.BitwiseORExpression) 1355 } 1356 1357 var ErrInvalidAST = errors.New("invalid AST") 1358