From 38f45457861e5ae1ea0fc3bb06aeeb000072f5f9 Mon Sep 17 00:00:00 2001 From: andrew <1297077+andrewmd5@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:03:10 +0900 Subject: [PATCH 1/2] generator(cs): make union members extend a partial interface This should make extending logical of generated code easier --- .env | 4 +-- Core/Generators/CSharp/CSharpGenerator.cs | 39 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/.env b/.env index 0832629f..d5fda3d9 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -VERSION="3.0.13" +VERSION="3.0.14" MAJOR=3 MINOR=0 -PATCH=13 +PATCH=14 diff --git a/Core/Generators/CSharp/CSharpGenerator.cs b/Core/Generators/CSharp/CSharpGenerator.cs index f59e75b3..0143a3d9 100644 --- a/Core/Generators/CSharp/CSharpGenerator.cs +++ b/Core/Generators/CSharp/CSharpGenerator.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Encodings.Web; @@ -121,7 +122,25 @@ public override ValueTask Compile(BebopSchema schema, GeneratorConfig co _ => string.Empty }; builder.AppendLine(recordAttribute); - builder.AppendLine($"public partial class {definition.ClassName()} : {BebopRecord}, {IDecodable}<{definition.ClassName()}>, global::System.IEquatable<{definition.ClassName()}> {{"); + + var implementedInterfaces = new List + { + BebopRecord, + $"{IDecodable}<{definition.ClassName()}>", + $"global::System.IEquatable<{definition.ClassName()}>" + }; + + // Check if the definition's parent is a UnionDefinition + if (definition.Parent is UnionDefinition ud) + { + // Add the union interface to the list of implemented interfaces + implementedInterfaces.Add($"I{ud.ClassName()}Member"); + } + + // Join the interfaces with commas + var interfaceList = string.Join(", ", implementedInterfaces); + + builder.AppendLine($"public partial class {definition.ClassName()} : {interfaceList} {{"); builder.Indent(indentStep); if (fd is MessageDefinition) @@ -475,11 +494,15 @@ private void CompileUnionFamily(IndentedStringBuilder builder, UnionDefinition u var genericConstraints = string.Join(' ', ud.Branches.Select(b => $"where T{b.GenericIndex()}: {PrefixNamespace(b.Definition.ClassName())}")).Trim(); var structName = $"{ud.ClassName()}Union"; + var interfaceName = $"I{ud.ClassName()}Member"; + var nullCheck = LanguageVersion == CSharpNine ? "is null" : "== null"; var notNullCheck = LanguageVersion == CSharpNine ? "is not null" : "!= null"; var isCheck = LanguageVersion == CSharpNine ? "is" : "=="; + + void CompileValueProperty() { builder.AppendLine($"public {BebopRecord} Value => _discriminator switch {{").Indent(4); @@ -573,6 +596,18 @@ void CompileEquals(bool isClass) CompileHashCode(); builder.AppendLine("#endregion"); } + + void CompileUnionInterface() + { + builder.AppendLine("/// "); + builder.AppendLine($"/// Interface for members of the {ud.ClassName()} union"); + builder.AppendLine("/// "); + builder.AppendLine(GeneratedAttribute); + builder.AppendLine($"public partial interface ${interfaceName} {{").Indent(indentStep); + + builder.Dedent(indentStep).AppendLine("}").AppendLine(); + } + // Compiles a read-only struct which holds our union. void CompileUnionStruct() { @@ -722,7 +757,7 @@ void CompileUnionConcreteClass() builder.Dedent(indentStep).AppendLine("}").AppendLine(); } - + CompileUnionInterface(); CompileUnionBaseClass(); CompileUnionConcreteClass(); CompileUnionStruct(); From ccb3e2fd22692dcca1dd89a5168cf8e2031f7e56 Mon Sep 17 00:00:00 2001 From: andrew <1297077+andrewmd5@users.noreply.github.com> Date: Mon, 12 Aug 2024 18:23:35 +0900 Subject: [PATCH 2/2] fix(cs): generator lingering $ --- Core/Generators/CSharp/CSharpGenerator.cs | 8 ++++++-- Laboratory/C#/README.md | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/Generators/CSharp/CSharpGenerator.cs b/Core/Generators/CSharp/CSharpGenerator.cs index 0143a3d9..514c7a05 100644 --- a/Core/Generators/CSharp/CSharpGenerator.cs +++ b/Core/Generators/CSharp/CSharpGenerator.cs @@ -488,6 +488,8 @@ private string CompileDecodeUnion(UnionDefinition definition) /// private void CompileUnionFamily(IndentedStringBuilder builder, UnionDefinition ud) { + + var recordAttribute = "[global::Bebop.Attributes.BebopRecord(global::Bebop.Runtime.BebopKind.Union)]"; var genericPositionalArguments = string.Join(", ", ud.Branches.Select(b => $"T{b.GenericIndex()}")).Trim(); var genericTypeArguments = string.Join(", ", ud.Branches.Select(b => $"{PrefixNamespace(b.Definition.ClassName())}")).Trim(); @@ -497,6 +499,7 @@ private void CompileUnionFamily(IndentedStringBuilder builder, UnionDefinition u var interfaceName = $"I{ud.ClassName()}Member"; + var nullCheck = LanguageVersion == CSharpNine ? "is null" : "== null"; var notNullCheck = LanguageVersion == CSharpNine ? "is not null" : "!= null"; var isCheck = LanguageVersion == CSharpNine ? "is" : "=="; @@ -603,7 +606,7 @@ void CompileUnionInterface() builder.AppendLine($"/// Interface for members of the {ud.ClassName()} union"); builder.AppendLine("/// "); builder.AppendLine(GeneratedAttribute); - builder.AppendLine($"public partial interface ${interfaceName} {{").Indent(indentStep); + builder.AppendLine($"public partial interface {interfaceName} {{").Indent(indentStep); builder.Dedent(indentStep).AppendLine("}").AppendLine(); } @@ -757,10 +760,11 @@ void CompileUnionConcreteClass() builder.Dedent(indentStep).AppendLine("}").AppendLine(); } - CompileUnionInterface(); + CompileUnionBaseClass(); CompileUnionConcreteClass(); CompileUnionStruct(); + CompileUnionInterface(); } #endregion diff --git a/Laboratory/C#/README.md b/Laboratory/C#/README.md index 82299f7e..15d56bd7 100644 --- a/Laboratory/C#/README.md +++ b/Laboratory/C#/README.md @@ -1,6 +1,5 @@ # C# Bebop Laboratory To run the C# tests, from PowerShell: - - dotnet run --project ..\..\Compiler\ --cs ".\GeneratedTestCode\Output.g.cs" --namespace Bebop.Codegen --files (gci ..\Schemas\Valid\*.bop) + dotnet run --project ../../Compiler/ -i ../Schemas/Valid/*.bop build -g "cs:./GeneratedTestCode/Output.g.cs,namespace=Bebop.Codegen" dotnet test -nowarn:CS0618