#define DEBUG using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; namespace AspClassic.Parser; /// /// The root class of all trees. /// public abstract class Tree { private readonly TreeType _Type; private readonly Span _Span; private Tree _Parent; private ReadOnlyCollection _Children; /// /// The type of the tree. /// public TreeType Type => _Type; /// /// The location of the tree. /// /// /// The span ends at the first character beyond the tree /// public Span Span => _Span; /// /// The parent of the tree. Nothing if the root tree. /// public Tree Parent => _Parent; /// /// The children of the tree. /// public ReadOnlyCollection Children { get { if (_Children == null) { List ChildList = new List(); GetChildTrees(ChildList); _Children = new ReadOnlyCollection(ChildList); } return _Children; } } /// /// Whether the tree is 'bad'. /// public virtual bool IsBad => false; protected Tree(TreeType type, Span span) { Debug.Assert(type >= TreeType.SyntaxError && type <= TreeType.File); _Type = type; _Span = span; } protected void SetParent(Tree child) { if (child != null) { child._Parent = this; } } protected void SetParents(IList children) where T : Tree { if (children == null) { return; } foreach (Tree Child in children) { SetParent(Child); } } protected static void AddChild(IList childList, Tree child) { if (child != null) { childList.Add(child); } } protected static void AddChildren(IList childList, ReadOnlyCollection children) where T : Tree { if (children == null) { return; } foreach (Tree Child in children) { childList.Add(Child); } } protected virtual void GetChildTrees(IList childList) { } }