internal MemberMapping?FindDeclaringMapping(MemberMapping member, out StructMapping?declaringMapping, string?parent) { declaringMapping = null; if (BaseMapping != null) { MemberMapping?baseMember = BaseMapping.FindDeclaringMapping(member, out declaringMapping, parent); if (baseMember != null) { return(baseMember); } } if (_members == null) { return(null); } for (int i = 0; i < _members.Length; i++) { if (_members[i].Name == member.Name) { if (_members[i].TypeDesc != member.TypeDesc) { throw new InvalidOperationException(SR.Format(SR.XmlHiddenMember, parent, member.Name, member.TypeDesc !.FullName, this.TypeName, _members[i].Name, _members[i].TypeDesc !.FullName)); } else if (!_members[i].Match(member)) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidXmlOverride, parent, member.Name, this.TypeName, _members[i].Name)); } declaringMapping = this; return(_members[i]); } } return(null); }
internal LambdaExpression CreateInlineMapExpression(Type sourceType, Type destinationType, MapType mapType, CompileContext context, MemberMapping?mapping = null) { var tuple = new TypeTuple(sourceType, destinationType); var subFunction = context.IsSubFunction(); if (!subFunction) { if (context.Running.Contains(tuple)) { if (mapType == MapType.Projection) { throw new InvalidOperationException("Projection does not support circular reference"); } return(CreateMapInvokeExpression(sourceType, destinationType, mapType)); } context.Running.Add(tuple); } try { var arg = GetCompileArgument(tuple, mapType, context); if (mapping != null) { arg.Settings.Resolvers.AddRange(mapping.NextResolvers); arg.Settings.Ignore.Apply(mapping.NextIgnore); arg.UseDestinationValue = mapping.UseDestinationValue; } return(CreateMapExpression(arg)); } finally { if (!subFunction) { context.Running.Remove(tuple); } } }
internal Expression CreateAdaptExpression(Expression source, Type destinationType, CompileArgument arg, MemberMapping?mapping, Expression?destination = null) { if (source.Type == destinationType && (arg.Settings.ShallowCopyForSameType == true || arg.MapType == MapType.Projection)) { return(source); } //adapt(source); var exp = CreateAdaptExpressionCore(source, destinationType, arg, mapping, destination); //transform(adapt(source)); var transform = arg.Settings.DestinationTransforms.Find(it => it.Condition(exp.Type)); if (transform != null) { exp = transform.TransformFunc(exp.Type).Apply(arg.MapType, exp); } return(exp.To(destinationType)); }
private static Expression CreateAdaptExpressionCore(Expression source, Type destinationType, CompileArgument arg, MemberMapping?mapping = null, Expression?destination = null) { var mapType = arg.MapType == MapType.MapToTarget && destination == null ? MapType.Map : mapping?.UseDestinationValue == true ? MapType.MapToTarget : arg.MapType; var extraParams = new HashSet <ParameterExpression>(); try { if (mapping != null && mapping.HasSettings()) { if (arg.Context.ExtraParameters.Add(mapping.Source)) { extraParams.Add(mapping.Source); } if (mapping.Destination != null && arg.Context.ExtraParameters.Add(mapping.Destination)) { extraParams.Add(mapping.Destination); } } var lambda = arg.Context.Config.CreateInlineMapExpression(source.Type, destinationType, mapType, arg.Context, mapping); var paramList = new List <Expression> { source }; if (destination != null) { paramList.Add(destination); } paramList.AddRange(lambda.Parameters.Skip(paramList.Count)); if (!lambda.IsMultiLine()) { return(lambda.Apply(arg.MapType, paramList.ToArray())); } return(Expression.Invoke(lambda, paramList.ToArray())); } finally { arg.Context.ExtraParameters.ExceptWith(extraParams); } }