1 package scope 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "reflect" 8 "testing" 9 10 "vimagination.zapto.org/javascript" 11 "vimagination.zapto.org/parser" 12 ) 13 14 type indentPrinter struct { 15 io.Writer 16 } 17 18 var indent = []byte{' '} 19 20 func (i *indentPrinter) Write(p []byte) (int, error) { 21 var ( 22 total int 23 last int 24 ) 25 for n, c := range p { 26 if c == '\n' { 27 m, err := i.Writer.Write(p[last : n+1]) 28 total += m 29 if err != nil { 30 return total, err 31 } 32 _, err = i.Writer.Write(indent) 33 if err != nil { 34 return total, err 35 } 36 last = n + 1 37 } 38 } 39 if last != len(p) { 40 m, err := i.Writer.Write(p[last:]) 41 total += m 42 if err != nil { 43 return total, err 44 } 45 } 46 return total, nil 47 } 48 49 func (i *indentPrinter) Print(args ...interface{}) { 50 fmt.Fprint(i, args...) 51 } 52 53 func (i *indentPrinter) Printf(format string, args ...interface{}) { 54 fmt.Fprintf(i, format, args...) 55 } 56 57 func (i *indentPrinter) WriteString(s string) (int, error) { 58 return i.Write([]byte(s)) 59 } 60 61 func (s *Scope) Format(st fmt.State, _ rune) { s.printScope(&indentPrinter{st}) } 62 63 func (s *Scope) printScope(w *indentPrinter) { 64 if s.IsLexicalScope { 65 w.WriteString("LexicalScope {") 66 } else { 67 w.WriteString("Scope {") 68 } 69 pp := &indentPrinter{w} 70 qq := &indentPrinter{pp} 71 rr := &indentPrinter{qq} 72 pp.WriteString("\nParent: ") 73 if s.Parent == nil { 74 pp.WriteString("nil") 75 } else { 76 pp.Printf("%p", s.Parent) 77 } 78 pp.WriteString("\nScopes: [") 79 for t, scope := range s.Scopes { 80 qq.WriteString("\n") 81 qq.Printf("%p", t) 82 qq.WriteString(": ") 83 scope.printScope(qq) 84 } 85 pp.WriteString("\n]\nBindings: [") 86 for ref, bindings := range s.Bindings { 87 qq.WriteString("\n") 88 qq.WriteString(ref) 89 qq.WriteString(": [") 90 for _, binding := range bindings { 91 rr.WriteString("\n[") 92 rr.WriteString("\n BindingType: ") 93 rr.Print(binding.BindingType) 94 rr.WriteString("\n Scope: ") 95 rr.Printf("%p", binding.Scope) 96 rr.WriteString("\n Token: ") 97 rr.Print(binding.Token) 98 rr.WriteString("\n]") 99 } 100 qq.WriteString("\n]") 101 } 102 pp.WriteString("\n]") 103 w.WriteString("\n}") 104 } 105 106 func TestScriptScope(t *testing.T) { 107 for n, test := range [...]struct { 108 Input string 109 Output func(*javascript.Script) (*Scope, error) 110 }{ 111 { // 1 112 ``, 113 func(s *javascript.Script) (*Scope, error) { 114 return NewScope(), nil 115 }, 116 }, 117 { // 2 118 `if(true) false;`, 119 func(s *javascript.Script) (*Scope, error) { 120 return NewScope(), nil 121 }, 122 }, 123 { // 3 124 `{}`, 125 func(s *javascript.Script) (*Scope, error) { 126 scope := NewScope() 127 scope.newLexicalScope(s.StatementList[0].Statement.BlockStatement) 128 return scope, nil 129 }, 130 }, 131 { // 4 132 `a`, 133 func(s *javascript.Script) (*Scope, error) { 134 scope := NewScope() 135 scope.addBinding(javascript.UnwrapConditional(s.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, BindingRef) 136 return scope, nil 137 }, 138 }, 139 { // 5 140 `function a(){}`, 141 func(s *javascript.Script) (*Scope, error) { 142 scope := NewScope() 143 if err := scope.setBinding(s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, BindingHoistable); err != nil { 144 return nil, err 145 } 146 scope.newFunctionScope(s.StatementList[0].Declaration.FunctionDeclaration) 147 return scope, nil 148 }, 149 }, 150 { // 6 151 `const a = () => true`, 152 func(s *javascript.Script) (*Scope, error) { 153 scope := NewScope() 154 if err := scope.setBinding(s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, BindingLexicalConst); err != nil { 155 return nil, err 156 } 157 scope.newArrowFunctionScope(s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction) 158 return scope, nil 159 }, 160 }, 161 { // 7 162 `a`, 163 func(s *javascript.Script) (*Scope, error) { 164 scope := &Scope{ 165 Scopes: make(map[javascript.Type]*Scope), 166 } 167 scope.Bindings = map[string][]Binding{ 168 "a": { 169 { 170 BindingType: BindingRef, 171 Scope: scope, 172 Token: javascript.UnwrapConditional(s.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 173 }, 174 }, 175 } 176 return scope, nil 177 }, 178 }, 179 { // 8 180 `{}`, 181 func(s *javascript.Script) (*Scope, error) { 182 scope := &Scope{ 183 Bindings: make(map[string][]Binding), 184 } 185 scope.Scopes = map[javascript.Type]*Scope{ 186 s.StatementList[0].Statement.BlockStatement: { 187 IsLexicalScope: true, 188 Parent: scope, 189 Scopes: make(map[javascript.Type]*Scope), 190 Bindings: make(map[string][]Binding), 191 }, 192 } 193 return scope, nil 194 }, 195 }, 196 { // 9 197 `function a(){}`, 198 func(s *javascript.Script) (*Scope, error) { 199 scope := &Scope{} 200 scope.Bindings = map[string][]Binding{ 201 "a": { 202 { 203 BindingType: BindingHoistable, 204 Scope: scope, 205 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 206 }, 207 }, 208 } 209 fScope := &Scope{ 210 Parent: scope, 211 Scopes: make(map[javascript.Type]*Scope), 212 Bindings: map[string][]Binding{ 213 "this": {}, 214 "arguments": {}, 215 }, 216 } 217 scope.Scopes = map[javascript.Type]*Scope{ 218 s.StatementList[0].Declaration.FunctionDeclaration: fScope, 219 } 220 return scope, nil 221 }, 222 }, 223 { // 10 224 `const a = () => true`, 225 func(s *javascript.Script) (*Scope, error) { 226 scope := new(Scope) 227 scope.Bindings = map[string][]Binding{ 228 "a": { 229 { 230 BindingType: BindingLexicalConst, 231 Scope: scope, 232 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 233 }, 234 }, 235 } 236 scope.Scopes = map[javascript.Type]*Scope{ 237 s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: { 238 Parent: scope, 239 Scopes: make(map[javascript.Type]*Scope), 240 Bindings: make(map[string][]Binding), 241 }, 242 } 243 return scope, nil 244 }, 245 }, 246 { // 11 247 `let a, a`, 248 func(s *javascript.Script) (*Scope, error) { 249 return nil, ErrDuplicateDeclaration{ 250 Declaration: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 251 Duplicate: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[1].BindingIdentifier, 252 } 253 }, 254 }, 255 { // 12 256 `let a;a`, 257 func(s *javascript.Script) (*Scope, error) { 258 scope := &Scope{ 259 Scopes: make(map[javascript.Type]*Scope), 260 } 261 scope.Bindings = map[string][]Binding{ 262 "a": { 263 { 264 BindingType: BindingLexicalLet, 265 Scope: scope, 266 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 267 }, 268 { 269 BindingType: BindingRef, 270 Scope: scope, 271 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 272 }, 273 }, 274 } 275 return scope, nil 276 }, 277 }, 278 { // 13 279 `let a;{a}`, 280 func(s *javascript.Script) (*Scope, error) { 281 scope := new(Scope) 282 bscope := &Scope{ 283 IsLexicalScope: true, 284 Parent: scope, 285 Scopes: make(map[javascript.Type]*Scope), 286 Bindings: make(map[string][]Binding), 287 } 288 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 289 scope.Bindings = map[string][]Binding{ 290 "a": { 291 { 292 BindingType: BindingLexicalLet, 293 Scope: scope, 294 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 295 }, 296 { 297 BindingType: BindingRef, 298 Scope: bscope, 299 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 300 }, 301 }, 302 } 303 return scope, nil 304 }, 305 }, 306 { // 14 307 `let a;{let a}`, 308 func(s *javascript.Script) (*Scope, error) { 309 scope := new(Scope) 310 bscope := &Scope{ 311 IsLexicalScope: true, 312 Parent: scope, 313 Scopes: make(map[javascript.Type]*Scope), 314 } 315 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 316 scope.Bindings = map[string][]Binding{ 317 "a": { 318 { 319 BindingType: BindingLexicalLet, 320 Scope: scope, 321 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 322 }, 323 }, 324 } 325 bscope.Bindings = map[string][]Binding{ 326 "a": { 327 { 328 BindingType: BindingLexicalLet, 329 Scope: bscope, 330 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 331 }, 332 }, 333 } 334 return scope, nil 335 }, 336 }, 337 { // 15 338 `{function a(){}}`, 339 func(s *javascript.Script) (*Scope, error) { 340 scope := new(Scope) 341 bscope := &Scope{ 342 IsLexicalScope: true, 343 Parent: scope, 344 } 345 abind := []Binding{ 346 { 347 BindingType: BindingHoistable, 348 Scope: bscope, 349 Token: s.StatementList[0].Statement.BlockStatement.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 350 }, 351 } 352 bscope.Bindings = map[string][]Binding{"a": abind} 353 bscope.Scopes = map[javascript.Type]*Scope{ 354 s.StatementList[0].Statement.BlockStatement.StatementList[0].Declaration.FunctionDeclaration: { 355 Parent: bscope, 356 Scopes: make(map[javascript.Type]*Scope), 357 Bindings: map[string][]Binding{ 358 "this": {}, 359 "arguments": {}, 360 }, 361 }, 362 } 363 scope.Bindings = map[string][]Binding{"a": abind} 364 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Statement.BlockStatement: bscope} 365 return scope, nil 366 }, 367 }, 368 { // 16 369 `let a;{function a(){}}`, 370 func(s *javascript.Script) (*Scope, error) { 371 scope := new(Scope) 372 bscope := &Scope{ 373 IsLexicalScope: true, 374 Parent: scope, 375 } 376 bscope.Bindings = map[string][]Binding{ 377 "a": { 378 { 379 BindingType: BindingHoistable, 380 Scope: bscope, 381 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 382 }, 383 }, 384 } 385 bscope.Scopes = map[javascript.Type]*Scope{ 386 s.StatementList[1].Statement.BlockStatement.StatementList[0].Declaration.FunctionDeclaration: { 387 Parent: bscope, 388 Scopes: make(map[javascript.Type]*Scope), 389 Bindings: map[string][]Binding{ 390 "this": {}, 391 "arguments": {}, 392 }, 393 }, 394 } 395 scope.Bindings = map[string][]Binding{ 396 "a": { 397 { 398 BindingType: BindingLexicalLet, 399 Scope: scope, 400 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 401 }, 402 }, 403 } 404 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 405 return scope, nil 406 }, 407 }, 408 { // 17 409 `var a`, 410 func(s *javascript.Script) (*Scope, error) { 411 scope := &Scope{ 412 Scopes: make(map[javascript.Type]*Scope), 413 } 414 scope.Bindings = map[string][]Binding{ 415 "a": { 416 { 417 BindingType: BindingVar, 418 Scope: scope, 419 Token: s.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 420 }, 421 }, 422 } 423 return scope, nil 424 }, 425 }, 426 { // 18 427 `var a;a`, 428 func(s *javascript.Script) (*Scope, error) { 429 scope := &Scope{ 430 Scopes: make(map[javascript.Type]*Scope), 431 } 432 scope.Bindings = map[string][]Binding{ 433 "a": { 434 { 435 BindingType: BindingVar, 436 Scope: scope, 437 Token: s.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 438 }, 439 { 440 BindingType: BindingRef, 441 Scope: scope, 442 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 443 }, 444 }, 445 } 446 return scope, nil 447 }, 448 }, 449 { // 19 450 `var a;{a}`, 451 func(s *javascript.Script) (*Scope, error) { 452 scope := &Scope{} 453 bscope := &Scope{ 454 IsLexicalScope: true, 455 Parent: scope, 456 Scopes: make(map[javascript.Type]*Scope), 457 Bindings: make(map[string][]Binding), 458 } 459 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 460 scope.Bindings = map[string][]Binding{ 461 "a": { 462 { 463 BindingType: BindingVar, 464 Scope: scope, 465 Token: s.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 466 }, 467 { 468 BindingType: BindingRef, 469 Scope: bscope, 470 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 471 }, 472 }, 473 } 474 return scope, nil 475 }, 476 }, 477 { // 20 478 `a;{var a}`, 479 func(s *javascript.Script) (*Scope, error) { 480 scope := &Scope{} 481 bscope := &Scope{ 482 IsLexicalScope: true, 483 Parent: scope, 484 Scopes: make(map[javascript.Type]*Scope), 485 } 486 bscope.Bindings = map[string][]Binding{ 487 "a": { 488 { 489 BindingType: BindingVar, 490 Scope: bscope, 491 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 492 }, 493 }, 494 } 495 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 496 scope.Bindings = map[string][]Binding{ 497 "a": { 498 { 499 BindingType: BindingVar, 500 Scope: bscope, 501 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 502 }, 503 { 504 BindingType: BindingRef, 505 Scope: scope, 506 Token: javascript.UnwrapConditional(s.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 507 }, 508 }, 509 } 510 return scope, nil 511 }, 512 }, 513 { // 21 514 `var a;{var a}`, 515 func(s *javascript.Script) (*Scope, error) { 516 scope := &Scope{} 517 bscope := &Scope{ 518 IsLexicalScope: true, 519 Parent: scope, 520 Scopes: make(map[javascript.Type]*Scope), 521 } 522 bscope.Bindings = map[string][]Binding{ 523 "a": { 524 { 525 BindingType: BindingVar, 526 Scope: bscope, 527 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 528 }, 529 }, 530 } 531 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Statement.BlockStatement: bscope} 532 scope.Bindings = map[string][]Binding{ 533 "a": { 534 { 535 BindingType: BindingVar, 536 Scope: scope, 537 Token: s.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 538 }, 539 { 540 BindingType: BindingVar, 541 Scope: bscope, 542 Token: s.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 543 }, 544 }, 545 } 546 return scope, nil 547 }, 548 }, 549 { // 22 550 `function b(){var a}`, 551 func(s *javascript.Script) (*Scope, error) { 552 scope := new(Scope) 553 fscope := &Scope{ 554 Parent: scope, 555 Scopes: make(map[javascript.Type]*Scope), 556 } 557 fscope.Bindings = map[string][]Binding{ 558 "this": {}, 559 "arguments": {}, 560 "a": { 561 { 562 BindingType: BindingVar, 563 Scope: fscope, 564 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 565 }, 566 }, 567 } 568 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 569 scope.Bindings = map[string][]Binding{ 570 "b": { 571 { 572 BindingType: BindingHoistable, 573 Scope: scope, 574 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 575 }, 576 }, 577 } 578 return scope, nil 579 }, 580 }, 581 { // 23 582 `function b() {var a;a}`, 583 func(s *javascript.Script) (*Scope, error) { 584 scope := new(Scope) 585 fscope := &Scope{ 586 Parent: scope, 587 Scopes: make(map[javascript.Type]*Scope), 588 } 589 fscope.Bindings = map[string][]Binding{ 590 "this": {}, 591 "arguments": {}, 592 "a": { 593 { 594 BindingType: BindingVar, 595 Scope: fscope, 596 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 597 }, 598 { 599 BindingType: BindingRef, 600 Scope: fscope, 601 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 602 }, 603 }, 604 } 605 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 606 scope.Bindings = map[string][]Binding{ 607 "b": { 608 { 609 BindingType: BindingHoistable, 610 Scope: scope, 611 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 612 }, 613 }, 614 } 615 return scope, nil 616 }, 617 }, 618 { // 24 619 `function b() {var a;{a}}`, 620 func(s *javascript.Script) (*Scope, error) { 621 scope := new(Scope) 622 fscope := &Scope{ 623 Parent: scope, 624 } 625 bscope := &Scope{ 626 IsLexicalScope: true, 627 Parent: fscope, 628 Scopes: make(map[javascript.Type]*Scope), 629 Bindings: make(map[string][]Binding), 630 } 631 fscope.Scopes = map[javascript.Type]*Scope{ 632 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement: bscope, 633 } 634 fscope.Bindings = map[string][]Binding{ 635 "this": {}, 636 "arguments": {}, 637 "a": { 638 { 639 BindingType: BindingVar, 640 Scope: fscope, 641 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 642 }, 643 { 644 BindingType: BindingRef, 645 Scope: bscope, 646 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 647 }, 648 }, 649 } 650 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 651 scope.Bindings = map[string][]Binding{ 652 "b": { 653 { 654 BindingType: BindingHoistable, 655 Scope: scope, 656 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 657 }, 658 }, 659 } 660 return scope, nil 661 }, 662 }, 663 { // 25 664 `function b(){a;{var a}}`, 665 func(s *javascript.Script) (*Scope, error) { 666 scope := new(Scope) 667 fscope := &Scope{ 668 Parent: scope, 669 } 670 bscope := &Scope{ 671 IsLexicalScope: true, 672 Parent: fscope, 673 Scopes: make(map[javascript.Type]*Scope), 674 } 675 bscope.Bindings = map[string][]Binding{ 676 "a": { 677 { 678 BindingType: BindingVar, 679 Scope: bscope, 680 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 681 }, 682 }, 683 } 684 fscope.Scopes = map[javascript.Type]*Scope{ 685 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement: bscope, 686 } 687 fscope.Bindings = map[string][]Binding{ 688 "this": {}, 689 "arguments": {}, 690 "a": { 691 { 692 BindingType: BindingVar, 693 Scope: bscope, 694 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 695 }, 696 { 697 BindingType: BindingRef, 698 Scope: fscope, 699 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 700 }, 701 }, 702 } 703 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 704 scope.Bindings = map[string][]Binding{ 705 "b": { 706 { 707 BindingType: BindingHoistable, 708 Scope: scope, 709 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 710 }, 711 }, 712 } 713 return scope, nil 714 }, 715 }, 716 { // 26 717 `function b(){var a;{var a}}`, 718 func(s *javascript.Script) (*Scope, error) { 719 scope := new(Scope) 720 fscope := &Scope{ 721 Parent: scope, 722 } 723 bscope := &Scope{ 724 IsLexicalScope: true, 725 Parent: fscope, 726 Scopes: make(map[javascript.Type]*Scope), 727 } 728 bscope.Bindings = map[string][]Binding{ 729 "a": { 730 { 731 BindingType: BindingVar, 732 Scope: bscope, 733 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 734 }, 735 }, 736 } 737 fscope.Scopes = map[javascript.Type]*Scope{ 738 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement: bscope, 739 } 740 fscope.Bindings = map[string][]Binding{ 741 "this": {}, 742 "arguments": {}, 743 "a": { 744 { 745 BindingType: BindingVar, 746 Scope: fscope, 747 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 748 }, 749 { 750 BindingType: BindingVar, 751 Scope: bscope, 752 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 753 }, 754 }, 755 } 756 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 757 scope.Bindings = map[string][]Binding{ 758 "b": { 759 { 760 BindingType: BindingHoistable, 761 Scope: scope, 762 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 763 }, 764 }, 765 } 766 return scope, nil 767 }, 768 }, 769 { // 27 770 `function a(b, c, ...d) {b}`, 771 func(s *javascript.Script) (*Scope, error) { 772 scope := new(Scope) 773 fscope := &Scope{ 774 Parent: scope, 775 Scopes: make(map[javascript.Type]*Scope), 776 } 777 fscope.Bindings = map[string][]Binding{ 778 "this": {}, 779 "arguments": {}, 780 "b": { 781 { 782 BindingType: BindingFunctionParam, 783 Scope: fscope, 784 Token: s.StatementList[0].Declaration.FunctionDeclaration.FormalParameters.FormalParameterList[0].SingleNameBinding, 785 }, 786 { 787 BindingType: BindingRef, 788 Scope: fscope, 789 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 790 }, 791 }, 792 "c": { 793 { 794 BindingType: BindingFunctionParam, 795 Scope: fscope, 796 Token: s.StatementList[0].Declaration.FunctionDeclaration.FormalParameters.FormalParameterList[1].SingleNameBinding, 797 }, 798 }, 799 "d": { 800 { 801 BindingType: BindingFunctionParam, 802 Scope: fscope, 803 Token: s.StatementList[0].Declaration.FunctionDeclaration.FormalParameters.BindingIdentifier, 804 }, 805 }, 806 } 807 scope.Scopes = map[javascript.Type]*Scope{ 808 s.StatementList[0].Declaration.FunctionDeclaration: fscope, 809 } 810 scope.Bindings = map[string][]Binding{ 811 "a": { 812 { 813 BindingType: BindingHoistable, 814 Scope: scope, 815 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 816 }, 817 }, 818 } 819 return scope, nil 820 }, 821 }, 822 { // 28 823 `const a = b => b`, 824 func(s *javascript.Script) (*Scope, error) { 825 scope := new(Scope) 826 ascope := &Scope{ 827 Parent: scope, 828 Scopes: make(map[javascript.Type]*Scope), 829 } 830 ascope.Bindings = map[string][]Binding{ 831 "b": { 832 { 833 BindingType: BindingFunctionParam, 834 Scope: ascope, 835 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.BindingIdentifier, 836 }, 837 { 838 BindingType: BindingRef, 839 Scope: ascope, 840 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 841 }, 842 }, 843 } 844 scope.Scopes = map[javascript.Type]*Scope{ 845 s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: ascope, 846 } 847 scope.Bindings = map[string][]Binding{ 848 "a": { 849 { 850 BindingType: BindingLexicalConst, 851 Scope: scope, 852 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 853 }, 854 }, 855 } 856 return scope, nil 857 }, 858 }, 859 { // 29 860 `function a() {let [b, c, ...d] = [0, 1, 2, 3];d}`, 861 func(s *javascript.Script) (*Scope, error) { 862 scope := new(Scope) 863 fscope := &Scope{ 864 Parent: scope, 865 Scopes: make(map[javascript.Type]*Scope), 866 } 867 fscope.Bindings = map[string][]Binding{ 868 "this": {}, 869 "arguments": {}, 870 "b": { 871 { 872 BindingType: BindingLexicalLet, 873 Scope: fscope, 874 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ArrayBindingPattern.BindingElementList[0].SingleNameBinding, 875 }, 876 }, 877 "c": { 878 { 879 BindingType: BindingLexicalLet, 880 Scope: fscope, 881 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ArrayBindingPattern.BindingElementList[1].SingleNameBinding, 882 }, 883 }, 884 "d": { 885 { 886 BindingType: BindingLexicalLet, 887 Scope: fscope, 888 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ArrayBindingPattern.BindingRestElement.SingleNameBinding, 889 }, 890 { 891 BindingType: BindingRef, 892 Scope: fscope, 893 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 894 }, 895 }, 896 } 897 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 898 scope.Bindings = map[string][]Binding{ 899 "a": { 900 { 901 BindingType: BindingHoistable, 902 Scope: scope, 903 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 904 }, 905 }, 906 } 907 return scope, nil 908 }, 909 }, 910 { // 30 911 `function a() {let {z: b, c, ...d} = {};d}`, 912 func(s *javascript.Script) (*Scope, error) { 913 scope := new(Scope) 914 fscope := &Scope{ 915 Parent: scope, 916 Scopes: make(map[javascript.Type]*Scope), 917 } 918 fscope.Bindings = map[string][]Binding{ 919 "this": {}, 920 "arguments": {}, 921 "b": { 922 { 923 BindingType: BindingLexicalLet, 924 Scope: fscope, 925 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[0].BindingElement.SingleNameBinding, 926 }, 927 }, 928 "c": { 929 { 930 BindingType: BindingLexicalLet, 931 Scope: fscope, 932 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[1].BindingElement.SingleNameBinding, 933 }, 934 }, 935 "d": { 936 { 937 BindingType: BindingLexicalLet, 938 Scope: fscope, 939 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingRestProperty, 940 }, 941 { 942 BindingType: BindingRef, 943 Scope: fscope, 944 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 945 }, 946 }, 947 } 948 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 949 scope.Bindings = map[string][]Binding{ 950 "a": { 951 { 952 BindingType: BindingHoistable, 953 Scope: scope, 954 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 955 }, 956 }, 957 } 958 return scope, nil 959 }, 960 }, 961 { // 31 962 `function a(b) {let c = b => [b, d], d = 1;[d, b] = c(b)}`, 963 func(s *javascript.Script) (*Scope, error) { 964 scope := new(Scope) 965 fscope := &Scope{ 966 Parent: scope, 967 } 968 ascope := &Scope{ 969 Parent: fscope, 970 Scopes: make(map[javascript.Type]*Scope), 971 } 972 ascope.Bindings = map[string][]Binding{ 973 "b": { 974 { 975 BindingType: BindingFunctionParam, 976 Scope: ascope, 977 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.BindingIdentifier, 978 }, 979 { 980 BindingType: BindingRef, 981 Scope: ascope, 982 Token: javascript.UnwrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.ArrayLiteral).ElementList[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 983 }, 984 }, 985 } 986 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: ascope} 987 fscope.Bindings = map[string][]Binding{ 988 "this": {}, 989 "arguments": {}, 990 "b": { 991 { 992 BindingType: BindingFunctionParam, 993 Scope: fscope, 994 Token: s.StatementList[0].Declaration.FunctionDeclaration.FormalParameters.FormalParameterList[0].SingleNameBinding, 995 }, 996 { 997 BindingType: BindingRef, 998 Scope: fscope, 999 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].AssignmentPattern.ArrayAssignmentPattern.AssignmentElements[1].DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1000 }, 1001 { 1002 BindingType: BindingRef, 1003 Scope: fscope, 1004 Token: javascript.UnwrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].AssignmentExpression.ConditionalExpression).(*javascript.CallExpression).Arguments.ArgumentList[0].AssignmentExpression.ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1005 }, 1006 }, 1007 "c": { 1008 { 1009 BindingType: BindingLexicalLet, 1010 Scope: fscope, 1011 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1012 }, 1013 { 1014 BindingType: BindingRef, 1015 Scope: fscope, 1016 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].AssignmentExpression.ConditionalExpression).(*javascript.CallExpression).MemberExpression.PrimaryExpression.IdentifierReference, 1017 }, 1018 }, 1019 "d": { 1020 { 1021 BindingType: BindingLexicalLet, 1022 Scope: fscope, 1023 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[1].BindingIdentifier, 1024 }, 1025 { 1026 BindingType: BindingRef, 1027 Scope: ascope, 1028 Token: javascript.UnwrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.ArrayLiteral).ElementList[1].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1029 }, 1030 { 1031 BindingType: BindingRef, 1032 Scope: fscope, 1033 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.ExpressionStatement.Expressions[0].AssignmentPattern.ArrayAssignmentPattern.AssignmentElements[0].DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1034 }, 1035 }, 1036 } 1037 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1038 scope.Bindings = map[string][]Binding{ 1039 "a": { 1040 { 1041 BindingType: BindingHoistable, 1042 Scope: scope, 1043 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1044 }, 1045 }, 1046 } 1047 return scope, nil 1048 }, 1049 }, 1050 { // 32 1051 `function a() {return this}`, 1052 func(s *javascript.Script) (*Scope, error) { 1053 scope := new(Scope) 1054 fscope := &Scope{ 1055 Parent: scope, 1056 Scopes: make(map[javascript.Type]*Scope), 1057 } 1058 fscope.Bindings = map[string][]Binding{ 1059 "this": { 1060 { 1061 BindingType: BindingRef, 1062 Scope: fscope, 1063 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).This, 1064 }, 1065 }, 1066 "arguments": {}, 1067 } 1068 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1069 scope.Bindings = map[string][]Binding{ 1070 "a": { 1071 { 1072 BindingType: BindingHoistable, 1073 Scope: scope, 1074 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1075 }, 1076 }, 1077 } 1078 return scope, nil 1079 }, 1080 }, 1081 { // 33 1082 `function a() {return arguments}`, 1083 func(s *javascript.Script) (*Scope, error) { 1084 scope := new(Scope) 1085 fscope := &Scope{ 1086 Parent: scope, 1087 Scopes: make(map[javascript.Type]*Scope), 1088 } 1089 fscope.Bindings = map[string][]Binding{ 1090 "this": {}, 1091 "arguments": { 1092 { 1093 BindingType: BindingRef, 1094 Scope: fscope, 1095 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1096 }, 1097 }, 1098 } 1099 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1100 scope.Bindings = map[string][]Binding{ 1101 "a": { 1102 { 1103 BindingType: BindingHoistable, 1104 Scope: scope, 1105 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1106 }, 1107 }, 1108 } 1109 return scope, nil 1110 }, 1111 }, 1112 { // 34 1113 `let a;function b() {return a}`, 1114 func(s *javascript.Script) (*Scope, error) { 1115 scope := new(Scope) 1116 fscope := &Scope{ 1117 Parent: scope, 1118 Scopes: make(map[javascript.Type]*Scope), 1119 } 1120 fscope.Bindings = map[string][]Binding{ 1121 "this": {}, 1122 "arguments": {}, 1123 } 1124 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[1].Declaration.FunctionDeclaration: fscope} 1125 scope.Bindings = map[string][]Binding{ 1126 "a": { 1127 { 1128 BindingType: BindingLexicalLet, 1129 Scope: scope, 1130 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1131 }, 1132 { 1133 BindingType: BindingRef, 1134 Scope: fscope, 1135 Token: javascript.UnwrapConditional(s.StatementList[1].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1136 }, 1137 }, 1138 "b": { 1139 { 1140 BindingType: BindingHoistable, 1141 Scope: scope, 1142 Token: s.StatementList[1].Declaration.FunctionDeclaration.BindingIdentifier, 1143 }, 1144 }, 1145 } 1146 return scope, nil 1147 }, 1148 }, 1149 { // 35 1150 `const {a: b, c, ...d} = {}`, 1151 func(s *javascript.Script) (*Scope, error) { 1152 scope := &Scope{ 1153 Scopes: make(map[javascript.Type]*Scope), 1154 } 1155 scope.Bindings = map[string][]Binding{ 1156 "b": { 1157 { 1158 BindingType: BindingLexicalConst, 1159 Scope: scope, 1160 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[0].BindingElement.SingleNameBinding, 1161 }, 1162 }, 1163 "c": { 1164 { 1165 BindingType: BindingLexicalConst, 1166 Scope: scope, 1167 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[1].BindingElement.SingleNameBinding, 1168 }, 1169 }, 1170 "d": { 1171 { 1172 BindingType: BindingLexicalConst, 1173 Scope: scope, 1174 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingRestProperty, 1175 }, 1176 }, 1177 } 1178 return scope, nil 1179 }, 1180 }, 1181 { // 36 1182 `let {a, b} = {};({a, b} = {})`, 1183 func(s *javascript.Script) (*Scope, error) { 1184 scope := &Scope{ 1185 Scopes: make(map[javascript.Type]*Scope), 1186 } 1187 scope.Bindings = map[string][]Binding{ 1188 "a": { 1189 { 1190 BindingType: BindingLexicalLet, 1191 Scope: scope, 1192 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[0].BindingElement.SingleNameBinding, 1193 }, 1194 { 1195 BindingType: BindingRef, 1196 Scope: scope, 1197 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.ParenthesizedExpression).Expressions[0].AssignmentPattern.ObjectAssignmentPattern.AssignmentPropertyList[0].DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1198 }, 1199 }, 1200 "b": { 1201 { 1202 BindingType: BindingLexicalLet, 1203 Scope: scope, 1204 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[1].BindingElement.SingleNameBinding, 1205 }, 1206 { 1207 BindingType: BindingRef, 1208 Scope: scope, 1209 Token: javascript.UnwrapConditional(s.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.ParenthesizedExpression).Expressions[0].AssignmentPattern.ObjectAssignmentPattern.AssignmentPropertyList[1].DestructuringAssignmentTarget.LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1210 }, 1211 }, 1212 } 1213 return scope, nil 1214 }, 1215 }, 1216 { // 37 1217 `var c;{let c;{var c}}`, 1218 func(s *javascript.Script) (*Scope, error) { 1219 return nil, ErrDuplicateDeclaration{ 1220 Declaration: s.StatementList[1].Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1221 Duplicate: s.StatementList[1].Statement.BlockStatement.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1222 } 1223 }, 1224 }, 1225 { // 38 1226 `const {a: [b]} = {}`, 1227 func(s *javascript.Script) (*Scope, error) { 1228 scope := &Scope{ 1229 Scopes: make(map[javascript.Type]*Scope), 1230 } 1231 scope.Bindings = map[string][]Binding{ 1232 "b": { 1233 { 1234 BindingType: BindingLexicalConst, 1235 Scope: scope, 1236 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].ObjectBindingPattern.BindingPropertyList[0].BindingElement.ArrayBindingPattern.BindingElementList[0].SingleNameBinding, 1237 }, 1238 }, 1239 } 1240 return scope, nil 1241 }, 1242 }, 1243 { // 39 1244 `var [{a}] = []`, 1245 func(s *javascript.Script) (*Scope, error) { 1246 scope := &Scope{ 1247 Scopes: make(map[javascript.Type]*Scope), 1248 } 1249 scope.Bindings = map[string][]Binding{ 1250 "a": { 1251 { 1252 BindingType: BindingVar, 1253 Scope: scope, 1254 Token: s.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].ArrayBindingPattern.BindingElementList[0].ObjectBindingPattern.BindingPropertyList[0].BindingElement.SingleNameBinding, 1255 }, 1256 }, 1257 } 1258 return scope, nil 1259 }, 1260 }, 1261 { // 40 1262 `function a() {for (let a = 0; a < 2; a++){}}`, 1263 func(s *javascript.Script) (*Scope, error) { 1264 scope := new(Scope) 1265 fscope := &Scope{Parent: scope} 1266 iscope := &Scope{ 1267 IsLexicalScope: true, 1268 Parent: fscope, 1269 } 1270 iscope.Scopes = map[javascript.Type]*Scope{ 1271 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: { 1272 IsLexicalScope: true, 1273 Parent: iscope, 1274 Scopes: make(map[javascript.Type]*Scope), 1275 Bindings: make(map[string][]Binding), 1276 }, 1277 } 1278 iscope.Bindings = map[string][]Binding{ 1279 "a": { 1280 { 1281 BindingType: BindingLexicalLet, 1282 Scope: iscope, 1283 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.InitLexical.BindingList[0].BindingIdentifier, 1284 }, 1285 { 1286 BindingType: BindingRef, 1287 Scope: iscope, 1288 Token: javascript.UnwrapConditional(javascript.WrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Conditional.Expressions[0].ConditionalExpression).(*javascript.RelationalExpression).RelationalExpression)).(*javascript.PrimaryExpression).IdentifierReference, 1289 }, 1290 { 1291 BindingType: BindingRef, 1292 Scope: iscope, 1293 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Afterthought.Expressions[0].ConditionalExpression).(*javascript.UpdateExpression).LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1294 }, 1295 }, 1296 } 1297 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1298 fscope.Bindings = map[string][]Binding{ 1299 "this": {}, 1300 "arguments": {}, 1301 } 1302 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1303 scope.Bindings = map[string][]Binding{ 1304 "a": { 1305 { 1306 BindingType: BindingHoistable, 1307 Scope: scope, 1308 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1309 }, 1310 }, 1311 } 1312 return scope, nil 1313 }, 1314 }, 1315 { // 41 1316 `function a() {for (var a = 0; a < 2; a++){}}`, 1317 func(s *javascript.Script) (*Scope, error) { 1318 scope := new(Scope) 1319 fscope := &Scope{ 1320 Parent: scope, 1321 } 1322 iscope := &Scope{ 1323 IsLexicalScope: true, 1324 Parent: fscope, 1325 } 1326 bscope := &Scope{ 1327 IsLexicalScope: true, 1328 Parent: iscope, 1329 Scopes: make(map[javascript.Type]*Scope), 1330 Bindings: make(map[string][]Binding), 1331 } 1332 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1333 iscope.Bindings = map[string][]Binding{ 1334 "a": { 1335 { 1336 BindingType: BindingVar, 1337 Scope: iscope, 1338 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.InitVar[0].BindingIdentifier, 1339 }, 1340 { 1341 BindingType: BindingRef, 1342 Scope: iscope, 1343 Token: javascript.UnwrapConditional(javascript.WrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Conditional.Expressions[0].ConditionalExpression).(*javascript.RelationalExpression).RelationalExpression)).(*javascript.PrimaryExpression).IdentifierReference, 1344 }, 1345 { 1346 BindingType: BindingRef, 1347 Scope: iscope, 1348 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Afterthought.Expressions[0].ConditionalExpression).(*javascript.UpdateExpression).LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1349 }, 1350 }, 1351 } 1352 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1353 fscope.Bindings = map[string][]Binding{ 1354 "this": {}, 1355 "arguments": {}, 1356 "a": iscope.Bindings["a"], 1357 } 1358 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1359 scope.Bindings = map[string][]Binding{ 1360 "a": { 1361 { 1362 BindingType: BindingHoistable, 1363 Scope: scope, 1364 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1365 }, 1366 }, 1367 } 1368 return scope, nil 1369 }, 1370 }, 1371 { // 42 1372 `function a() {for (b = 0; b < 2; b++){}}`, 1373 func(s *javascript.Script) (*Scope, error) { 1374 scope := new(Scope) 1375 fscope := &Scope{ 1376 Parent: scope, 1377 } 1378 iscope := &Scope{ 1379 IsLexicalScope: true, 1380 Parent: fscope, 1381 Bindings: make(map[string][]Binding), 1382 } 1383 bscope := &Scope{ 1384 IsLexicalScope: true, 1385 Parent: iscope, 1386 Scopes: make(map[javascript.Type]*Scope), 1387 Bindings: make(map[string][]Binding), 1388 } 1389 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1390 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1391 fscope.Bindings = map[string][]Binding{ 1392 "this": {}, 1393 "arguments": {}, 1394 } 1395 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1396 scope.Bindings = map[string][]Binding{ 1397 "a": { 1398 { 1399 BindingType: BindingHoistable, 1400 Scope: scope, 1401 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1402 }, 1403 }, 1404 "b": { 1405 { 1406 BindingType: BindingBare, 1407 Scope: iscope, 1408 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.InitExpression.Expressions[0].LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1409 }, 1410 { 1411 BindingType: BindingRef, 1412 Scope: iscope, 1413 Token: javascript.UnwrapConditional(javascript.WrapConditional(javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Conditional.Expressions[0].ConditionalExpression).(*javascript.RelationalExpression).RelationalExpression)).(*javascript.PrimaryExpression).IdentifierReference, 1414 }, 1415 { 1416 BindingType: BindingRef, 1417 Scope: iscope, 1418 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Afterthought.Expressions[0].ConditionalExpression).(*javascript.UpdateExpression).LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 1419 }, 1420 }, 1421 } 1422 return scope, nil 1423 }, 1424 }, 1425 { // 43 1426 `function a() {let a;for (const a in {}){}}`, 1427 func(s *javascript.Script) (*Scope, error) { 1428 scope := new(Scope) 1429 fscope := &Scope{ 1430 Parent: scope, 1431 } 1432 iscope := &Scope{ 1433 IsLexicalScope: true, 1434 Parent: fscope, 1435 } 1436 bscope := &Scope{ 1437 IsLexicalScope: true, 1438 Parent: iscope, 1439 Scopes: make(map[javascript.Type]*Scope), 1440 Bindings: make(map[string][]Binding), 1441 } 1442 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1443 iscope.Bindings = map[string][]Binding{ 1444 "a": { 1445 { 1446 BindingType: BindingLexicalConst, 1447 Scope: iscope, 1448 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor.ForBindingIdentifier, 1449 }, 1450 }, 1451 } 1452 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor: iscope} 1453 fscope.Bindings = map[string][]Binding{ 1454 "this": {}, 1455 "arguments": {}, 1456 "a": { 1457 { 1458 BindingType: BindingLexicalLet, 1459 Scope: fscope, 1460 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1461 }, 1462 }, 1463 } 1464 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1465 scope.Bindings = map[string][]Binding{ 1466 "a": { 1467 { 1468 BindingType: BindingHoistable, 1469 Scope: scope, 1470 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1471 }, 1472 }, 1473 } 1474 return scope, nil 1475 }, 1476 }, 1477 { // 44 1478 `function a() {let a;for (const a of []){}}`, 1479 func(s *javascript.Script) (*Scope, error) { 1480 scope := new(Scope) 1481 fscope := &Scope{ 1482 Parent: scope, 1483 } 1484 iscope := &Scope{ 1485 IsLexicalScope: true, 1486 Parent: fscope, 1487 } 1488 bscope := &Scope{ 1489 IsLexicalScope: true, 1490 Parent: iscope, 1491 Scopes: make(map[javascript.Type]*Scope), 1492 Bindings: make(map[string][]Binding), 1493 } 1494 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1495 iscope.Bindings = map[string][]Binding{ 1496 "a": { 1497 { 1498 BindingType: BindingLexicalConst, 1499 Scope: iscope, 1500 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor.ForBindingIdentifier, 1501 }, 1502 }, 1503 } 1504 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.IterationStatementFor: iscope} 1505 fscope.Bindings = map[string][]Binding{ 1506 "this": {}, 1507 "arguments": {}, 1508 "a": { 1509 { 1510 BindingType: BindingLexicalLet, 1511 Scope: fscope, 1512 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1513 }, 1514 }, 1515 } 1516 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1517 scope.Bindings = map[string][]Binding{ 1518 "a": { 1519 { 1520 BindingType: BindingHoistable, 1521 Scope: scope, 1522 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1523 }, 1524 }, 1525 } 1526 return scope, nil 1527 }, 1528 }, 1529 { // 45 1530 `function a() {for (var a of []){}}`, 1531 func(s *javascript.Script) (*Scope, error) { 1532 scope := new(Scope) 1533 fscope := &Scope{ 1534 Parent: scope, 1535 } 1536 iscope := &Scope{ 1537 IsLexicalScope: true, 1538 Parent: fscope, 1539 } 1540 bscope := &Scope{ 1541 IsLexicalScope: true, 1542 Parent: iscope, 1543 Scopes: make(map[javascript.Type]*Scope), 1544 Bindings: make(map[string][]Binding), 1545 } 1546 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1547 iscope.Bindings = map[string][]Binding{ 1548 "a": { 1549 { 1550 BindingType: BindingVar, 1551 Scope: iscope, 1552 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.ForBindingIdentifier, 1553 }, 1554 }, 1555 } 1556 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1557 fscope.Bindings = map[string][]Binding{ 1558 "this": {}, 1559 "arguments": {}, 1560 "a": iscope.Bindings["a"], 1561 } 1562 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1563 scope.Bindings = map[string][]Binding{ 1564 "a": { 1565 { 1566 BindingType: BindingHoistable, 1567 Scope: scope, 1568 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1569 }, 1570 }, 1571 } 1572 return scope, nil 1573 }, 1574 }, 1575 { // 46 1576 `function a() {for (let [a] of []){}}`, 1577 func(s *javascript.Script) (*Scope, error) { 1578 scope := new(Scope) 1579 fscope := &Scope{ 1580 Parent: scope, 1581 } 1582 iscope := &Scope{ 1583 IsLexicalScope: true, 1584 Parent: fscope, 1585 } 1586 bscope := &Scope{ 1587 IsLexicalScope: true, 1588 Parent: iscope, 1589 Scopes: make(map[javascript.Type]*Scope), 1590 Bindings: make(map[string][]Binding), 1591 } 1592 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1593 iscope.Bindings = map[string][]Binding{ 1594 "a": { 1595 { 1596 BindingType: BindingLexicalLet, 1597 Scope: iscope, 1598 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.ForBindingPatternArray.BindingElementList[0].SingleNameBinding, 1599 }, 1600 }, 1601 } 1602 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1603 fscope.Bindings = map[string][]Binding{ 1604 "this": {}, 1605 "arguments": {}, 1606 } 1607 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1608 scope.Bindings = map[string][]Binding{ 1609 "a": { 1610 { 1611 BindingType: BindingHoistable, 1612 Scope: scope, 1613 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1614 }, 1615 }, 1616 } 1617 return scope, nil 1618 }, 1619 }, 1620 { // 47 1621 `function a() {for (let {a} of []){}}`, 1622 func(s *javascript.Script) (*Scope, error) { 1623 scope := new(Scope) 1624 fscope := &Scope{ 1625 Parent: scope, 1626 } 1627 iscope := &Scope{ 1628 IsLexicalScope: true, 1629 Parent: fscope, 1630 } 1631 bscope := &Scope{ 1632 IsLexicalScope: true, 1633 Parent: iscope, 1634 Scopes: make(map[javascript.Type]*Scope), 1635 Bindings: make(map[string][]Binding), 1636 } 1637 iscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.Statement.BlockStatement: bscope} 1638 iscope.Bindings = map[string][]Binding{ 1639 "a": { 1640 { 1641 BindingType: BindingLexicalLet, 1642 Scope: iscope, 1643 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor.ForBindingPatternObject.BindingPropertyList[0].BindingElement.SingleNameBinding, 1644 }, 1645 }, 1646 } 1647 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.IterationStatementFor: iscope} 1648 fscope.Bindings = map[string][]Binding{ 1649 "this": {}, 1650 "arguments": {}, 1651 } 1652 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1653 scope.Bindings = map[string][]Binding{ 1654 "a": { 1655 { 1656 BindingType: BindingHoistable, 1657 Scope: scope, 1658 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1659 }, 1660 }, 1661 } 1662 return scope, nil 1663 }, 1664 }, 1665 { // 48 1666 `function a() {var a;try{}catch(a){a}}`, 1667 func(s *javascript.Script) (*Scope, error) { 1668 scope := new(Scope) 1669 fscope := &Scope{ 1670 Parent: scope, 1671 } 1672 tscope := &Scope{ 1673 IsLexicalScope: true, 1674 Parent: fscope, 1675 Scopes: make(map[javascript.Type]*Scope), 1676 } 1677 tscope.Bindings = map[string][]Binding{ 1678 "a": { 1679 { 1680 BindingType: BindingCatch, 1681 Scope: tscope, 1682 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchParameterBindingIdentifier, 1683 }, 1684 { 1685 BindingType: BindingRef, 1686 Scope: tscope, 1687 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1688 }, 1689 }, 1690 } 1691 fscope.Scopes = map[javascript.Type]*Scope{ 1692 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock: { 1693 IsLexicalScope: true, 1694 Parent: fscope, 1695 Scopes: make(map[javascript.Type]*Scope), 1696 Bindings: make(map[string][]Binding), 1697 }, 1698 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock: tscope, 1699 } 1700 fscope.Bindings = map[string][]Binding{ 1701 "this": {}, 1702 "arguments": {}, 1703 "a": { 1704 { 1705 BindingType: BindingVar, 1706 Scope: fscope, 1707 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1708 }, 1709 }, 1710 } 1711 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1712 scope.Bindings = map[string][]Binding{ 1713 "a": { 1714 { 1715 BindingType: BindingHoistable, 1716 Scope: scope, 1717 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1718 }, 1719 }, 1720 } 1721 return scope, nil 1722 }, 1723 }, 1724 { // 49 1725 `function a() {var a;try{}catch(a){let a}}`, 1726 func(s *javascript.Script) (*Scope, error) { 1727 return nil, ErrDuplicateDeclaration{ 1728 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchParameterBindingIdentifier, 1729 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1730 } 1731 }, 1732 }, 1733 { // 50 1734 `function a() {var a;try{}catch(a){a;var a}}`, 1735 func(s *javascript.Script) (*Scope, error) { 1736 scope := new(Scope) 1737 fscope := &Scope{ 1738 Parent: scope, 1739 } 1740 tscope := &Scope{ 1741 IsLexicalScope: true, 1742 Parent: fscope, 1743 Scopes: make(map[javascript.Type]*Scope), 1744 } 1745 tscope.Bindings = map[string][]Binding{ 1746 "a": { 1747 { 1748 BindingType: BindingCatch, 1749 Scope: tscope, 1750 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchParameterBindingIdentifier, 1751 }, 1752 { 1753 BindingType: BindingVar, 1754 Scope: tscope, 1755 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[1].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1756 }, 1757 { 1758 BindingType: BindingRef, 1759 Scope: tscope, 1760 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1761 }, 1762 }, 1763 } 1764 fscope.Scopes = map[javascript.Type]*Scope{ 1765 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock: { 1766 IsLexicalScope: true, 1767 Parent: fscope, 1768 Scopes: make(map[javascript.Type]*Scope), 1769 Bindings: make(map[string][]Binding), 1770 }, 1771 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock: tscope, 1772 } 1773 fscope.Bindings = map[string][]Binding{ 1774 "this": {}, 1775 "arguments": {}, 1776 "a": { 1777 { 1778 BindingType: BindingVar, 1779 Scope: fscope, 1780 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1781 }, 1782 }, 1783 } 1784 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1785 scope.Bindings = map[string][]Binding{ 1786 "a": { 1787 { 1788 BindingType: BindingHoistable, 1789 Scope: scope, 1790 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1791 }, 1792 }, 1793 } 1794 return scope, nil 1795 }, 1796 }, 1797 { // 51 1798 `function a() {var a;try{}catch(a){{let a}}}`, 1799 func(s *javascript.Script) (*Scope, error) { 1800 scope := new(Scope) 1801 fscope := &Scope{ 1802 Parent: scope, 1803 } 1804 tscope := &Scope{ 1805 IsLexicalScope: true, 1806 Parent: fscope, 1807 } 1808 bscope := &Scope{ 1809 IsLexicalScope: true, 1810 Parent: tscope, 1811 Scopes: make(map[javascript.Type]*Scope), 1812 } 1813 bscope.Bindings = map[string][]Binding{ 1814 "a": { 1815 { 1816 BindingType: BindingLexicalLet, 1817 Scope: bscope, 1818 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[0].Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1819 }, 1820 }, 1821 } 1822 tscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock.StatementList[0].Statement.BlockStatement: bscope} 1823 tscope.Bindings = map[string][]Binding{ 1824 "a": { 1825 { 1826 BindingType: BindingCatch, 1827 Scope: tscope, 1828 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchParameterBindingIdentifier, 1829 }, 1830 }, 1831 } 1832 fscope.Scopes = map[javascript.Type]*Scope{ 1833 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock: { 1834 IsLexicalScope: true, 1835 Parent: fscope, 1836 Scopes: make(map[javascript.Type]*Scope), 1837 Bindings: make(map[string][]Binding), 1838 }, 1839 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.CatchBlock: tscope, 1840 } 1841 fscope.Bindings = map[string][]Binding{ 1842 "this": {}, 1843 "arguments": {}, 1844 "a": { 1845 { 1846 BindingType: BindingVar, 1847 Scope: fscope, 1848 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1849 }, 1850 }, 1851 } 1852 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1853 scope.Bindings = map[string][]Binding{ 1854 "a": { 1855 { 1856 BindingType: BindingHoistable, 1857 Scope: scope, 1858 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1859 }, 1860 }, 1861 } 1862 return scope, nil 1863 }, 1864 }, 1865 { // 52 1866 `function a() {var a;try{a}finally{}}`, 1867 func(s *javascript.Script) (*Scope, error) { 1868 scope := new(Scope) 1869 fscope := &Scope{ 1870 Parent: scope, 1871 } 1872 tscope := &Scope{ 1873 IsLexicalScope: true, 1874 Parent: fscope, 1875 Scopes: make(map[javascript.Type]*Scope), 1876 Bindings: make(map[string][]Binding), 1877 } 1878 fscope.Scopes = map[javascript.Type]*Scope{ 1879 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock: tscope, 1880 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.FinallyBlock: { 1881 IsLexicalScope: true, 1882 Parent: fscope, 1883 Scopes: make(map[javascript.Type]*Scope), 1884 Bindings: make(map[string][]Binding), 1885 }, 1886 } 1887 fscope.Bindings = map[string][]Binding{ 1888 "this": {}, 1889 "arguments": {}, 1890 "a": { 1891 { 1892 BindingType: BindingVar, 1893 Scope: fscope, 1894 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1895 }, 1896 { 1897 BindingType: BindingRef, 1898 Scope: tscope, 1899 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 1900 }, 1901 }, 1902 } 1903 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1904 scope.Bindings = map[string][]Binding{ 1905 "a": { 1906 { 1907 BindingType: BindingHoistable, 1908 Scope: scope, 1909 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1910 }, 1911 }, 1912 } 1913 return scope, nil 1914 }, 1915 }, 1916 { // 53 1917 `function a() {var a;try{let a}finally{}}`, 1918 func(s *javascript.Script) (*Scope, error) { 1919 scope := new(Scope) 1920 fscope := &Scope{ 1921 Parent: scope, 1922 } 1923 tscope := &Scope{ 1924 IsLexicalScope: true, 1925 Parent: fscope, 1926 Scopes: make(map[javascript.Type]*Scope), 1927 } 1928 tscope.Bindings = map[string][]Binding{ 1929 "a": { 1930 { 1931 BindingType: BindingLexicalLet, 1932 Scope: tscope, 1933 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 1934 }, 1935 }, 1936 } 1937 fscope.Scopes = map[javascript.Type]*Scope{ 1938 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.TryBlock: tscope, 1939 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.TryStatement.FinallyBlock: { 1940 IsLexicalScope: true, 1941 Parent: fscope, 1942 Scopes: make(map[javascript.Type]*Scope), 1943 Bindings: make(map[string][]Binding), 1944 }, 1945 } 1946 fscope.Bindings = map[string][]Binding{ 1947 "this": {}, 1948 "arguments": {}, 1949 "a": { 1950 { 1951 BindingType: BindingVar, 1952 Scope: fscope, 1953 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1954 }, 1955 }, 1956 } 1957 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 1958 scope.Bindings = map[string][]Binding{ 1959 "a": { 1960 { 1961 BindingType: BindingHoistable, 1962 Scope: scope, 1963 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 1964 }, 1965 }, 1966 } 1967 return scope, nil 1968 }, 1969 }, 1970 { // 54 1971 `function a() {try{var a}finally{}}`, 1972 func(s *javascript.Script) (*Scope, error) { 1973 scope := new(Scope) 1974 fscope := &Scope{ 1975 Parent: scope, 1976 } 1977 tscope := &Scope{ 1978 IsLexicalScope: true, 1979 Parent: fscope, 1980 Scopes: make(map[javascript.Type]*Scope), 1981 } 1982 tscope.Bindings = map[string][]Binding{ 1983 "a": { 1984 { 1985 BindingType: BindingVar, 1986 Scope: tscope, 1987 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 1988 }, 1989 }, 1990 } 1991 fscope.Scopes = map[javascript.Type]*Scope{ 1992 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock: tscope, 1993 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.FinallyBlock: { 1994 IsLexicalScope: true, 1995 Parent: fscope, 1996 Scopes: make(map[javascript.Type]*Scope), 1997 Bindings: make(map[string][]Binding), 1998 }, 1999 } 2000 fscope.Bindings = map[string][]Binding{ 2001 "this": {}, 2002 "arguments": {}, 2003 "a": tscope.Bindings["a"], 2004 } 2005 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2006 scope.Bindings = map[string][]Binding{ 2007 "a": { 2008 { 2009 BindingType: BindingHoistable, 2010 Scope: scope, 2011 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2012 }, 2013 }, 2014 } 2015 return scope, nil 2016 }, 2017 }, 2018 { // 55 2019 `function a() {try{}catch(b){var a}}`, 2020 func(s *javascript.Script) (*Scope, error) { 2021 scope := new(Scope) 2022 fscope := &Scope{ 2023 Parent: scope, 2024 } 2025 tscope := &Scope{ 2026 IsLexicalScope: true, 2027 Parent: fscope, 2028 Scopes: make(map[javascript.Type]*Scope), 2029 } 2030 tscope.Bindings = map[string][]Binding{ 2031 "b": { 2032 { 2033 BindingType: BindingCatch, 2034 Scope: tscope, 2035 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchParameterBindingIdentifier, 2036 }, 2037 }, 2038 "a": { 2039 { 2040 BindingType: BindingVar, 2041 Scope: tscope, 2042 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchBlock.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 2043 }, 2044 }, 2045 } 2046 fscope.Scopes = map[javascript.Type]*Scope{ 2047 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock: { 2048 IsLexicalScope: true, 2049 Parent: fscope, 2050 Scopes: make(map[javascript.Type]*Scope), 2051 Bindings: make(map[string][]Binding), 2052 }, 2053 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchBlock: tscope, 2054 } 2055 fscope.Bindings = map[string][]Binding{ 2056 "this": {}, 2057 "arguments": {}, 2058 "a": tscope.Bindings["a"], 2059 } 2060 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2061 scope.Bindings = map[string][]Binding{ 2062 "a": { 2063 { 2064 BindingType: BindingHoistable, 2065 Scope: scope, 2066 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2067 }, 2068 }, 2069 } 2070 return scope, nil 2071 }, 2072 }, 2073 { // 56 2074 `function a() {try{}catch(b){let a}}`, 2075 func(s *javascript.Script) (*Scope, error) { 2076 scope := new(Scope) 2077 fscope := &Scope{ 2078 Parent: scope, 2079 } 2080 tscope := &Scope{ 2081 IsLexicalScope: true, 2082 Parent: fscope, 2083 Scopes: make(map[javascript.Type]*Scope), 2084 } 2085 tscope.Bindings = map[string][]Binding{ 2086 "b": { 2087 { 2088 BindingType: BindingCatch, 2089 Scope: tscope, 2090 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchParameterBindingIdentifier, 2091 }, 2092 }, 2093 "a": { 2094 { 2095 BindingType: BindingLexicalLet, 2096 Scope: tscope, 2097 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchBlock.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2098 }, 2099 }, 2100 } 2101 fscope.Scopes = map[javascript.Type]*Scope{ 2102 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock: { 2103 IsLexicalScope: true, 2104 Parent: fscope, 2105 Scopes: make(map[javascript.Type]*Scope), 2106 Bindings: make(map[string][]Binding), 2107 }, 2108 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.CatchBlock: tscope, 2109 } 2110 fscope.Bindings = map[string][]Binding{ 2111 "this": {}, 2112 "arguments": {}, 2113 } 2114 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2115 scope.Bindings = map[string][]Binding{ 2116 "a": { 2117 { 2118 BindingType: BindingHoistable, 2119 Scope: scope, 2120 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2121 }, 2122 }, 2123 } 2124 return scope, nil 2125 }, 2126 }, 2127 { // 57 2128 `function a() {try{}finally{var a}}`, 2129 func(s *javascript.Script) (*Scope, error) { 2130 scope := new(Scope) 2131 fscope := &Scope{ 2132 Parent: scope, 2133 } 2134 tscope := &Scope{ 2135 IsLexicalScope: true, 2136 Parent: fscope, 2137 Scopes: make(map[javascript.Type]*Scope), 2138 } 2139 tscope.Bindings = map[string][]Binding{ 2140 "a": { 2141 { 2142 BindingType: BindingVar, 2143 Scope: tscope, 2144 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.FinallyBlock.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 2145 }, 2146 }, 2147 } 2148 fscope.Scopes = map[javascript.Type]*Scope{ 2149 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock: { 2150 IsLexicalScope: true, 2151 Parent: fscope, 2152 Scopes: make(map[javascript.Type]*Scope), 2153 Bindings: make(map[string][]Binding), 2154 }, 2155 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.FinallyBlock: tscope, 2156 } 2157 fscope.Bindings = map[string][]Binding{ 2158 "this": {}, 2159 "arguments": {}, 2160 "a": tscope.Bindings["a"], 2161 } 2162 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2163 scope.Bindings = map[string][]Binding{ 2164 "a": { 2165 { 2166 BindingType: BindingHoistable, 2167 Scope: scope, 2168 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2169 }, 2170 }, 2171 } 2172 return scope, nil 2173 }, 2174 }, 2175 { // 58 2176 `function a() {try{}finally{let a}}`, 2177 func(s *javascript.Script) (*Scope, error) { 2178 scope := new(Scope) 2179 fscope := &Scope{ 2180 Parent: scope, 2181 } 2182 tscope := &Scope{ 2183 IsLexicalScope: true, 2184 Parent: fscope, 2185 Scopes: make(map[javascript.Type]*Scope), 2186 } 2187 tscope.Bindings = map[string][]Binding{ 2188 "a": { 2189 { 2190 BindingType: BindingLexicalLet, 2191 Scope: tscope, 2192 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.FinallyBlock.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2193 }, 2194 }, 2195 } 2196 fscope.Scopes = map[javascript.Type]*Scope{ 2197 &s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.TryBlock: { 2198 IsLexicalScope: true, 2199 Parent: fscope, 2200 Scopes: make(map[javascript.Type]*Scope), 2201 Bindings: make(map[string][]Binding), 2202 }, 2203 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.TryStatement.FinallyBlock: tscope, 2204 } 2205 fscope.Bindings = map[string][]Binding{ 2206 "this": {}, 2207 "arguments": {}, 2208 } 2209 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2210 scope.Bindings = map[string][]Binding{ 2211 "a": { 2212 { 2213 BindingType: BindingHoistable, 2214 Scope: scope, 2215 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2216 }, 2217 }, 2218 } 2219 return scope, nil 2220 }, 2221 }, 2222 { // 59 2223 `function a() {let a;switch(a){}}`, 2224 func(s *javascript.Script) (*Scope, error) { 2225 scope := new(Scope) 2226 fscope := &Scope{ 2227 Parent: scope, 2228 } 2229 sscope := &Scope{ 2230 IsLexicalScope: true, 2231 Parent: fscope, 2232 Scopes: make(map[javascript.Type]*Scope), 2233 Bindings: make(map[string][]Binding), 2234 } 2235 fscope.Scopes = map[javascript.Type]*Scope{ 2236 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement: sscope, 2237 } 2238 fscope.Bindings = map[string][]Binding{ 2239 "this": {}, 2240 "arguments": {}, 2241 "a": { 2242 { 2243 BindingType: BindingLexicalLet, 2244 Scope: fscope, 2245 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2246 }, 2247 { 2248 BindingType: BindingRef, 2249 Scope: fscope, 2250 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.Expression.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2251 }, 2252 }, 2253 } 2254 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2255 scope.Bindings = map[string][]Binding{ 2256 "a": { 2257 { 2258 BindingType: BindingHoistable, 2259 Scope: scope, 2260 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2261 }, 2262 }, 2263 } 2264 return scope, nil 2265 }, 2266 }, 2267 { // 60 2268 `function a() {let a;switch(a){case a:}}`, 2269 func(s *javascript.Script) (*Scope, error) { 2270 scope := new(Scope) 2271 fscope := &Scope{ 2272 Parent: scope, 2273 } 2274 sscope := &Scope{ 2275 IsLexicalScope: true, 2276 Parent: fscope, 2277 Scopes: make(map[javascript.Type]*Scope), 2278 Bindings: make(map[string][]Binding), 2279 } 2280 fscope.Scopes = map[javascript.Type]*Scope{ 2281 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement: sscope, 2282 } 2283 fscope.Bindings = map[string][]Binding{ 2284 "this": {}, 2285 "arguments": {}, 2286 "a": { 2287 { 2288 BindingType: BindingLexicalLet, 2289 Scope: fscope, 2290 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2291 }, 2292 { 2293 BindingType: BindingRef, 2294 Scope: fscope, 2295 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.Expression.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2296 }, 2297 { 2298 BindingType: BindingRef, 2299 Scope: sscope, 2300 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].Expression.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2301 }, 2302 }, 2303 } 2304 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2305 scope.Bindings = map[string][]Binding{ 2306 "a": { 2307 { 2308 BindingType: BindingHoistable, 2309 Scope: scope, 2310 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2311 }, 2312 }, 2313 } 2314 return scope, nil 2315 }, 2316 }, 2317 { // 61 2318 `function a() {let a;switch(a){case a:let a}}`, 2319 func(s *javascript.Script) (*Scope, error) { 2320 scope := new(Scope) 2321 fscope := &Scope{ 2322 Parent: scope, 2323 } 2324 sscope := &Scope{ 2325 IsLexicalScope: true, 2326 Parent: fscope, 2327 Scopes: make(map[javascript.Type]*Scope), 2328 } 2329 sscope.Bindings = map[string][]Binding{ 2330 "a": { 2331 { 2332 BindingType: BindingLexicalLet, 2333 Scope: sscope, 2334 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2335 }, 2336 { 2337 BindingType: BindingRef, 2338 Scope: sscope, 2339 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].Expression.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2340 }, 2341 }, 2342 } 2343 fscope.Scopes = map[javascript.Type]*Scope{ 2344 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement: sscope, 2345 } 2346 fscope.Bindings = map[string][]Binding{ 2347 "this": {}, 2348 "arguments": {}, 2349 "a": { 2350 { 2351 BindingType: BindingLexicalLet, 2352 Scope: fscope, 2353 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2354 }, 2355 { 2356 BindingType: BindingRef, 2357 Scope: fscope, 2358 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.Expression.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2359 }, 2360 }, 2361 } 2362 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2363 scope.Bindings = map[string][]Binding{ 2364 "a": { 2365 { 2366 BindingType: BindingHoistable, 2367 Scope: scope, 2368 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2369 }, 2370 }, 2371 } 2372 return scope, nil 2373 }, 2374 }, 2375 { // 62 2376 `function a() {let a;switch(a){case 1:let a;break;case 2:let a}}`, 2377 func(s *javascript.Script) (*Scope, error) { 2378 return nil, ErrDuplicateDeclaration{ 2379 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2380 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[1].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2381 } 2382 }, 2383 }, 2384 { // 63 2385 `function a() {let a;switch(a){case 1:let a;break;default:break;case 2:let a}}`, 2386 func(s *javascript.Script) (*Scope, error) { 2387 return nil, ErrDuplicateDeclaration{ 2388 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2389 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.PostDefaultCaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2390 } 2391 }, 2392 }, 2393 { // 64 2394 `function a() {let a;switch(a){default:break;case 1:let a;break;case 2:let a}}`, 2395 func(s *javascript.Script) (*Scope, error) { 2396 return nil, ErrDuplicateDeclaration{ 2397 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.PostDefaultCaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2398 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.PostDefaultCaseClauses[1].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2399 } 2400 }, 2401 }, 2402 { // 65 2403 `function a() {let a;switch(a){default:let a;break;case 2:let a}}`, 2404 func(s *javascript.Script) (*Scope, error) { 2405 return nil, ErrDuplicateDeclaration{ 2406 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.DefaultClause[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2407 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.PostDefaultCaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2408 } 2409 }, 2410 }, 2411 { // 66 2412 `function a() {let a;switch(a){case 1:let a;break;default:let a}}`, 2413 func(s *javascript.Script) (*Scope, error) { 2414 return nil, ErrDuplicateDeclaration{ 2415 Declaration: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2416 Duplicate: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[1].Statement.SwitchStatement.DefaultClause[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2417 } 2418 }, 2419 }, 2420 { // 67 2421 `function a() {switch(0){case 1:{let a};case 2:{let a}}}`, 2422 func(s *javascript.Script) (*Scope, error) { 2423 scope := new(Scope) 2424 fscope := &Scope{ 2425 Parent: scope, 2426 } 2427 sscope := &Scope{ 2428 IsLexicalScope: true, 2429 Parent: fscope, 2430 Bindings: make(map[string][]Binding), 2431 } 2432 bscopea := &Scope{ 2433 IsLexicalScope: true, 2434 Parent: sscope, 2435 Scopes: make(map[javascript.Type]*Scope), 2436 } 2437 bscopeb := &Scope{ 2438 IsLexicalScope: true, 2439 Parent: sscope, 2440 Scopes: make(map[javascript.Type]*Scope), 2441 } 2442 bscopea.Bindings = map[string][]Binding{ 2443 "a": { 2444 { 2445 BindingType: BindingLexicalLet, 2446 Scope: bscopea, 2447 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2448 }, 2449 }, 2450 } 2451 bscopeb.Bindings = map[string][]Binding{ 2452 "a": { 2453 { 2454 BindingType: BindingLexicalLet, 2455 Scope: bscopeb, 2456 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.SwitchStatement.CaseClauses[1].StatementList[0].Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2457 }, 2458 }, 2459 } 2460 sscope.Scopes = map[javascript.Type]*Scope{ 2461 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.SwitchStatement.CaseClauses[0].StatementList[0].Statement.BlockStatement: bscopea, 2462 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.SwitchStatement.CaseClauses[1].StatementList[0].Statement.BlockStatement: bscopeb, 2463 } 2464 fscope.Scopes = map[javascript.Type]*Scope{ 2465 s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.SwitchStatement: sscope, 2466 } 2467 fscope.Bindings = map[string][]Binding{ 2468 "this": {}, 2469 "arguments": {}, 2470 } 2471 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2472 scope.Bindings = map[string][]Binding{ 2473 "a": { 2474 { 2475 BindingType: BindingHoistable, 2476 Scope: scope, 2477 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2478 }, 2479 }, 2480 } 2481 return scope, nil 2482 }, 2483 }, 2484 { // 68 2485 `function a() {const a = () => this}`, 2486 func(s *javascript.Script) (*Scope, error) { 2487 scope := new(Scope) 2488 fscope := &Scope{ 2489 Parent: scope, 2490 } 2491 ascope := &Scope{ 2492 Parent: fscope, 2493 Scopes: make(map[javascript.Type]*Scope), 2494 Bindings: make(map[string][]Binding), 2495 } 2496 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: ascope} 2497 fscope.Bindings = map[string][]Binding{ 2498 "this": { 2499 { 2500 BindingType: BindingRef, 2501 Scope: ascope, 2502 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.PrimaryExpression).This, 2503 }, 2504 }, 2505 "arguments": {}, 2506 "a": { 2507 { 2508 BindingType: BindingLexicalConst, 2509 Scope: fscope, 2510 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2511 }, 2512 }, 2513 } 2514 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2515 scope.Bindings = map[string][]Binding{ 2516 "a": { 2517 { 2518 BindingType: BindingHoistable, 2519 Scope: scope, 2520 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2521 }, 2522 }, 2523 } 2524 return scope, nil 2525 }, 2526 }, 2527 { // 69 2528 `function a() {const a = () => arguments}`, 2529 func(s *javascript.Script) (*Scope, error) { 2530 scope := new(Scope) 2531 fscope := &Scope{ 2532 Parent: scope, 2533 } 2534 ascope := &Scope{ 2535 Parent: fscope, 2536 Scopes: make(map[javascript.Type]*Scope), 2537 Bindings: make(map[string][]Binding), 2538 } 2539 fscope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: ascope} 2540 fscope.Bindings = map[string][]Binding{ 2541 "this": {}, 2542 "arguments": { 2543 { 2544 BindingType: BindingRef, 2545 Scope: ascope, 2546 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2547 }, 2548 }, 2549 "a": { 2550 { 2551 BindingType: BindingLexicalConst, 2552 Scope: fscope, 2553 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2554 }, 2555 }, 2556 } 2557 scope.Scopes = map[javascript.Type]*Scope{s.StatementList[0].Declaration.FunctionDeclaration: fscope} 2558 scope.Bindings = map[string][]Binding{ 2559 "a": { 2560 { 2561 BindingType: BindingHoistable, 2562 Scope: scope, 2563 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2564 }, 2565 }, 2566 } 2567 return scope, nil 2568 }, 2569 }, 2570 { // 70 2571 `class a{}`, 2572 func(s *javascript.Script) (*Scope, error) { 2573 scope := &Scope{ 2574 Scopes: make(map[javascript.Type]*Scope), 2575 } 2576 scope.Bindings = map[string][]Binding{ 2577 "a": { 2578 { 2579 BindingType: BindingHoistable, 2580 Scope: scope, 2581 Token: s.StatementList[0].Declaration.ClassDeclaration.BindingIdentifier, 2582 }, 2583 }, 2584 } 2585 return scope, nil 2586 }, 2587 }, 2588 { // 71 2589 `class a{}class b extends a{}`, 2590 func(s *javascript.Script) (*Scope, error) { 2591 scope := &Scope{ 2592 Scopes: make(map[javascript.Type]*Scope), 2593 } 2594 scope.Bindings = map[string][]Binding{ 2595 "a": { 2596 { 2597 BindingType: BindingHoistable, 2598 Scope: scope, 2599 Token: s.StatementList[0].Declaration.ClassDeclaration.BindingIdentifier, 2600 }, 2601 { 2602 BindingType: BindingRef, 2603 Scope: scope, 2604 Token: s.StatementList[1].Declaration.ClassDeclaration.ClassHeritage.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 2605 }, 2606 }, 2607 "b": { 2608 { 2609 BindingType: BindingHoistable, 2610 Scope: scope, 2611 Token: s.StatementList[1].Declaration.ClassDeclaration.BindingIdentifier, 2612 }, 2613 }, 2614 } 2615 return scope, nil 2616 }, 2617 }, 2618 { // 72 2619 `class a{b(){}}`, 2620 func(s *javascript.Script) (*Scope, error) { 2621 scope := new(Scope) 2622 mscope := &Scope{ 2623 Parent: scope, 2624 Scopes: make(map[javascript.Type]*Scope), 2625 } 2626 mscope.Bindings = map[string][]Binding{ 2627 "this": {}, 2628 "arguments": {}, 2629 } 2630 scope.Scopes = map[javascript.Type]*Scope{ 2631 s.StatementList[0].Declaration.ClassDeclaration.ClassBody[0].MethodDefinition: mscope, 2632 } 2633 scope.Bindings = map[string][]Binding{ 2634 "a": { 2635 { 2636 BindingType: BindingHoistable, 2637 Scope: scope, 2638 Token: s.StatementList[0].Declaration.ClassDeclaration.BindingIdentifier, 2639 }, 2640 }, 2641 } 2642 return scope, nil 2643 }, 2644 }, 2645 { // 73 2646 `class a{b(){}a(){}}`, 2647 func(s *javascript.Script) (*Scope, error) { 2648 scope := new(Scope) 2649 mscopea := &Scope{ 2650 Parent: scope, 2651 Scopes: make(map[javascript.Type]*Scope), 2652 } 2653 mscopea.Bindings = map[string][]Binding{ 2654 "this": {}, 2655 "arguments": {}, 2656 } 2657 mscopeb := &Scope{ 2658 Parent: scope, 2659 Scopes: make(map[javascript.Type]*Scope), 2660 } 2661 mscopeb.Bindings = map[string][]Binding{ 2662 "this": {}, 2663 "arguments": {}, 2664 } 2665 scope.Scopes = map[javascript.Type]*Scope{ 2666 s.StatementList[0].Declaration.ClassDeclaration.ClassBody[0].MethodDefinition: mscopea, 2667 s.StatementList[0].Declaration.ClassDeclaration.ClassBody[1].MethodDefinition: mscopeb, 2668 } 2669 scope.Bindings = map[string][]Binding{ 2670 "a": { 2671 { 2672 BindingType: BindingHoistable, 2673 Scope: scope, 2674 Token: s.StatementList[0].Declaration.ClassDeclaration.BindingIdentifier, 2675 }, 2676 }, 2677 } 2678 return scope, nil 2679 }, 2680 }, 2681 { // 74 2682 `class a{b(){var a;let b}}`, 2683 func(s *javascript.Script) (*Scope, error) { 2684 scope := new(Scope) 2685 mscope := &Scope{ 2686 Parent: scope, 2687 Scopes: make(map[javascript.Type]*Scope), 2688 } 2689 mscope.Bindings = map[string][]Binding{ 2690 "this": {}, 2691 "arguments": {}, 2692 "a": { 2693 { 2694 BindingType: BindingVar, 2695 Scope: mscope, 2696 Token: s.StatementList[0].Declaration.ClassDeclaration.ClassBody[0].MethodDefinition.FunctionBody.StatementList[0].Statement.VariableStatement.VariableDeclarationList[0].BindingIdentifier, 2697 }, 2698 }, 2699 "b": { 2700 { 2701 BindingType: BindingLexicalLet, 2702 Scope: mscope, 2703 Token: s.StatementList[0].Declaration.ClassDeclaration.ClassBody[0].MethodDefinition.FunctionBody.StatementList[1].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2704 }, 2705 }, 2706 } 2707 scope.Scopes = map[javascript.Type]*Scope{ 2708 s.StatementList[0].Declaration.ClassDeclaration.ClassBody[0].MethodDefinition: mscope, 2709 } 2710 scope.Bindings = map[string][]Binding{ 2711 "a": { 2712 { 2713 BindingType: BindingHoistable, 2714 Scope: scope, 2715 Token: s.StatementList[0].Declaration.ClassDeclaration.BindingIdentifier, 2716 }, 2717 }, 2718 } 2719 return scope, nil 2720 }, 2721 }, 2722 { // 75 2723 `const a = (a) => a`, 2724 func(s *javascript.Script) (*Scope, error) { 2725 scope := new(Scope) 2726 ascope := &Scope{ 2727 Parent: scope, 2728 Scopes: make(map[javascript.Type]*Scope), 2729 } 2730 ascope.Bindings = map[string][]Binding{ 2731 "a": { 2732 { 2733 BindingType: BindingFunctionParam, 2734 Scope: ascope, 2735 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.FormalParameters.FormalParameterList[0].SingleNameBinding, 2736 }, 2737 { 2738 BindingType: BindingRef, 2739 Scope: ascope, 2740 Token: javascript.UnwrapConditional(s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction.AssignmentExpression.ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2741 }, 2742 }, 2743 } 2744 scope.Scopes = map[javascript.Type]*Scope{ 2745 s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].Initializer.ArrowFunction: ascope, 2746 } 2747 scope.Bindings = map[string][]Binding{ 2748 "a": { 2749 { 2750 BindingType: BindingLexicalConst, 2751 Scope: scope, 2752 Token: s.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2753 }, 2754 }, 2755 } 2756 return scope, nil 2757 }, 2758 }, 2759 { // 76 2760 `function a() {b = 1}let b = 0;`, 2761 func(s *javascript.Script) (*Scope, error) { 2762 scope := new(Scope) 2763 fscope := &Scope{ 2764 Parent: scope, 2765 Scopes: map[javascript.Type]*Scope{}, 2766 Bindings: map[string][]Binding{ 2767 "this": {}, 2768 "arguments": {}, 2769 }, 2770 } 2771 scope.Scopes = map[javascript.Type]*Scope{ 2772 s.StatementList[0].Declaration.FunctionDeclaration: fscope, 2773 } 2774 scope.Bindings = map[string][]Binding{ 2775 "a": { 2776 { 2777 BindingType: BindingHoistable, 2778 Scope: scope, 2779 Token: s.StatementList[0].Declaration.FunctionDeclaration.BindingIdentifier, 2780 }, 2781 }, 2782 "b": { 2783 { 2784 BindingType: BindingLexicalLet, 2785 Scope: scope, 2786 Token: s.StatementList[1].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2787 }, 2788 { 2789 BindingType: BindingBare, 2790 Scope: fscope, 2791 Token: s.StatementList[0].Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 2792 }, 2793 }, 2794 } 2795 return scope, nil 2796 }, 2797 }, 2798 } { 2799 tk := parser.NewStringTokeniser(test.Input) 2800 source, err := javascript.ParseScript(&tk) 2801 if err != nil { 2802 t.Errorf("test %d: unexpected error parsing script: %s", n+1, err) 2803 } else { 2804 tscope, terr := test.Output(source) 2805 scope, err := ScriptScope(source, nil) 2806 if terr != nil && err != nil { 2807 if !errors.Is(terr, err) { 2808 t.Errorf("test %d: expecting error: %v\ngot: %v", n+1, terr, err) 2809 } 2810 } else if terr != nil { 2811 t.Errorf("test %d: received no error when expecting: %s", n+1, terr) 2812 } else if err != nil { 2813 t.Errorf("test %d: receieved error when expecting none: %s", n+1, err) 2814 } else if !reflect.DeepEqual(scope, tscope) { 2815 t.Errorf("test %d: result did not match expected\nexpecting: %s\ngot: %s", n+1, tscope, scope) 2816 } 2817 } 2818 } 2819 } 2820 2821 func TestModuleScope(t *testing.T) { 2822 for n, test := range [...]struct { 2823 Input string 2824 Output func(*javascript.Module) (*Scope, error) 2825 }{ 2826 { // 1 2827 `import {a as b} from './lib.js';let a = 0`, 2828 func(m *javascript.Module) (*Scope, error) { 2829 scope := &Scope{ 2830 Scopes: make(map[javascript.Type]*Scope), 2831 } 2832 scope.Bindings = map[string][]Binding{ 2833 "b": { 2834 { 2835 BindingType: BindingImport, 2836 Scope: scope, 2837 Token: m.ModuleListItems[0].ImportDeclaration.ImportClause.NamedImports.ImportList[0].ImportedBinding, 2838 }, 2839 }, 2840 "a": { 2841 { 2842 BindingType: BindingLexicalLet, 2843 Scope: scope, 2844 Token: m.ModuleListItems[1].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2845 }, 2846 }, 2847 } 2848 return scope, nil 2849 }, 2850 }, 2851 { // 2 2852 `export default class MyClass {}`, 2853 func(m *javascript.Module) (*Scope, error) { 2854 scope := &Scope{ 2855 Scopes: make(map[javascript.Type]*Scope), 2856 } 2857 scope.Bindings = map[string][]Binding{ 2858 "MyClass": { 2859 { 2860 BindingType: BindingHoistable, 2861 Scope: scope, 2862 Token: m.ModuleListItems[0].ExportDeclaration.DefaultClass.BindingIdentifier, 2863 }, 2864 }, 2865 } 2866 return scope, nil 2867 }, 2868 }, 2869 { // 3 2870 `export default class MyClass {static INSTANCE = new MyClass()}`, 2871 func(m *javascript.Module) (*Scope, error) { 2872 scope := &Scope{ 2873 Scopes: make(map[javascript.Type]*Scope), 2874 } 2875 scope.Bindings = map[string][]Binding{ 2876 "MyClass": { 2877 { 2878 BindingType: BindingHoistable, 2879 Scope: scope, 2880 Token: m.ModuleListItems[0].ExportDeclaration.DefaultClass.BindingIdentifier, 2881 }, 2882 { 2883 BindingType: BindingRef, 2884 Scope: scope, 2885 Token: javascript.UnwrapConditional(m.ModuleListItems[0].ExportDeclaration.DefaultClass.ClassBody[0].FieldDefinition.Initializer.ConditionalExpression).(*javascript.MemberExpression).MemberExpression.PrimaryExpression.IdentifierReference, 2886 }, 2887 }, 2888 } 2889 return scope, nil 2890 }, 2891 }, 2892 { // 4 2893 `export default function MyFunc() {}`, 2894 func(m *javascript.Module) (*Scope, error) { 2895 scope := new(Scope) 2896 fscope := &Scope{ 2897 Parent: scope, 2898 Scopes: map[javascript.Type]*Scope{}, 2899 Bindings: map[string][]Binding{ 2900 "this": {}, 2901 "arguments": {}, 2902 }, 2903 } 2904 scope.Scopes = map[javascript.Type]*Scope{ 2905 m.ModuleListItems[0].ExportDeclaration.DefaultFunction: fscope, 2906 } 2907 scope.Bindings = map[string][]Binding{ 2908 "MyFunc": { 2909 { 2910 BindingType: BindingHoistable, 2911 Scope: scope, 2912 Token: m.ModuleListItems[0].ExportDeclaration.DefaultFunction.BindingIdentifier, 2913 }, 2914 }, 2915 } 2916 return scope, nil 2917 }, 2918 }, 2919 { // 5 2920 `export default function MyFunc() {MyFunc()}`, 2921 func(m *javascript.Module) (*Scope, error) { 2922 scope := new(Scope) 2923 fscope := &Scope{ 2924 Parent: scope, 2925 Scopes: map[javascript.Type]*Scope{}, 2926 Bindings: map[string][]Binding{ 2927 "this": {}, 2928 "arguments": {}, 2929 }, 2930 } 2931 scope.Scopes = map[javascript.Type]*Scope{ 2932 m.ModuleListItems[0].ExportDeclaration.DefaultFunction: fscope, 2933 } 2934 scope.Bindings = map[string][]Binding{ 2935 "MyFunc": { 2936 { 2937 BindingType: BindingHoistable, 2938 Scope: scope, 2939 Token: m.ModuleListItems[0].ExportDeclaration.DefaultFunction.BindingIdentifier, 2940 }, 2941 { 2942 BindingType: BindingRef, 2943 Scope: fscope, 2944 Token: javascript.UnwrapConditional(m.ModuleListItems[0].ExportDeclaration.DefaultFunction.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.CallExpression).MemberExpression.PrimaryExpression.IdentifierReference, 2945 }, 2946 }, 2947 } 2948 return scope, nil 2949 }, 2950 }, 2951 { // 6 2952 `globalThis.console;window;let a = 1;{a;window}`, 2953 func(m *javascript.Module) (*Scope, error) { 2954 scope := new(Scope) 2955 bscope := &Scope{ 2956 IsLexicalScope: true, 2957 Parent: scope, 2958 Scopes: map[javascript.Type]*Scope{}, 2959 Bindings: map[string][]Binding{}, 2960 } 2961 scope.Scopes = map[javascript.Type]*Scope{ 2962 m.ModuleListItems[3].StatementListItem.Statement.BlockStatement: bscope, 2963 } 2964 scope.Bindings = map[string][]Binding{ 2965 "globalThis": { 2966 { 2967 BindingType: BindingRef, 2968 Scope: scope, 2969 Token: javascript.UnwrapConditional(m.ModuleListItems[0].StatementListItem.Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.MemberExpression).MemberExpression.PrimaryExpression.IdentifierReference, 2970 }, 2971 }, 2972 "window": { 2973 { 2974 BindingType: BindingRef, 2975 Scope: scope, 2976 Token: javascript.UnwrapConditional(m.ModuleListItems[1].StatementListItem.Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2977 }, 2978 { 2979 BindingType: BindingRef, 2980 Scope: bscope, 2981 Token: javascript.UnwrapConditional(m.ModuleListItems[3].StatementListItem.Statement.BlockStatement.StatementList[1].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2982 }, 2983 }, 2984 "a": { 2985 { 2986 BindingType: BindingLexicalLet, 2987 Scope: scope, 2988 Token: m.ModuleListItems[2].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 2989 }, 2990 { 2991 BindingType: BindingRef, 2992 Scope: bscope, 2993 Token: javascript.UnwrapConditional(m.ModuleListItems[3].StatementListItem.Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 2994 }, 2995 }, 2996 } 2997 return scope, nil 2998 }, 2999 }, 3000 { // 7 3001 `{a}`, 3002 func(m *javascript.Module) (*Scope, error) { 3003 scope := new(Scope) 3004 bscope := &Scope{ 3005 IsLexicalScope: true, 3006 Parent: scope, 3007 Scopes: map[javascript.Type]*Scope{}, 3008 Bindings: map[string][]Binding{}, 3009 } 3010 scope.Scopes = map[javascript.Type]*Scope{ 3011 m.ModuleListItems[0].StatementListItem.Statement.BlockStatement: bscope, 3012 } 3013 scope.Bindings = map[string][]Binding{ 3014 "a": { 3015 { 3016 BindingType: BindingRef, 3017 Scope: bscope, 3018 Token: javascript.UnwrapConditional(m.ModuleListItems[0].StatementListItem.Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 3019 }, 3020 }, 3021 } 3022 return scope, nil 3023 }, 3024 }, 3025 { // 8 3026 `function b() {a}`, 3027 func(m *javascript.Module) (*Scope, error) { 3028 scope := new(Scope) 3029 fscope := &Scope{ 3030 Parent: scope, 3031 Scopes: map[javascript.Type]*Scope{}, 3032 Bindings: map[string][]Binding{ 3033 "this": {}, 3034 "arguments": {}, 3035 }, 3036 } 3037 scope.Scopes = map[javascript.Type]*Scope{ 3038 m.ModuleListItems[0].StatementListItem.Declaration.FunctionDeclaration: fscope, 3039 } 3040 scope.Bindings = map[string][]Binding{ 3041 "a": { 3042 { 3043 BindingType: BindingRef, 3044 Scope: fscope, 3045 Token: javascript.UnwrapConditional(m.ModuleListItems[0].StatementListItem.Declaration.FunctionDeclaration.FunctionBody.StatementList[0].Statement.ExpressionStatement.Expressions[0].ConditionalExpression).(*javascript.PrimaryExpression).IdentifierReference, 3046 }, 3047 }, 3048 "b": { 3049 { 3050 BindingType: BindingHoistable, 3051 Scope: scope, 3052 Token: m.ModuleListItems[0].StatementListItem.Declaration.FunctionDeclaration.BindingIdentifier, 3053 }, 3054 }, 3055 } 3056 return scope, nil 3057 }, 3058 }, 3059 { // 9 3060 "let aValue = 1;{let bValue = 2;{aValue = 3}}", 3061 func(m *javascript.Module) (*Scope, error) { 3062 scope := new(Scope) 3063 bscope := &Scope{ 3064 IsLexicalScope: true, 3065 Parent: scope, 3066 Scopes: map[javascript.Type]*Scope{}, 3067 Bindings: map[string][]Binding{}, 3068 } 3069 bbscope := &Scope{ 3070 IsLexicalScope: true, 3071 Parent: bscope, 3072 Scopes: map[javascript.Type]*Scope{}, 3073 Bindings: map[string][]Binding{}, 3074 } 3075 bscope.Scopes = map[javascript.Type]*Scope{ 3076 m.ModuleListItems[1].StatementListItem.Statement.BlockStatement.StatementList[1].Statement.BlockStatement: bbscope, 3077 } 3078 bscope.Bindings = map[string][]Binding{ 3079 "bValue": { 3080 { 3081 BindingType: BindingLexicalLet, 3082 Scope: bscope, 3083 Token: m.ModuleListItems[1].StatementListItem.Statement.BlockStatement.StatementList[0].Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 3084 }, 3085 }, 3086 } 3087 scope.Scopes = map[javascript.Type]*Scope{ 3088 m.ModuleListItems[1].StatementListItem.Statement.BlockStatement: bscope, 3089 } 3090 scope.Bindings = map[string][]Binding{ 3091 "aValue": { 3092 { 3093 BindingType: BindingLexicalLet, 3094 Scope: scope, 3095 Token: m.ModuleListItems[0].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 3096 }, 3097 { 3098 BindingType: BindingBare, 3099 Scope: bbscope, 3100 Token: m.ModuleListItems[1].StatementListItem.Statement.BlockStatement.StatementList[1].Statement.BlockStatement.StatementList[0].Statement.ExpressionStatement.Expressions[0].LeftHandSideExpression.NewExpression.MemberExpression.PrimaryExpression.IdentifierReference, 3101 }, 3102 }, 3103 } 3104 return scope, nil 3105 }, 3106 }, 3107 { // 10 3108 "const aFunc = function b() {}", 3109 func(m *javascript.Module) (*Scope, error) { 3110 scope := new(Scope) 3111 fscope := &Scope{ 3112 Parent: scope, 3113 Scopes: map[javascript.Type]*Scope{}, 3114 Bindings: map[string][]Binding{ 3115 "this": {}, 3116 "arguments": {}, 3117 }, 3118 } 3119 scope.Scopes = map[javascript.Type]*Scope{ 3120 javascript.UnwrapConditional(m.ModuleListItems[0].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].Initializer.ConditionalExpression).(*javascript.FunctionDeclaration): fscope, 3121 } 3122 scope.Bindings = map[string][]Binding{ 3123 "aFunc": { 3124 { 3125 BindingType: BindingLexicalConst, 3126 Scope: scope, 3127 Token: m.ModuleListItems[0].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 3128 }, 3129 }, 3130 } 3131 return scope, nil 3132 }, 3133 }, 3134 { // 10 3135 "const aClass = class b {}", 3136 func(m *javascript.Module) (*Scope, error) { 3137 scope := &Scope{ 3138 Scopes: make(map[javascript.Type]*Scope), 3139 } 3140 scope.Bindings = map[string][]Binding{ 3141 "aClass": { 3142 { 3143 BindingType: BindingLexicalConst, 3144 Scope: scope, 3145 Token: m.ModuleListItems[0].StatementListItem.Declaration.LexicalDeclaration.BindingList[0].BindingIdentifier, 3146 }, 3147 }, 3148 } 3149 return scope, nil 3150 }, 3151 }, 3152 } { 3153 tk := parser.NewStringTokeniser(test.Input) 3154 source, err := javascript.ParseModule(&tk) 3155 if err != nil { 3156 t.Errorf("test %d: unexpected error parsing script: %s", n+1, err) 3157 } else { 3158 tscope, terr := test.Output(source) 3159 scope, err := ModuleScope(source, nil) 3160 if terr != nil && err != nil { 3161 if !errors.Is(terr, err) { 3162 t.Errorf("test %d: expecting error: %v\ngot: %v", n+1, terr, err) 3163 } 3164 } else if terr != nil { 3165 t.Errorf("test %d: received no error when expecting: %s", n+1, terr) 3166 } else if err != nil { 3167 t.Errorf("test %d: receieved error when expecting none: %s", n+1, err) 3168 } else if !reflect.DeepEqual(scope, tscope) { 3169 t.Errorf("test %d: result did not match expected\nexpecting: %s\ngot: %s", n+1, tscope, scope) 3170 } 3171 } 3172 } 3173 } 3174