Skip to content

Commit 75c8ecb

Browse files
authored
Merge pull request #17517 from tinganho/IgnoredCatchParameter
Ignored catch parameter
2 parents d262567 + 3da1a53 commit 75c8ecb

21 files changed

+202
-115
lines changed

src/compiler/binder.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2921,7 +2921,10 @@ namespace ts {
29212921
function computeCatchClause(node: CatchClause, subtreeFlags: TransformFlags) {
29222922
let transformFlags = subtreeFlags;
29232923

2924-
if (node.variableDeclaration && isBindingPattern(node.variableDeclaration.name)) {
2924+
if (!node.variableDeclaration) {
2925+
transformFlags |= TransformFlags.AssertESNext;
2926+
}
2927+
else if (isBindingPattern(node.variableDeclaration.name)) {
29252928
transformFlags |= TransformFlags.AssertES2015;
29262929
}
29272930

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ namespace ts {
481481
Type,
482482
ResolvedBaseConstructorType,
483483
DeclaredType,
484-
ResolvedReturnType
484+
ResolvedReturnType,
485485
}
486486

487487
const enum CheckMode {

src/compiler/emitter.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -2133,10 +2133,12 @@ namespace ts {
21332133
function emitCatchClause(node: CatchClause) {
21342134
const openParenPos = writeToken(SyntaxKind.CatchKeyword, node.pos);
21352135
write(" ");
2136-
writeToken(SyntaxKind.OpenParenToken, openParenPos);
2137-
emit(node.variableDeclaration);
2138-
writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration ? node.variableDeclaration.end : openParenPos);
2139-
write(" ");
2136+
if (node.variableDeclaration) {
2137+
writeToken(SyntaxKind.OpenParenToken, openParenPos);
2138+
emit(node.variableDeclaration);
2139+
writeToken(SyntaxKind.CloseParenToken, node.variableDeclaration.end);
2140+
write(" ");
2141+
}
21402142
emit(node.block);
21412143
}
21422144

src/compiler/factory.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2128,14 +2128,14 @@ namespace ts {
21282128
: node;
21292129
}
21302130

2131-
export function createCatchClause(variableDeclaration: string | VariableDeclaration, block: Block) {
2131+
export function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block) {
21322132
const node = <CatchClause>createSynthesizedNode(SyntaxKind.CatchClause);
21332133
node.variableDeclaration = typeof variableDeclaration === "string" ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
21342134
node.block = block;
21352135
return node;
21362136
}
21372137

2138-
export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration, block: Block) {
2138+
export function updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration | undefined, block: Block) {
21392139
return node.variableDeclaration !== variableDeclaration
21402140
|| node.block !== block
21412141
? updateNode(createCatchClause(variableDeclaration, block), node)

src/compiler/parser.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -4799,11 +4799,16 @@ namespace ts {
47994799
function parseCatchClause(): CatchClause {
48004800
const result = <CatchClause>createNode(SyntaxKind.CatchClause);
48014801
parseExpected(SyntaxKind.CatchKeyword);
4802-
if (parseExpected(SyntaxKind.OpenParenToken)) {
4802+
4803+
if (parseOptional(SyntaxKind.OpenParenToken)) {
48034804
result.variableDeclaration = parseVariableDeclaration();
4805+
parseExpected(SyntaxKind.CloseParenToken);
4806+
}
4807+
else {
4808+
// Keep shape of node to avoid degrading performance.
4809+
result.variableDeclaration = undefined;
48044810
}
48054811

4806-
parseExpected(SyntaxKind.CloseParenToken);
48074812
result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
48084813
return finishNode(result);
48094814
}

src/compiler/transformers/es2015.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2491,7 +2491,7 @@ namespace ts {
24912491
const catchVariable = getGeneratedNameForNode(errorRecord);
24922492
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
24932493
const values = createValuesHelper(context, expression, node.expression);
2494-
const next = createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []);
2494+
const next = createCall(createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
24952495

24962496
hoistVariableDeclaration(errorRecord);
24972497
hoistVariableDeclaration(returnMethod);
@@ -3173,6 +3173,7 @@ namespace ts {
31733173
function visitCatchClause(node: CatchClause): CatchClause {
31743174
const ancestorFacts = enterSubtree(HierarchyFacts.BlockScopeExcludes, HierarchyFacts.BlockScopeIncludes);
31753175
let updated: CatchClause;
3176+
Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
31763177
if (isBindingPattern(node.variableDeclaration.name)) {
31773178
const temp = createTempVariable(/*recordTempVariable*/ undefined);
31783179
const newVariableDeclaration = createVariableDeclaration(temp);

src/compiler/transformers/esnext.ts

+13
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ namespace ts {
101101
return visitExpressionStatement(node as ExpressionStatement);
102102
case SyntaxKind.ParenthesizedExpression:
103103
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
104+
case SyntaxKind.CatchClause:
105+
return visitCatchClause(node as CatchClause);
104106
default:
105107
return visitEachChild(node, visitor, context);
106108
}
@@ -212,6 +214,17 @@ namespace ts {
212214
return visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
213215
}
214216

217+
function visitCatchClause(node: CatchClause): CatchClause {
218+
if (!node.variableDeclaration) {
219+
return updateCatchClause(
220+
node,
221+
createVariableDeclaration(createTempVariable(/*recordTempVariable*/ undefined)),
222+
visitNode(node.block, visitor, isBlock)
223+
);
224+
}
225+
return visitEachChild(node, visitor, context);
226+
}
227+
215228
/**
216229
* Visits a BinaryExpression that contains a destructuring assignment.
217230
*

src/compiler/types.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,7 @@ namespace ts {
18081808
export interface CatchClause extends Node {
18091809
kind: SyntaxKind.CatchClause;
18101810
parent?: TryStatement;
1811-
variableDeclaration: VariableDeclaration;
1811+
variableDeclaration?: VariableDeclaration;
18121812
block: Block;
18131813
}
18141814

@@ -4020,7 +4020,6 @@ namespace ts {
40204020
ContainsBindingPattern = 1 << 23,
40214021
ContainsYield = 1 << 24,
40224022
ContainsHoistedDeclarationOrCompletion = 1 << 25,
4023-
40244023
ContainsDynamicImport = 1 << 26,
40254024

40264025
// Please leave this as 1 << 29.

tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(138,13): error T
3434
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(141,32): error TS1005: '{' expected.
3535
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(143,13): error TS1005: 'try' expected.
3636
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,24): error TS1109: Expression expected.
37-
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,30): error TS1005: '(' expected.
37+
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,30): error TS1005: '{' expected.
3838
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,31): error TS2304: Cannot find name 'Property'.
3939
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(166,13): error TS2365: Operator '+=' cannot be applied to types 'number' and 'void'.
4040
tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,40): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead.
@@ -323,7 +323,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
323323
~~~~~
324324
!!! error TS1109: Expression expected.
325325
~
326-
!!! error TS1005: '(' expected.
326+
!!! error TS1005: '{' expected.
327327
~~~~~~~~
328328
!!! error TS2304: Cannot find name 'Property'.
329329
retVal += c.Member();

tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ var BasicFeatures = (function () {
441441
var xx = c;
442442
retVal += ;
443443
try { }
444-
catch () { }
444+
catch (_a) { }
445445
Property;
446446
retVal += c.Member();
447447
retVal += xx.Foo() ? 0 : 1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [emitter.noCatchBinding.esnext.ts]
2+
function f() {
3+
try { } catch { }
4+
try { } catch {
5+
try { } catch { }
6+
}
7+
try { } catch { } finally { }
8+
}
9+
10+
//// [emitter.noCatchBinding.esnext.js]
11+
function f() {
12+
try { }
13+
catch { }
14+
try { }
15+
catch {
16+
try { }
17+
catch { }
18+
}
19+
try { }
20+
catch { }
21+
finally { }
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/emitter/esnext/noCatchBinding/emitter.noCatchBinding.esnext.ts ===
2+
function f() {
3+
>f : Symbol(f, Decl(emitter.noCatchBinding.esnext.ts, 0, 0))
4+
5+
try { } catch { }
6+
try { } catch {
7+
try { } catch { }
8+
}
9+
try { } catch { } finally { }
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/emitter/esnext/noCatchBinding/emitter.noCatchBinding.esnext.ts ===
2+
function f() {
3+
>f : () => void
4+
5+
try { } catch { }
6+
try { } catch {
7+
try { } catch { }
8+
}
9+
try { } catch { } finally { }
10+
}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(3,13): error TS1005: '(' expected.
2-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(6,5): error TS1005: 'try' expected.
3-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(12,5): error TS1005: 'try' expected.
4-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(13,5): error TS1005: 'try' expected.
5-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(22,5): error TS1005: 'try' expected.
6-
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(26,5): error TS1005: 'try' expected.
1+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(2,5): error TS1005: 'try' expected.
2+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(6,12): error TS1005: 'finally' expected.
3+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(10,5): error TS1005: 'try' expected.
4+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(11,5): error TS1005: 'try' expected.
5+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(15,5): error TS1005: 'try' expected.
6+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(17,5): error TS1005: 'try' expected.
7+
tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(19,20): error TS1003: Identifier expected.
78

89

9-
==== tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts (6 errors) ====
10+
==== tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts (7 errors) ====
1011
function fn() {
11-
try {
12-
} catch { // syntax error, missing '(x)'
13-
~
14-
!!! error TS1005: '(' expected.
15-
}
16-
1712
catch(x) { } // error missing try
1813
~~~~~
1914
!!! error TS1005: 'try' expected.
2015

21-
finally{ } // potential error; can be absorbed by the 'catch'
16+
finally { } // potential error; can be absorbed by the 'catch'
17+
18+
try { }; // error missing finally
19+
~
20+
!!! error TS1005: 'finally' expected.
2221
}
2322

2423
function fn2() {
@@ -28,22 +27,18 @@ tests/cases/conformance/statements/tryStatements/invalidTryStatements2.ts(26,5):
2827
catch (x) { } // error missing try
2928
~~~~~
3029
!!! error TS1005: 'try' expected.
30+
31+
try { } finally { } // statement is here, so the 'catch' clause above doesn't absorb errors from the 'finally' clause below
3132

32-
// no error
33-
try {
34-
}
35-
finally {
36-
}
37-
38-
// error missing try
39-
finally {
33+
finally { } // error missing try
4034
~~~~~~~
4135
!!! error TS1005: 'try' expected.
42-
}
43-
44-
// error missing try
45-
catch (x) {
36+
37+
catch (x) { } // error missing try
4638
~~~~~
4739
!!! error TS1005: 'try' expected.
48-
}
40+
41+
try { } catch () { } // error missing catch binding
42+
~
43+
!!! error TS1003: Identifier expected.
4944
}
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,34 @@
11
//// [invalidTryStatements2.ts]
22
function fn() {
3-
try {
4-
} catch { // syntax error, missing '(x)'
5-
}
6-
73
catch(x) { } // error missing try
84

9-
finally{ } // potential error; can be absorbed by the 'catch'
5+
finally { } // potential error; can be absorbed by the 'catch'
6+
7+
try { }; // error missing finally
108
}
119

1210
function fn2() {
1311
finally { } // error missing try
1412
catch (x) { } // error missing try
13+
14+
try { } finally { } // statement is here, so the 'catch' clause above doesn't absorb errors from the 'finally' clause below
1515

16-
// no error
17-
try {
18-
}
19-
finally {
20-
}
21-
22-
// error missing try
23-
finally {
24-
}
16+
finally { } // error missing try
17+
18+
catch (x) { } // error missing try
2519

26-
// error missing try
27-
catch (x) {
28-
}
20+
try { } catch () { } // error missing catch binding
2921
}
3022

3123
//// [invalidTryStatements2.js]
3224
function fn() {
33-
try {
34-
}
35-
catch () {
36-
}
3725
try {
3826
}
3927
catch (x) { } // error missing try
4028
finally { } // potential error; can be absorbed by the 'catch'
29+
try { }
30+
finally { }
31+
; // error missing finally
4132
}
4233
function fn2() {
4334
try {
@@ -46,19 +37,14 @@ function fn2() {
4637
try {
4738
}
4839
catch (x) { } // error missing try
49-
// no error
40+
try { }
41+
finally { } // statement is here, so the 'catch' clause above doesn't absorb errors from the 'finally' clause below
5042
try {
5143
}
52-
finally {
53-
}
54-
// error missing try
55-
try {
56-
}
57-
finally {
58-
}
59-
// error missing try
44+
finally { } // error missing try
6045
try {
6146
}
62-
catch (x) {
63-
}
47+
catch (x) { } // error missing try
48+
try { }
49+
catch () { } // error missing catch binding
6450
}

0 commit comments

Comments
 (0)