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

Fix assignment tracking #166

Merged
merged 1 commit into from
Jun 15, 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
27 changes: 20 additions & 7 deletions src/generator/Generator.Deserialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ private static MethodDeclarationSyntax GenerateCustomDeserializeMethod(
<= 64 => "ulong",
_ => throw new InvalidOperationException("Too many members in type")
};
var (cases, locals, assignedMask) = InitCasesAndLocals();
string typeCreationExpr = GenerateTypeCreation(context, typeFqn, type, members);
var (cases, locals, requiredMask) = InitCasesAndLocals();
string typeCreationExpr = GenerateTypeCreation(context, typeFqn, type, members, requiredMask);

const string typeInfoLocalName = "_l_typeInfo";
const string indexLocalName = "_l_index_";
Expand All @@ -96,7 +96,7 @@ private static MethodDeclarationSyntax GenerateCustomDeserializeMethod(
static {{typeFqn}} Serde.IDeserialize<{{typeFqn}}>.Deserialize(IDeserializer deserializer)
{
{{locals}}
{{assignedVarType}} {{AssignedVarName}} = {{assignedMask}};
{{assignedVarType}} {{AssignedVarName}} = 0;

var {{typeInfoLocalName}} = {{type.Name}}SerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType({{typeInfoLocalName}});
Expand All @@ -119,10 +119,12 @@ private static MethodDeclarationSyntax GenerateCustomDeserializeMethod(
var casesBuilder = new StringBuilder();
var localsBuilder = new StringBuilder();
long assignedMaskValue = 0;
var skippedIndices = new List<int>();
for (int i = 0; i < members.Count; i++)
{
if (members[i].SkipDeserialize)
{
skippedIndices.Add(i);
continue;
}

Expand Down Expand Up @@ -160,7 +162,7 @@ private static MethodDeclarationSyntax GenerateCustomDeserializeMethod(
{AssignedVarName} |= (({assignedVarType})1) << {i};
break;
""");
if (m.IsNullable && !m.ThrowIfMissing)
if (!m.IsNullable || m.ThrowIfMissing)
{
assignedMaskValue |= 1L << i;
}
Expand All @@ -170,6 +172,12 @@ private static MethodDeclarationSyntax GenerateCustomDeserializeMethod(
throw new InvalidDeserializeValueException("Unexpected field or property name in type {type.Name}: '" + _l_errorName + "'");
"""
: "break;";
foreach (var i in skippedIndices)
{
casesBuilder.AppendLine($"""
case {i}:
""");
}
casesBuilder.AppendLine($"""
case Serde.IDeserializeType.IndexNotFound:
{unknownMemberBehavior}
Expand Down Expand Up @@ -452,7 +460,7 @@ private static MemberDeclarationSyntax GenerateCustomTypeVisitor(
_ => throw new InvalidOperationException("Too many members in type")
};
var (cases, locals, assignedMask) = InitCasesAndLocals();
string typeCreationExpr = GenerateTypeCreation(context, typeName, type, members);
string typeCreationExpr = GenerateTypeCreation(context, typeName, type, members, assignedMask);
var methodText = $$"""
{{typeName}} Serde.IDeserializeVisitor<{{typeName}}>.VisitDictionary<D>(ref D d)
{
Expand Down Expand Up @@ -529,7 +537,12 @@ private static MemberDeclarationSyntax GenerateCustomTypeVisitor(
/// must be a constructor signature as specified by the ConstructorSignature property
/// in the SerdeTypeOptions.
/// </summary>
private static string GenerateTypeCreation(GeneratorExecutionContext context, string typeName, ITypeSymbol type, List<DataMemberSymbol> members)
private static string GenerateTypeCreation(
GeneratorExecutionContext context,
string typeName,
ITypeSymbol type,
List<DataMemberSymbol> members,
string assignedMask)
{
var targetSignature = SymbolUtilities.GetTypeOptions(type).ConstructorSignature;
var targetTuple = targetSignature as INamedTypeSymbol;
Expand Down Expand Up @@ -602,7 +615,7 @@ private static string GenerateTypeCreation(GeneratorExecutionContext context, st
}
var mask = new string('1', members.Count);
return $$"""
if ({{AssignedVarName}} != 0b{{mask}})
if (({{AssignedVarName}} & {{assignedMask}}) != {{assignedMask}})
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ partial record AllInOne : Serde.IDeserialize<Serde.Test.AllInOne>
int[][] _l_nestedarr = default !;
System.Collections.Immutable.ImmutableArray<int> _l_intimm = default !;
Serde.Test.AllInOne.ColorEnum _l_color = default !;
ushort _r_assignedValid = 0b100000000000;
ushort _r_assignedValid = 0;
var _l_typeInfo = AllInOneSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand Down Expand Up @@ -105,7 +105,7 @@ partial record AllInOne : Serde.IDeserialize<Serde.Test.AllInOne>
}
}

if (_r_assignedValid != 0b1111111111111111)
if ((_r_assignedValid & 0b1111011111111111) != 0b1111011111111111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ static C Serde.IDeserialize<C>.Deserialize(IDeserializer deserializer)
ColorByte _l_colorbyte = default !;
ColorLong _l_colorlong = default !;
ColorULong _l_colorulong = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = CSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand Down Expand Up @@ -43,7 +43,7 @@ static C Serde.IDeserialize<C>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b1111)
if ((_r_assignedValid & 0b1111) != 0b1111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ partial record struct OptsWrap : Serde.IDeserialize<System.Runtime.InteropServic
int _l_dwtickcountdeadline = default !;
int _l_grfflags = default !;
int _l_grfmode = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = BIND_OPTSSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand Down Expand Up @@ -43,7 +43,7 @@ partial record struct OptsWrap : Serde.IDeserialize<System.Runtime.InteropServic
}
}

if (_r_assignedValid != 0b1111)
if ((_r_assignedValid & 0b1111) != 0b1111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial struct S : Serde.IDeserialize<S>
static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
{
System.Collections.Immutable.ImmutableArray<System.Runtime.InteropServices.ComTypes.BIND_OPTS> _l_opts = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = SSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -28,7 +28,7 @@ static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b1) != 0b1)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial class ArrayField : Serde.IDeserialize<ArrayField>
static ArrayField Serde.IDeserialize<ArrayField>.Deserialize(IDeserializer deserializer)
{
int[] _l_intarr = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = ArrayFieldSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -28,7 +28,7 @@ static ArrayField Serde.IDeserialize<ArrayField>.Deserialize(IDeserializer deser
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b1) != 0b1)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static SetToNull Serde.IDeserialize<SetToNull>.Deserialize(IDeserializer deseria
string _l_present = default !;
string? _l_missing = default !;
string? _l_throwmissing = default !;
byte _r_assignedValid = 0b10;
byte _r_assignedValid = 0;
var _l_typeInfo = SetToNullSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -38,7 +38,7 @@ static SetToNull Serde.IDeserialize<SetToNull>.Deserialize(IDeserializer deseria
}
}

if (_r_assignedValid != 0b111)
if ((_r_assignedValid & 0b101) != 0b101)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ partial record struct Wrap : Serde.IDeserialize<System.Runtime.InteropServices.C
int _l_dwtickcountdeadline = default !;
int _l_grfflags = default !;
int _l_grfmode = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = BIND_OPTSSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand Down Expand Up @@ -43,7 +43,7 @@ partial record struct Wrap : Serde.IDeserialize<System.Runtime.InteropServices.C
}
}

if (_r_assignedValid != 0b1111)
if ((_r_assignedValid & 0b1111) != 0b1111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
{
byte _l_red = default !;
byte _l_blue = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = RgbSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -33,7 +33,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b11)
if ((_r_assignedValid & 0b11) != 0b11)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
{
byte _l_red = default !;
byte _l_blue = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = RgbSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -26,14 +26,15 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
_l_blue = typeDeserialize.ReadValue<byte, ByteWrap>(_l_index_);
_r_assignedValid |= ((byte)1) << 2;
break;
case 1:
case Serde.IDeserializeType.IndexNotFound:
break;
default:
throw new InvalidOperationException("Unexpected index: " + _l_index_);
}
}

if (_r_assignedValid != 0b111)
if ((_r_assignedValid & 0b101) != 0b101)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
byte _l_red = default !;
byte _l_green = default !;
byte _l_blue = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = RgbSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -38,7 +38,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b111)
if ((_r_assignedValid & 0b111) != 0b111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ partial class D : Serde.IDeserialize<A.B.C.D>
static A.B.C.D Serde.IDeserialize<A.B.C.D>.Deserialize(IDeserializer deserializer)
{
int _l_field = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = DSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -34,7 +34,7 @@ partial class D : Serde.IDeserialize<A.B.C.D>
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b1) != 0b1)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial struct S : Serde.IDeserialize<S>
static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
{
string? _l_f = default !;
byte _r_assignedValid = 0b1;
byte _r_assignedValid = 0;
var _l_typeInfo = SSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -28,7 +28,7 @@ static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b0) != 0b0)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
byte _l_red = default !;
byte _l_green = default !;
byte _l_blue = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = RgbSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -38,7 +38,7 @@ static Rgb Serde.IDeserialize<Rgb>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b111)
if ((_r_assignedValid & 0b111) != 0b111)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial struct S : Serde.IDeserialize<S>
static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
{
ColorEnum _l_e = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = SSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -28,7 +28,7 @@ static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b1) != 0b1)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial struct S2 : Serde.IDeserialize<S2>
static S2 Serde.IDeserialize<S2>.Deserialize(IDeserializer deserializer)
{
ColorEnum _l_e = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = S2SerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -28,7 +28,7 @@ static S2 Serde.IDeserialize<S2>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b1)
if ((_r_assignedValid & 0b1) != 0b1)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
{
int _l_one = default !;
int _l_twoword = default !;
byte _r_assignedValid = 0b0;
byte _r_assignedValid = 0;
var _l_typeInfo = SSerdeTypeInfo.TypeInfo;
var typeDeserialize = deserializer.DeserializeType(_l_typeInfo);
int _l_index_;
Expand All @@ -33,7 +33,7 @@ static S Serde.IDeserialize<S>.Deserialize(IDeserializer deserializer)
}
}

if (_r_assignedValid != 0b11)
if ((_r_assignedValid & 0b11) != 0b11)
{
throw new Serde.InvalidDeserializeValueException("Not all members were assigned");
}
Expand Down
Loading
Loading