/// <summary> /// Просто выполняет переход по ребру и строит выражения для перечисления массивов и словарей. /// </summary> private static void BuildTreeMutator(this ModelConfigurationNode node, ModelConfigurationEdge edge, Stack <ModelConfigurationEdge> edges, ModelConfigurationNode root, List <KeyValuePair <Expression, Expression> > aliases, List <Expression> localResult, HashSet <ModelConfigurationNode> visitedNodes, HashSet <ModelConfigurationNode> processedNodes, List <Expression> globalResult, List <ParameterExpression> invariantParameters) { var child = node.children[edge]; if (edge.IsMemberAccess || edge.IsArrayIndex || edge.IsConvertation || edge.IsIndexerParams) { child.BuildTreeMutator(edges, root, aliases, localResult, visitedNodes, processedNodes, globalResult, invariantParameters); } else if (edge.IsEachMethod) { var path = node.Path.ResolveAliases(aliases); if (node.NodeType.IsDictionary()) { node.BuildTreeMutatorForDictionary(child, edges, root, aliases, localResult, visitedNodes, processedNodes, path, globalResult, invariantParameters); } else { node.BuildTreeMutatorForArray(child, edges, root, aliases, localResult, visitedNodes, processedNodes, path, globalResult, invariantParameters); } } else { throw new InvalidOperationException(); } }
private static ModelConfigurationNode GoTo(ModelConfigurationNode node, ModelConfigurationEdge edge) { if (node == null) { return(null); } return(node.children.TryGetValue(edge, out var result) ? result : null); }
private static ModelConfigurationNode GotoIndexer(this ModelConfigurationNode node, object[] parameters, bool create) { var edge = new ModelConfigurationEdge(parameters); var property = node.NodeType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance); if (property == null) { throw new InvalidOperationException("Type '" + node.NodeType + "' doesn't contain indexer"); } if (!property.CanRead || !property.CanWrite) { throw new InvalidOperationException("Type '" + node.NodeType + "' has indexer that doesn't contain either getter or setter"); } return(node.GetChild(edge, property.GetGetMethod().ReturnType, create)); }
internal static ModelConfigurationNode GotoMember(this ModelConfigurationNode node, MemberInfo member, bool create) { var edge = new ModelConfigurationEdge(member); switch (member.MemberType) { case MemberTypes.Field: return(node.GetChild(edge, ((FieldInfo)member).FieldType, create)); case MemberTypes.Property: return(node.GetChild(edge, ((PropertyInfo)member).PropertyType, create)); default: throw new NotSupportedException("Member rootType " + member.MemberType + " is not supported"); } }
private static ModelConfigurationNode GetChild(this ModelConfigurationNode node, ModelConfigurationEdge edge, Type childType, bool create) { if (!node.children.TryGetValue(edge, out var child) && create) { Expression path; if (edge.IsArrayIndex) { path = node.Path.MakeArrayIndex((int)edge.Value); } else if (edge.IsMemberAccess) { path = node.Path.MakeMemberAccess((MemberInfo)edge.Value); } else if (edge.IsEachMethod) { path = node.Path.MakeEachCall(childType); } else if (edge.IsConvertation) { path = node.Path.MakeConvertation((Type)edge.Value); } else if (edge.IsIndexerParams) { path = node.Path.MakeIndexerCall((object[])edge.Value, node.NodeType); } else { throw new InvalidOperationException(); } child = new ModelConfigurationNode(node.RootType, childType, node.Root, node, edge, path); node.children.Add(edge, child); } return(child); }
private static ModelConfigurationNode GotoConvertation(this ModelConfigurationNode node, Type type, bool create) { var edge = new ModelConfigurationEdge(type); return(node.GetChild(edge, type, create)); }