From 57ad5a81db04b43a26995565752e8e1b655efc7f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Jun 2025 14:37:54 -0700 Subject: [PATCH] Port optional catch clause transform --- internal/ast/ast.go | 6 +++- .../estransforms/optionalcatch.go | 20 ++++++++++- ...constructorWithIncompleteTypeAnnotation.js | 2 +- ...ructorWithIncompleteTypeAnnotation.js.diff | 11 +------ ...rolFlowDestructuringVariablesInTryCatch.js | 2 +- ...owDestructuringVariablesInTryCatch.js.diff | 11 +------ .../potentiallyUnassignedVariableInCatch.js | 2 +- ...tentiallyUnassignedVariableInCatch.js.diff | 9 +---- .../compiler/tryCatchFinallyControlFlow.js | 2 +- .../tryCatchFinallyControlFlow.js.diff | 11 +------ .../conformance/asyncWithVarShadowing_es6.js | 2 +- .../asyncWithVarShadowing_es6.js.diff | 2 +- ...awaitUsingDeclarations.1(target=es2015).js | 2 +- ...UsingDeclarations.1(target=es2015).js.diff | 10 ++---- ...awaitUsingDeclarations.1(target=es2017).js | 2 +- ...UsingDeclarations.1(target=es2017).js.diff | 11 +------ .../awaitUsingDeclarations.1(target=es5).js | 2 +- ...aitUsingDeclarations.1(target=es5).js.diff | 10 ++---- .../submodule/conformance/tryStatements.js | 12 +++---- .../conformance/tryStatements.js.diff | 33 ------------------- .../usingDeclarations.1(target=es2015).js | 2 +- ...usingDeclarations.1(target=es2015).js.diff | 2 +- .../usingDeclarations.1(target=es2017).js | 2 +- ...usingDeclarations.1(target=es2017).js.diff | 2 +- .../usingDeclarations.1(target=es5).js | 2 +- .../usingDeclarations.1(target=es5).js.diff | 2 +- 26 files changed, 56 insertions(+), 118 deletions(-) delete mode 100644 testdata/baselines/reference/submodule/conformance/tryStatements.js.diff diff --git a/internal/ast/ast.go b/internal/ast/ast.go index f7abb99c14..fc1d9fba94 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -2927,8 +2927,12 @@ func (node *CatchClause) Clone(f NodeFactoryCoercible) *Node { } func (node *CatchClause) computeSubtreeFacts() SubtreeFacts { - return propagateSubtreeFacts(node.VariableDeclaration) | + res := propagateSubtreeFacts(node.VariableDeclaration) | propagateSubtreeFacts(node.Block) + if node.VariableDeclaration == nil { + res |= SubtreeContainsES2019 + } + return res } func (node *CatchClause) propagateSubtreeFacts() SubtreeFacts { diff --git a/internal/transformers/estransforms/optionalcatch.go b/internal/transformers/estransforms/optionalcatch.go index aabd41377a..a51d4bbaea 100644 --- a/internal/transformers/estransforms/optionalcatch.go +++ b/internal/transformers/estransforms/optionalcatch.go @@ -11,7 +11,25 @@ type optionalCatchTransformer struct { } func (ch *optionalCatchTransformer) visit(node *ast.Node) *ast.Node { - return node // !!! + if node.SubtreeFacts()&ast.SubtreeContainsES2019 == 0 { + return node + } + switch node.Kind { + case ast.KindCatchClause: + return ch.visitCatchClause(node.AsCatchClause()) + default: + return ch.Visitor().VisitEachChild(node) + } +} + +func (ch *optionalCatchTransformer) visitCatchClause(node *ast.CatchClause) *ast.Node { + if node.VariableDeclaration == nil { + return ch.Factory().NewCatchClause( + ch.Factory().NewVariableDeclaration(ch.Factory().NewTempVariable(), nil, nil, nil), + ch.Visitor().Visit(node.Block), + ) + } + return ch.Visitor().VisitEachChild(node.AsNode()) } func newOptionalCatchTransformer(emitContext *printer.EmitContext) *transformers.Transformer { diff --git a/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js b/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js index a352f7dc87..6e7de480a0 100644 --- a/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js +++ b/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js @@ -424,7 +424,7 @@ class BasicFeatures { var xx = c; retVal += ; try { } - catch { } + catch (_a) { } Property; retVal += c.Member(); retVal += xx.Foo() ? 0 : 1; diff --git a/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js.diff b/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js.diff index d1a4296c99..4237e5af02 100644 --- a/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js.diff +++ b/testdata/baselines/reference/submodule/compiler/constructorWithIncompleteTypeAnnotation.js.diff @@ -30,16 +30,7 @@ if(retValue) { } } TypeScriptAllInOne.Program = Program; -@@= skipped -130, +131 lines =@@ - var xx = c; - retVal += ; - try { } -- catch (_a) { } -+ catch { } - Property; - retVal += c.Member(); - retVal += xx.Foo() ? 0 : 1; -@@= skipped -48, +48 lines =@@ +@@= skipped -178, +179 lines =@@ } } class CLASS { diff --git a/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js b/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js index 1466f87024..15e72f45fe 100644 --- a/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js +++ b/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js @@ -31,7 +31,7 @@ try { var [d = 1] = []; var { e = 1 } = {}; } -catch { +catch (_a) { console.error("error"); } a; diff --git a/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js.diff b/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js.diff index c2ece0ab7c..21a1816de1 100644 --- a/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js.diff +++ b/testdata/baselines/reference/submodule/compiler/controlFlowDestructuringVariablesInTryCatch.js.diff @@ -7,13 +7,4 @@ -"use strict"; try { var a = f1(); - var [b] = f2(); -@@= skipped -8, +7 lines =@@ - var [d = 1] = []; - var { e = 1 } = {}; - } --catch (_a) { -+catch { - console.error("error"); - } - a; \ No newline at end of file + var [b] = f2(); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js b/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js index 79792f517d..080c0b8c91 100644 --- a/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js +++ b/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js @@ -18,6 +18,6 @@ try { foo = 1234; } } -catch { +catch (_a) { foo; } diff --git a/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js.diff b/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js.diff index d12a9aa06c..81ffab8fe6 100644 --- a/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js.diff +++ b/testdata/baselines/reference/submodule/compiler/potentiallyUnassignedVariableInCatch.js.diff @@ -7,11 +7,4 @@ -"use strict"; let foo; try { - if (Math.random() > 0.5) { - foo = 1234; - } - } --catch (_a) { -+catch { - foo; - } \ No newline at end of file + if (Math.random() > 0.5) { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js b/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js index 063f9cda7f..11f206024b 100644 --- a/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js +++ b/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js @@ -551,7 +551,7 @@ const main = () => { hoge = 'hoge!'; return; } - catch { + catch (_a) { return; } finally { diff --git a/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js.diff b/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js.diff index c1ef4b4fac..42cb3614bd 100644 --- a/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js.diff +++ b/testdata/baselines/reference/submodule/compiler/tryCatchFinallyControlFlow.js.diff @@ -7,13 +7,4 @@ -"use strict"; // Repro from #34797 function f1() { - let a = null; -@@= skipped -220, +219 lines =@@ - hoge = 'hoge!'; - return; - } -- catch (_a) { -+ catch { - return; - } - finally { \ No newline at end of file + let a = null; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js b/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js index 263e0c01d9..4f047831bf 100644 --- a/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js +++ b/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js @@ -394,7 +394,7 @@ async function fn39(x) { async function fn40(x) { try { } - catch { + catch (_a) { var x; } } diff --git a/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js.diff b/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js.diff index 6540fe0acf..ebe3013028 100644 --- a/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js.diff +++ b/testdata/baselines/reference/submodule/conformance/asyncWithVarShadowing_es6.js.diff @@ -444,7 +444,7 @@ +async function fn40(x) { + try { + } -+ catch { ++ catch (_a) { + var x; + } } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js index 97799c1322..cec1987e5c 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js @@ -323,7 +323,7 @@ try { await result_4; } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { async [Symbol.asyncDispose]() { } }, true); diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js.diff b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js.diff index bba9cc3621..6508a6525f 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js.diff +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2015).js.diff @@ -292,12 +292,8 @@ } catch (e_4) { env_5.error = e_4; -@@= skipped -14, +12 lines =@@ - await result_4; - } - } -- catch (_a) { -+ catch { +@@= skipped -17, +15 lines =@@ + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { - const d24 = __addDisposableResource(env_6, { [Symbol.asyncDispose]() { @@ -307,7 +303,7 @@ } catch (e_5) { env_6.error = e_5; -@@= skipped -20, +18 lines =@@ +@@= skipped -17, +15 lines =@@ finally { const env_7 = { stack: [], error: void 0, hasError: false }; try { diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js index 97799c1322..cec1987e5c 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js @@ -323,7 +323,7 @@ try { await result_4; } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { async [Symbol.asyncDispose]() { } }, true); diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js.diff b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js.diff index d264f84d3c..579fb298e9 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js.diff +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es2017).js.diff @@ -143,13 +143,4 @@ + } } }; - { -@@= skipped -89, +87 lines =@@ - await result_4; - } - } -- catch (_a) { -+ catch { - const env_6 = { stack: [], error: void 0, hasError: false }; - try { - const d24 = __addDisposableResource(env_6, { async [Symbol.asyncDispose]() { } }, true); \ No newline at end of file + { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js index 97799c1322..cec1987e5c 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js @@ -323,7 +323,7 @@ try { await result_4; } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { async [Symbol.asyncDispose]() { } }, true); diff --git a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js.diff b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js.diff index c5780692f5..24bc7c73b2 100644 --- a/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js.diff +++ b/testdata/baselines/reference/submodule/conformance/awaitUsingDeclarations.1(target=es5).js.diff @@ -292,12 +292,8 @@ } catch (e_4) { env_5.error = e_4; -@@= skipped -14, +12 lines =@@ - await result_4; - } - } -- catch (_a) { -+ catch { +@@= skipped -17, +15 lines =@@ + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { - const d24 = __addDisposableResource(env_6, { [Symbol.asyncDispose]() { @@ -307,7 +303,7 @@ } catch (e_5) { env_6.error = e_5; -@@= skipped -20, +18 lines =@@ +@@= skipped -17, +15 lines =@@ finally { const env_7 = { stack: [], error: void 0, hasError: false }; try { diff --git a/testdata/baselines/reference/submodule/conformance/tryStatements.js b/testdata/baselines/reference/submodule/conformance/tryStatements.js index 8738043469..0440b20e3e 100644 --- a/testdata/baselines/reference/submodule/conformance/tryStatements.js +++ b/testdata/baselines/reference/submodule/conformance/tryStatements.js @@ -23,16 +23,16 @@ function fn() { //// [tryStatements.js] function fn() { try { } - catch { } + catch (_a) { } try { } - catch { + catch (_b) { try { } - catch { + catch (_c) { try { } - catch { } + catch (_d) { } } try { } - catch { } + catch (_e) { } } try { } catch (x) { @@ -41,7 +41,7 @@ function fn() { try { } finally { } try { } - catch { } + catch (_f) { } finally { } try { } catch (z) { } diff --git a/testdata/baselines/reference/submodule/conformance/tryStatements.js.diff b/testdata/baselines/reference/submodule/conformance/tryStatements.js.diff deleted file mode 100644 index a607b77b73..0000000000 --- a/testdata/baselines/reference/submodule/conformance/tryStatements.js.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- old.tryStatements.js -+++ new.tryStatements.js -@@= skipped -22, +22 lines =@@ - //// [tryStatements.js] - function fn() { - try { } -- catch (_a) { } -+ catch { } - try { } -- catch (_b) { -+ catch { - try { } -- catch (_c) { -+ catch { - try { } -- catch (_d) { } -+ catch { } - } - try { } -- catch (_e) { } -+ catch { } - } - try { } - catch (x) { -@@= skipped -18, +18 lines =@@ - try { } - finally { } - try { } -- catch (_f) { } -+ catch { } - finally { } - try { } - catch (z) { } \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js index 56dce846db..8c45d26dea 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js @@ -510,7 +510,7 @@ try { __disposeResources(env_5); } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js.diff b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js.diff index 0a44b48837..9dd78e0770 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js.diff +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2015).js.diff @@ -380,7 +380,7 @@ } } - catch (_b) { -+ catch { ++ catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js index 56dce846db..8c45d26dea 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js @@ -510,7 +510,7 @@ try { __disposeResources(env_5); } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js.diff b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js.diff index b9eae62adb..8e171859f3 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js.diff +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es2017).js.diff @@ -327,7 +327,7 @@ } } - catch (_b) { -+ catch { ++ catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js index 56dce846db..8c45d26dea 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js @@ -510,7 +510,7 @@ try { __disposeResources(env_5); } } - catch { + catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); diff --git a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js.diff b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js.diff index 6cdac94811..e6f61342cd 100644 --- a/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js.diff +++ b/testdata/baselines/reference/submodule/conformance/usingDeclarations.1(target=es5).js.diff @@ -380,7 +380,7 @@ } } - catch (_b) { -+ catch { ++ catch (_a) { const env_6 = { stack: [], error: void 0, hasError: false }; try { const d24 = __addDisposableResource(env_6, { [Symbol.dispose]() { } }, false); \ No newline at end of file