Skip to content

Commit

Permalink
Merge pull request #345 from betwixt-labs/cs-union-interface
Browse files Browse the repository at this point in the history
generator(cs): make union members extend a partial interface
  • Loading branch information
andrewmd5 authored Aug 12, 2024
2 parents 1a78cd6 + ccb3e2f commit 2108a61
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION="3.0.13"
VERSION="3.0.14"
MAJOR=3
MINOR=0
PATCH=13
PATCH=14
41 changes: 40 additions & 1 deletion Core/Generators/CSharp/CSharpGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
Expand Down Expand Up @@ -121,7 +122,25 @@ public override ValueTask<string> 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<string>
{
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)
Expand Down Expand Up @@ -469,17 +488,24 @@ private string CompileDecodeUnion(UnionDefinition definition)
/// </summary>
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();
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);
Expand Down Expand Up @@ -573,6 +599,18 @@ void CompileEquals(bool isClass)
CompileHashCode();
builder.AppendLine("#endregion");
}

void CompileUnionInterface()
{
builder.AppendLine("/// <summary>");
builder.AppendLine($"/// Interface for members of the {ud.ClassName()} union");
builder.AppendLine("/// </summary>");
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()
{
Expand Down Expand Up @@ -726,6 +764,7 @@ void CompileUnionConcreteClass()
CompileUnionBaseClass();
CompileUnionConcreteClass();
CompileUnionStruct();
CompileUnionInterface();
}

#endregion
Expand Down
3 changes: 1 addition & 2 deletions Laboratory/C#/README.md
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2108a61

Please sign in to comment.