private Assignment ProcessTypeMap(TypeMap rootMap, string srcFieldName, string destFieldName) { var coder = new Coder(); foreach (PropertyMap propertyMap in rootMap.PropertyMaps) { RememberTypeLocations(propertyMap); var context = new PropertyNameContext(propertyMap, srcFieldName, destFieldName); if (propertyMap.Ignored) { continue; } //assign without explicit cast if (propertyMap.DestType.IsAssignableFrom(propertyMap.SrcType) || propertyMap.DestType.IsImplicitCastableFrom(propertyMap.SrcType)) { //TODO: need to determine explicit casts and produce cast operators coder.SimpleAssign(context); continue; } else { bool referenceType = propertyMap.DestType.IsClass; //TODO: perfomance degrades on each null check! Try to avoid it if possible! if (referenceType) { coder.NullCheck(context); coder.AttachRawCode(" else {{"); coder.AppendNoParameterlessCtorException(context, propertyMap.DestType); } ProcessPropertyTypePair(coder, context, propertyMap); if (referenceType) { coder.AttachRawCode("}}"); } } } var assignment = coder.GetAssignment(); TemplateCache.AddIfNotExist(rootMap.TypePair, assignment.RelativeTemplate); return(assignment); }
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); }