public static GraphNodePath From(IGraphNode root, [NotNull] MemberPath memberPath, out NodeIndex index) { if (memberPath == null) { throw new ArgumentNullException(nameof(memberPath)); } var result = new GraphNodePath(root); index = NodeIndex.Empty; var memberPathItems = memberPath.Decompose(); for (int i = 0; i < memberPathItems.Count; i++) { var memberPathItem = memberPathItems[i]; bool lastItem = i == memberPathItems.Count - 1; if (memberPathItem.MemberDescriptor != null) { result.PushMember(memberPathItem.MemberDescriptor.Name); } else if (memberPathItem.GetIndex() != null) { var localIndex = new NodeIndex(memberPathItem.GetIndex()); if (lastItem) { // If last item, we directly return the index rather than add it to the path index = localIndex; } else { result.PushIndex(localIndex); } } // Don't apply Target on last item if (!lastItem) { // If this is a reference, add a target element to the path var node = result.GetNode(); var objectReference = (node as IMemberNode)?.TargetReference; if (objectReference?.TargetNode != null) { result.PushTarget(); } } } return(result); }
/// <summary> /// Visits the <see cref="ObjectReference"/> contained in the given node, if any. /// </summary> /// <param name="node">The node being visited.</param> protected virtual void VisitMemberTarget([NotNull] IMemberNode node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (node.TargetReference?.TargetNode != null) { if (ShouldVisitMemberTarget(node)) { CurrentPath.PushTarget(); VisitReference(node, node.TargetReference); CurrentPath.Pop(); } } }