Skip to content

Commit

Permalink
Only emit explicit enum values when there are discards
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed May 10, 2024
1 parent cf24b1d commit 32ec407
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public async Task should_generate_enums()
});

code.ShouldContain("public enum Foo : short");
code.ShouldContain("Default = 0,");
code.ShouldContain("Default,");
code.ShouldContain("Bar = -2,");
code.ShouldContain("Baz = Bar");
code.ShouldContain("[EnumAttr]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,9 @@ enum Counter
);

var enumDef = msg.Enums.ExpectedSingle();
enumDef.Members.Select(m => m.CSharpValue).ShouldEqual([

enumDef.UseInferredValues.ShouldBeTrue();
enumDef.Members.Select(m => m.InferredValueAsCSharpString).ShouldEqual([
"0",
"1",
"2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[EnumAttr]
public enum Foo : short
{
Default = 0,
Default,

[Description("Beer!")]
Bar = -2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
[System.CodeDom.Compiler.GeneratedCode("Abc.Zebus.MessageDsl", "1.2.3.4")]
internal enum Foo
{
Default = 0
Default
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[EnumAttr]
public enum Foo
{
Default = 0,
Default,
Bar = -2,
Baz = -1
Baz
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
[ProtoContract(EnumPassthru = true)]
public enum Foo
{
Default = 0
Default
}
88 changes: 33 additions & 55 deletions src/Abc.Zebus.MessageDsl/Analysis/AstProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,71 +89,49 @@ private static void ResolveTags(MessageDefinition message)

private static void ResolveEnumValues(EnumDefinition enumDef)
{
ResolveCSharpValues();
ResolveProtoValues();
var lastValue = (string?)null;
var lastValueAsNumber = (long?)null;
var lastValueIsParsed = false;
var lastOffset = 0L;

void ResolveCSharpValues()
{
var lastValue = (string?)null;
var lastValueAsNumber = (long?)null;
var lastValueIsParsed = false;
var lastOffset = 0L;
enumDef.UseInferredValues = enumDef.Members.Any(i => i.IsDiscarded);

foreach (var member in enumDef.Members)
foreach (var member in enumDef.Members)
{
if (!string.IsNullOrEmpty(member.Value))
{
if (!string.IsNullOrEmpty(member.Value))
{
lastValue = member.CSharpValue = member.Value;
lastValueAsNumber = null;
lastValueIsParsed = false;
lastOffset = 0;
}
else if (lastValue is null)
lastValue = member.InferredValueAsCSharpString = member.Value;
lastValueAsNumber = null;
lastValueIsParsed = false;
lastOffset = 0;
}
else if (lastValue is null)
{
lastValue = member.InferredValueAsCSharpString = "0";
lastValueAsNumber = 0;
lastValueIsParsed = true;
lastOffset = 0;
}
else
{
if (lastValueAsNumber is null && !lastValueIsParsed)
{
lastValue = member.CSharpValue = "0";
lastValueAsNumber = 0;
if (long.TryParse(lastValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var lastValueParsed))
lastValueAsNumber = lastValueParsed;
else if (lastValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase) && long.TryParse(lastValue.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out lastValueParsed))
lastValueAsNumber = lastValueParsed;

lastValueIsParsed = true;
lastOffset = 0;
}
else
{
if (lastValueAsNumber is null && !lastValueIsParsed)
{
if (long.TryParse(lastValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var lastValueParsed))
lastValueAsNumber = lastValueParsed;
else if (lastValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase) && long.TryParse(lastValue.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out lastValueParsed))
lastValueAsNumber = lastValueParsed;

lastValueIsParsed = true;
}

++lastOffset;
++lastOffset;

member.CSharpValue = lastValueAsNumber is { } lastBaseValue
? checked(lastBaseValue + lastOffset).ToString(CultureInfo.InvariantCulture)
: $"({lastValue}) + {lastOffset}";
}
member.InferredValueAsCSharpString = lastValueAsNumber is { } lastBaseValue
? checked(lastBaseValue + lastOffset).ToString(CultureInfo.InvariantCulture)
: $"({lastValue}) + {lastOffset}";
}
}

void ResolveProtoValues()
{
if (!enumDef.Options.Proto)
return;

if (enumDef.UnderlyingType.NetType != "int")
return;

var nextValue = (int?)0;

foreach (var member in enumDef.Members)
{
member.ProtoValue = string.IsNullOrEmpty(member.Value)
? nextValue
: enumDef.GetValidUnderlyingValue(member.Value) as int?;

nextValue = member.ProtoValue + 1;
}
member.InferredValueAsNumber = enumDef.GetValidUnderlyingValue(member.InferredValueAsCSharpString);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/Abc.Zebus.MessageDsl/Ast/EnumDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class EnumDefinition : AstNode, IMemberNode
public AttributeSet Attributes { get; } = new();
public IList<EnumMemberDefinition> Members { get; } = new List<EnumMemberDefinition>();

internal bool UseInferredValues { get; set; }

public MemberOptions Options
{
get => _options ??= new MemberOptions();
Expand Down
4 changes: 2 additions & 2 deletions src/Abc.Zebus.MessageDsl/Ast/EnumMemberDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public class EnumMemberDefinition : AstNode, INamedNode
public string? Value { get; set; }
public AttributeSet Attributes { get; } = new();

internal string? CSharpValue { get; set; }
internal int? ProtoValue { get; set; }
internal string? InferredValueAsCSharpString { get; set; }
internal object? InferredValueAsNumber { get; set; }
internal bool IsDiscarded { get; set; }

public override string ToString()
Expand Down
6 changes: 3 additions & 3 deletions src/Abc.Zebus.MessageDsl/Generator/CSharpGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ private void WriteEnum(EnumDefinition enumDef)

Writer.Write(Identifier(member.Name));

if (!string.IsNullOrEmpty(member.CSharpValue))
Writer.Write(" = {0}", member.CSharpValue);
else if (!string.IsNullOrEmpty(member.Value))
if (!string.IsNullOrEmpty(member.Value))
Writer.Write(" = {0}", member.Value);
else if (enumDef.UseInferredValues && !string.IsNullOrEmpty(member.InferredValueAsCSharpString))
Writer.Write(" = {0}", member.InferredValueAsCSharpString);

if (member != lastMember)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Abc.Zebus.MessageDsl/Generator/ProtoGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ private void WriteEnum(EnumDefinition enumDef)

using (Block())
{
if (enumDef.Members.Where(i => i.ProtoValue != null).GroupBy(i => i.ProtoValue.GetValueOrDefault()).Any(g => g.Count() > 1))
if (enumDef.Members.Where(i => i.InferredValueAsNumber != null).GroupBy(i => i.InferredValueAsNumber).Any(g => g.Count() > 1))
Writer.WriteLine("option allow_alias = true;");

foreach (var member in enumDef.Members)
Writer.WriteLine("{0} = {1};", member.Name, member.ProtoValue ?? (object)"TODO");
Writer.WriteLine("{0} = {1};", member.Name, member.InferredValueAsNumber ?? "TODO");
}
}

Expand Down

0 comments on commit 32ec407

Please sign in to comment.