Beispiel #1
0
        private Assignment ProcessTypeMap(TypeMap rootMap)
        {
            var recorder = new Recorder();

            using (var bfm = new BeforeMapPrinter(new TypeNameContext(rootMap), recorder)) { }

            foreach (PropertyMap propertyMap in rootMap.PropertyMaps)
            {
                if (propertyMap.Ignored)
                {
                    continue;
                }

                RememberTypeLocations(propertyMap);

                var ctx = new PropertyNameContext(propertyMap);

                //using (var condition = new ConditionPrinter(context, Recorder))
                using (var condition = new ConditionPrinterV2(ctx, recorder))
                {
                    //assign without explicit cast
                    var st = propertyMap.SrcType;
                    var dt = propertyMap.DestType;

                    if (dt.IsAssignableFrom(st) || dt.IsImplicitCastableFrom(st))
                    {
                        recorder.AppendAssignment(Assign.AsNoCast, ctx);
                        continue;
                    }
                    //assign with explicit cast
                    if (dt.IsExplicitCastableFrom(st))
                    {
                        recorder.AppendAssignment(Assign.AsExplicitCast, ctx);
                        continue;
                    }
                    //assign with src.ToString() call
                    if (dt == typeof(string) && st != typeof(string))
                    {
                        recorder.AppendAssignment(Assign.AsToStringCall, ctx);
                        continue;
                    }
                    //assign with Convert call
                    if (st == typeof(string) && dt.IsValueType)
                    {
                        recorder.AppendAssignment(Assign.AsStringToValueTypeConvert, ctx);
                        continue;
                    }

                    if (!st.IsValueType && !dt.IsValueType)
                    {
                        using (var block = new Block(recorder, "if", $"{{0}}.{ctx.SrcMemberName} == null"))
                        {
                            recorder.AppendLine($"{{1}}.{ctx.DestMemberName} = null;");
                        }

                        using (var block = new Block(recorder, "else"))
                        {
                            if (st.IsCollectionType() && dt.IsCollectionType())
                            {
                                string template = AssignCollections(ctx)
                                                  .AddPropertyNamesToTemplate(ctx.SrcMemberName, ctx.DestMemberName);

                                recorder.AppendLine(template);
                            }

                            else
                            {
                                string template = AssignReferenceTypes(ctx)
                                                  .AddPropertyNamesToTemplate(ctx.SrcMemberName, ctx.DestMemberName);

                                recorder.AppendLine(template);
                            }
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }

            var assignment = recorder.ToAssignment();

            TemplateCache.AddIfNotExist(rootMap.TypePair, assignment.RelativeTemplate);

            return(assignment);
        }
Beispiel #2
0
        private string AssignCollections(IPropertyNameContext ctx)
        {
            var recorder = new Recorder();

            var itemSrcType  = ctx.SrcType.GenericTypeArguments[0];
            var itemDestType = ctx.DestType.GenericTypeArguments[0];

            using (var block = new Block(recorder, "if", "{1} == null"))
            {
                string newCollection = CreationTemplates.NewCollection(ctx.DestType, "{0}.Count");
                recorder.AppendLine($"{{1}} = {newCollection};");
            }
            using (var block = new Block(recorder, "else"))
            {
                recorder.AppendLine("{1}.Clear();");
            }

            //fill new (or cleared) collection with the new set of items
            recorder.AppendLine(CreationTemplates.Add("{1}", "{0}.Count", itemDestType));

            //inner cycle variables (on each iteration itemSrcName is mapped to itemDestName).
            string itemSrcName  = "src_" + NamingTools.NewGuid(4);
            string itemDestName = "dest_" + NamingTools.NewGuid(4);

            var typePair = new TypePair(itemSrcType, itemDestType);

            Assignment itemAssignment = new Assignment();

            string cachedTemplate;

            if (TemplateCache.TryGetValue(typePair, out cachedTemplate))
            {
                itemAssignment.RelativeTemplate = cachedTemplate;
            }
            else if (itemSrcType.IsCollectionType() && itemDestType.IsCollectionType())
            {
                var innerContext = PropertyNameContextFactory.CreateWithoutPropertyMap(
                    itemSrcType, itemDestType, itemSrcName, itemDestName);

                string innerTemplate = AssignCollections(innerContext);

                itemAssignment.RelativeTemplate = innerTemplate;
            }
            else
            {
                var nodeMap = GetTypeMap(typePair);

                itemAssignment = ProcessTypeMap(nodeMap);
            }

            string iterationCode = itemAssignment.GetCode(itemSrcName, itemDestName);

            string forCode = StatementTemplates.For(iterationCode,
                                                    new ForDeclarationContext("{0}", "{1}", itemSrcName, itemDestName));

            recorder.AppendLine(forCode);

            string template = recorder.ToAssignment().RelativeTemplate;

            return(template);
        }