private static IEnumerable<PathPart> SplitExpressionRecursive(Expression expression, bool isRootCall) { var node = expression; Expression index = null; if (expression.NodeType == ExpressionType.Index) { var idx = (IndexExpression) expression; index = idx; node = idx.Object; } if (expression.NodeType == ExpressionType.Call) { var idx = (MethodCallExpression) expression; index = idx; node = idx.Object; } if (expression.NodeType == ExpressionType.ArrayIndex) { var idx = (BinaryExpression) expression; index = idx; node = idx.Left; } var pathPart = new PathPart { Indexer = index, Member = node, Path = expression.ToPathWithEmptyIndexer(), IsMostRightPart = isRootCall }; if (node.NodeType == ExpressionType.MemberAccess) { var memberAccess = (MemberExpression) node; foreach (var parent in SplitExpressionRecursive(memberAccess.Expression, false)) yield return parent; } yield return pathPart; }
private static void CreateNodes( PathPart[] parts, Expression source, object converter, int index, Dictionary<string, MappingBuilderNode> nodeMap, MappingBuilderNode parentNode = null) { var part = parts[index]; MappingBuilderNode currentNode; if (!nodeMap.TryGetValue(part.Path, out currentNode)) { // Create node var currentNodes = CreateNode( part.Member, part.Indexer, index == parts.Length - 1 ? source : null, converter).ToArray(); for (var i = 0; i < currentNodes.Length - 1; i++) currentNodes[i].Children.Add(currentNodes[i + 1]); foreach (var c in currentNodes) if (!nodeMap.ContainsKey(c.Path)) nodeMap.Add(c.Path, c); parentNode?.Children.Add(currentNodes.First()); currentNode = currentNodes.Last(); } if (index + 1 < parts.Length) CreateNodes(parts, source, converter, index + 1, nodeMap, currentNode); }