diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Union/Parts/UnionMatchPart.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/Parts/UnionMatchPart.cs new file mode 100644 index 0000000..6e64654 --- /dev/null +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/Parts/UnionMatchPart.cs @@ -0,0 +1,51 @@ +using System.CodeDom.Compiler; + +namespace Appegy.Union.Generator; + +public class UnionMatchPart : GeneratorPart +{ + public override void Generate(IndentedTextWriter codeWriter, UnionAttributePartInput input) + { + var types = input.Types; + + codeWriter.WriteLine("public void Match("); + + using (codeWriter.IndentScope()) + { + for (var i = 0; i < types.Count; i++) + { + var type = types[i]; + codeWriter.Write("global::System.Action<"); + codeWriter.Write(type.FullName); + codeWriter.Write('>'); + codeWriter.Write(' '); + codeWriter.Write(type.ParamName); + codeWriter.WriteLine(i != types.Count - 1 ? "," : ")"); + } + } + + codeWriter.WriteLine("{"); + using (codeWriter.IndentScope()) + { + codeWriter.WriteLine("switch (Type)"); + codeWriter.WriteLine("{"); + using (codeWriter.IndentScope()) + { + foreach (var type in types) + { + codeWriter.Write("case Kind."); + codeWriter.Write(type.Name); + codeWriter.Write(": "); + codeWriter.Write(type.ParamName); + codeWriter.Write("("); + codeWriter.Write(type.FieldName); + codeWriter.Write("); break;"); + codeWriter.WriteLine(); + } + codeWriter.WriteLine("default: throw new global::System.InvalidOperationException($\"Unknown type of union: {_type}\");"); + } + codeWriter.WriteLine("}"); + } + codeWriter.WriteLine("}"); + } +} \ No newline at end of file diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributeGenerator.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributeGenerator.cs index f50fc7c..509ebee 100644 --- a/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributeGenerator.cs +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributeGenerator.cs @@ -25,6 +25,7 @@ public class UnionAttributeGenerator : IIncrementalGenerator new UnionFieldsPart(), new UnionPropertiesPart(), new UnionConstructorsPart(), + new UnionMatchPart(), new UnionToStringPart(), new UnionGetHashCodePart(), new UnionEqualsPart(), diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributePartInput.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributePartInput.cs index b7f3681..e614190 100644 --- a/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributePartInput.cs +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Union/UnionAttributePartInput.cs @@ -12,4 +12,5 @@ public readonly struct UnionTypeInfo(INamedTypeSymbol symbol) public readonly INamedTypeSymbol Symbol = symbol; public readonly string FullName = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); public readonly string FieldName = symbol.GetFieldName(); + public readonly string ParamName = symbol.GetParamName(); } \ No newline at end of file diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/CodeWriterExtensions.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/CodeWriterExtensions.cs index 8e5bf13..8308df6 100644 --- a/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/CodeWriterExtensions.cs +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/CodeWriterExtensions.cs @@ -1,4 +1,5 @@ -using System.CodeDom.Compiler; +using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -23,6 +24,11 @@ public static void AppendParts(this IndentedTextWriter codeWriter, IReadOnlyL } } + public static IDisposable IndentScope(this IndentedTextWriter codeWriter) + { + return new DisposableIndent(codeWriter); + } + public static void WriteFieldName(this IndentedTextWriter codeWriter, ISymbol symbol) { var name = symbol.Name; diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/DisposableIndent.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/DisposableIndent.cs new file mode 100644 index 0000000..f032b1d --- /dev/null +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/DisposableIndent.cs @@ -0,0 +1,24 @@ +using System; +using System.CodeDom.Compiler; + +namespace Appegy.Union.Generator; + +public struct DisposableIndent : IDisposable +{ + private readonly IndentedTextWriter _codeWriter; + private bool _isDisposed; + + public DisposableIndent(IndentedTextWriter codeWriter) + { + _isDisposed = false; + _codeWriter = codeWriter; + _codeWriter.Indent++; + } + + public void Dispose() + { + if (_isDisposed) return; + _codeWriter.Indent--; + _isDisposed = true; + } +} \ No newline at end of file diff --git a/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/SyntaxTreeExtensions.cs b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/SyntaxTreeExtensions.cs index ce45943..5089380 100644 --- a/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/SyntaxTreeExtensions.cs +++ b/Appegy.Union.Generator~/Appegy.Union.Generator/Utilities/SyntaxTreeExtensions.cs @@ -28,13 +28,23 @@ public static ImmutableList GetTypesFromConstructor(this Attri } public static string GetFieldName(this INamedTypeSymbol symbol) + { + var name = symbol.Name; + var param = symbol.GetParamName(); + + if (string.IsNullOrEmpty(param)) return string.Empty; + + return "_" + param; + } + + public static string GetParamName(this INamedTypeSymbol symbol) { var name = symbol.Name; if (string.IsNullOrEmpty(name)) return string.Empty; return name.Length > 1 - ? "_" + char.ToLower(name[0]) + name.Substring(1) - : "_" + char.ToLower(name[0]); + ? char.ToLower(name[0]) + name.Substring(1) + : name.ToLower(); } } \ No newline at end of file diff --git a/Runtime/Appegy.Union.Generator.dll b/Runtime/Appegy.Union.Generator.dll index 7ccddaf..225a4ac 100644 --- a/Runtime/Appegy.Union.Generator.dll +++ b/Runtime/Appegy.Union.Generator.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dfb6f14913fc4a5224b91604329dc26ddb6aceda20efd5c0f6b1d3cc263316c6 -size 55296 +oid sha256:f2005c0ac57cd3ba43df4e6216d5d0eef2f777890f2db89bf942dd7d9737d7bb +size 56832 diff --git a/Runtime/Appegy.Union.Generator.pdb b/Runtime/Appegy.Union.Generator.pdb index aeedcdf..686aa93 100644 Binary files a/Runtime/Appegy.Union.Generator.pdb and b/Runtime/Appegy.Union.Generator.pdb differ