From dfc39e3964780a58cb3a08d1cf912a00a7099f3b Mon Sep 17 00:00:00 2001 From: GGG Date: Wed, 31 Jan 2024 23:54:20 -0300 Subject: [PATCH] Migrate the green tree root to the scriban template system. --- .../Sample.Internal.GreenRoot.g.cs | 102 +++++++++++ .../Sample.Internal.g.cs | 90 ---------- Tsu.Trees.RedGreen/src/GreenTreeGenerator.cs | 164 ------------------ .../src/Templates/Internal/GreenRoot.sbn-cs | 118 +++++++++++++ 4 files changed, 220 insertions(+), 254 deletions(-) create mode 100644 Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.GreenRoot.g.cs create mode 100644 Tsu.Trees.RedGreen/src/Templates/Internal/GreenRoot.sbn-cs diff --git a/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.GreenRoot.g.cs b/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.GreenRoot.g.cs new file mode 100644 index 0000000..2d24a1e --- /dev/null +++ b/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.GreenRoot.g.cs @@ -0,0 +1,102 @@ +// + +#nullable enable + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Tsu.Trees.RedGreen.Sample.Internal +{ + abstract partial class GreenNode + { + private readonly global::Tsu.Trees.RedGreen.Sample.SampleKind _kind; + private byte _slotCount; + + protected GreenNode(global::Tsu.Trees.RedGreen.Sample.SampleKind kind) + { + this._kind = kind; + } + + public global::Tsu.Trees.RedGreen.Sample.SampleKind Kind => this._kind; + + public int SlotCount + { + get + { + int count = this._slotCount; + if (count == byte.MaxValue) + count = this.GetSlotCount(); + return count; + } + protected set => _slotCount = (byte) value; + } + + public abstract global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode? GetSlot(int index); + + public global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode GetRequiredSlot(int index) + { + var node = this.GetSlot(index); + Debug.Assert(node != null); + return node!; + } + + protected virtual int GetSlotCount() => _slotCount; + + public global::System.Collections.Generic.IEnumerable ChildNodes() + { + var count = this.SlotCount; + for (var index = 0; index < count; index++) + yield return this.GetRequiredSlot(index); + } + + public global::System.Collections.Generic.IEnumerable EnumerateDescendants() + { + var stack = new Stack(24); + stack.Push(this); + + while (stack.Count > 0) + { + var current = stack.Pop(); + + yield return current; + + foreach (var child in current.ChildNodes().Reverse()) + { + stack.Push(child); + } + } + } + + public virtual bool IsEquivalentTo([NotNullWhen(true)] global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode? other) + { + if (this == other) return true; + if (other == null) return false; + if (this.Kind != other.Kind) return false; + + var n = this.SlotCount; + if (n != other.SlotCount) return false; + + for (int i = 0; i < n; i++) + { + var thisChild = this.GetSlot(i); + var otherChild = other.GetSlot(i); + if (thisChild != null && otherChild != null && !thisChild.IsEquivalentTo(otherChild)) + { + return false; + } + } + + return true; + } + + public global::Tsu.Trees.RedGreen.Sample.SampleNode CreateRed() => this.CreateRed(null); + public abstract global::Tsu.Trees.RedGreen.Sample.SampleNode CreateRed(global::Tsu.Trees.RedGreen.Sample.SampleNode? parent); + + public abstract void Accept(global::Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor); + public abstract TResult? Accept(global::Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor); + public abstract TResult? Accept(global::Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1); + public abstract TResult? Accept(global::Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1, T2 arg2); + public abstract TResult? Accept(global::Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1, T2 arg2, T3 arg3); + } +} \ No newline at end of file diff --git a/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.g.cs b/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.g.cs index 8a3556e..59ada0d 100644 --- a/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.g.cs +++ b/Tsu.Trees.RedGreen/sample/Generated/Tsu.Trees.RedGreen/Tsu.Trees.RedGreen.SourceGenerator.Generator/Sample.Internal.g.cs @@ -8,96 +8,6 @@ namespace Tsu.Trees.RedGreen.Sample.Internal { - abstract partial class GreenNode - { - private readonly global::Tsu.Trees.RedGreen.Sample.SampleKind _kind; - private byte _slotCount; - - protected GreenNode(global::Tsu.Trees.RedGreen.Sample.SampleKind kind) - { - this._kind = kind; - } - - public global::Tsu.Trees.RedGreen.Sample.SampleKind Kind => this._kind; - - public int SlotCount - { - get - { - int count = this._slotCount; - if (count == byte.MaxValue) - count = this.GetSlotCount(); - return count; - } - protected set => _slotCount = (byte) value; - } - - public abstract global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode? GetSlot(int index); - - public global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode GetRequiredSlot(int index) - { - var node = this.GetSlot(index); - Debug.Assert(node != null); - return node!; - } - - protected virtual int GetSlotCount() => _slotCount; - - public global::System.Collections.Generic.IEnumerable ChildNodes() - { - var count = this.SlotCount; - for (var index = 0; index < count; index++) - yield return this.GetRequiredSlot(index); - } - - public global::System.Collections.Generic.IEnumerable EnumerateDescendants() - { - var stack = new Stack(24); - stack.Push(this); - - while (stack.Count > 0) - { - var current = stack.Pop(); - - yield return current; - - foreach (var child in current.ChildNodes().Reverse()) - { - stack.Push(child); - } - } - } - - public virtual bool IsEquivalentTo([NotNullWhen(true)] global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode? other) - { - if (this == other) return true; - if (other == null) return false; - if (this.Kind != other.Kind) return false; - - var n = this.SlotCount; - if (n != other.SlotCount) return false; - - for (int i = 0; i < n; i++) - { - var thisChild = this.GetSlot(i); - var otherChild = other.GetSlot(i); - if (thisChild != null && otherChild != null && !thisChild.IsEquivalentTo(otherChild)) - { - return false; - } - } - - return true; - } - - public global::Tsu.Trees.RedGreen.Sample.SampleNode CreateRed() => this.CreateRed(null); - public abstract global::Tsu.Trees.RedGreen.Sample.SampleNode CreateRed(global::Tsu.Trees.RedGreen.Sample.SampleNode? parent); - public abstract void Accept(Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor); - public abstract TResult? Accept(Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor); - public abstract TResult? Accept(Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1); - public abstract TResult? Accept(Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1, T2 arg2); - public abstract TResult? Accept(Tsu.Trees.RedGreen.Sample.Internal.SampleVisitor visitor, T1 arg1, T2 arg2, T3 arg3); - } partial class SemicolonTokenSample : global::Tsu.Trees.RedGreen.Sample.Internal.GreenNode { diff --git a/Tsu.Trees.RedGreen/src/GreenTreeGenerator.cs b/Tsu.Trees.RedGreen/src/GreenTreeGenerator.cs index c856a15..04fb071 100644 --- a/Tsu.Trees.RedGreen/src/GreenTreeGenerator.cs +++ b/Tsu.Trees.RedGreen/src/GreenTreeGenerator.cs @@ -53,8 +53,6 @@ public static void RegisterGreenOutput(this IncrementalGeneratorInitializationCo writer.WriteLine('{'); writer.Indent++; - writer.WriteGreenRoot(tree, tree.Root); - var queue = new Queue(); foreach (var node in tree.Root.Descendants) queue.Enqueue(node); @@ -98,168 +96,6 @@ public static void RegisterGreenOutput(this IncrementalGeneratorInitializationCo }); } - private static void WriteGreenRoot(this IndentedTextWriter writer, Tree tree, Node root) - { - writer.WriteLine("abstract partial class {0}", root.TypeSymbol.Name); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("private readonly {0} _kind;", tree.KindEnum.ToCSharpString()); - writer.WriteLine("private byte _slotCount;"); - writer.WriteLineNoTabs(""); - - writer.WriteGreenConstructor(root); - writer.WriteLineNoTabs(""); - - foreach (var component in root.Components) - { - writer.WriteLine("public {0} {1} => this.{2};", component.Type.ToCSharpString(), component.PropertyName, component.FieldName); - } - writer.WriteLineNoTabs(""); - - #region int SlotCount - writer.WriteLine("public int SlotCount"); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("get"); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("int count = this._slotCount;"); - writer.WriteLine("if (count == byte.MaxValue)"); - writer.Indent++; - writer.WriteLine("count = this.GetSlotCount();"); - writer.Indent--; - writer.WriteLine("return count;"); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLine("protected set => _slotCount = (byte) value;"); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - #endregion int SlotCount - - writer.WriteLine("public abstract {0}? GetSlot(int index);", tree.GreenBase.ToCSharpString()); - writer.WriteLineNoTabs(""); - - #region TGreenRoot GetRequiredSlot(int index) - writer.WriteLine("public {0} GetRequiredSlot(int index)", tree.GreenBase.ToCSharpString()); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("var node = this.GetSlot(index);"); - writer.WriteLine("Debug.Assert(node != null);"); - writer.WriteLine("return node!;"); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - #endregion TGreenRoot GetRequiredSlot(int index) - - writer.WriteLine("protected virtual int GetSlotCount() => _slotCount;"); - writer.WriteLineNoTabs(""); - - #region IEnumerable ChildNodes() - writer.WriteLine("public global::System.Collections.Generic.IEnumerable<{0}> ChildNodes()", tree.GreenBase.ToCSharpString()); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("var count = this.SlotCount;"); - writer.WriteLine("for (var index = 0; index < count; index++)"); - writer.Indent++; - writer.WriteLine("yield return this.GetRequiredSlot(index);"); - writer.Indent--; - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - #endregion IEnumerable ChildNodes() - - #region IEnumerable EnumerateDescendants() - writer.WriteLine("public global::System.Collections.Generic.IEnumerable<{0}> EnumerateDescendants()", tree.GreenBase.ToCSharpString()); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("var stack = new Stack<{0}>(24);", tree.GreenBase.ToCSharpString()); - writer.WriteLine("stack.Push(this);"); - writer.WriteLineNoTabs(""); - writer.WriteLine("while (stack.Count > 0)"); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("var current = stack.Pop();"); - writer.WriteLineNoTabs(""); - writer.WriteLine("yield return current;"); - writer.WriteLineNoTabs(""); - writer.WriteLine("foreach (var child in current.ChildNodes().Reverse())"); - writer.WriteLine('{'); - writer.Indent++; - writer.WriteLine("stack.Push(child);"); - writer.Indent--; - writer.WriteLine('}'); - } - writer.Indent--; - writer.WriteLine('}'); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - #endregion IEnumerable EnumerateDescendants() - - #region bool IsEquivalentTo(TGreenRoot? other) - writer.WriteLine("public virtual bool IsEquivalentTo([NotNullWhen(true)] {0}? other)", tree.GreenBase.ToCSharpString()); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("if (this == other) return true;"); - writer.WriteLine("if (other == null) return false;"); - foreach (var extraData in root.ExtraData) - { - writer.WriteLine("if (this.{0} != other.{0}) return false;", extraData.PropertyName); - } - writer.WriteLineNoTabs(""); - writer.WriteLine("var n = this.SlotCount;"); - writer.WriteLine("if (n != other.SlotCount) return false;"); - writer.WriteLineNoTabs(""); - writer.WriteLine("for (int i = 0; i < n; i++)"); - writer.WriteLine('{'); - writer.Indent++; - { - writer.WriteLine("var thisChild = this.GetSlot(i);"); - writer.WriteLine("var otherChild = other.GetSlot(i);"); - writer.WriteLine("if (thisChild != null && otherChild != null && !thisChild.IsEquivalentTo(otherChild))"); - writer.WriteLine('{'); - writer.Indent++; - writer.WriteLine("return false;"); - writer.Indent--; - writer.WriteLine('}'); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - writer.WriteLine("return true;"); - } - writer.Indent--; - writer.WriteLine('}'); - writer.WriteLineNoTabs(""); - #endregion bool IsEquivalentTo(TGreenRoot? other) - - #region TRedRoot CreateRed() - writer.WriteLine("public {0} CreateRed() => this.CreateRed(null);", tree.RedBase.ToCSharpString()); - writer.WriteLine("public abstract {0} CreateRed({0}? parent);", tree.RedBase.ToCSharpString()); - #endregion TRedRoot CreateRed() - - #region T Accept(Visitor visitor) - writer.WriteAbstractAcceptMethods(tree, tree.GreenBase.ContainingNamespace); - #endregion T Accept(Visitor visitor) - } - writer.Indent--; - writer.WriteLine('}'); - } - private static void WriteGreenNode(this IndentedTextWriter writer, Tree tree, Node node) { if (node.TypeSymbol.IsAbstract) diff --git a/Tsu.Trees.RedGreen/src/Templates/Internal/GreenRoot.sbn-cs b/Tsu.Trees.RedGreen/src/Templates/Internal/GreenRoot.sbn-cs new file mode 100644 index 0000000..74b4d49 --- /dev/null +++ b/Tsu.Trees.RedGreen/src/Templates/Internal/GreenRoot.sbn-cs @@ -0,0 +1,118 @@ +// + +#nullable enable + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace {{ green_base.namespace_no_global }} +{ + abstract partial class {{ green_base.name }} + { +{{~ for component in root.components ~}} + private readonly {{ component.type.csharp }} {{ component.field_name }}; +{{~ end ~}} + private byte _slotCount; + + protected {{ green_base.name }}({{- for component in root.components -}} + {{ if !for.first }}, {{ end }}{{ component.type.csharp }} {{ component.parameter_name }} +{{- end -}}) + { +{{~ for component in root.components ~}} + this.{{ component.field_name }} = {{ component.parameter_name }}; +{{~ end ~}} + } + +{{ for component in root.components ~}} + public {{ component.type.csharp }} {{ component.property_name }} => this.{{ component.field_name }}; +{{~ end ~}} + + public int SlotCount + { + get + { + int count = this._slotCount; + if (count == byte.MaxValue) + count = this.GetSlotCount(); + return count; + } + protected set => _slotCount = (byte) value; + } + + public abstract {{ green_base.csharp_no_nullable }}? GetSlot(int index); + + public {{ green_base.csharp_no_nullable }} GetRequiredSlot(int index) + { + var node = this.GetSlot(index); + Debug.Assert(node != null); + return node!; + } + + protected virtual int GetSlotCount() => _slotCount; + + public global::System.Collections.Generic.IEnumerable<{{ green_base.csharp_no_nullable }}> ChildNodes() + { + var count = this.SlotCount; + for (var index = 0; index < count; index++) + yield return this.GetRequiredSlot(index); + } + + public global::System.Collections.Generic.IEnumerable<{{ green_base.csharp_no_nullable }}> EnumerateDescendants() + { + var stack = new Stack<{{ green_base.csharp_no_nullable }}>(24); + stack.Push(this); + + while (stack.Count > 0) + { + var current = stack.Pop(); + + yield return current; + + foreach (var child in current.ChildNodes().Reverse()) + { + stack.Push(child); + } + } + } + + public virtual bool IsEquivalentTo([NotNullWhen(true)] {{ green_base.csharp_no_nullable }}? other) + { + if (this == other) return true; + if (other == null) return false; +{{~ for component in root.components ~}} + if (this.{{ component.property_name }} != other.{{ component.property_name }}) return false; +{{~ end ~}} + + var n = this.SlotCount; + if (n != other.SlotCount) return false; + + for (int i = 0; i < n; i++) + { + var thisChild = this.GetSlot(i); + var otherChild = other.GetSlot(i); + if (thisChild != null && otherChild != null && !thisChild.IsEquivalentTo(otherChild)) + { + return false; + } + } + + return true; + } + + public {{ red_base.csharp_no_nullable }} CreateRed() => this.CreateRed(null); + public abstract {{ red_base.csharp_no_nullable }} CreateRed({{ red_base.csharp_no_nullable }}? parent); + +{{~ if create_visitors || create_walker ~}} + public abstract void Accept({{ green_base.namespace }}.{{ suffix }}Visitor visitor); +{{~ end ~}} +{{~ if create_visitors || create_rewriter ~}} + public abstract TResult? Accept({{ green_base.namespace }}.{{ suffix }}Visitor visitor); +{{~ end ~}} +{{~ if create_visitors ~}} + public abstract TResult? Accept({{ green_base.namespace }}.{{ suffix }}Visitor visitor, T1 arg1); + public abstract TResult? Accept({{ green_base.namespace }}.{{ suffix }}Visitor visitor, T1 arg1, T2 arg2); + public abstract TResult? Accept({{ green_base.namespace }}.{{ suffix }}Visitor visitor, T1 arg1, T2 arg2, T3 arg3); +{{~ end ~}} + } +} \ No newline at end of file