@@ -649,7 +649,7 @@ export class Parser extends DiagnosticEmitter { |
649 | 649 | let parameters: TypeNode[] | null = null; |
650 | 650 |
|
651 | 651 | // Name<T> |
652 | | - if (tn.skip(Token.LessThan)) { |
| 652 | + if (!tn.peekOnNewLine() && tn.skip(Token.LessThan)) { |
653 | 653 | do { |
654 | 654 | let parameter = this.parseType(tn, true, suppressErrors); |
655 | 655 | if (!parameter) return null; |
@@ -703,7 +703,7 @@ export class Parser extends DiagnosticEmitter { |
703 | 703 | } |
704 | 704 | } |
705 | 705 | // ... [][] |
706 | | - while (tn.skip(Token.OpenBracket)) { |
| 706 | + while (!tn.peekOnNewLine() && tn.skip(Token.OpenBracket)) { |
707 | 707 | let bracketStart = tn.tokenPos; |
708 | 708 | if (!tn.skip(Token.CloseBracket)) { |
709 | 709 | if (!suppressErrors) { |
@@ -991,7 +991,8 @@ export class Parser extends DiagnosticEmitter { |
991 | 991 | } while (tn.skip(Token.Comma)); |
992 | 992 |
|
993 | 993 | let ret = Node.createVariableStatement(decorators, declarations, tn.range(startPos, tn.pos)); |
994 | | - if (!tn.skip(Token.Semicolon) && !isFor) this.checkASI(tn); |
| 994 | + if (isFor) tn.skip(Token.Semicolon); |
| 995 | + else this.parseSemicolon(tn); |
995 | 996 | return ret; |
996 | 997 | } |
997 | 998 |
|
@@ -1019,7 +1020,8 @@ export class Parser extends DiagnosticEmitter { |
1019 | 1020 | ); |
1020 | 1021 | } |
1021 | 1022 | let flags = parentFlags; |
1022 | | - if (tn.skip(Token.Exclamation)) { |
| 1023 | + if (tn.peek() == Token.Exclamation && !tn.peekOnNewLine()) { |
| 1024 | + tn.next(); |
1023 | 1025 | flags |= CommonFlags.DefinitelyAssigned; |
1024 | 1026 | } |
1025 | 1027 |
|
@@ -1175,7 +1177,7 @@ export class Parser extends DiagnosticEmitter { |
1175 | 1177 | } |
1176 | 1178 |
|
1177 | 1179 | let ret = Node.createReturnStatement(expr, tn.range(startPos, tn.pos)); |
1178 | | - if (!tn.skip(Token.Semicolon)) this.checkASI(tn); |
| 1180 | + this.parseSemicolon(tn); |
1179 | 1181 | return ret; |
1180 | 1182 | } |
1181 | 1183 |
|
@@ -1601,7 +1603,8 @@ export class Parser extends DiagnosticEmitter { |
1601 | 1603 | tn.range(startPos, tn.pos) |
1602 | 1604 | ); |
1603 | 1605 | ret.overriddenModuleName = this.currentModuleName; |
1604 | | - tn.skip(Token.Semicolon); |
| 1606 | + if (body) tn.skip(Token.Semicolon); |
| 1607 | + else this.parseSemicolon(tn); |
1605 | 1608 | return ret; |
1606 | 1609 | } |
1607 | 1610 |
|
@@ -1669,6 +1672,13 @@ export class Parser extends DiagnosticEmitter { |
1669 | 1672 | } |
1670 | 1673 |
|
1671 | 1674 | if (arrowKind) { |
| 1675 | + if (tn.peek() == Token.Equals_GreaterThan && tn.peekOnNewLine()) { |
| 1676 | + this.error( |
| 1677 | + DiagnosticCode.Unexpected_token, |
| 1678 | + tn.range(tn.nextTokenPos) |
| 1679 | + ); |
| 1680 | + return null; |
| 1681 | + } |
1672 | 1682 | if (!tn.skip(Token.Equals_GreaterThan)) { |
1673 | 1683 | this.error( |
1674 | 1684 | DiagnosticCode._0_expected, |
@@ -2203,7 +2213,7 @@ export class Parser extends DiagnosticEmitter { |
2203 | 2213 | } |
2204 | 2214 | return null; |
2205 | 2215 | } |
2206 | | - tn.skip(Token.Semicolon); |
| 2216 | + this.parseSemicolon(tn); |
2207 | 2217 | return retIndex; |
2208 | 2218 | } |
2209 | 2219 | if (!tn.skipIdentifier(IdentifierHandling.Always)) { |
@@ -2367,8 +2377,10 @@ export class Parser extends DiagnosticEmitter { |
2367 | 2377 | body, |
2368 | 2378 | tn.range(startPos, tn.pos) |
2369 | 2379 | ); |
2370 | | - if (!(isInterface && tn.skip(Token.Comma))) { |
2371 | | - tn.skip(Token.Semicolon); |
| 2380 | + let hasComma = isInterface && tn.skip(Token.Comma); |
| 2381 | + if (!hasComma) { |
| 2382 | + if (body) tn.skip(Token.Semicolon); |
| 2383 | + else this.parseSemicolon(tn); |
2372 | 2384 | } |
2373 | 2385 | return retMethod; |
2374 | 2386 |
|
@@ -2421,7 +2433,8 @@ export class Parser extends DiagnosticEmitter { |
2421 | 2433 | tn.range(startPos, tn.pos) |
2422 | 2434 | ); |
2423 | 2435 | } |
2424 | | - if (tn.skip(Token.Exclamation)) { |
| 2436 | + if (tn.peek() == Token.Exclamation && !tn.peekOnNewLine()) { |
| 2437 | + tn.next(); |
2425 | 2438 | flags |= CommonFlags.DefinitelyAssigned; |
2426 | 2439 | } |
2427 | 2440 | if (tn.skip(Token.Colon)) { |
@@ -2465,9 +2478,7 @@ export class Parser extends DiagnosticEmitter { |
2465 | 2478 | initializer, |
2466 | 2479 | range |
2467 | 2480 | ); |
2468 | | - if (!(isInterface && tn.skip(Token.Comma))) { |
2469 | | - tn.skip(Token.Semicolon); |
2470 | | - } |
| 2481 | + if (!(isInterface && tn.skip(Token.Comma))) this.parseSemicolon(tn); |
2471 | 2482 | return retField; |
2472 | 2483 | } |
2473 | 2484 | return null; |
@@ -2656,7 +2667,7 @@ export class Parser extends DiagnosticEmitter { |
2656 | 2667 | this.seenlog.add(internalPath); |
2657 | 2668 | } |
2658 | 2669 | } |
2659 | | - tn.skip(Token.Semicolon); |
| 2670 | + this.parseSemicolon(tn); |
2660 | 2671 | return ret; |
2661 | 2672 | } else if (tn.skip(Token.Asterisk)) { |
2662 | 2673 | if (tn.skip(Token.From)) { |
@@ -2672,7 +2683,7 @@ export class Parser extends DiagnosticEmitter { |
2672 | 2683 | this.dependees.set(internalPath, new Dependee(currentSource, path)); |
2673 | 2684 | this.backlog.push(internalPath); |
2674 | 2685 | } |
2675 | | - tn.skip(Token.Semicolon); |
| 2686 | + this.parseSemicolon(tn); |
2676 | 2687 | return ret; |
2677 | 2688 | } else { |
2678 | 2689 | this.error( |
@@ -2754,7 +2765,7 @@ export class Parser extends DiagnosticEmitter { |
2754 | 2765 | range |
2755 | 2766 | ) |
2756 | 2767 | ], null, false, tn.range(startPos, tn.pos)); |
2757 | | - tn.skip(Token.Semicolon); |
| 2768 | + this.parseSemicolon(tn); |
2758 | 2769 | return ret; |
2759 | 2770 | } |
2760 | 2771 |
|
@@ -2844,7 +2855,7 @@ export class Parser extends DiagnosticEmitter { |
2844 | 2855 | this.dependees.set(internalPath, new Dependee(assert(this.currentSource), path)); |
2845 | 2856 | this.backlog.push(internalPath); |
2846 | 2857 | } |
2847 | | - tn.skip(Token.Semicolon); |
| 2858 | + this.parseSemicolon(tn); |
2848 | 2859 | return ret; |
2849 | 2860 | } else { |
2850 | 2861 | this.error( |
@@ -2915,7 +2926,7 @@ export class Parser extends DiagnosticEmitter { |
2915 | 2926 | if (tn.skipIdentifier()) { |
2916 | 2927 | let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range()); |
2917 | 2928 | let ret = Node.createExportImportStatement(identifier, asIdentifier, tn.range(startPos, tn.pos)); |
2918 | | - tn.skip(Token.Semicolon); |
| 2929 | + this.parseSemicolon(tn); |
2919 | 2930 | return ret; |
2920 | 2931 | } else { |
2921 | 2932 | this.error( |
@@ -3078,7 +3089,7 @@ export class Parser extends DiagnosticEmitter { |
3078 | 3089 | identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range()); |
3079 | 3090 | } |
3080 | 3091 | let ret = Node.createBreakStatement(identifier, tn.range()); |
3081 | | - tn.skip(Token.Semicolon); |
| 3092 | + this.parseSemicolon(tn); |
3082 | 3093 | return ret; |
3083 | 3094 | } |
3084 | 3095 |
|
@@ -3094,7 +3105,7 @@ export class Parser extends DiagnosticEmitter { |
3094 | 3105 | identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range()); |
3095 | 3106 | } |
3096 | 3107 | let ret = Node.createContinueStatement(identifier, tn.range()); |
3097 | | - tn.skip(Token.Semicolon); |
| 3108 | + this.parseSemicolon(tn); |
3098 | 3109 | return ret; |
3099 | 3110 | } |
3100 | 3111 |
|
@@ -3140,7 +3151,8 @@ export class Parser extends DiagnosticEmitter { |
3140 | 3151 | } |
3141 | 3152 |
|
3142 | 3153 | parseExpressionStatement( |
3143 | | - tn: Tokenizer |
| 3154 | + tn: Tokenizer, |
| 3155 | + isFor: bool = false |
3144 | 3156 | ): ExpressionStatement | null { |
3145 | 3157 |
|
3146 | 3158 | // at previous token |
@@ -3149,7 +3161,8 @@ export class Parser extends DiagnosticEmitter { |
3149 | 3161 | if (!expr) return null; |
3150 | 3162 |
|
3151 | 3163 | let ret = Node.createExpressionStatement(expr); |
3152 | | - tn.skip(Token.Semicolon); |
| 3164 | + if (isFor) tn.skip(Token.Semicolon); |
| 3165 | + else this.parseSemicolon(tn); |
3153 | 3166 | return ret; |
3154 | 3167 | } |
3155 | 3168 |
|
@@ -3172,7 +3185,7 @@ export class Parser extends DiagnosticEmitter { |
3172 | 3185 | initializer = this.parseVariable(tn, CommonFlags.None, null, tn.tokenPos, true); |
3173 | 3186 |
|
3174 | 3187 | } else if (!tn.skip(Token.Semicolon)) { |
3175 | | - initializer = this.parseExpressionStatement(tn); |
| 3188 | + initializer = this.parseExpressionStatement(tn, true); |
3176 | 3189 | if (!initializer) return null; |
3177 | 3190 | } |
3178 | 3191 |
|
@@ -3234,7 +3247,7 @@ export class Parser extends DiagnosticEmitter { |
3234 | 3247 | if (tn.token == Token.Semicolon) { |
3235 | 3248 | let condition: ExpressionStatement | null = null; |
3236 | 3249 | if (!tn.skip(Token.Semicolon)) { |
3237 | | - condition = this.parseExpressionStatement(tn); |
| 3250 | + condition = this.parseExpressionStatement(tn, true); |
3238 | 3251 | if (!condition) return null; |
3239 | 3252 | } |
3240 | 3253 |
|
@@ -3375,7 +3388,6 @@ export class Parser extends DiagnosticEmitter { |
3375 | 3388 | switchCases.push(switchCase); |
3376 | 3389 | } |
3377 | 3390 | let ret = Node.createSwitchStatement(condition, switchCases, tn.range(startPos, tn.pos)); |
3378 | | - tn.skip(Token.Semicolon); |
3379 | 3391 | return ret; |
3380 | 3392 | } else { |
3381 | 3393 | this.error( |
@@ -3467,10 +3479,17 @@ export class Parser extends DiagnosticEmitter { |
3467 | 3479 | // at 'throw': Expression ';'? |
3468 | 3480 |
|
3469 | 3481 | let startPos = tn.tokenPos; |
| 3482 | + if (tn.peekOnNewLine()) { |
| 3483 | + this.error( |
| 3484 | + DiagnosticCode.Unexpected_token, |
| 3485 | + tn.range(tn.nextTokenPos) |
| 3486 | + ); |
| 3487 | + return null; |
| 3488 | + } |
3470 | 3489 | let expression = this.parseExpression(tn); |
3471 | 3490 | if (!expression) return null; |
3472 | 3491 | let ret = Node.createThrowStatement(expression, tn.range(startPos, tn.pos)); |
3473 | | - if (!tn.skip(Token.Semicolon)) this.checkASI(tn); |
| 3492 | + this.parseSemicolon(tn); |
3474 | 3493 | return ret; |
3475 | 3494 | } |
3476 | 3495 |
|
@@ -3561,7 +3580,6 @@ export class Parser extends DiagnosticEmitter { |
3561 | 3580 | finallyStatements, |
3562 | 3581 | tn.range(startPos, tn.pos) |
3563 | 3582 | ); |
3564 | | - tn.skip(Token.Semicolon); |
3565 | 3583 | return ret; |
3566 | 3584 | } else { |
3567 | 3585 | this.error( |
@@ -3608,7 +3626,7 @@ export class Parser extends DiagnosticEmitter { |
3608 | 3626 | type, |
3609 | 3627 | tn.range(startPos, tn.pos) |
3610 | 3628 | ); |
3611 | | - tn.skip(Token.Semicolon); |
| 3629 | + this.parseSemicolon(tn); |
3612 | 3630 | ret.overriddenModuleName = this.currentModuleName; |
3613 | 3631 | return ret; |
3614 | 3632 | } else { |
@@ -3638,7 +3656,7 @@ export class Parser extends DiagnosticEmitter { |
3638 | 3656 | let moduleName = tn.readString(); |
3639 | 3657 | let ret = Node.createModuleDeclaration(moduleName, flags, tn.range(startPos, tn.pos)); |
3640 | 3658 | this.currentModuleName = moduleName; |
3641 | | - tn.skip(Token.Semicolon); |
| 3659 | + this.parseSemicolon(tn); |
3642 | 3660 | return ret; |
3643 | 3661 | } |
3644 | 3662 |
|
@@ -3649,10 +3667,10 @@ export class Parser extends DiagnosticEmitter { |
3649 | 3667 | // at 'void': Expression ';'? |
3650 | 3668 |
|
3651 | 3669 | let startPos = tn.tokenPos; |
3652 | | - let expression = this.parseExpression(tn, Precedence.Grouping); |
| 3670 | + let expression = this.parseExpression(tn, Precedence.UnaryPrefix); |
3653 | 3671 | if (!expression) return null; |
3654 | 3672 | let ret = Node.createVoidStatement(expression, tn.range(startPos, tn.pos)); |
3655 | | - tn.skip(Token.Semicolon); |
| 3673 | + this.parseSemicolon(tn); |
3656 | 3674 | return ret; |
3657 | 3675 | } |
3658 | 3676 |
|
@@ -3670,7 +3688,6 @@ export class Parser extends DiagnosticEmitter { |
3670 | 3688 | let statement = this.parseStatement(tn); |
3671 | 3689 | if (!statement) return null; |
3672 | 3690 | let ret = Node.createWhileStatement(expression, statement, tn.range(startPos, tn.pos)); |
3673 | | - tn.skip(Token.Semicolon); |
3674 | 3691 | return ret; |
3675 | 3692 | } else { |
3676 | 3693 | this.error( |
@@ -4131,6 +4148,15 @@ export class Parser extends DiagnosticEmitter { |
4131 | 4148 | while ( |
4132 | 4149 | (nextPrecedence = determinePrecedence(tn.peek())) >= precedence |
4133 | 4150 | ) { |
| 4151 | + let nextToken = tn.peek(); |
| 4152 | + if ( |
| 4153 | + ( |
| 4154 | + nextToken == Token.Plus_Plus || |
| 4155 | + nextToken == Token.Minus_Minus || |
| 4156 | + nextToken == Token.As || |
| 4157 | + nextToken == Token.Exclamation |
| 4158 | + ) && tn.peekOnNewLine() |
| 4159 | + ) break; |
4134 | 4160 | let token = tn.next(); |
4135 | 4161 | switch (token) { |
4136 | 4162 |
|
@@ -4430,6 +4456,12 @@ export class Parser extends DiagnosticEmitter { |
4430 | 4456 | ); |
4431 | 4457 | } |
4432 | 4458 |
|
| 4459 | + private parseSemicolon( |
| 4460 | + tn: Tokenizer |
| 4461 | + ): void { |
| 4462 | + if (!tn.skip(Token.Semicolon)) this.checkASI(tn); |
| 4463 | + } |
| 4464 | + |
4433 | 4465 | /** Skips over a statement on errors in an attempt to reduce unnecessary diagnostic noise. */ |
4434 | 4466 | skipStatement(tn: Tokenizer): void { |
4435 | 4467 | if (tn.peekOnNewLine()) tn.next(); // if reset() to the previous line |
|