@@ -2,10 +2,11 @@ import * as ts from "typescript";
22import * as lua from "../../LuaAST" ;
33import { FunctionVisitor } from "../context" ;
44import { createUnpackCall } from "../utils/lua-ast" ;
5- import { findScope , ScopeType } from "../utils/scope" ;
5+ import { ScopeType } from "../utils/scope" ;
66import { transformScopeBlock } from "./block" ;
77import { transformIdentifier } from "./identifier" ;
88import { isInMultiReturnFunction } from "./language-extensions/multi" ;
9+ import { createReturnStatement } from "./return" ;
910
1011export const transformTryStatement : FunctionVisitor < ts . TryStatement > = ( statement , context ) => {
1112 const [ tryBlock , tryScope ] = transformScopeBlock ( context , statement . tryBlock , ScopeType . Try ) ;
@@ -15,24 +16,24 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
1516
1617 const result : lua . Statement [ ] = [ ] ;
1718
18- let returnedIdentifier : lua . Identifier | undefined ;
19+ const returnedIdentifier = lua . createIdentifier ( "____hasReturned" ) ;
1920 let returnCondition : lua . Expression | undefined ;
2021
2122 const pCall = lua . createIdentifier ( "pcall" ) ;
2223 const tryCall = lua . createCallExpression ( pCall , [ lua . createFunctionExpression ( tryBlock ) ] ) ;
2324
2425 if ( statement . catchClause && statement . catchClause . block . statements . length > 0 ) {
2526 // try with catch
26- let [ catchBlock , catchScope ] = transformScopeBlock ( context , statement . catchClause . block , ScopeType . Catch ) ;
27- if ( statement . catchClause . variableDeclaration ) {
28- // Replace ____returned with catch variable
29- returnedIdentifier = transformIdentifier (
30- context ,
31- statement . catchClause . variableDeclaration . name as ts . Identifier
32- ) ;
33- } else if ( tryScope . functionReturned || catchScope . functionReturned ) {
34- returnedIdentifier = lua . createIdentifier ( "____returned" ) ;
35- }
27+ const [ catchBlock , catchScope ] = transformScopeBlock ( context , statement . catchClause . block , ScopeType . Catch ) ;
28+
29+ const catchParameter = statement . catchClause . variableDeclaration
30+ ? transformIdentifier ( context , statement . catchClause . variableDeclaration . name as ts . Identifier )
31+ : undefined ;
32+ const catchParameters = ( ) => ( catchParameter ? [ lua . cloneIdentifier ( catchParameter ) ] : [ ] ) ;
33+
34+ const catchIdentifier = lua . createIdentifier ( "____catch" ) ;
35+ const catchFunction = lua . createFunctionExpression ( catchBlock , catchParameters ( ) ) ;
36+ result . push ( lua . createVariableDeclarationStatement ( catchIdentifier , catchFunction ) ) ;
3637
3738 const tryReturnIdentifiers = [ tryResultIdentifier ] ; // ____try
3839 if ( returnedIdentifier ) {
@@ -44,20 +45,18 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
4445 }
4546 result . push ( lua . createVariableDeclarationStatement ( tryReturnIdentifiers , tryCall ) ) ;
4647
47- if ( ( tryScope . functionReturned || catchScope . functionReturned ) && returnedIdentifier ) {
48- // Wrap catch in function if try or catch has return
49- const catchCall = lua . createCallExpression ( lua . createFunctionExpression ( catchBlock ) , [ ] ) ;
50- const catchAssign = lua . createAssignmentStatement (
51- [ lua . cloneIdentifier ( returnedIdentifier ) , lua . cloneIdentifier ( returnValueIdentifier ) ] ,
52- catchCall
53- ) ;
54- catchBlock = lua . createBlock ( [ catchAssign ] ) ;
55- }
48+ // Wrap catch in function if try or catch has return
49+ const catchCall = lua . createCallExpression ( catchIdentifier , [ lua . cloneIdentifier ( returnedIdentifier ) ] ) ;
50+ const catchAssign = lua . createAssignmentStatement (
51+ [ lua . cloneIdentifier ( returnedIdentifier ) , lua . cloneIdentifier ( returnValueIdentifier ) ] ,
52+ catchCall
53+ ) ;
54+
5655 const notTryCondition = lua . createUnaryExpression ( tryResultIdentifier , lua . SyntaxKind . NotOperator ) ;
57- result . push ( lua . createIfStatement ( notTryCondition , catchBlock ) ) ;
56+ result . push ( lua . createIfStatement ( notTryCondition , lua . createBlock ( [ catchAssign ] ) ) ) ;
5857 } else if ( tryScope . functionReturned ) {
5958 // try with return, but no catch
60- returnedIdentifier = lua . createIdentifier ( "____returned" ) ;
59+ // returnedIdentifier = lua.createIdentifier("____returned");
6160 const returnedVariables = [ tryResultIdentifier , returnedIdentifier , returnValueIdentifier ] ;
6261 result . push ( lua . createVariableDeclarationStatement ( returnedVariables , tryCall ) ) ;
6362
@@ -77,24 +76,15 @@ export const transformTryStatement: FunctionVisitor<ts.TryStatement> = (statemen
7776 }
7877
7978 if ( returnCondition && returnedIdentifier ) {
80- // With catch clause:
81- // if ____returned then return ____returnValue end
82- // No catch clause:
83- // if ____try and ____returned then return ____returnValue end
8479 const returnValues : lua . Expression [ ] = [ ] ;
85- const parentTryCatch = findScope ( context , ScopeType . Function | ScopeType . Try | ScopeType . Catch ) ;
86- if ( parentTryCatch && parentTryCatch . type !== ScopeType . Function ) {
87- // Nested try/catch needs to prefix a 'true' return value
88- returnValues . push ( lua . createBooleanLiteral ( true ) ) ;
89- }
9080
9181 if ( isInMultiReturnFunction ( context , statement ) ) {
9282 returnValues . push ( createUnpackCall ( context , lua . cloneIdentifier ( returnValueIdentifier ) ) ) ;
9383 } else {
9484 returnValues . push ( lua . cloneIdentifier ( returnValueIdentifier ) ) ;
9585 }
9686
97- const returnStatement = lua . createReturnStatement ( returnValues ) ;
87+ const returnStatement = createReturnStatement ( context , returnValues , statement ) ;
9888 const ifReturnedStatement = lua . createIfStatement ( returnCondition , lua . createBlock ( [ returnStatement ] ) ) ;
9989 result . push ( ifReturnedStatement ) ;
10090 }
0 commit comments