Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generator(cs): make union members extend a partial interface #345

Merged
merged 2 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading