protected override Expression VisitParameter(ParameterExpression node) { InfoDictionary.Add(node, TypeMappings); var pair = InfoDictionary.SingleOrDefault(a => a.Key.Equals(node)); return(!pair.Equals(default(KeyValuePair <Type, MapperInfo>)) ? pair.Value.NewParameter : base.VisitParameter(node)); }
protected override Expression VisitMember(MemberExpression node) { var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { var baseExpression = node.GetBaseOfMemberExpression(); if (baseExpression?.NodeType == ExpressionType.Constant) { return(this.Visit ( Expression.Constant ( GetConstantValue ( ((ConstantExpression)baseExpression).Value, node.GetPropertyFullName(), baseExpression.Type ), node.Type ) )); } return(base.VisitMember(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); return(GetMappedMemberExpression(node.GetBaseOfMemberExpression(), new List <PropertyMapInfo>())); Expression GetMappedMemberExpression(Expression parentExpression, List <PropertyMapInfo> propertyMapInfoList) { Expression mappedParentExpression = this.Visit(parentExpression); FindDestinationFullName(parentExpression.Type, mappedParentExpression.Type, node.GetPropertyFullName(), propertyMapInfoList); if (propertyMapInfoList.Any(x => x.CustomExpression != null)) { var fromCustomExpression = GetMemberExpressionFromCustomExpression ( propertyMapInfoList, propertyMapInfoList.Last(x => x.CustomExpression != null), mappedParentExpression ); this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, fromCustomExpression.Type); return(fromCustomExpression); } var memberExpression = GetMemberExpressionFromMemberMaps(BuildFullName(propertyMapInfoList), mappedParentExpression); this.TypeMappings.AddTypeMapping(ConfigurationProvider, node.Type, memberExpression.Type); return(memberExpression); } }
protected override Expression VisitMember(MemberExpression node) { var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { return(base.VisitMember(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); return(GetMappedMemberExpression(node.GetBaseOfMemberExpression(), new List <PropertyMapInfo>())); Expression GetMappedMemberExpression(Expression parentExpression, List <PropertyMapInfo> propertyMapInfoList) { Expression mappedParentExpression = this.Visit(parentExpression); FindDestinationFullName(parentExpression.Type, mappedParentExpression.Type, node.GetPropertyFullName(), propertyMapInfoList); if (propertyMapInfoList.Any(x => x.CustomExpression != null))//CustomExpression takes precedence over DestinationPropertyInfo { return(GetMemberExpression ( new FindMemberExpressionsVisitor(mappedParentExpression), GetMemberExpressionFromCustomExpression ( propertyMapInfoList, propertyMapInfoList.Last(x => x.CustomExpression != null), mappedParentExpression ) )); } return(GetExpressionForInclude ( GetMemberExpressionFromMemberMaps ( BuildFullName(propertyMapInfoList), mappedParentExpression ) )); } Expression GetExpressionForInclude(MemberExpression memberExpression) => memberExpression.Type.IsLiteralType() ? memberExpression.Expression : memberExpression; MemberExpression GetMemberExpression(FindMemberExpressionsVisitor visitor, Expression mappedExpression) { visitor.Visit(mappedExpression); return(visitor.Result); } }
protected override Expression VisitMethodCall(MethodCallExpression node) { var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { return(base.VisitMethodCall(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); var listOfArgumentsForNewMethod = node.Arguments.Aggregate(new List <Expression>(), (lst, next) => { var mappedNext = ArgumentMapper.Create(this, next).MappedArgumentExpression; TypeMappings.AddTypeMapping(next.Type, mappedNext.Type); lst.Add(mappedNext); return(lst); });//Arguments could be expressions or other objects. e.g. s => s.UserId or a string "ZZZ". For extention methods node.Arguments[0] is usually the helper object itself //type args are the generic type args e.g. T1 and T2 MethodName<T1, T2>(method arguments); var typeArgsForNewMethod = node.Method.IsGenericMethod ? node.Method.GetGenericArguments().Select(i => TypeMappings.ContainsKey(i) ? TypeMappings[i] : i).ToList()//not converting the type it is not in the typeMappings dictionary : null; MethodCallExpression resultExp; if (!node.Method.IsStatic) { var instance = ArgumentMapper.Create(this, node.Object).MappedArgumentExpression; resultExp = node.Method.IsGenericMethod ? Expression.Call(instance, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(instance, node.Method, listOfArgumentsForNewMethod.ToArray()); } else { resultExp = node.Method.IsGenericMethod ? Expression.Call(node.Method.DeclaringType, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(node.Method, listOfArgumentsForNewMethod.ToArray()); } return(resultExp); }
protected override Expression VisitMethodCall(MethodCallExpression node) { var parameterExpression = node.GetParameterExpression(); if (parameterExpression != null) { InfoDictionary.Add(parameterExpression, TypeMappings); } var listOfArgumentsForNewMethod = node.Arguments.Aggregate(new List <Expression>(), (lst, next) => { var mappedNext = this.Visit(next); TypeMappings.AddTypeMapping(ConfigurationProvider, next.Type, mappedNext.Type); lst.Add(mappedNext); return(lst); });//Arguments could be expressions or other objects. e.g. s => s.UserId or a string "ZZZ". For extention methods node.Arguments[0] is usually the helper object itself //type args are the generic type args e.g. T1 and T2 MethodName<T1, T2>(method arguments); var typeArgsForNewMethod = node.Method.IsGenericMethod ? node.Method.GetGenericArguments().Select(type => this.TypeMappings.ReplaceType(type)).ToList()//not converting the type it is not in the typeMappings dictionary : null; ConvertTypesIfNecessary(node.Method.GetParameters(), listOfArgumentsForNewMethod, node.Method); return(node.Method.IsStatic ? GetStaticExpression() : GetInstanceExpression(this.Visit(node.Object))); MethodCallExpression GetInstanceExpression(Expression instance) => node.Method.IsGenericMethod ? Expression.Call(instance, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(instance, node.Method, listOfArgumentsForNewMethod.ToArray()); MethodCallExpression GetStaticExpression() => node.Method.IsGenericMethod ? Expression.Call(node.Method.DeclaringType, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(node.Method, listOfArgumentsForNewMethod.ToArray()); }
protected override Expression VisitMember(MemberExpression node) { if (node.NodeType == ExpressionType.Constant) { return(base.VisitMember(node)); } string sourcePath; var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { return(base.VisitMember(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); var sType = parameterExpression.Type; if (InfoDictionary.ContainsKey(parameterExpression) && node.IsMemberExpression()) { sourcePath = node.GetPropertyFullName(); } else { return(base.VisitMember(node)); } var propertyMapInfoList = new List <PropertyMapInfo>(); FindDestinationFullName(sType, InfoDictionary[parameterExpression].DestType, sourcePath, propertyMapInfoList); string fullName; if (propertyMapInfoList.Any(x => x.CustomExpression != null)) { var last = propertyMapInfoList.Last(x => x.CustomExpression != null); var beforeCustExpression = propertyMapInfoList.Aggregate(new List <PropertyMapInfo>(), (list, next) => { if (propertyMapInfoList.IndexOf(next) < propertyMapInfoList.IndexOf(last)) { list.Add(next); } return(list); }); var afterCustExpression = propertyMapInfoList.Aggregate(new List <PropertyMapInfo>(), (list, next) => { if (propertyMapInfoList.IndexOf(next) > propertyMapInfoList.IndexOf(last)) { list.Add(next); } return(list); }); fullName = BuildFullName(beforeCustExpression); var visitor = new PrependParentNameVisitor(last.CustomExpression.Parameters[0].Type /*Parent type of current property*/, fullName, InfoDictionary[parameterExpression].NewParameter); var ex = propertyMapInfoList[propertyMapInfoList.Count - 1] != last ? visitor.Visit(last.CustomExpression.Body.AddExpressions(afterCustExpression)) : visitor.Visit(last.CustomExpression.Body); return(ex); } fullName = BuildFullName(propertyMapInfoList); var me = InfoDictionary[parameterExpression].NewParameter.BuildExpression(fullName); return(me); }
protected override Expression VisitMember(MemberExpression node) { string sourcePath; var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { return(base.VisitMember(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); var sType = parameterExpression.Type; if (sType != null && InfoDictionary.ContainsKey(parameterExpression) && node.IsMemberExpression()) { sourcePath = node.GetPropertyFullName(); } else { return(base.VisitMember(node)); } var propertyMapInfoList = new List <PropertyMapInfo>(); FindDestinationFullName(sType, InfoDictionary[parameterExpression].DestType, sourcePath, propertyMapInfoList); string fullName; if (propertyMapInfoList.Any(x => x.CustomExpression != null))//CustomExpression takes precedence over DestinationPropertyInfo { var last = propertyMapInfoList.Last(x => x.CustomExpression != null); var beforeCustExpression = propertyMapInfoList.Aggregate(new List <PropertyMapInfo>(), (list, next) => { if (propertyMapInfoList.IndexOf(next) < propertyMapInfoList.IndexOf(last)) { list.Add(next); } return(list); }); var afterCustExpression = propertyMapInfoList.Aggregate(new List <PropertyMapInfo>(), (list, next) => { if (propertyMapInfoList.IndexOf(next) > propertyMapInfoList.IndexOf(last)) { list.Add(next); } return(list); }); fullName = BuildFullName(beforeCustExpression); var visitor = new PrependParentNameVisitor(last.CustomExpression.Parameters[0].Type /*Parent type of current property*/, fullName, InfoDictionary[parameterExpression].NewParameter); var ex = propertyMapInfoList[propertyMapInfoList.Count - 1] != last ? visitor.Visit(last.CustomExpression.Body.MemberAccesses(afterCustExpression)) : visitor.Visit(last.CustomExpression.Body); var v = new FindMemberExpressionsVisitor(InfoDictionary[parameterExpression].NewParameter); v.Visit(ex); return(v.Result); } fullName = BuildFullName(propertyMapInfoList); var me = ExpressionFactory.MemberAccesses(fullName, InfoDictionary[parameterExpression].NewParameter); if (me.Expression.NodeType == ExpressionType.MemberAccess && (me.Type == typeof(string) || me.Type.GetTypeInfo().IsValueType || (me.Type.GetTypeInfo().IsGenericType && me.Type.GetGenericTypeDefinition() == typeof(Nullable <>) && Nullable.GetUnderlyingType(me.Type).GetTypeInfo().IsValueType))) { return(me.Expression); } return(me); }
public void UpdateData <T>() { // Check if context type has change if (!string.Equals(typeof(T).AssemblyQualifiedName, _declaringTypeName)) { _declaringTypeName = typeof(T).AssemblyQualifiedName; foreach (KeyValuePair <string, SerializableInfo> pair in InfoDictionary) { pair.Value.DeclaringTypeName = _declaringTypeName; } } // Handle fields FieldInfo[] fieldInfos = typeof(T).GetFields(SerializableInfo.DefaultBindingFlags); foreach (FieldInfo fieldInfo in fieldInfos) { if (PortDictionary.ContainsKey(fieldInfo.Name)) { continue; } SerializableInfo serializableFieldInfo = new SerializableInfo(fieldInfo); PortDictionary.Add(fieldInfo.Name, serializableFieldInfo.PortName); NodePort newPort = AddDynamicOutput(serializableFieldInfo.Type, ConnectionType.Multiple, TypeConstraint.None, serializableFieldInfo.PortName); InfoDictionary.Add(serializableFieldInfo.PortName, serializableFieldInfo); // Redirect port using FormerlySerializedAsAttribute FormerlySerializedAsAttribute attribute = fieldInfo.GetCustomAttribute <FormerlySerializedAsAttribute>(); if (attribute != null && PortDictionary.ContainsKey(attribute.oldName)) { GetPort(PortDictionary[attribute.oldName]).SwapConnections(newPort); } } // Handle properties PropertyInfo[] propertyInfos = typeof(T).GetProperties(SerializableInfo.DefaultBindingFlags); foreach (PropertyInfo propertyInfo in propertyInfos) { if (PortDictionary.ContainsKey(propertyInfo.Name)) { continue; } SerializableInfo serializablePropertyInfo = new SerializableInfo(propertyInfo); PortDictionary.Add(propertyInfo.Name, serializablePropertyInfo.PortName); NodePort newPort = AddDynamicOutput(serializablePropertyInfo.Type, ConnectionType.Multiple, TypeConstraint.None, serializablePropertyInfo.PortName); InfoDictionary.Add(serializablePropertyInfo.PortName, serializablePropertyInfo); // Redirect port using FormerlySerializedAsAttribute FormerlySerializedAsAttribute attribute = propertyInfo.GetCustomAttribute <FormerlySerializedAsAttribute>(); if (attribute != null && PortDictionary.ContainsKey(attribute.oldName)) { GetPort(PortDictionary[attribute.oldName]).SwapConnections(newPort); } } // Remove old ports for (int i = PortDictionary.Count - 1; i >= 0; i--) { if (fieldInfos.Any(info => info.Name == PortDictionary.ElementAt(i).Key)) { continue; } if (propertyInfos.Any(info => info.Name == PortDictionary.ElementAt(i).Key)) { continue; } RemoveDynamicPort(PortDictionary.ElementAt(i).Value); InfoDictionary.Remove(PortDictionary.ElementAt(i).Value); PortDictionary.Remove(PortDictionary.ElementAt(i).Key); } }