public void TestExtensionMethod()
        {
            var p1     = Expression.Parameter(typeof(int));
            var p2     = Expression.Parameter(typeof(int));
            var lambda = Expression.Lambda <Func <int, int, int> >(
                Expression.Add(p1, p2),
                p1, p2);
            var translator = new ExpressionTranslator(new TypeDefinitions
            {
                IsStatic  = true,
                Namespace = "ExpressionDebugger.Tests",
                TypeName  = "MockClass"
            });

            translator.VisitLambda(lambda, ExpressionTranslator.LambdaType.ExtensionMethod, "Add");
            var str = translator.ToString();

            Assert.AreEqual(@"
namespace ExpressionDebugger.Tests
{
    public static partial class MockClass
    {
        public static int Add(this int p1, int p2)
        {
            return p1 + p2;
        }
    }
}".Trim(), str);
        }
Ejemplo n.º 2
0
        private static void CreateModel(ModelOptions opt, Type type, BaseAdaptAttribute attr)
        {
            var definitions = new TypeDefinitions
            {
                Namespace         = opt.Namespace ?? type.Namespace,
                TypeName          = attr.Name !.Replace("[name]", type.Name),
                PrintFullTypeName = opt.PrintFullTypeName,
            };
            var translator = new ExpressionTranslator(definitions);
            var isAdaptTo  = attr is AdaptToAttribute;
            var isTwoWays  = attr is AdaptTwoWaysAttribute;
            var side       = isAdaptTo ? MemberSide.Source : MemberSide.Destination;
            var properties = type.GetFieldsAndProperties().Where(it =>
                                                                 !it.SafeGetCustomAttributes().OfType <AdaptIgnoreAttribute>()
                                                                 .Any(it2 => isTwoWays || it2.Side == null || it2.Side == side));

            if (attr.IgnoreAttributes != null)
            {
                properties = properties.Where(it =>
                                              !it.SafeGetCustomAttributes()
                                              .Select(it2 => it2.GetType())
                                              .Intersect(attr.IgnoreAttributes)
                                              .Any());
            }

            if (attr.IgnoreNoAttributes != null)
            {
                properties = properties.Where(it =>
                                              it.SafeGetCustomAttributes()
                                              .Select(it2 => it2.GetType())
                                              .Intersect(attr.IgnoreNoAttributes)
                                              .Any());
            }

            if (attr.IgnoreNamespaces != null)
            {
                foreach (var ns in attr.IgnoreNamespaces)
                {
                    properties = properties.Where(it => getPropType(it).Namespace?.StartsWith(ns) != true);
                }
            }
            var isReadOnly = isAdaptTo && attr.MapToConstructor;
            var isNullable = !isAdaptTo && attr.IgnoreNullValues;

            foreach (var member in properties)
            {
                var adaptMember = member.GetCustomAttribute <AdaptMemberAttribute>();
                var propType    = GetPropertyType(member, getPropType(member), attr.GetType(), opt.Namespace);
                translator.Properties.Add(new PropertyDefinitions
                {
                    Name       = adaptMember?.Name ?? member.Name,
                    Type       = isNullable ? propType.MakeNullable() : propType,
                    IsReadOnly = isReadOnly
                });
            }

            var code = translator.ToString();
            var path = Path.Combine(Path.GetFullPath(opt.Output), definitions.TypeName + ".g.cs");

            WriteFile(code, path);
        public void TestProperties()
        {
            var translator = new ExpressionTranslator(new TypeDefinitions
            {
                IsStatic  = false,
                Namespace = "ExpressionDebugger.Tests",
                TypeName  = "MockClass"
            });

            translator.Properties.Add(new PropertyDefinitions
            {
                Name = "Prop1",
                Type = typeof(string)
            });
            translator.Properties.Add(new PropertyDefinitions
            {
                Name       = "Prop2",
                Type       = typeof(string),
                IsReadOnly = true
            });
            var str = translator.ToString();

            Assert.AreEqual(@"
namespace ExpressionDebugger.Tests
{
    public partial class MockClass
    {
        public string Prop1 { get; set; }
        public string Prop2 { get; }
        
        public MockClass(string prop2)
        {
            this.Prop2 = prop2;
        }
    }
}".Trim(), str);
        }
Ejemplo n.º 4
0
        private static void GenerateMappers(MapperOptions opt)
        {
            using var dynamicContext = new AssemblyResolver(Path.GetFullPath(opt.Assembly));
            var assembly = dynamicContext.Assembly;
            var config   = TypeAdapterConfig.GlobalSettings;

            config.SelfContainedCodeGeneration = true;
            config.Scan(assembly);

            foreach (var type in assembly.GetTypes())
            {
                if (!type.IsInterface)
                {
                    continue;
                }
                var attr = type.GetCustomAttribute <MapperAttribute>();
                if (attr == null)
                {
                    continue;
                }

                Console.WriteLine($"Processing: {type.FullName}");

                var definitions = new TypeDefinitions
                {
                    Implements        = new[] { type },
                    Namespace         = opt.Namespace ?? type.Namespace,
                    TypeName          = attr.Name ?? GetImplName(type.Name),
                    IsInternal        = attr.IsInternal,
                    PrintFullTypeName = opt.PrintFullTypeName,
                };
                var translator = new ExpressionTranslator(definitions);
                var interfaces = type.GetAllInterfaces();
                foreach (var @interface in interfaces)
                {
                    foreach (var prop in @interface.GetProperties())
                    {
                        if (!prop.PropertyType.IsGenericType)
                        {
                            continue;
                        }
                        if (prop.PropertyType.GetGenericTypeDefinition() != typeof(Expression <>))
                        {
                            continue;
                        }
                        var propArgs = prop.PropertyType.GetGenericArguments()[0];
                        if (!propArgs.IsGenericType)
                        {
                            continue;
                        }
                        if (propArgs.GetGenericTypeDefinition() != typeof(Func <,>))
                        {
                            continue;
                        }
                        var funcArgs = propArgs.GetGenericArguments();
                        var tuple    = new TypeTuple(funcArgs[0], funcArgs[1]);
                        var expr     = config.CreateMapExpression(tuple, MapType.Projection);
                        translator.VisitLambda(expr, ExpressionTranslator.LambdaType.PublicLambda,
                                               prop.Name);
                    }
                }

                foreach (var @interface in interfaces)
                {
                    foreach (var method in @interface.GetMethods())
                    {
                        if (method.IsGenericMethod)
                        {
                            continue;
                        }
                        if (method.ReturnType == typeof(void))
                        {
                            continue;
                        }
                        var methodArgs = method.GetParameters();
                        if (methodArgs.Length < 1 || methodArgs.Length > 2)
                        {
                            continue;
                        }
                        var tuple = new TypeTuple(methodArgs[0].ParameterType, method.ReturnType);
                        var expr  = config.CreateMapExpression(tuple,
                                                               methodArgs.Length == 1 ? MapType.Map : MapType.MapToTarget);
                        translator.VisitLambda(expr, ExpressionTranslator.LambdaType.PublicMethod,
                                               method.Name);
                    }
                }

                var code = translator.ToString();
                var path = Path.Combine(Path.GetFullPath(opt.Output), definitions.TypeName + ".g.cs");
                WriteFile(code, path);
            }
        }