/// <summary> /// Initializes a new instance of the <see cref="Path"/> class. /// </summary> /// <param name="next">The next node in the path; or <see langword="null"/>.</param> /// <param name="link">The associated link; or <see langword="null"/>.</param> /// <param name="frame">The associated stack frame.</param> /// <param name="length"></param> public Path(Path next, Link link, Frame frame, int length) { #region Contract Contract.Requires<ArgumentNullException>(frame != null); Contract.Requires<ArgumentOutOfRangeException>(length >= 0); #endregion this.Next = next; this.Link = link; this.Frame = frame; this.Length = length; this.AncestorCount = next != null ? next.AncestorCount + 1 : 0; this.label = this.Link?.Label; }
/// <summary> /// Determines all paths from this frame to the root frame. /// </summary> /// <param name="parent"></param> /// <param name="targetLink">The link to look for, or <see langword="null"/> to find all paths.</param> /// <param name="seen">Whether <paramref name="targetLink"/> has been seen.</param> /// <param name="arity"></param> /// <param name="length"></param> /// <returns></returns> private IEnumerable<Path> DoGetAllPathsToRoot(Path parent, Link targetLink, bool seen, int arity, int length) { // TODO: Understand! if (arity == 0 && seen) { return new[] { new Path(parent, null, this, length) }; } else if (arity > 0) { List<Path> paths = new List<Path>(); foreach (var link in this.Links.Reverse()) { bool seenIt = seen || (link == targetLink); Path n = new Path(parent, link, this, link.Length); paths.AddRange(link.Parent.DoGetAllPathsToRoot(n, targetLink, seenIt, arity - 1, length + link.Length)); } return paths; } else return Enumerable.Empty<Path>(); }