Skip to content

Commit 16e7a57

Browse files
committed
Eagerly create Node.Children.
1 parent 0f362e7 commit 16e7a57

2 files changed

Lines changed: 21 additions & 14 deletions

File tree

src/MrKWatkins.Ast/Node.Structure.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
using System.Runtime.CompilerServices;
2+
13
namespace MrKWatkins.Ast;
24

35
public abstract partial class Node<TNode>
46
where TNode : Node<TNode>
57
{
68
private TNode? parent;
7-
private Children<TNode>? children;
89

910
/// <summary>
1011
/// Initialises a new instance of the <see cref="Node{TNode}" /> class with the specified children.
@@ -13,7 +14,7 @@ public abstract partial class Node<TNode>
1314
/// <exception cref="InvalidOperationException">If any of <see cref="Children" /> already have a <see cref="Parent" />.</exception>
1415
protected Node([InstantHandle] IEnumerable<TNode> children)
1516
{
16-
this.children = new Children<TNode>(This, children);
17+
Children = new Children<TNode>(This, children);
1718
}
1819

1920
/// <summary>
@@ -58,12 +59,16 @@ internal set
5859
/// <summary>
5960
/// The children of this node.
6061
/// </summary>
61-
public Children<TNode> Children => children ??= new Children<TNode>(This);
62+
public Children<TNode> Children { get; }
6263

6364
/// <summary>
64-
/// Returns <c>true</c> if this node has any <see cref="Children" />, <c>false</c> otherwise.
65+
/// Returns <c>true</c> if this node has any <see cref="Children" />, <c>false</c> otherwise.
6566
/// </summary>
66-
public bool HasChildren => children is { Count: > 0 };
67+
public bool HasChildren
68+
{
69+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
70+
get => Children.Count > 0;
71+
}
6772

6873
/// <summary>
6974
/// Moves this node to a new parent.
@@ -73,7 +78,7 @@ internal set
7378
/// <summary>
7479
/// Removes this node from it's parent and puts another node in its place.
7580
/// </summary>
76-
public void ReplaceWith(Node<TNode> other) => Parent.Children.Replace(This, (TNode)other);
81+
public void ReplaceWith(Node<TNode> other) => Parent.Children.Replace(This, (TNode) other);
7782

7883
/// <summary>
7984
/// Lazily enumerates over this node and then the specified enumeration of nodes.
@@ -138,7 +143,7 @@ public IEnumerable<TAncestor> ThisAndAncestorsOfType<TAncestor>()
138143
public TNode Root => HasParent ? Ancestors.Last() : This;
139144

140145
[Pure]
141-
private int GetIndexOfSelf() => Parent.Children.IndexOf(This); // Can never be -1.
146+
private int GetIndexOfSelf() => Parent.Children.IndexOf(This); // Can never be -1.
142147

143148
/// <summary>
144149
/// The next sibling, i.e. the child from the same <see cref="Parent" /> at the next positional index. Returns <c>null</c> if this node is the last child.
@@ -312,21 +317,21 @@ public void AddPreviousSibling(TNode previousSibling)
312317
/// Returns the first child of this node.
313318
/// </summary>
314319
/// <exception cref="InvalidOperationException">If this node has no children.</exception>
315-
public TNode FirstChild => Children.Count > 0 ? Children[0] : throw new InvalidOperationException("Node has no children.");
320+
public TNode FirstChild => HasChildren ? Children[0] : throw new InvalidOperationException("Node has no children.");
316321

317322
/// <summary>
318323
/// Returns the first child of this node or <c>null</c> if it has no children.
319324
/// </summary>
320-
public TNode? FirstChildOrNull => Children.Count > 0 ? Children[0] : null;
325+
public TNode? FirstChildOrNull => HasChildren ? Children[0] : null;
321326

322327
/// <summary>
323328
/// Returns the last child of this node.
324329
/// </summary>
325330
/// <exception cref="InvalidOperationException">If this node has no children.</exception>
326-
public TNode LastChild => Children.Count > 0 ? Children[^1] : throw new InvalidOperationException("Node has no children.");
331+
public TNode LastChild => HasChildren ? Children[^1] : throw new InvalidOperationException("Node has no children.");
327332

328333
/// <summary>
329334
/// Returns the last child of this node or <c>null</c> if it has no children.
330335
/// </summary>
331-
public TNode? LastChildOrNull => Children.Count > 0 ? Children[^1] : null;
336+
public TNode? LastChildOrNull => HasChildren ? Children[^1] : null;
332337
}

src/MrKWatkins.Ast/Node.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ public abstract partial class Node<TNode>
1616
/// </summary>
1717
protected Node()
1818
{
19+
Children = new Children<TNode>(This);
1920
}
2021

21-
private TNode This => (TNode)this;
22+
private TNode This => (TNode) this;
2223

2324
/// <summary>
2425
/// The <see cref="MrKWatkins.Ast.Properties" /> associated with this node.
@@ -50,10 +51,11 @@ public TNode Copy(INodeFactory<TNode> nodeFactory)
5051
{
5152
var copy = nodeFactory.Create(GetType());
5253
copy.properties = properties?.Copy();
53-
if (children != null)
54+
if (Children != null)
5455
{
55-
copy.Children.Add(children.Select(c => c.Copy(nodeFactory)));
56+
copy.Children.Add(Children.Select(c => c.Copy(nodeFactory)));
5657
}
58+
5759
return copy;
5860
}
5961

0 commit comments

Comments
 (0)