@@ -16,11 +16,27 @@ import {
1616import { invalidMultiFunctionReturnType } from "../utils/diagnostics" ;
1717import { isInAsyncFunction } from "../utils/typescript" ;
1818
19- function transformExpressionsInReturn (
20- context : TransformationContext ,
21- node : ts . Expression ,
22- insideTryCatch : boolean
23- ) : lua . Expression [ ] {
19+ function transformReturnExpressionForTryCatch ( context : TransformationContext , node : ts . Expression ) : lua . Expression {
20+ const innerNode = ts . skipOuterExpressions ( node , ts . OuterExpressionKinds . Assertions ) ;
21+
22+ if ( ts . isCallExpression ( innerNode ) ) {
23+ if ( isMultiFunctionCall ( context , innerNode ) ) {
24+ const type = context . checker . getContextualType ( node ) ;
25+ if ( type && ! canBeMultiReturnType ( type ) ) {
26+ context . diagnostics . push ( invalidMultiFunctionReturnType ( innerNode ) ) ;
27+ }
28+ return wrapInTable ( ...transformArguments ( context , innerNode . arguments ) ) ;
29+ }
30+
31+ if ( returnsMultiType ( context , innerNode ) && ! shouldMultiReturnCallBeWrapped ( context , innerNode ) ) {
32+ return wrapInTable ( context . transformExpression ( node ) ) ;
33+ }
34+ }
35+
36+ return context . transformExpression ( node ) ;
37+ }
38+
39+ function transformExpressionsInReturn ( context : TransformationContext , node : ts . Expression ) : lua . Expression [ ] {
2440 const expressionType = context . checker . getTypeAtLocation ( node ) ;
2541
2642 // skip type assertions
@@ -36,20 +52,7 @@ function transformExpressionsInReturn(
3652 context . diagnostics . push ( invalidMultiFunctionReturnType ( innerNode ) ) ;
3753 }
3854
39- let returnValues = transformArguments ( context , innerNode . arguments ) ;
40- if ( insideTryCatch ) {
41- returnValues = [ wrapInTable ( ...returnValues ) ] ; // Wrap results when returning inside try/catch
42- }
43- return returnValues ;
44- }
45-
46- // Force-wrap LuaMultiReturn when returning inside try/catch
47- if (
48- insideTryCatch &&
49- returnsMultiType ( context , innerNode ) &&
50- ! shouldMultiReturnCallBeWrapped ( context , innerNode )
51- ) {
52- return [ wrapInTable ( context . transformExpression ( node ) ) ] ;
55+ return transformArguments ( context , innerNode . arguments ) ;
5356 }
5457 } else if ( isInMultiReturnFunction ( context , innerNode ) && isMultiReturnType ( expressionType ) ) {
5558 // Unpack objects typed as LuaMultiReturn
@@ -63,33 +66,19 @@ export function transformExpressionBodyToReturnStatement(
6366 context : TransformationContext ,
6467 node : ts . Expression
6568) : lua . Statement {
66- const expressions = transformExpressionsInReturn ( context , node , false ) ;
69+ const expressions = transformExpressionsInReturn ( context , node ) ;
6770 return createReturnStatement ( context , expressions , node ) ;
6871}
6972
7073export const transformReturnStatement : FunctionVisitor < ts . ReturnStatement > = ( statement , context ) => {
7174 const asyncTryScope = isInAsyncFunction ( statement ) ? findAsyncTryScopeInStack ( context ) : undefined ;
7275
73- let results : lua . Expression [ ] ;
74-
7576 if ( statement . expression ) {
7677 const expressionType = context . checker . getTypeAtLocation ( statement . expression ) ;
7778 const returnType = context . checker . getContextualType ( statement . expression ) ;
7879 if ( returnType ) {
7980 validateAssignment ( context , statement , expressionType , returnType ) ;
8081 }
81-
82- // In async try, we handle return propagation via flag variables (asyncTryHasReturn)
83- // rather than pcall return values (functionReturned set by isInTryCatch), so we skip
84- // isInTryCatch but still need insideTryCatch=true for multi-return wrapping.
85- results = transformExpressionsInReturn (
86- context ,
87- statement . expression ,
88- asyncTryScope ? true : isInTryCatch ( context )
89- ) ;
90- } else {
91- // Empty return
92- results = [ ] ;
9382 }
9483
9584 if ( asyncTryScope ) {
@@ -101,13 +90,23 @@ export const transformReturnStatement: FunctionVisitor<ts.ReturnStatement> = (st
10190 statement
10291 ) ,
10392 ] ;
104- if ( results . length > 0 ) {
105- stmts . push ( lua . createAssignmentStatement ( lua . createIdentifier ( "____returnValue" ) , results [ 0 ] , statement ) ) ;
93+ if ( statement . expression ) {
94+ const returnValue = transformReturnExpressionForTryCatch ( context , statement . expression ) ;
95+ stmts . push ( lua . createAssignmentStatement ( lua . createIdentifier ( "____returnValue" ) , returnValue , statement ) ) ;
10696 }
10797 stmts . push ( lua . createReturnStatement ( [ ] , statement ) ) ;
10898 return stmts ;
10999 }
110100
101+ let results : lua . Expression [ ] ;
102+ if ( ! statement . expression ) {
103+ results = [ ] ;
104+ } else if ( isInTryCatch ( context ) ) {
105+ results = [ transformReturnExpressionForTryCatch ( context , statement . expression ) ] ;
106+ } else {
107+ results = transformExpressionsInReturn ( context , statement . expression ) ;
108+ }
109+
111110 return createReturnStatement ( context , results , statement ) ;
112111} ;
113112
0 commit comments