@@ -1117,44 +1117,58 @@ private void WriteModifier(bool isPublic)
11171117
11181118 private Expression VisitLambda ( LambdaExpression node , LambdaType type )
11191119 {
1120- if ( type == LambdaType . Function || type == LambdaType . Main )
1121- {
1122- var name = type == LambdaType . Main
1123- ? ( Definitions ? . MethodName ?? "Main" )
1124- : GetName ( node ) ;
1125- WriteModifier ( type == LambdaType . Main ) ;
1126- Write ( Translate ( node . ReturnType ) , " " , name ) ;
1127- var args = VisitArguments ( "(" , node . Parameters , VisitParameterDeclaration , ")" ) ;
1128- Indent ( ) ;
1129- var body = VisitBody ( node . Body , true ) ;
1130-
1131- Outdent ( ) ;
1132-
1133- return Expression . Lambda ( body , name , node . TailCall , args ) ;
1134- }
1135- else
1120+ if ( type == LambdaType . Inline || this . Definitions ? . IsExpression == true )
11361121 {
1122+ if ( type == LambdaType . Main )
1123+ {
1124+ var name = Definitions ? . MethodName ?? "Main" ;
1125+ WriteModifier ( true ) ;
1126+ var funcType = MakeDelegateType ( node . ReturnType , node . Parameters . Select ( it => it . Type ) . ToArray ( ) ) ;
1127+ var exprType = typeof ( Expression < > ) . MakeGenericType ( funcType ) ;
1128+ Write ( Translate ( exprType ) , " " , name , " = " ) ;
1129+ }
11371130 IList < ParameterExpression > args ;
11381131 if ( node . Parameters . Count == 1 )
11391132 {
11401133 args = new List < ParameterExpression > ( ) ;
11411134 var arg = VisitParameter ( node . Parameters [ 0 ] ) ;
1142- args . Add ( ( ParameterExpression ) arg ) ;
1135+ args . Add ( ( ParameterExpression ) arg ) ;
11431136 }
11441137 else
11451138 {
1146- args = VisitArguments ( "(" , node . Parameters . ToList ( ) , p => ( ParameterExpression ) VisitParameter ( p ) , ")" ) ;
1139+ args = VisitArguments ( "(" , node . Parameters . ToList ( ) , p => ( ParameterExpression ) VisitParameter ( p ) , ")" ) ;
11471140 }
1141+
11481142 Write ( " => " ) ;
11491143 var body = VisitGroup ( node . Body , ExpressionType . Quote ) ;
1144+ if ( type == LambdaType . Main )
1145+ Write ( ";" ) ;
11501146 return Expression . Lambda ( body , node . Name , node . TailCall , args ) ;
11511147 }
1148+ else
1149+ {
1150+ var name = type == LambdaType . Main
1151+ ? ( Definitions ? . MethodName ?? "Main" )
1152+ : GetName ( node ) ;
1153+ WriteModifier ( type == LambdaType . Main ) ;
1154+ Write ( Translate ( node . ReturnType ) , " " , name ) ;
1155+ var args = VisitArguments ( "(" , node . Parameters , VisitParameterDeclaration , ")" ) ;
1156+ Indent ( ) ;
1157+ var body = VisitBody ( node . Body , true ) ;
1158+
1159+ Outdent ( ) ;
1160+
1161+ return Expression . Lambda ( body , name , node . TailCall , args ) ;
1162+ }
11521163 }
11531164
11541165 private HashSet < LambdaExpression > _visitedLambda ;
11551166 private int _writerLevel ;
11561167 protected override Expression VisitLambda < T > ( Expression < T > node )
11571168 {
1169+ if ( this . Definitions ? . IsExpression == true )
1170+ return VisitLambda ( node , LambdaType . Function ) ;
1171+
11581172 Write ( GetName ( node ) ) ;
11591173
11601174 if ( _visitedLambda == null )
@@ -1282,14 +1296,25 @@ protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBind
12821296 return node . Update ( args ) ;
12831297 }
12841298
1285- private static Type GetDelegateType ( MethodInfo method )
1299+ private static Type MakeDelegateType ( Type returnType , params Type [ ] parameters )
12861300 {
1287- if ( method . GetParameters ( ) . Any ( it => it . IsOut || it . ParameterType . IsByRef ) )
1288- throw new InvalidOperationException ( "Cannot handle non-public method" ) ;
1301+ var del = GetDelegateType ( returnType != typeof ( void ) , parameters . Length ) ;
1302+ if ( del . GetTypeInfo ( ) . IsGenericTypeDefinition )
1303+ {
1304+ var types = parameters . AsEnumerable ( ) ;
1305+ if ( returnType != typeof ( void ) )
1306+ types = types . Concat ( new [ ] { returnType } ) ;
1307+ del = del . MakeGenericType ( types . ToArray ( ) ) ;
1308+ }
12891309
1290- if ( method . ReturnType == typeof ( void ) )
1310+ return del ;
1311+ }
1312+
1313+ private static Type GetDelegateType ( bool isFunc , int argCount )
1314+ {
1315+ if ( ! isFunc )
12911316 {
1292- switch ( method . GetParameters ( ) . Length )
1317+ switch ( argCount )
12931318 {
12941319 case 0 : return typeof ( Action ) ;
12951320 case 1 : return typeof ( Action < > ) ;
@@ -1313,7 +1338,7 @@ private static Type GetDelegateType(MethodInfo method)
13131338 }
13141339 else
13151340 {
1316- switch ( method . GetParameters ( ) . Length )
1341+ switch ( argCount )
13171342 {
13181343 case 0 : return typeof ( Func < > ) ;
13191344 case 1 : return typeof ( Func < , > ) ;
@@ -1352,14 +1377,10 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
13521377 else if ( ! node . Method . IsPublic || node . Method . DeclaringType ? . GetTypeInfo ( ) . IsNotPublic == true)
13531378 {
13541379 isNotPublic = true ;
1355- var del = GetDelegateType ( node . Method ) ;
1356- if ( del . GetTypeInfo ( ) . IsGenericTypeDefinition )
1357- {
1358- var types = node . Method . GetParameters ( ) . Select ( it => it . ParameterType ) ;
1359- if ( node . Method . ReturnType != typeof ( void ) )
1360- types = types . Concat ( new [ ] { node . Method . ReturnType } ) ;
1361- del = del . MakeGenericType ( types . ToArray ( ) ) ;
1362- }
1380+ if ( node . Method . GetParameters ( ) . Any ( it => it . IsOut || it . ParameterType . IsByRef ) )
1381+ throw new InvalidOperationException ( "Cannot handle non-public method" ) ;
1382+
1383+ var del = MakeDelegateType ( node . Method . ReturnType , node . Method . GetParameters ( ) . Select ( it => it . ParameterType ) . ToArray ( ) ) ;
13631384 var func = node . Method . CreateDelegate ( del ) ;
13641385 Write ( GetConstant ( func , GetVarName ( node . Method . Name ) ) , ".Invoke" ) ;
13651386 }
0 commit comments