()
| 446 | } |
| 447 | |
| 448 | private getComplexIdentifier(): string { |
| 449 | let cp = this.codePointAt(this.index); |
| 450 | let id = Character.fromCodePoint(cp); |
| 451 | this.index += id.length; |
| 452 | |
| 453 | // '\u' (U+005C, U+0075) denotes an escaped character. |
| 454 | let ch; |
| 455 | if (cp === 0x5C) { |
| 456 | if (this.source.charCodeAt(this.index) !== 0x75) { |
| 457 | this.throwUnexpectedToken(); |
| 458 | } |
| 459 | ++this.index; |
| 460 | if (this.source[this.index] === '{') { |
| 461 | ++this.index; |
| 462 | ch = this.scanUnicodeCodePointEscape(); |
| 463 | } else { |
| 464 | ch = this.scanHexEscape('u'); |
| 465 | if (ch === null || ch === '\\' || !Character.isIdentifierStart(ch.charCodeAt(0))) { |
| 466 | this.throwUnexpectedToken(); |
| 467 | } |
| 468 | } |
| 469 | id = ch; |
| 470 | } |
| 471 | |
| 472 | while (!this.eof()) { |
| 473 | cp = this.codePointAt(this.index); |
| 474 | if (!Character.isIdentifierPart(cp)) { |
| 475 | break; |
| 476 | } |
| 477 | ch = Character.fromCodePoint(cp); |
| 478 | id += ch; |
| 479 | this.index += ch.length; |
| 480 | |
| 481 | // '\u' (U+005C, U+0075) denotes an escaped character. |
| 482 | if (cp === 0x5C) { |
| 483 | id = id.substr(0, id.length - 1); |
| 484 | if (this.source.charCodeAt(this.index) !== 0x75) { |
| 485 | this.throwUnexpectedToken(); |
| 486 | } |
| 487 | ++this.index; |
| 488 | if (this.source[this.index] === '{') { |
| 489 | ++this.index; |
| 490 | ch = this.scanUnicodeCodePointEscape(); |
| 491 | } else { |
| 492 | ch = this.scanHexEscape('u'); |
| 493 | if (ch === null || ch === '\\' || !Character.isIdentifierPart(ch.charCodeAt(0))) { |
| 494 | this.throwUnexpectedToken(); |
| 495 | } |
| 496 | } |
| 497 | id += ch; |
| 498 | } |
| 499 | } |
| 500 | |
| 501 | return id; |
| 502 | } |
| 503 | |
| 504 | private octalToDecimal(ch: string) { |
| 505 | // \0 is not octal escape sequence |
no test coverage detected