| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -165,6 +165,7 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen | |||
| 165 | 165 | ||
| 166 | 166 | const tryResultIdentifier = lua.createIdentifier("____try"); | |
| 167 | 167 | const returnValueIdentifier = lua.createIdentifier("____returnValue"); | |
| 168 | + const rethrowIdentifier = lua.createIdentifier("____rethrow"); | ||
| 168 | 169 | ||
| 169 | 170 | const result: lua.Statement[] = []; | |
| 170 | 171 | ||
@@ -191,6 +192,9 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen | |||
| 191 | 192 | } | |
| 192 | 193 | } | |
| 193 | 194 | result.push(lua.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); | |
| 195 | + if (statement.finallyBlock) { | ||
| 196 | + result.push(lua.createVariableDeclarationStatement(rethrowIdentifier)); | ||
| 197 | + } | ||
| 194 | 198 | ||
| 195 | 199 | const catchCall = lua.createCallExpression( | |
| 196 | 200 | catchIdentifier, | |
@@ -203,8 +207,22 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen | |||
| 203 | 207 | ) | |
| 204 | 208 | : lua.createExpressionStatement(catchCall); | |
| 205 | 209 | ||
| 210 | + const catchCallFunction = lua.createFunctionExpression(lua.createBlock([catchCallStatement])); | ||
| 211 | + | ||
| 212 | + const tryCatchCall = lua.createCallExpression(pCall, [catchCallFunction]); | ||
| 213 | + | ||
| 214 | + const tryCatchCallStatement = lua.createAssignmentStatement( | ||
| 215 | + [lua.cloneIdentifier(tryResultIdentifier), lua.cloneIdentifier(rethrowIdentifier)], | ||
| 216 | + tryCatchCall | ||
| 217 | + ); | ||
| 218 | + | ||
| 206 | 219 | const notTryCondition = lua.createUnaryExpression(tryResultIdentifier, lua.SyntaxKind.NotOperator); | |
| 207 | - result.push(lua.createIfStatement(notTryCondition, lua.createBlock([catchCallStatement]))); | ||
| 220 | + result.push( | ||
| 221 | + lua.createIfStatement( | ||
| 222 | + notTryCondition, | ||
| 223 | + lua.createBlock(statement.finallyBlock ? [tryCatchCallStatement] : [catchCallStatement]) | ||
| 224 | + ) | ||
| 225 | + ); | ||
| 208 | 226 | } else if (tryScope.functionReturned) { | |
| 209 | 227 | // try with return, but no catch | |
| 210 | 228 | // returnedIdentifier = lua.createIdentifier("____returned"); | |
@@ -230,21 +248,33 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen | |||
| 230 | 248 | result.push(...context.transformStatements(statement.finallyBlock)); | |
| 231 | 249 | } | |
| 232 | 250 | ||
| 233 | - // Re-throw error if try had no catch but had a finally. | ||
| 251 | + // Re-throw error if try had a finally. | ||
| 234 | 252 | // On pcall failure the error is the second return value, which lands in | |
| 235 | 253 | // ____hasReturned (when functionReturned) or ____error (otherwise). | |
| 236 | - if (!statement.catchClause && statement.finallyBlock) { | ||
| 254 | + if (statement.finallyBlock) { | ||
| 237 | 255 | const notTryCondition = lua.createUnaryExpression( | |
| 238 | 256 | lua.cloneIdentifier(tryResultIdentifier), | |
| 239 | 257 | lua.SyntaxKind.NotOperator | |
| 240 | 258 | ); | |
| 241 | - const errorIdentifier = tryScope.functionReturned | ||
| 242 | - ? lua.cloneIdentifier(returnedIdentifier) | ||
| 243 | - : lua.createIdentifier("____error"); | ||
| 244 | - const rethrow = lua.createExpressionStatement( | ||
| 245 | - lua.createCallExpression(lua.createIdentifier("error"), [errorIdentifier, lua.createNumericLiteral(0)]) | ||
| 246 | - ); | ||
| 247 | - result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); | ||
| 259 | + | ||
| 260 | + if (!statement.catchClause) { | ||
| 261 | + const errorIdentifier = tryScope.functionReturned | ||
| 262 | + ? lua.cloneIdentifier(returnedIdentifier) | ||
| 263 | + : lua.createIdentifier("____error"); | ||
| 264 | + const rethrow = lua.createExpressionStatement( | ||
| 265 | + lua.createCallExpression(lua.createIdentifier("error"), [errorIdentifier, lua.createNumericLiteral(0)]) | ||
| 266 | + ); | ||
| 267 | + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); | ||
| 268 | + } else if (statement.catchClause.block.statements.length > 0) { | ||
| 269 | + // Re-throw is possible only from non-empty blocks. | ||
| 270 | + const rethrow = lua.createExpressionStatement( | ||
| 271 | + lua.createCallExpression(lua.createIdentifier("error"), [ | ||
| 272 | + rethrowIdentifier, | ||
| 273 | + lua.createNumericLiteral(0), | ||
| 274 | + ]) | ||
| 275 | + ); | ||
| 276 | + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); | ||
| 277 | + } | ||
| 248 | 278 | } | |
| 249 | 279 | ||
| 250 | 280 | if (returnCondition && returnedIdentifier) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,31 +7,40 @@ test("throwString", () => { | |||
| 7 | 7 | `.expectToEqual(new util.ExecutionError("Some Error")); | |
| 8 | 8 | }); | |
| 9 | 9 | ||
| 10 | - // TODO: Finally does not behave like it should, see #1137 | ||
| 11 | - // eslint-disable-next-line jest/no-disabled-tests | ||
| 12 | - test.skip.each([0, 1, 2])("re-throw (%p)", i => { | ||
| 10 | + test.each([ | ||
| 11 | + { innerTry: false, innerFinally: false, outerFinally: false }, | ||
| 12 | + { innerTry: false, innerFinally: false, outerFinally: true }, | ||
| 13 | + { innerTry: false, innerFinally: true, outerFinally: false }, | ||
| 14 | + { innerTry: false, innerFinally: true, outerFinally: true }, | ||
| 15 | + { innerTry: true, innerFinally: false, outerFinally: false }, | ||
| 16 | + { innerTry: true, innerFinally: false, outerFinally: true }, | ||
| 17 | + { innerTry: true, innerFinally: true, outerFinally: false }, | ||
| 18 | + { innerTry: true, innerFinally: true, outerFinally: true }, | ||
| 19 | + ])("re-throw (%j)", o => { | ||
| 13 | 20 | util.testFunction` | |
| 14 | - const i: number = ${i}; | ||
| 21 | + const innerTry: boolean = ${o.innerTry}; | ||
| 22 | + const innerFinally: boolean = ${o.innerFinally}; | ||
| 23 | + const outerFinally: boolean = ${o.outerFinally}; | ||
| 15 | 24 | function foo() { | |
| 16 | 25 | try { | |
| 17 | 26 | try { | |
| 18 | - if (i === 0) { throw "z"; } | ||
| 27 | + if (innerTry) { throw "inner.try"; } | ||
| 19 | 28 | } catch (e) { | |
| 20 | - throw "a"; | ||
| 29 | + throw (e as string) + "->" + "inner.catch"; | ||
| 21 | 30 | } finally { | |
| 22 | - if (i === 1) { throw "b"; } | ||
| 31 | + if (innerFinally) { throw "inner.finally"; } | ||
| 23 | 32 | } | |
| 24 | 33 | } catch (e) { | |
| 25 | - throw (e as string).toUpperCase(); | ||
| 34 | + throw (e as string) + "->" + "outer.catch"; | ||
| 26 | 35 | } finally { | |
| 27 | - throw "C"; | ||
| 36 | + if (outerFinally) { throw "outer.finally"; } | ||
| 28 | 37 | } | |
| 29 | 38 | } | |
| 30 | 39 | let result: string = "x"; | |
| 31 | 40 | try { | |
| 32 | 41 | foo(); | |
| 33 | 42 | } catch (e) { | |
| 34 | - result = (e as string)[(e as string).length - 1]; | ||
| 43 | + result = e as string; | ||
| 35 | 44 | } | |
| 36 | 45 | return result; | |
| 37 | 46 | `.expectToMatchJsResult(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments