1111using System . Linq . Expressions ;
1212using System . Reflection ;
1313using System . Runtime . CompilerServices ;
14+ using System . Xml . Linq ;
1415
1516namespace ExpressionDebugger
1617{
@@ -1268,6 +1269,88 @@ public Expression VisitLambda(LambdaExpression node, LambdaType type, string? me
12681269 }
12691270 }
12701271
1272+ public Expression VisitLambdaForGenerateMappers ( LambdaExpression node , LambdaType type , Type InterfaceType , string ? methodName = null ,
1273+ bool isInternal = false )
1274+ {
1275+ VisitLambda ( node , type , methodName , isInternal ) ;
1276+
1277+ if ( ! isInternal )
1278+ isInternal = node . ReturnType . GetTypeInfo ( ) . IsNotPublic ||
1279+ node . Parameters . Any ( it => it . Type . GetTypeInfo ( ) . IsNotPublic ) ;
1280+
1281+ if ( ! isInternal )
1282+ return node ; // skip create interface implimentation if public only
1283+
1284+ if ( type == LambdaType . PrivateLambda || type == LambdaType . PublicLambda )
1285+ {
1286+ _inlineCount ++ ;
1287+ if ( type == LambdaType . PublicLambda )
1288+ {
1289+ var name = methodName != null ? $ "{ InterfaceType . FullName } .{ methodName } " : "Main" ;
1290+ WriteLine ( ) ;
1291+ var funcType = MakeDelegateType ( node . ReturnType , node . Parameters . Select ( it => it . Type ) . ToArray ( ) ) ;
1292+ var exprType = typeof ( Expression < > ) . MakeGenericType ( funcType ) ;
1293+ Write ( Translate ( exprType ) , " " , name , " => " ) ;
1294+ }
1295+
1296+ IList < ParameterExpression > args ;
1297+ if ( node . Parameters . Count == 1 )
1298+ {
1299+ args = new List < ParameterExpression > ( ) ;
1300+ var arg = VisitParameter ( node . Parameters [ 0 ] ) ;
1301+ args . Add ( ( ParameterExpression ) arg ) ;
1302+ }
1303+ else
1304+ {
1305+ args = VisitArguments ( "(" , node . Parameters . ToList ( ) , p => ( ParameterExpression ) VisitParameter ( p ) ,
1306+ ")" ) ;
1307+ }
1308+
1309+ Write ( " => " ) ;
1310+ var body = VisitGroup ( node . Body , ExpressionType . Quote ) ;
1311+ if ( type == LambdaType . PublicLambda )
1312+ Write ( ";" ) ;
1313+ _inlineCount -- ;
1314+ return Expression . Lambda ( body , node . Name , node . TailCall , args ) ;
1315+ }
1316+ else
1317+ {
1318+ var name = methodName != null ? $ "{ InterfaceType . FullName } .{ methodName } " : "Main" ;
1319+ if ( type == LambdaType . PublicMethod || type == LambdaType . ExtensionMethod )
1320+ {
1321+ if ( ! isInternal )
1322+ isInternal = node . ReturnType . GetTypeInfo ( ) . IsNotPublic ||
1323+ node . Parameters . Any ( it => it . Type . GetTypeInfo ( ) . IsNotPublic ) ;
1324+ WriteLine ( ) ;
1325+ Methods [ name ] = node . Type ;
1326+ }
1327+ else
1328+ {
1329+ name = GetName ( node , name ) ;
1330+ WriteModifierNextLine ( "private" ) ;
1331+ }
1332+
1333+ Write ( Translate ( node . ReturnType ) , " " , name ) ;
1334+ var open = "(" ;
1335+ if ( type == LambdaType . ExtensionMethod )
1336+ {
1337+ if ( Definitions ? . IsStatic != true )
1338+ throw new InvalidOperationException ( "Extension method requires static class" ) ;
1339+ if ( node . Parameters . Count == 0 )
1340+ throw new InvalidOperationException ( "Extension method requires at least 1 parameter" ) ;
1341+ open = "(this " ;
1342+ }
1343+
1344+ var args = VisitArguments ( open , node . Parameters , VisitParameterDeclaration , ")" ) ;
1345+ Indent ( ) ;
1346+ var body = VisitBody ( node . Body , true ) ;
1347+
1348+ Outdent ( ) ;
1349+
1350+ return Expression . Lambda ( body , name , node . TailCall , args ) ;
1351+ }
1352+ }
1353+
12711354 private HashSet < LambdaExpression > ? _visitedLambda ;
12721355 private int _writerLevel ;
12731356
@@ -1865,9 +1948,16 @@ public override string ToString()
18651948 WriteNextLine ( "using " , ns , ";" ) ;
18661949 }
18671950
1868- WriteLine ( ) ;
18691951 }
18701952
1953+ foreach ( var ns in Definitions . GeneratedAttributes . Select ( x => x . NameSpace ) . Distinct ( ) )
1954+ {
1955+ WriteNextLine ( "using " , ns , ";" ) ;
1956+ }
1957+
1958+ if ( _usings != null || Definitions . GeneratedAttributes . Count != 0 )
1959+ WriteLine ( ) ;
1960+
18711961 // NOTE: type alias cannot solve all name conflicted case, user should use PrintFullTypeName
18721962 // keep logic here for compatibility
18731963 if ( _typeNames != null )
@@ -1891,6 +1981,11 @@ public override string ToString()
18911981 Indent ( ) ;
18921982 }
18931983
1984+ foreach ( var gAttr in Definitions . GeneratedAttributes )
1985+ {
1986+ WriteNextLine ( gAttr . Implimentation ) ;
1987+ }
1988+
18941989 var isInternal = Definitions . IsInternal ;
18951990 if ( ! isInternal )
18961991 isInternal = Definitions . Implements ? . Any ( it =>
0 commit comments