mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-12 18:57:51 -04:00
Fix Equals and GetHashCode for types containing Lists and Arrays in C# (#2710)
This commit is contained in:
@@ -6,35 +6,290 @@ using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Utils;
|
||||
|
||||
public record MemberDeclaration(
|
||||
string Name,
|
||||
string Type,
|
||||
string TypeInfo,
|
||||
bool IsNullableReferenceType
|
||||
)
|
||||
/// <summary>
|
||||
/// The type of a member of one of the types we are generating code for.
|
||||
///
|
||||
/// Knows how to serialize and deserialize the member.
|
||||
///
|
||||
/// Also knows how to compare the member for equality and compute its hash code.
|
||||
/// We can't just use Equals and GetHashCode for this, because they implement reference
|
||||
/// equality for arrays and Lists.
|
||||
///
|
||||
/// (It would be nice to be able to dynamically build EqualityComparers at runtime
|
||||
/// to do these operations, but this seems to require either (A) reflective calls
|
||||
/// or (B) instantiating generics at runtime. These are (A) slow and (B) very slow
|
||||
/// when compiling under IL2CPP. Instead, we just inline the needed loops to compute
|
||||
/// the relevant values. This is very simple for IL2CPP to optimize.
|
||||
/// That's good, since Equals and GetHashCode for BSATN types are used in hot parts
|
||||
/// of the codebase.)
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the type</param>
|
||||
/// <param name="BSATNName">The name of the BSATN struct for the type.</param>
|
||||
public abstract record TypeUse(string Name, string BSATNName)
|
||||
{
|
||||
public MemberDeclaration(ISymbol member, ITypeSymbol type, DiagReporter diag)
|
||||
: this(member.Name, SymbolToName(type), "", Utils.IsNullableReferenceType(type))
|
||||
/// <summary>
|
||||
/// Parse a type use for a member.
|
||||
/// </summary>
|
||||
/// <param name="member">The member name. Only used for reporting parsing failures.</param>
|
||||
/// <param name="typeSymbol">The type we are using. May not be the type of the member: this method is called recursively.</param>
|
||||
/// <param name="diag"></param>
|
||||
/// <returns></returns>
|
||||
public static TypeUse Parse(ISymbol member, ITypeSymbol typeSymbol, DiagReporter diag)
|
||||
{
|
||||
var type = SymbolToName(typeSymbol);
|
||||
string typeInfo;
|
||||
|
||||
try
|
||||
{
|
||||
TypeInfo = GetTypeInfo(type);
|
||||
typeInfo = GetTypeInfo(typeSymbol);
|
||||
}
|
||||
catch (UnresolvedTypeException)
|
||||
{
|
||||
// If it's an unresolved type, this error will have been already highlighted by .NET itself, no need to add noise.
|
||||
// Just add some dummy type to avoid further errors.
|
||||
// Note that we just use `object` here because emitting the unresolved type's name again would produce more of said noise.
|
||||
TypeInfo = "SpacetimeDB.BSATN.Unsupported<object>";
|
||||
typeInfo = "SpacetimeDB.BSATN.Unsupported<object>";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
diag.Report(ErrorDescriptor.UnsupportedType, (member, type, e));
|
||||
diag.Report(ErrorDescriptor.UnsupportedType, (member, typeSymbol, e));
|
||||
// dummy BSATN implementation to produce fewer noisy errors
|
||||
TypeInfo = $"SpacetimeDB.BSATN.Unsupported<{Type}>";
|
||||
typeInfo = $"SpacetimeDB.BSATN.Unsupported<{type}>";
|
||||
}
|
||||
|
||||
return typeSymbol switch
|
||||
{
|
||||
ITypeParameterSymbol => new ReferenceUse(type, typeInfo),
|
||||
IArrayTypeSymbol { ElementType: var elementType } => new ArrayUse(
|
||||
type,
|
||||
typeInfo,
|
||||
Parse(member, elementType, diag)
|
||||
),
|
||||
INamedTypeSymbol named => named.OriginalDefinition.ToString() switch
|
||||
{
|
||||
"System.Collections.Generic.List<T>" => new ListUse(
|
||||
type,
|
||||
typeInfo,
|
||||
Parse(member, named.TypeArguments[0], diag)
|
||||
),
|
||||
_ => named.IsValueType
|
||||
? new ValueUse(type, typeInfo)
|
||||
: new ReferenceUse(type, typeInfo),
|
||||
},
|
||||
_ => throw new InvalidOperationException($"Unsupported type {type}"),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a statement that declares outVar and assigns (inVar1 logically-equals inVar2) to it.
|
||||
/// logically-equals:
|
||||
/// - recursively compares lists and arrays by sequence equality.
|
||||
/// - is the same as .Equals( ) for everything else.
|
||||
///
|
||||
/// This can't be an expression because some types need to use loops.
|
||||
/// </summary>
|
||||
/// <param name="inVar1">A variable of type `Type` that we want to hash.</param>
|
||||
/// <param name="inVar2">A variable of type `Type` that we want to hash.</param>
|
||||
/// <param name="outVar">The variable to declare and store the `Equals` bool in.</param>
|
||||
/// <param name="level">Iteration level counter. You don't need to set this.</param>
|
||||
/// <returns></returns>
|
||||
public abstract string EqualsStatement(
|
||||
string inVar1,
|
||||
string inVar2,
|
||||
string outVar,
|
||||
int level = 0
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get a statement that declares outVar and assigns the hash code of inVar to it.
|
||||
///
|
||||
/// This can't be an expression because some types need to use loops.
|
||||
/// </summary>
|
||||
/// <param name="inVar">A variable of type `Type` that we want to hash.</param>
|
||||
/// <param name="outVar">The variable to declare and store the hash in.</param>
|
||||
/// <param name="level">Iteration level counter. You don't need to set this.</param>
|
||||
/// <returns></returns>
|
||||
public abstract string GetHashCodeStatement(string inVar, string outVar, int level = 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A use of a value type.
|
||||
/// </summary>
|
||||
/// <param name="Type"></param>
|
||||
/// <param name="TypeInfo"></param>
|
||||
public record ValueUse(string Type, string TypeInfo) : TypeUse(Type, TypeInfo)
|
||||
{
|
||||
public override string EqualsStatement(
|
||||
string inVar1,
|
||||
string inVar2,
|
||||
string outVar,
|
||||
int level = 0
|
||||
) => $"var {outVar} = {inVar1}.Equals({inVar2});";
|
||||
|
||||
public override string GetHashCodeStatement(string inVar, string outVar, int level = 0) =>
|
||||
$"var {outVar} = {inVar}.GetHashCode();";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A use of a reference type.
|
||||
/// </summary>
|
||||
/// <param name="Type"></param>
|
||||
/// <param name="TypeInfo"></param>
|
||||
public record ReferenceUse(string Type, string TypeInfo) : TypeUse(Type, TypeInfo)
|
||||
{
|
||||
public override string EqualsStatement(
|
||||
string inVar1,
|
||||
string inVar2,
|
||||
string outVar,
|
||||
int level = 0
|
||||
) => $"var {outVar} = {inVar1} == null ? {inVar2} == null : {inVar1}.Equals({inVar2});";
|
||||
|
||||
public override string GetHashCodeStatement(string inVar, string outVar, int level = 0) =>
|
||||
$"var {outVar} = {inVar} == null ? 0 : {inVar}.GetHashCode();";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A use of an array type.
|
||||
/// </summary>
|
||||
/// <param name="Type"></param>
|
||||
/// <param name="TypeInfo"></param>
|
||||
/// <param name="ElementType"></param>
|
||||
public record ArrayUse(string Type, string TypeInfo, TypeUse ElementType) : TypeUse(Type, TypeInfo)
|
||||
{
|
||||
public override string EqualsStatement(
|
||||
string inVar1,
|
||||
string inVar2,
|
||||
string outVar,
|
||||
int level = 0
|
||||
)
|
||||
{
|
||||
var iterVar = $"___i{level}";
|
||||
var innerOutVar = $"___out{level + 1}";
|
||||
|
||||
return $$"""
|
||||
var {{outVar}} = true;
|
||||
if ({{inVar1}} == null || {{inVar2}} == null) {
|
||||
{{outVar}} = {{inVar1}} == {{inVar2}};
|
||||
} else if ({{inVar1}}.Length != {{inVar2}}.Length) {
|
||||
{{outVar}} = false;
|
||||
} else {
|
||||
for (int {{iterVar}} = 0; {{iterVar}} < {{inVar1}}.Length; {{iterVar}}++) {
|
||||
{{ElementType.EqualsStatement(
|
||||
$"{inVar1}[{iterVar}]",
|
||||
$"{inVar2}[{iterVar}]",
|
||||
innerOutVar,
|
||||
level + 1
|
||||
)}}
|
||||
if (!{{innerOutVar}}) {
|
||||
{{outVar}} = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
||||
public override string GetHashCodeStatement(string inVar, string outVar, int level = 0)
|
||||
{
|
||||
var iterVar = $"___i{level}";
|
||||
var innerHashCode = $"___hc{level}";
|
||||
var innerOutVar = $"___out{level + 1}";
|
||||
|
||||
return $$"""
|
||||
var {{outVar}} = 0;
|
||||
if ({{inVar}} != null) {
|
||||
var {{innerHashCode}} = new System.HashCode();
|
||||
for (int {{iterVar}} = 0; {{iterVar}} < {{inVar}}.Length; {{iterVar}}++) {
|
||||
{{ElementType.GetHashCodeStatement(
|
||||
$"{inVar}[{iterVar}]",
|
||||
innerOutVar,
|
||||
level + 1
|
||||
)}}
|
||||
{{innerHashCode}}.Add({{innerOutVar}});
|
||||
}
|
||||
{{outVar}} = {{innerHashCode}}.ToHashCode();
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A use of a list type.
|
||||
/// </summary>
|
||||
/// <param name="Type"></param>
|
||||
/// <param name="TypeInfo"></param>
|
||||
/// <param name="ElementType"></param>
|
||||
public record ListUse(string Type, string TypeInfo, TypeUse ElementType) : TypeUse(Type, TypeInfo)
|
||||
{
|
||||
public override string EqualsStatement(
|
||||
string inVar1,
|
||||
string inVar2,
|
||||
string outVar,
|
||||
int level = 0
|
||||
)
|
||||
{
|
||||
var iterVar = $"___i{level}";
|
||||
// needed to avoid warnings on list re-reference.
|
||||
var innerTmp1 = $"___tmpA{level}";
|
||||
var innerTmp2 = $"___tmpB{level}";
|
||||
var innerOutVar = $"___out{level + 1}";
|
||||
|
||||
return $$"""
|
||||
var {{outVar}} = true;
|
||||
if ({{inVar1}} == null || {{inVar2}} == null) {
|
||||
{{outVar}} = {{inVar1}} == {{inVar2}};
|
||||
} else if ({{inVar1}}.Count != {{inVar2}}.Count) {
|
||||
{{outVar}} = false;
|
||||
} else {
|
||||
for (int {{iterVar}} = 0; {{iterVar}} < {{inVar1}}.Count; {{iterVar}}++) {
|
||||
var {{innerTmp1}} = {{inVar1}}[{{iterVar}}];
|
||||
var {{innerTmp2}} = {{inVar2}}[{{iterVar}}];
|
||||
{{ElementType.EqualsStatement(innerTmp1, innerTmp2, innerOutVar, level + 1)}}
|
||||
if (!{{innerOutVar}}) {
|
||||
{{outVar}} = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
||||
public override string GetHashCodeStatement(string inVar, string outVar, int level = 0)
|
||||
{
|
||||
var iterVar = $"___i{level}";
|
||||
var innerTmp = $"___tmp{level}";
|
||||
var innerHashCode = $"___hc{level}";
|
||||
var innerOutVar = $"___out{level + 1}";
|
||||
|
||||
return $$"""
|
||||
var {{outVar}} = 0;
|
||||
if ({{inVar}} != null) {
|
||||
var {{innerHashCode}} = new System.HashCode();
|
||||
for (int {{iterVar}} = 0; {{iterVar}} < {{inVar}}.Count; {{iterVar}}++) {
|
||||
var {{innerTmp}} = {{inVar}}[{{iterVar}}];
|
||||
{{ElementType.GetHashCodeStatement(innerTmp, innerOutVar, level + 1)}}
|
||||
{{innerHashCode}}.Add({{innerOutVar}});
|
||||
}
|
||||
{{outVar}} = {{innerHashCode}}.ToHashCode();
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A declaration of a member of a product or sum type.
|
||||
/// </summary>
|
||||
/// <param name="Name">The name of the member.</param>
|
||||
/// <param name="Type">Type information relevant to the member.</param>
|
||||
public record MemberDeclaration(
|
||||
string Name,
|
||||
// TODO: rename to `Type` once I've checked uses
|
||||
TypeUse Type
|
||||
)
|
||||
{
|
||||
public MemberDeclaration(ISymbol member, ITypeSymbol type, DiagReporter diag)
|
||||
: this(member.Name, TypeUse.Parse(member, type, diag)) { }
|
||||
|
||||
public MemberDeclaration(IFieldSymbol field, DiagReporter diag)
|
||||
: this(field, field.Type, diag) { }
|
||||
|
||||
@@ -46,7 +301,7 @@ public record MemberDeclaration(
|
||||
var visStr = SyntaxFacts.GetText(visibility);
|
||||
return string.Join(
|
||||
"\n ",
|
||||
members.Select(m => $"{visStr} static readonly {m.TypeInfo} {m.Name} = new();")
|
||||
members.Select(m => $"{visStr} static readonly {m.Type.BSATNName} {m.Name} = new();")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -191,7 +446,7 @@ public abstract record BaseTypeDeclaration<M>
|
||||
// To avoid this, we append an underscore to the field name.
|
||||
// In most cases the field name shouldn't matter anyway as you'll idiomatically use pattern matching to extract the value.
|
||||
$$"""
|
||||
public sealed record {{m.Name}}({{m.Type}} {{m.Name}}_) : {{ShortName}}
|
||||
public sealed record {{m.Name}}({{m.Type.Name}} {{m.Name}}_) : {{ShortName}}
|
||||
{
|
||||
public override string ToString() =>
|
||||
$"{{m.Name}}({ SpacetimeDB.BSATN.StringUtil.GenericToString({{m.Name}}_) })";
|
||||
@@ -234,20 +489,12 @@ public abstract record BaseTypeDeclaration<M>
|
||||
bsatnDecls
|
||||
.Select(member =>
|
||||
{
|
||||
string innerGetHash;
|
||||
|
||||
if (member.IsNullableReferenceType)
|
||||
{
|
||||
innerGetHash = "inner == null ? 0 : inner.GetHashCode()";
|
||||
}
|
||||
else
|
||||
{
|
||||
innerGetHash = "inner.GetHashCode()";
|
||||
}
|
||||
var hashName = $"___hash{member.Name}";
|
||||
|
||||
return $"""
|
||||
case {member.Name}(var inner):
|
||||
return {innerGetHash};
|
||||
{member.Type.GetHashCodeStatement("inner", hashName)}
|
||||
return {hashName};
|
||||
""";
|
||||
}))}}
|
||||
default:
|
||||
@@ -256,7 +503,7 @@ public abstract record BaseTypeDeclaration<M>
|
||||
""";
|
||||
|
||||
bsatnDecls = bsatnDecls.Prepend(
|
||||
new("__enumTag", "@enum", "SpacetimeDB.BSATN.Enum<@enum>", false)
|
||||
new("__enumTag", new ValueUse("@enum", "SpacetimeDB.BSATN.Enum<@enum>"))
|
||||
);
|
||||
}
|
||||
else
|
||||
@@ -300,20 +547,13 @@ public abstract record BaseTypeDeclaration<M>
|
||||
|
||||
write = "value.WriteFields(writer);";
|
||||
|
||||
var declHashName = (MemberDeclaration decl) => $"___hash{decl.Name}";
|
||||
|
||||
getHashCode = $$"""
|
||||
{{string.Join("\n", bsatnDecls.Select(decl => decl.Type.GetHashCodeStatement(decl.Name, declHashName(decl))))}}
|
||||
return {{JoinOrValue(
|
||||
" ^\n ",
|
||||
bsatnDecls.Select(decl =>
|
||||
{
|
||||
if (decl.IsNullableReferenceType)
|
||||
{
|
||||
return $"({decl.Name} == null ? 0 : {decl.Name}.GetHashCode())";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{decl.Name}.GetHashCode()";
|
||||
}
|
||||
}),
|
||||
bsatnDecls.Select(declHashName),
|
||||
"0" // if there are no members, the hash is 0.
|
||||
)}};
|
||||
""";
|
||||
@@ -354,6 +594,7 @@ public abstract record BaseTypeDeclaration<M>
|
||||
// If we are a reference type, various equality methods need to take nullable references.
|
||||
// If we are a value type, everything is pleasantly by-value.
|
||||
var fullNameMaybeRef = $"{FullName}{(Scope.IsStruct ? "" : "?")}";
|
||||
var declEqualsName = (MemberDeclaration decl) => $"___eq{decl.Name}";
|
||||
|
||||
extensions.Contents.Append(
|
||||
$$"""
|
||||
@@ -361,19 +602,11 @@ public abstract record BaseTypeDeclaration<M>
|
||||
#nullable enable
|
||||
public bool Equals({{fullNameMaybeRef}} that)
|
||||
{
|
||||
{{(Scope.IsStruct ? "" : "if (((object?)that) == null) { return false; }\n ")}}return {{JoinOrValue(
|
||||
{{(Scope.IsStruct ? "" : "if (((object?)that) == null) { return false; }\n ")}}
|
||||
{{string.Join("\n", bsatnDecls.Select(decl => decl.Type.EqualsStatement($"this.{decl.Name}", $"that.{decl.Name}", declEqualsName(decl))))}}
|
||||
return {{JoinOrValue(
|
||||
" &&\n ",
|
||||
bsatnDecls.Select(member =>
|
||||
{
|
||||
if (member.IsNullableReferenceType)
|
||||
{
|
||||
return $"({member.Name} == null ? that.{member.Name} == null : {member.Name}.Equals(that.{member.Name}))";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{member.Name}.Equals(that.{member.Name})";
|
||||
}
|
||||
}),
|
||||
bsatnDecls.Select(declEqualsName),
|
||||
"true" // if there are no elements, the structs are equal :)
|
||||
)}};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
namespace SpacetimeDB;
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CsCheck;
|
||||
using SpacetimeDB.BSATN;
|
||||
using Xunit;
|
||||
|
||||
public static partial class BSATNRuntimeTests
|
||||
@@ -296,9 +298,77 @@ public static partial class BSATNRuntimeTests
|
||||
(int X, string Y, int? Z, string? W) c2
|
||||
)> GenTwoBasic = Gen.Select(GenBasic, GenBasic, (c1, c2) => (c1, c2));
|
||||
|
||||
[Fact]
|
||||
public static void TestGeneratedEquals()
|
||||
/// <summary>
|
||||
/// Count collisions when comparing hashcodes of non-equal structures.
|
||||
/// </summary>
|
||||
struct CollisionCounter
|
||||
{
|
||||
private uint Comparisons;
|
||||
private uint Collisions;
|
||||
|
||||
public void Add(bool collides)
|
||||
{
|
||||
Comparisons += 1;
|
||||
if (collides)
|
||||
{
|
||||
Collisions += 1;
|
||||
}
|
||||
}
|
||||
|
||||
public double CollisionFraction
|
||||
{
|
||||
get => (double)Collisions / (double)Comparisons;
|
||||
}
|
||||
|
||||
public void AssertCollisionsLessThan(double fraction)
|
||||
{
|
||||
Assert.True(
|
||||
CollisionFraction < fraction,
|
||||
$"Expected {fraction} portion of collisions, but got {CollisionFraction} = {Collisions} / {Comparisons}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void TestRoundTrip<T, BSATN>(Gen<T> gen, BSATN serializer)
|
||||
where BSATN : IReadWrite<T>
|
||||
{
|
||||
gen.Sample(
|
||||
(value) =>
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new BinaryWriter(stream);
|
||||
serializer.Write(writer, value);
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
var reader = new BinaryReader(stream);
|
||||
var result = serializer.Read(reader);
|
||||
Assert.Equal(value, result);
|
||||
},
|
||||
iter: 10_000
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedProductRoundTrip()
|
||||
{
|
||||
TestRoundTrip(
|
||||
GenBasic.Select(value => new BasicDataClass(value)),
|
||||
new BasicDataClass.BSATN()
|
||||
);
|
||||
TestRoundTrip(
|
||||
GenBasic.Select(value => new BasicDataRecord(value)),
|
||||
new BasicDataRecord.BSATN()
|
||||
);
|
||||
TestRoundTrip(
|
||||
GenBasic.Select(value => new BasicDataStruct(value)),
|
||||
new BasicDataStruct.BSATN()
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedProductEqualsWorks()
|
||||
{
|
||||
CollisionCounter collisionCounter = new();
|
||||
|
||||
GenTwoBasic.Sample(
|
||||
example =>
|
||||
{
|
||||
@@ -355,10 +425,13 @@ public static partial class BSATNRuntimeTests
|
||||
// hash code should not depend on the type of object.
|
||||
Assert.Equal(class1.GetHashCode(), record1.GetHashCode());
|
||||
Assert.Equal(record1.GetHashCode(), struct1.GetHashCode());
|
||||
|
||||
collisionCounter.Add(class1.GetHashCode() == class2.GetHashCode());
|
||||
}
|
||||
},
|
||||
iter: 10_000
|
||||
);
|
||||
collisionCounter.AssertCollisionsLessThan(0.05);
|
||||
}
|
||||
|
||||
[Type]
|
||||
@@ -395,22 +468,17 @@ public static partial class BSATNRuntimeTests
|
||||
(e1, e2) => (e1, e2)
|
||||
);
|
||||
|
||||
[Type]
|
||||
public partial class ContainsList
|
||||
[Fact]
|
||||
public static void GeneratedSumRoundTrip()
|
||||
{
|
||||
public List<BasicEnum?> TheList = [];
|
||||
|
||||
public ContainsList() { }
|
||||
|
||||
public ContainsList(List<BasicEnum?> theList)
|
||||
{
|
||||
TheList = theList;
|
||||
}
|
||||
TestRoundTrip(GenBasicEnum, new BasicEnum.BSATN());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedEnumsWork()
|
||||
public static void GeneratedSumEqualsWorks()
|
||||
{
|
||||
CollisionCounter collisionCounter = new();
|
||||
|
||||
GenTwoBasicEnum.Sample(
|
||||
example =>
|
||||
{
|
||||
@@ -442,10 +510,186 @@ public static partial class BSATNRuntimeTests
|
||||
Assert.False(example.e1 == example.e2);
|
||||
Assert.True(example.e1 != example.e2);
|
||||
Assert.NotEqual(example.e1.ToString(), example.e2.ToString());
|
||||
collisionCounter.Add(example.e1.GetHashCode() == example.e2.GetHashCode());
|
||||
}
|
||||
},
|
||||
iter: 10_000
|
||||
);
|
||||
collisionCounter.AssertCollisionsLessThan(0.05);
|
||||
}
|
||||
|
||||
[Type]
|
||||
public partial class ContainsList
|
||||
{
|
||||
public List<BasicEnum?>? TheList = [];
|
||||
|
||||
public ContainsList() { }
|
||||
|
||||
public ContainsList(List<BasicEnum?>? theList)
|
||||
{
|
||||
TheList = theList;
|
||||
}
|
||||
}
|
||||
|
||||
static readonly Gen<ContainsList> GenContainsList = GenBasicEnum
|
||||
.Null()
|
||||
.List[0, 2]
|
||||
.Null()
|
||||
.Select(list => new ContainsList(list));
|
||||
static readonly Gen<(ContainsList e1, ContainsList e2)> GenTwoContainsList = Gen.Select(
|
||||
GenContainsList,
|
||||
GenContainsList,
|
||||
(e1, e2) => (e1, e2)
|
||||
);
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedListRoundTrip()
|
||||
{
|
||||
TestRoundTrip(GenContainsList, new ContainsList.BSATN());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedListEqualsWorks()
|
||||
{
|
||||
CollisionCounter collisionCounter = new();
|
||||
GenTwoContainsList.Sample(
|
||||
example =>
|
||||
{
|
||||
var equal =
|
||||
example.e1.TheList == null
|
||||
? example.e2.TheList == null
|
||||
: (
|
||||
example.e2.TheList == null
|
||||
? false
|
||||
: example.e1.TheList.SequenceEqual(example.e2.TheList)
|
||||
);
|
||||
|
||||
if (equal)
|
||||
{
|
||||
Assert.Equal(example.e1, example.e2);
|
||||
Assert.True(example.e1 == example.e2);
|
||||
Assert.False(example.e1 != example.e2);
|
||||
Assert.Equal(example.e1.ToString(), example.e2.ToString());
|
||||
Assert.Equal(example.e1.GetHashCode(), example.e2.GetHashCode());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.NotEqual(example.e1, example.e2);
|
||||
Assert.False(example.e1 == example.e2);
|
||||
Assert.True(example.e1 != example.e2);
|
||||
Assert.NotEqual(example.e1.ToString(), example.e2.ToString());
|
||||
collisionCounter.Add(example.e1.GetHashCode() == example.e2.GetHashCode());
|
||||
}
|
||||
},
|
||||
iter: 10_000
|
||||
);
|
||||
collisionCounter.AssertCollisionsLessThan(0.05);
|
||||
}
|
||||
|
||||
[Type]
|
||||
public partial class ContainsNestedList
|
||||
{
|
||||
public List<BasicEnum[][]> TheList = [];
|
||||
|
||||
public ContainsNestedList() { }
|
||||
|
||||
public ContainsNestedList(List<BasicEnum[][]> theList)
|
||||
{
|
||||
TheList = theList;
|
||||
}
|
||||
}
|
||||
|
||||
// For the serialization test, forbid nulls.
|
||||
static readonly Gen<ContainsNestedList> GenContainsNestedListNoNulls = GenBasicEnum
|
||||
.Array[0, 2]
|
||||
.Array[0, 2]
|
||||
.List[0, 2]
|
||||
.Select(list => new ContainsNestedList(list));
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedNestedListRoundTrip()
|
||||
{
|
||||
TestRoundTrip(GenContainsNestedListNoNulls, new ContainsNestedList.BSATN());
|
||||
}
|
||||
|
||||
// However, for the equals + hashcode test, throw in some nulls, just to be paranoid.
|
||||
// The user might have constructed a bad one of these in-memory.
|
||||
|
||||
#pragma warning disable CS8620 // Argument cannot be used for parameter due to differences in the nullability of reference types.
|
||||
static readonly Gen<ContainsNestedList> GenContainsNestedList = GenBasicEnum
|
||||
.Null()
|
||||
.Array[0, 2]
|
||||
.Null()
|
||||
.Array[0, 2]
|
||||
.Null()
|
||||
.List[0, 2]
|
||||
.Select(list => new ContainsNestedList(list));
|
||||
#pragma warning restore CS8620 // Argument cannot be used for parameter due to differences in the nullability of reference types.
|
||||
|
||||
|
||||
static readonly Gen<(ContainsNestedList e1, ContainsNestedList e2)> GenTwoContainsNestedList =
|
||||
Gen.Select(GenContainsNestedList, GenContainsNestedList, (e1, e2) => (e1, e2));
|
||||
|
||||
class EnumerableEqualityComparer<T> : EqualityComparer<IEnumerable<T>>
|
||||
{
|
||||
private readonly EqualityComparer<T> EqualityComparer;
|
||||
|
||||
public EnumerableEqualityComparer(EqualityComparer<T> equalityComparer)
|
||||
{
|
||||
EqualityComparer = equalityComparer;
|
||||
}
|
||||
|
||||
public override bool Equals(IEnumerable<T>? x, IEnumerable<T>? y) =>
|
||||
x == null ? y == null : (y == null ? false : x.SequenceEqual(y, EqualityComparer));
|
||||
|
||||
public override int GetHashCode([DisallowNull] IEnumerable<T> obj)
|
||||
{
|
||||
var hashCode = 0;
|
||||
foreach (var item in obj)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
hashCode ^= EqualityComparer.GetHashCode(item);
|
||||
}
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GeneratedNestedListEqualsWorks()
|
||||
{
|
||||
var equalityComparer = new EnumerableEqualityComparer<IEnumerable<IEnumerable<BasicEnum>>>(
|
||||
new EnumerableEqualityComparer<IEnumerable<BasicEnum>>(
|
||||
new EnumerableEqualityComparer<BasicEnum>(EqualityComparer<BasicEnum>.Default)
|
||||
)
|
||||
);
|
||||
CollisionCounter collisionCounter = new();
|
||||
GenTwoContainsNestedList.Sample(
|
||||
example =>
|
||||
{
|
||||
var equal = equalityComparer.Equals(example.e1.TheList, example.e2.TheList);
|
||||
|
||||
if (equal)
|
||||
{
|
||||
Assert.Equal(example.e1, example.e2);
|
||||
Assert.True(example.e1 == example.e2);
|
||||
Assert.False(example.e1 != example.e2);
|
||||
Assert.Equal(example.e1.ToString(), example.e2.ToString());
|
||||
Assert.Equal(example.e1.GetHashCode(), example.e2.GetHashCode());
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.NotEqual(example.e1, example.e2);
|
||||
Assert.False(example.e1 == example.e2);
|
||||
Assert.True(example.e1 != example.e2);
|
||||
Assert.NotEqual(example.e1.ToString(), example.e2.ToString());
|
||||
collisionCounter.Add(example.e1.GetHashCode() == example.e2.GetHashCode());
|
||||
}
|
||||
},
|
||||
iter: 10_000
|
||||
);
|
||||
collisionCounter.AssertCollisionsLessThan(0.05);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -516,5 +760,19 @@ public static partial class BSATNRuntimeTests
|
||||
]
|
||||
).ToString()
|
||||
);
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
Assert.Equal(
|
||||
"ContainsNestedList { TheList = [ [ [ X(1), null ], null ], null ] }",
|
||||
new ContainsNestedList(
|
||||
[
|
||||
[
|
||||
[new BasicEnum.X(1), null],
|
||||
null,
|
||||
],
|
||||
null,
|
||||
]
|
||||
).ToString()
|
||||
);
|
||||
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public static class GeneratorSnapshotTests
|
||||
.Emit(Stream.Null)
|
||||
.Diagnostics.Where(diag => diag.Severity != DiagnosticSeverity.Hidden)
|
||||
// The order of diagnostics is not predictable, sort them by location to make the test deterministic.
|
||||
.OrderBy(diag => diag.Location.ToString());
|
||||
.OrderBy(diag => diag.GetMessage() + diag.Location.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
+9
-2
@@ -50,13 +50,20 @@ partial struct CustomClass : System.IEquatable<CustomClass>, SpacetimeDB.BSATN.I
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IntField.GetHashCode() ^ StringField.GetHashCode();
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
return ___hashIntField ^ ___hashStringField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(CustomClass that)
|
||||
{
|
||||
return IntField.Equals(that.IntField) && StringField.Equals(that.StringField);
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
return ___eqIntField && ___eqStringField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+9
-2
@@ -52,13 +52,20 @@ partial struct CustomStruct
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IntField.GetHashCode() ^ StringField.GetHashCode();
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
return ___hashIntField ^ ___hashStringField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(CustomStruct that)
|
||||
{
|
||||
return IntField.Equals(that.IntField) && StringField.Equals(that.StringField);
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
return ___eqIntField && ___eqStringField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+4
-2
@@ -77,9 +77,11 @@ partial record CustomTaggedEnum : System.IEquatable<CustomTaggedEnum>
|
||||
switch (this)
|
||||
{
|
||||
case IntVariant(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashIntVariant = inner.GetHashCode();
|
||||
return ___hashIntVariant;
|
||||
case StringVariant(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashStringVariant = inner == null ? 0 : inner.GetHashCode();
|
||||
return ___hashStringVariant;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+144
-54
@@ -155,65 +155,155 @@ partial struct PublicTable : System.IEquatable<PublicTable>, SpacetimeDB.BSATN.I
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ByteField.GetHashCode()
|
||||
^ UshortField.GetHashCode()
|
||||
^ UintField.GetHashCode()
|
||||
^ UlongField.GetHashCode()
|
||||
^ U128Field.GetHashCode()
|
||||
^ U256Field.GetHashCode()
|
||||
^ SbyteField.GetHashCode()
|
||||
^ ShortField.GetHashCode()
|
||||
^ IntField.GetHashCode()
|
||||
^ LongField.GetHashCode()
|
||||
^ I128Field.GetHashCode()
|
||||
^ I256Field.GetHashCode()
|
||||
^ BoolField.GetHashCode()
|
||||
^ FloatField.GetHashCode()
|
||||
^ DoubleField.GetHashCode()
|
||||
^ StringField.GetHashCode()
|
||||
^ IdentityField.GetHashCode()
|
||||
^ ConnectionIdField.GetHashCode()
|
||||
^ CustomStructField.GetHashCode()
|
||||
^ CustomClassField.GetHashCode()
|
||||
^ CustomEnumField.GetHashCode()
|
||||
^ CustomTaggedEnumField.GetHashCode()
|
||||
^ ListField.GetHashCode()
|
||||
^ NullableValueField.GetHashCode()
|
||||
^ (NullableReferenceField == null ? 0 : NullableReferenceField.GetHashCode());
|
||||
var ___hashByteField = ByteField.GetHashCode();
|
||||
var ___hashUshortField = UshortField.GetHashCode();
|
||||
var ___hashUintField = UintField.GetHashCode();
|
||||
var ___hashUlongField = UlongField.GetHashCode();
|
||||
var ___hashU128Field = U128Field.GetHashCode();
|
||||
var ___hashU256Field = U256Field.GetHashCode();
|
||||
var ___hashSbyteField = SbyteField.GetHashCode();
|
||||
var ___hashShortField = ShortField.GetHashCode();
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashLongField = LongField.GetHashCode();
|
||||
var ___hashI128Field = I128Field.GetHashCode();
|
||||
var ___hashI256Field = I256Field.GetHashCode();
|
||||
var ___hashBoolField = BoolField.GetHashCode();
|
||||
var ___hashFloatField = FloatField.GetHashCode();
|
||||
var ___hashDoubleField = DoubleField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
var ___hashIdentityField = IdentityField.GetHashCode();
|
||||
var ___hashConnectionIdField = ConnectionIdField.GetHashCode();
|
||||
var ___hashCustomStructField = CustomStructField.GetHashCode();
|
||||
var ___hashCustomClassField = CustomClassField.GetHashCode();
|
||||
var ___hashCustomEnumField = CustomEnumField.GetHashCode();
|
||||
var ___hashCustomTaggedEnumField =
|
||||
CustomTaggedEnumField == null ? 0 : CustomTaggedEnumField.GetHashCode();
|
||||
var ___hashListField = 0;
|
||||
if (ListField != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < ListField.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = ListField[___i0];
|
||||
var ___out1 = ___tmp0.GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashListField = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashNullableValueField = NullableValueField.GetHashCode();
|
||||
var ___hashNullableReferenceField =
|
||||
NullableReferenceField == null ? 0 : NullableReferenceField.GetHashCode();
|
||||
return ___hashByteField
|
||||
^ ___hashUshortField
|
||||
^ ___hashUintField
|
||||
^ ___hashUlongField
|
||||
^ ___hashU128Field
|
||||
^ ___hashU256Field
|
||||
^ ___hashSbyteField
|
||||
^ ___hashShortField
|
||||
^ ___hashIntField
|
||||
^ ___hashLongField
|
||||
^ ___hashI128Field
|
||||
^ ___hashI256Field
|
||||
^ ___hashBoolField
|
||||
^ ___hashFloatField
|
||||
^ ___hashDoubleField
|
||||
^ ___hashStringField
|
||||
^ ___hashIdentityField
|
||||
^ ___hashConnectionIdField
|
||||
^ ___hashCustomStructField
|
||||
^ ___hashCustomClassField
|
||||
^ ___hashCustomEnumField
|
||||
^ ___hashCustomTaggedEnumField
|
||||
^ ___hashListField
|
||||
^ ___hashNullableValueField
|
||||
^ ___hashNullableReferenceField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(PublicTable that)
|
||||
{
|
||||
return ByteField.Equals(that.ByteField)
|
||||
&& UshortField.Equals(that.UshortField)
|
||||
&& UintField.Equals(that.UintField)
|
||||
&& UlongField.Equals(that.UlongField)
|
||||
&& U128Field.Equals(that.U128Field)
|
||||
&& U256Field.Equals(that.U256Field)
|
||||
&& SbyteField.Equals(that.SbyteField)
|
||||
&& ShortField.Equals(that.ShortField)
|
||||
&& IntField.Equals(that.IntField)
|
||||
&& LongField.Equals(that.LongField)
|
||||
&& I128Field.Equals(that.I128Field)
|
||||
&& I256Field.Equals(that.I256Field)
|
||||
&& BoolField.Equals(that.BoolField)
|
||||
&& FloatField.Equals(that.FloatField)
|
||||
&& DoubleField.Equals(that.DoubleField)
|
||||
&& StringField.Equals(that.StringField)
|
||||
&& IdentityField.Equals(that.IdentityField)
|
||||
&& ConnectionIdField.Equals(that.ConnectionIdField)
|
||||
&& CustomStructField.Equals(that.CustomStructField)
|
||||
&& CustomClassField.Equals(that.CustomClassField)
|
||||
&& CustomEnumField.Equals(that.CustomEnumField)
|
||||
&& CustomTaggedEnumField.Equals(that.CustomTaggedEnumField)
|
||||
&& ListField.Equals(that.ListField)
|
||||
&& NullableValueField.Equals(that.NullableValueField)
|
||||
&& (
|
||||
NullableReferenceField == null
|
||||
? that.NullableReferenceField == null
|
||||
: NullableReferenceField.Equals(that.NullableReferenceField)
|
||||
);
|
||||
var ___eqByteField = this.ByteField.Equals(that.ByteField);
|
||||
var ___eqUshortField = this.UshortField.Equals(that.UshortField);
|
||||
var ___eqUintField = this.UintField.Equals(that.UintField);
|
||||
var ___eqUlongField = this.UlongField.Equals(that.UlongField);
|
||||
var ___eqU128Field = this.U128Field.Equals(that.U128Field);
|
||||
var ___eqU256Field = this.U256Field.Equals(that.U256Field);
|
||||
var ___eqSbyteField = this.SbyteField.Equals(that.SbyteField);
|
||||
var ___eqShortField = this.ShortField.Equals(that.ShortField);
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqLongField = this.LongField.Equals(that.LongField);
|
||||
var ___eqI128Field = this.I128Field.Equals(that.I128Field);
|
||||
var ___eqI256Field = this.I256Field.Equals(that.I256Field);
|
||||
var ___eqBoolField = this.BoolField.Equals(that.BoolField);
|
||||
var ___eqFloatField = this.FloatField.Equals(that.FloatField);
|
||||
var ___eqDoubleField = this.DoubleField.Equals(that.DoubleField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
var ___eqIdentityField = this.IdentityField.Equals(that.IdentityField);
|
||||
var ___eqConnectionIdField = this.ConnectionIdField.Equals(that.ConnectionIdField);
|
||||
var ___eqCustomStructField = this.CustomStructField.Equals(that.CustomStructField);
|
||||
var ___eqCustomClassField = this.CustomClassField.Equals(that.CustomClassField);
|
||||
var ___eqCustomEnumField = this.CustomEnumField.Equals(that.CustomEnumField);
|
||||
var ___eqCustomTaggedEnumField =
|
||||
this.CustomTaggedEnumField == null
|
||||
? that.CustomTaggedEnumField == null
|
||||
: this.CustomTaggedEnumField.Equals(that.CustomTaggedEnumField);
|
||||
var ___eqListField = true;
|
||||
if (this.ListField == null || that.ListField == null)
|
||||
{
|
||||
___eqListField = this.ListField == that.ListField;
|
||||
}
|
||||
else if (this.ListField.Count != that.ListField.Count)
|
||||
{
|
||||
___eqListField = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.ListField.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.ListField[___i0];
|
||||
var ___tmpB0 = that.ListField[___i0];
|
||||
var ___out1 = ___tmpA0.Equals(___tmpB0);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqListField = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqNullableValueField = this.NullableValueField.Equals(that.NullableValueField);
|
||||
var ___eqNullableReferenceField =
|
||||
this.NullableReferenceField == null
|
||||
? that.NullableReferenceField == null
|
||||
: this.NullableReferenceField.Equals(that.NullableReferenceField);
|
||||
return ___eqByteField
|
||||
&& ___eqUshortField
|
||||
&& ___eqUintField
|
||||
&& ___eqUlongField
|
||||
&& ___eqU128Field
|
||||
&& ___eqU256Field
|
||||
&& ___eqSbyteField
|
||||
&& ___eqShortField
|
||||
&& ___eqIntField
|
||||
&& ___eqLongField
|
||||
&& ___eqI128Field
|
||||
&& ___eqI256Field
|
||||
&& ___eqBoolField
|
||||
&& ___eqFloatField
|
||||
&& ___eqDoubleField
|
||||
&& ___eqStringField
|
||||
&& ___eqIdentityField
|
||||
&& ___eqConnectionIdField
|
||||
&& ___eqCustomStructField
|
||||
&& ___eqCustomClassField
|
||||
&& ___eqCustomEnumField
|
||||
&& ___eqCustomTaggedEnumField
|
||||
&& ___eqListField
|
||||
&& ___eqNullableValueField
|
||||
&& ___eqNullableReferenceField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+81
-125
@@ -1,17 +1,17 @@
|
||||
[
|
||||
{/*
|
||||
public Exception UnsupportedSystemType;
|
||||
public UnresolvedType UnresolvedType;
|
||||
^^^^^^^^^^^^^^
|
||||
public LocalEnum UnsupportedEnum;
|
||||
SpacetimeDB.Internal.Module.RegisterTable<global::TestUniqueNotEquatable, SpacetimeDB.Internal.TableHandles.TestUniqueNotEquatable>();
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FILTER);
|
||||
^^^^^^^^^
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FOURTH_FILTER);
|
||||
*/
|
||||
Message: The type or namespace name 'UnresolvedType' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Message: 'Module.MY_FILTER' is inaccessible due to its protection level,
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0246,
|
||||
Id: CS0122,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0246),
|
||||
MessageFormat: The type or namespace name '{0}' could not be found (are you missing a using directive or an assembly reference?),
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122),
|
||||
MessageFormat: '{0}' is inaccessible due to its protection level,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
@@ -46,73 +46,6 @@
|
||||
}
|
||||
},
|
||||
{/*
|
||||
{
|
||||
return Field.GetHashCode();
|
||||
^^^^^
|
||||
}
|
||||
*/
|
||||
Message: Dereference of a possibly null reference.,
|
||||
Severity: Warning,
|
||||
Descriptor: {
|
||||
Id: CS8602,
|
||||
Title: Dereference of a possibly null reference.,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS8602),
|
||||
MessageFormat: Dereference of a possibly null reference.,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Warning,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
{
|
||||
return Field.Equals(that.Field);
|
||||
^^^^^
|
||||
}
|
||||
*/
|
||||
Message: Dereference of a possibly null reference.,
|
||||
Severity: Warning,
|
||||
Descriptor: {
|
||||
Id: CS8602,
|
||||
Title: Dereference of a possibly null reference.,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS8602),
|
||||
MessageFormat: Dereference of a possibly null reference.,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Warning,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
{
|
||||
internal static readonly TRW Field = new();
|
||||
^^^
|
||||
|
||||
*/
|
||||
Message: The type or namespace name 'TRW' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0246,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0246),
|
||||
MessageFormat: The type or namespace name '{0}' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
|
||||
partial struct TestTypeParams<T> : System.IEquatable<TestTypeParams>, SpacetimeDB.BSATN.IStructuralReadWrite {
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -136,33 +69,10 @@ partial struct TestTypeParams<T> : System.IEquatable<TestTypeParams>, Spacetime
|
||||
}
|
||||
},
|
||||
{/*
|
||||
|
||||
partial struct TestTypeParams<T> : System.IEquatable<TestTypeParams>, SpacetimeDB.BSATN.IStructuralReadWrite {
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
*/
|
||||
Message: Using the generic type 'TestTypeParams<T>' requires 1 type arguments,
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0305,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0305),
|
||||
MessageFormat: Using the generic {1} '{0}' requires {2} type arguments,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
UnsupportedSystemType.GetHashCode() ^
|
||||
UnresolvedType.GetHashCode() ^
|
||||
^^^^^^^^^^^
|
||||
UnsupportedEnum.GetHashCode();
|
||||
var ___hashUnsupportedSystemType = UnsupportedSystemType == null ? 0 : UnsupportedSystemType.GetHashCode();
|
||||
var ___hashUnresolvedType = UnresolvedType == null ? 0 : UnresolvedType.GetHashCode();
|
||||
^^^^^^^^^^^
|
||||
var ___hashUnsupportedEnum = UnsupportedEnum.GetHashCode();
|
||||
*/
|
||||
Message: 'UnresolvedType' does not contain a definition for 'GetHashCode' and no accessible extension method 'GetHashCode' accepting a first argument of type 'UnresolvedType' could be found (are you missing a using directive or an assembly reference?),
|
||||
Severity: Error,
|
||||
@@ -182,29 +92,6 @@ partial struct TestTypeParams<T> : System.IEquatable<TestTypeParams>, Spacetime
|
||||
}
|
||||
},
|
||||
{/*
|
||||
SpacetimeDB.Internal.Module.RegisterTable<global::TestUniqueNotEquatable, SpacetimeDB.Internal.TableHandles.TestUniqueNotEquatable>();
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FILTER);
|
||||
^^^^^^^^^
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FOURTH_FILTER);
|
||||
*/
|
||||
Message: 'Module.MY_FILTER' is inaccessible due to its protection level,
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0122,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122),
|
||||
MessageFormat: '{0}' is inaccessible due to its protection level,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_SECOND_FILTER);
|
||||
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_THIRD_FILTER);
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -226,5 +113,74 @@ SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_THI
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
{
|
||||
internal static readonly TRW Field = new();
|
||||
^^^
|
||||
|
||||
*/
|
||||
Message: The type or namespace name 'TRW' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0246,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0246),
|
||||
MessageFormat: The type or namespace name '{0}' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
public Exception UnsupportedSystemType;
|
||||
public UnresolvedType UnresolvedType;
|
||||
^^^^^^^^^^^^^^
|
||||
public LocalEnum UnsupportedEnum;
|
||||
*/
|
||||
Message: The type or namespace name 'UnresolvedType' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0246,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0246),
|
||||
MessageFormat: The type or namespace name '{0}' could not be found (are you missing a using directive or an assembly reference?),
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
},
|
||||
{/*
|
||||
|
||||
partial struct TestTypeParams<T> : System.IEquatable<TestTypeParams>, SpacetimeDB.BSATN.IStructuralReadWrite {
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
*/
|
||||
Message: Using the generic type 'TestTypeParams<T>' requires 1 type arguments,
|
||||
Severity: Error,
|
||||
Descriptor: {
|
||||
Id: CS0305,
|
||||
Title: ,
|
||||
HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0305),
|
||||
MessageFormat: Using the generic {1} '{0}' requires {2} type arguments,
|
||||
Category: Compiler,
|
||||
DefaultSeverity: Error,
|
||||
IsEnabledByDefault: true,
|
||||
CustomTags: [
|
||||
Compiler,
|
||||
Telemetry,
|
||||
NotConfigurable
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
+9
-2
@@ -54,13 +54,20 @@ partial struct TestAutoIncNotInteger
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return AutoIncField.GetHashCode() ^ IdentityField.GetHashCode();
|
||||
var ___hashAutoIncField = AutoIncField.GetHashCode();
|
||||
var ___hashIdentityField = IdentityField == null ? 0 : IdentityField.GetHashCode();
|
||||
return ___hashAutoIncField ^ ___hashIdentityField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestAutoIncNotInteger that)
|
||||
{
|
||||
return AutoIncField.Equals(that.AutoIncField) && IdentityField.Equals(that.IdentityField);
|
||||
var ___eqAutoIncField = this.AutoIncField.Equals(that.AutoIncField);
|
||||
var ___eqIdentityField =
|
||||
this.IdentityField == null
|
||||
? that.IdentityField == null
|
||||
: this.IdentityField.Equals(that.IdentityField);
|
||||
return ___eqAutoIncField && ___eqIdentityField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
Generated
+4
-2
@@ -53,13 +53,15 @@ partial struct TestIndexIssues
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return SelfIndexingColumn.GetHashCode();
|
||||
var ___hashSelfIndexingColumn = SelfIndexingColumn.GetHashCode();
|
||||
return ___hashSelfIndexingColumn;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestIndexIssues that)
|
||||
{
|
||||
return SelfIndexingColumn.Equals(that.SelfIndexingColumn);
|
||||
var ___eqSelfIndexingColumn = this.SelfIndexingColumn.Equals(that.SelfIndexingColumn);
|
||||
return ___eqSelfIndexingColumn;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
Generated
+23
-8
@@ -68,19 +68,34 @@ partial struct TestScheduleIssues
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IdWrongType.GetHashCode()
|
||||
^ IdCorrectType.GetHashCode()
|
||||
^ ScheduleAtWrongType.GetHashCode()
|
||||
^ ScheduleAtCorrectType.GetHashCode();
|
||||
var ___hashIdWrongType = IdWrongType == null ? 0 : IdWrongType.GetHashCode();
|
||||
var ___hashIdCorrectType = IdCorrectType.GetHashCode();
|
||||
var ___hashScheduleAtWrongType = ScheduleAtWrongType.GetHashCode();
|
||||
var ___hashScheduleAtCorrectType =
|
||||
ScheduleAtCorrectType == null ? 0 : ScheduleAtCorrectType.GetHashCode();
|
||||
return ___hashIdWrongType
|
||||
^ ___hashIdCorrectType
|
||||
^ ___hashScheduleAtWrongType
|
||||
^ ___hashScheduleAtCorrectType;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestScheduleIssues that)
|
||||
{
|
||||
return IdWrongType.Equals(that.IdWrongType)
|
||||
&& IdCorrectType.Equals(that.IdCorrectType)
|
||||
&& ScheduleAtWrongType.Equals(that.ScheduleAtWrongType)
|
||||
&& ScheduleAtCorrectType.Equals(that.ScheduleAtCorrectType);
|
||||
var ___eqIdWrongType =
|
||||
this.IdWrongType == null
|
||||
? that.IdWrongType == null
|
||||
: this.IdWrongType.Equals(that.IdWrongType);
|
||||
var ___eqIdCorrectType = this.IdCorrectType.Equals(that.IdCorrectType);
|
||||
var ___eqScheduleAtWrongType = this.ScheduleAtWrongType.Equals(that.ScheduleAtWrongType);
|
||||
var ___eqScheduleAtCorrectType =
|
||||
this.ScheduleAtCorrectType == null
|
||||
? that.ScheduleAtCorrectType == null
|
||||
: this.ScheduleAtCorrectType.Equals(that.ScheduleAtCorrectType);
|
||||
return ___eqIdWrongType
|
||||
&& ___eqIdCorrectType
|
||||
&& ___eqScheduleAtWrongType
|
||||
&& ___eqScheduleAtCorrectType;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
Generated
+4
-2
@@ -79,9 +79,11 @@ partial record TestTableTaggedEnum : System.IEquatable<TestTableTaggedEnum>
|
||||
switch (this)
|
||||
{
|
||||
case X(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashX = inner.GetHashCode();
|
||||
return ___hashX;
|
||||
case Y(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashY = inner.GetHashCode();
|
||||
return ___hashY;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+6
-2
@@ -58,13 +58,17 @@ partial struct TestUniqueNotEquatable
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UniqueField.GetHashCode() ^ PrimaryKeyField.GetHashCode();
|
||||
var ___hashUniqueField = UniqueField.GetHashCode();
|
||||
var ___hashPrimaryKeyField = PrimaryKeyField.GetHashCode();
|
||||
return ___hashUniqueField ^ ___hashPrimaryKeyField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestUniqueNotEquatable that)
|
||||
{
|
||||
return UniqueField.Equals(that.UniqueField) && PrimaryKeyField.Equals(that.PrimaryKeyField);
|
||||
var ___eqUniqueField = this.UniqueField.Equals(that.UniqueField);
|
||||
var ___eqPrimaryKeyField = this.PrimaryKeyField.Equals(that.PrimaryKeyField);
|
||||
return ___eqUniqueField && ___eqPrimaryKeyField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
Generated
+4
-2
@@ -79,9 +79,11 @@ partial record TestTaggedEnumField : System.IEquatable<TestTaggedEnumField>
|
||||
switch (this)
|
||||
{
|
||||
case X(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashX = inner.GetHashCode();
|
||||
return ___hashX;
|
||||
case Y(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashY = inner.GetHashCode();
|
||||
return ___hashY;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-1
@@ -65,7 +65,8 @@ partial record TestTaggedEnumInlineTuple : System.IEquatable<TestTaggedEnumInlin
|
||||
switch (this)
|
||||
{
|
||||
case Item1(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashItem1 = inner.GetHashCode();
|
||||
return ___hashItem1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Generated
+4
-2
@@ -51,13 +51,15 @@ partial struct TestTypeParams<T>
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Field.GetHashCode();
|
||||
var ___hashField = Field == null ? 0 : Field.GetHashCode();
|
||||
return ___hashField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestTypeParams<T> that)
|
||||
{
|
||||
return Field.Equals(that.Field);
|
||||
var ___eqField = this.Field == null ? that.Field == null : this.Field.Equals(that.Field);
|
||||
return ___eqField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
Generated
+25
-8
@@ -70,19 +70,36 @@ partial struct TestUnsupportedType
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UnsupportedSpecialType.GetHashCode()
|
||||
^ UnsupportedSystemType.GetHashCode()
|
||||
^ UnresolvedType.GetHashCode()
|
||||
^ UnsupportedEnum.GetHashCode();
|
||||
var ___hashUnsupportedSpecialType = UnsupportedSpecialType.GetHashCode();
|
||||
var ___hashUnsupportedSystemType =
|
||||
UnsupportedSystemType == null ? 0 : UnsupportedSystemType.GetHashCode();
|
||||
var ___hashUnresolvedType = UnresolvedType == null ? 0 : UnresolvedType.GetHashCode();
|
||||
var ___hashUnsupportedEnum = UnsupportedEnum.GetHashCode();
|
||||
return ___hashUnsupportedSpecialType
|
||||
^ ___hashUnsupportedSystemType
|
||||
^ ___hashUnresolvedType
|
||||
^ ___hashUnsupportedEnum;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(TestUnsupportedType that)
|
||||
{
|
||||
return UnsupportedSpecialType.Equals(that.UnsupportedSpecialType)
|
||||
&& UnsupportedSystemType.Equals(that.UnsupportedSystemType)
|
||||
&& UnresolvedType.Equals(that.UnresolvedType)
|
||||
&& UnsupportedEnum.Equals(that.UnsupportedEnum);
|
||||
var ___eqUnsupportedSpecialType = this.UnsupportedSpecialType.Equals(
|
||||
that.UnsupportedSpecialType
|
||||
);
|
||||
var ___eqUnsupportedSystemType =
|
||||
this.UnsupportedSystemType == null
|
||||
? that.UnsupportedSystemType == null
|
||||
: this.UnsupportedSystemType.Equals(that.UnsupportedSystemType);
|
||||
var ___eqUnresolvedType =
|
||||
this.UnresolvedType == null
|
||||
? that.UnresolvedType == null
|
||||
: this.UnresolvedType.Equals(that.UnresolvedType);
|
||||
var ___eqUnsupportedEnum = this.UnsupportedEnum.Equals(that.UnsupportedEnum);
|
||||
return ___eqUnsupportedSpecialType
|
||||
&& ___eqUnsupportedSystemType
|
||||
&& ___eqUnresolvedType
|
||||
&& ___eqUnsupportedEnum;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
@@ -56,6 +56,19 @@ public partial class CustomNestedClass
|
||||
public CustomRecord? NestedNullableCustomRecord = null;
|
||||
}
|
||||
|
||||
[SpacetimeDB.Type]
|
||||
public partial class ContainsNestedLists
|
||||
{
|
||||
public List<int> IntList = [];
|
||||
public List<string> StringList = [];
|
||||
public int[] IntArray = [];
|
||||
public string[] StringArray = [];
|
||||
public List<int[][]> IntArrayArrayList = [];
|
||||
public List<List<int>>[] IntListListArray = [];
|
||||
public List<string[][]> StringArrayArrayList = [];
|
||||
public List<List<string>>[] StringListListArray = [];
|
||||
}
|
||||
|
||||
[SpacetimeDB.Type]
|
||||
public partial class EmptyClass { }
|
||||
|
||||
|
||||
+8
-2
@@ -58,13 +58,19 @@ partial struct BTreeMultiColumn
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
|
||||
var ___hashX = X.GetHashCode();
|
||||
var ___hashY = Y.GetHashCode();
|
||||
var ___hashZ = Z.GetHashCode();
|
||||
return ___hashX ^ ___hashY ^ ___hashZ;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(BTreeMultiColumn that)
|
||||
{
|
||||
return X.Equals(that.X) && Y.Equals(that.Y) && Z.Equals(that.Z);
|
||||
var ___eqX = this.X.Equals(that.X);
|
||||
var ___eqY = this.Y.Equals(that.Y);
|
||||
var ___eqZ = this.Z.Equals(that.Z);
|
||||
return ___eqX && ___eqY && ___eqZ;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+11
-5
@@ -58,16 +58,22 @@ partial struct BTreeViews : System.IEquatable<BTreeViews>, SpacetimeDB.BSATN.ISt
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ Faction.GetHashCode();
|
||||
var ___hashId = Id.GetHashCode();
|
||||
var ___hashX = X.GetHashCode();
|
||||
var ___hashY = Y.GetHashCode();
|
||||
var ___hashFaction = Faction == null ? 0 : Faction.GetHashCode();
|
||||
return ___hashId ^ ___hashX ^ ___hashY ^ ___hashFaction;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(BTreeViews that)
|
||||
{
|
||||
return Id.Equals(that.Id)
|
||||
&& X.Equals(that.X)
|
||||
&& Y.Equals(that.Y)
|
||||
&& Faction.Equals(that.Faction);
|
||||
var ___eqId = this.Id.Equals(that.Id);
|
||||
var ___eqX = this.X.Equals(that.X);
|
||||
var ___eqY = this.Y.Equals(that.Y);
|
||||
var ___eqFaction =
|
||||
this.Faction == null ? that.Faction == null : this.Faction.Equals(that.Faction);
|
||||
return ___eqId && ___eqX && ___eqY && ___eqFaction;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+8
-2
@@ -56,13 +56,19 @@ partial struct MultiTableRow
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Name.GetHashCode() ^ Foo.GetHashCode() ^ Bar.GetHashCode();
|
||||
var ___hashName = Name == null ? 0 : Name.GetHashCode();
|
||||
var ___hashFoo = Foo.GetHashCode();
|
||||
var ___hashBar = Bar.GetHashCode();
|
||||
return ___hashName ^ ___hashFoo ^ ___hashBar;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(MultiTableRow that)
|
||||
{
|
||||
return Name.Equals(that.Name) && Foo.Equals(that.Foo) && Bar.Equals(that.Bar);
|
||||
var ___eqName = this.Name == null ? that.Name == null : this.Name.Equals(that.Name);
|
||||
var ___eqFoo = this.Foo.Equals(that.Foo);
|
||||
var ___eqBar = this.Bar.Equals(that.Bar);
|
||||
return ___eqName && ___eqFoo && ___eqBar;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ partial class PrivateTable : System.IEquatable<PrivateTable>, SpacetimeDB.BSATN.
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+159
-60
@@ -167,71 +167,170 @@ partial struct PublicTable : System.IEquatable<PublicTable>, SpacetimeDB.BSATN.I
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode()
|
||||
^ ByteField.GetHashCode()
|
||||
^ UshortField.GetHashCode()
|
||||
^ UintField.GetHashCode()
|
||||
^ UlongField.GetHashCode()
|
||||
^ UInt128Field.GetHashCode()
|
||||
^ U128Field.GetHashCode()
|
||||
^ U256Field.GetHashCode()
|
||||
^ SbyteField.GetHashCode()
|
||||
^ ShortField.GetHashCode()
|
||||
^ IntField.GetHashCode()
|
||||
^ LongField.GetHashCode()
|
||||
^ Int128Field.GetHashCode()
|
||||
^ I128Field.GetHashCode()
|
||||
^ I256Field.GetHashCode()
|
||||
^ BoolField.GetHashCode()
|
||||
^ FloatField.GetHashCode()
|
||||
^ DoubleField.GetHashCode()
|
||||
^ StringField.GetHashCode()
|
||||
^ IdentityField.GetHashCode()
|
||||
^ ConnectionIdField.GetHashCode()
|
||||
^ CustomStructField.GetHashCode()
|
||||
^ CustomClassField.GetHashCode()
|
||||
^ CustomEnumField.GetHashCode()
|
||||
^ CustomTaggedEnumField.GetHashCode()
|
||||
^ ListField.GetHashCode()
|
||||
^ NullableValueField.GetHashCode()
|
||||
^ (NullableReferenceField == null ? 0 : NullableReferenceField.GetHashCode());
|
||||
var ___hashId = Id.GetHashCode();
|
||||
var ___hashByteField = ByteField.GetHashCode();
|
||||
var ___hashUshortField = UshortField.GetHashCode();
|
||||
var ___hashUintField = UintField.GetHashCode();
|
||||
var ___hashUlongField = UlongField.GetHashCode();
|
||||
var ___hashUInt128Field = UInt128Field.GetHashCode();
|
||||
var ___hashU128Field = U128Field.GetHashCode();
|
||||
var ___hashU256Field = U256Field.GetHashCode();
|
||||
var ___hashSbyteField = SbyteField.GetHashCode();
|
||||
var ___hashShortField = ShortField.GetHashCode();
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashLongField = LongField.GetHashCode();
|
||||
var ___hashInt128Field = Int128Field.GetHashCode();
|
||||
var ___hashI128Field = I128Field.GetHashCode();
|
||||
var ___hashI256Field = I256Field.GetHashCode();
|
||||
var ___hashBoolField = BoolField.GetHashCode();
|
||||
var ___hashFloatField = FloatField.GetHashCode();
|
||||
var ___hashDoubleField = DoubleField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
var ___hashIdentityField = IdentityField.GetHashCode();
|
||||
var ___hashConnectionIdField = ConnectionIdField.GetHashCode();
|
||||
var ___hashCustomStructField = CustomStructField.GetHashCode();
|
||||
var ___hashCustomClassField = CustomClassField == null ? 0 : CustomClassField.GetHashCode();
|
||||
var ___hashCustomEnumField = CustomEnumField.GetHashCode();
|
||||
var ___hashCustomTaggedEnumField =
|
||||
CustomTaggedEnumField == null ? 0 : CustomTaggedEnumField.GetHashCode();
|
||||
var ___hashListField = 0;
|
||||
if (ListField != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < ListField.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = ListField[___i0];
|
||||
var ___out1 = ___tmp0.GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashListField = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashNullableValueField = NullableValueField.GetHashCode();
|
||||
var ___hashNullableReferenceField =
|
||||
NullableReferenceField == null ? 0 : NullableReferenceField.GetHashCode();
|
||||
return ___hashId
|
||||
^ ___hashByteField
|
||||
^ ___hashUshortField
|
||||
^ ___hashUintField
|
||||
^ ___hashUlongField
|
||||
^ ___hashUInt128Field
|
||||
^ ___hashU128Field
|
||||
^ ___hashU256Field
|
||||
^ ___hashSbyteField
|
||||
^ ___hashShortField
|
||||
^ ___hashIntField
|
||||
^ ___hashLongField
|
||||
^ ___hashInt128Field
|
||||
^ ___hashI128Field
|
||||
^ ___hashI256Field
|
||||
^ ___hashBoolField
|
||||
^ ___hashFloatField
|
||||
^ ___hashDoubleField
|
||||
^ ___hashStringField
|
||||
^ ___hashIdentityField
|
||||
^ ___hashConnectionIdField
|
||||
^ ___hashCustomStructField
|
||||
^ ___hashCustomClassField
|
||||
^ ___hashCustomEnumField
|
||||
^ ___hashCustomTaggedEnumField
|
||||
^ ___hashListField
|
||||
^ ___hashNullableValueField
|
||||
^ ___hashNullableReferenceField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(PublicTable that)
|
||||
{
|
||||
return Id.Equals(that.Id)
|
||||
&& ByteField.Equals(that.ByteField)
|
||||
&& UshortField.Equals(that.UshortField)
|
||||
&& UintField.Equals(that.UintField)
|
||||
&& UlongField.Equals(that.UlongField)
|
||||
&& UInt128Field.Equals(that.UInt128Field)
|
||||
&& U128Field.Equals(that.U128Field)
|
||||
&& U256Field.Equals(that.U256Field)
|
||||
&& SbyteField.Equals(that.SbyteField)
|
||||
&& ShortField.Equals(that.ShortField)
|
||||
&& IntField.Equals(that.IntField)
|
||||
&& LongField.Equals(that.LongField)
|
||||
&& Int128Field.Equals(that.Int128Field)
|
||||
&& I128Field.Equals(that.I128Field)
|
||||
&& I256Field.Equals(that.I256Field)
|
||||
&& BoolField.Equals(that.BoolField)
|
||||
&& FloatField.Equals(that.FloatField)
|
||||
&& DoubleField.Equals(that.DoubleField)
|
||||
&& StringField.Equals(that.StringField)
|
||||
&& IdentityField.Equals(that.IdentityField)
|
||||
&& ConnectionIdField.Equals(that.ConnectionIdField)
|
||||
&& CustomStructField.Equals(that.CustomStructField)
|
||||
&& CustomClassField.Equals(that.CustomClassField)
|
||||
&& CustomEnumField.Equals(that.CustomEnumField)
|
||||
&& CustomTaggedEnumField.Equals(that.CustomTaggedEnumField)
|
||||
&& ListField.Equals(that.ListField)
|
||||
&& NullableValueField.Equals(that.NullableValueField)
|
||||
&& (
|
||||
NullableReferenceField == null
|
||||
? that.NullableReferenceField == null
|
||||
: NullableReferenceField.Equals(that.NullableReferenceField)
|
||||
);
|
||||
var ___eqId = this.Id.Equals(that.Id);
|
||||
var ___eqByteField = this.ByteField.Equals(that.ByteField);
|
||||
var ___eqUshortField = this.UshortField.Equals(that.UshortField);
|
||||
var ___eqUintField = this.UintField.Equals(that.UintField);
|
||||
var ___eqUlongField = this.UlongField.Equals(that.UlongField);
|
||||
var ___eqUInt128Field = this.UInt128Field.Equals(that.UInt128Field);
|
||||
var ___eqU128Field = this.U128Field.Equals(that.U128Field);
|
||||
var ___eqU256Field = this.U256Field.Equals(that.U256Field);
|
||||
var ___eqSbyteField = this.SbyteField.Equals(that.SbyteField);
|
||||
var ___eqShortField = this.ShortField.Equals(that.ShortField);
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqLongField = this.LongField.Equals(that.LongField);
|
||||
var ___eqInt128Field = this.Int128Field.Equals(that.Int128Field);
|
||||
var ___eqI128Field = this.I128Field.Equals(that.I128Field);
|
||||
var ___eqI256Field = this.I256Field.Equals(that.I256Field);
|
||||
var ___eqBoolField = this.BoolField.Equals(that.BoolField);
|
||||
var ___eqFloatField = this.FloatField.Equals(that.FloatField);
|
||||
var ___eqDoubleField = this.DoubleField.Equals(that.DoubleField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
var ___eqIdentityField = this.IdentityField.Equals(that.IdentityField);
|
||||
var ___eqConnectionIdField = this.ConnectionIdField.Equals(that.ConnectionIdField);
|
||||
var ___eqCustomStructField = this.CustomStructField.Equals(that.CustomStructField);
|
||||
var ___eqCustomClassField =
|
||||
this.CustomClassField == null
|
||||
? that.CustomClassField == null
|
||||
: this.CustomClassField.Equals(that.CustomClassField);
|
||||
var ___eqCustomEnumField = this.CustomEnumField.Equals(that.CustomEnumField);
|
||||
var ___eqCustomTaggedEnumField =
|
||||
this.CustomTaggedEnumField == null
|
||||
? that.CustomTaggedEnumField == null
|
||||
: this.CustomTaggedEnumField.Equals(that.CustomTaggedEnumField);
|
||||
var ___eqListField = true;
|
||||
if (this.ListField == null || that.ListField == null)
|
||||
{
|
||||
___eqListField = this.ListField == that.ListField;
|
||||
}
|
||||
else if (this.ListField.Count != that.ListField.Count)
|
||||
{
|
||||
___eqListField = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.ListField.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.ListField[___i0];
|
||||
var ___tmpB0 = that.ListField[___i0];
|
||||
var ___out1 = ___tmpA0.Equals(___tmpB0);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqListField = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqNullableValueField = this.NullableValueField.Equals(that.NullableValueField);
|
||||
var ___eqNullableReferenceField =
|
||||
this.NullableReferenceField == null
|
||||
? that.NullableReferenceField == null
|
||||
: this.NullableReferenceField.Equals(that.NullableReferenceField);
|
||||
return ___eqId
|
||||
&& ___eqByteField
|
||||
&& ___eqUshortField
|
||||
&& ___eqUintField
|
||||
&& ___eqUlongField
|
||||
&& ___eqUInt128Field
|
||||
&& ___eqU128Field
|
||||
&& ___eqU256Field
|
||||
&& ___eqSbyteField
|
||||
&& ___eqShortField
|
||||
&& ___eqIntField
|
||||
&& ___eqLongField
|
||||
&& ___eqInt128Field
|
||||
&& ___eqI128Field
|
||||
&& ___eqI256Field
|
||||
&& ___eqBoolField
|
||||
&& ___eqFloatField
|
||||
&& ___eqDoubleField
|
||||
&& ___eqStringField
|
||||
&& ___eqIdentityField
|
||||
&& ___eqConnectionIdField
|
||||
&& ___eqCustomStructField
|
||||
&& ___eqCustomClassField
|
||||
&& ___eqCustomEnumField
|
||||
&& ___eqCustomTaggedEnumField
|
||||
&& ___eqListField
|
||||
&& ___eqNullableValueField
|
||||
&& ___eqNullableReferenceField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+6
-2
@@ -60,13 +60,17 @@ partial struct RegressionMultipleUniqueIndexesHadSameName
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Unique1.GetHashCode() ^ Unique2.GetHashCode();
|
||||
var ___hashUnique1 = Unique1.GetHashCode();
|
||||
var ___hashUnique2 = Unique2.GetHashCode();
|
||||
return ___hashUnique1 ^ ___hashUnique2;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(RegressionMultipleUniqueIndexesHadSameName that)
|
||||
{
|
||||
return Unique1.Equals(that.Unique1) && Unique2.Equals(that.Unique2);
|
||||
var ___eqUnique1 = this.Unique1.Equals(that.Unique1);
|
||||
var ___eqUnique2 = this.Unique2.Equals(that.Unique2);
|
||||
return ___eqUnique1 && ___eqUnique2;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+11
-4
@@ -60,15 +60,22 @@ partial class Timers
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ScheduledId.GetHashCode() ^ ScheduledAt.GetHashCode() ^ Text.GetHashCode();
|
||||
var ___hashScheduledId = ScheduledId.GetHashCode();
|
||||
var ___hashScheduledAt = ScheduledAt == null ? 0 : ScheduledAt.GetHashCode();
|
||||
var ___hashText = Text == null ? 0 : Text.GetHashCode();
|
||||
return ___hashScheduledId ^ ___hashScheduledAt ^ ___hashText;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(Timers.SendMessageTimer that)
|
||||
{
|
||||
return ScheduledId.Equals(that.ScheduledId)
|
||||
&& ScheduledAt.Equals(that.ScheduledAt)
|
||||
&& Text.Equals(that.Text);
|
||||
var ___eqScheduledId = this.ScheduledId.Equals(that.ScheduledId);
|
||||
var ___eqScheduledAt =
|
||||
this.ScheduledAt == null
|
||||
? that.ScheduledAt == null
|
||||
: this.ScheduledAt.Equals(that.ScheduledAt);
|
||||
var ___eqText = this.Text == null ? that.Text == null : this.Text.Equals(that.Text);
|
||||
return ___eqScheduledId && ___eqScheduledAt && ___eqText;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+713
@@ -0,0 +1,713 @@
|
||||
//HintName: ContainsNestedLists.cs
|
||||
// <auto-generated />
|
||||
#nullable enable
|
||||
|
||||
partial class ContainsNestedLists
|
||||
: System.IEquatable<ContainsNestedLists>,
|
||||
SpacetimeDB.BSATN.IStructuralReadWrite
|
||||
{
|
||||
public void ReadFields(System.IO.BinaryReader reader)
|
||||
{
|
||||
IntList = BSATN.IntList.Read(reader);
|
||||
StringList = BSATN.StringList.Read(reader);
|
||||
IntArray = BSATN.IntArray.Read(reader);
|
||||
StringArray = BSATN.StringArray.Read(reader);
|
||||
IntArrayArrayList = BSATN.IntArrayArrayList.Read(reader);
|
||||
IntListListArray = BSATN.IntListListArray.Read(reader);
|
||||
StringArrayArrayList = BSATN.StringArrayArrayList.Read(reader);
|
||||
StringListListArray = BSATN.StringListListArray.Read(reader);
|
||||
}
|
||||
|
||||
public void WriteFields(System.IO.BinaryWriter writer)
|
||||
{
|
||||
BSATN.IntList.Write(writer, IntList);
|
||||
BSATN.StringList.Write(writer, StringList);
|
||||
BSATN.IntArray.Write(writer, IntArray);
|
||||
BSATN.StringArray.Write(writer, StringArray);
|
||||
BSATN.IntArrayArrayList.Write(writer, IntArrayArrayList);
|
||||
BSATN.IntListListArray.Write(writer, IntListListArray);
|
||||
BSATN.StringArrayArrayList.Write(writer, StringArrayArrayList);
|
||||
BSATN.StringListListArray.Write(writer, StringListListArray);
|
||||
}
|
||||
|
||||
public override string ToString() =>
|
||||
$"ContainsNestedLists {{ IntList = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntList)}, StringList = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringList)}, IntArray = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntArray)}, StringArray = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringArray)}, IntArrayArrayList = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntArrayArrayList)}, IntListListArray = {SpacetimeDB.BSATN.StringUtil.GenericToString(IntListListArray)}, StringArrayArrayList = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringArrayArrayList)}, StringListListArray = {SpacetimeDB.BSATN.StringUtil.GenericToString(StringListListArray)} }}";
|
||||
|
||||
public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite<ContainsNestedLists>
|
||||
{
|
||||
internal static readonly SpacetimeDB.BSATN.List<int, SpacetimeDB.BSATN.I32> IntList = new();
|
||||
internal static readonly SpacetimeDB.BSATN.List<
|
||||
string,
|
||||
SpacetimeDB.BSATN.String
|
||||
> StringList = new();
|
||||
internal static readonly SpacetimeDB.BSATN.Array<int, SpacetimeDB.BSATN.I32> IntArray =
|
||||
new();
|
||||
internal static readonly SpacetimeDB.BSATN.Array<
|
||||
string,
|
||||
SpacetimeDB.BSATN.String
|
||||
> StringArray = new();
|
||||
internal static readonly SpacetimeDB.BSATN.List<
|
||||
int[][],
|
||||
SpacetimeDB.BSATN.Array<int[], SpacetimeDB.BSATN.Array<int, SpacetimeDB.BSATN.I32>>
|
||||
> IntArrayArrayList = new();
|
||||
internal static readonly SpacetimeDB.BSATN.Array<
|
||||
System.Collections.Generic.List<System.Collections.Generic.List<int>>,
|
||||
SpacetimeDB.BSATN.List<
|
||||
System.Collections.Generic.List<int>,
|
||||
SpacetimeDB.BSATN.List<int, SpacetimeDB.BSATN.I32>
|
||||
>
|
||||
> IntListListArray = new();
|
||||
internal static readonly SpacetimeDB.BSATN.List<
|
||||
string[][],
|
||||
SpacetimeDB.BSATN.Array<
|
||||
string[],
|
||||
SpacetimeDB.BSATN.Array<string, SpacetimeDB.BSATN.String>
|
||||
>
|
||||
> StringArrayArrayList = new();
|
||||
internal static readonly SpacetimeDB.BSATN.Array<
|
||||
System.Collections.Generic.List<System.Collections.Generic.List<string>>,
|
||||
SpacetimeDB.BSATN.List<
|
||||
System.Collections.Generic.List<string>,
|
||||
SpacetimeDB.BSATN.List<string, SpacetimeDB.BSATN.String>
|
||||
>
|
||||
> StringListListArray = new();
|
||||
|
||||
public ContainsNestedLists Read(System.IO.BinaryReader reader) =>
|
||||
SpacetimeDB.BSATN.IStructuralReadWrite.Read<ContainsNestedLists>(reader);
|
||||
|
||||
public void Write(System.IO.BinaryWriter writer, ContainsNestedLists value)
|
||||
{
|
||||
value.WriteFields(writer);
|
||||
}
|
||||
|
||||
public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType(
|
||||
SpacetimeDB.BSATN.ITypeRegistrar registrar
|
||||
) =>
|
||||
registrar.RegisterType<ContainsNestedLists>(
|
||||
_ => new SpacetimeDB.BSATN.AlgebraicType.Product(
|
||||
new SpacetimeDB.BSATN.AggregateElement[]
|
||||
{
|
||||
new(nameof(IntList), IntList.GetAlgebraicType(registrar)),
|
||||
new(nameof(StringList), StringList.GetAlgebraicType(registrar)),
|
||||
new(nameof(IntArray), IntArray.GetAlgebraicType(registrar)),
|
||||
new(nameof(StringArray), StringArray.GetAlgebraicType(registrar)),
|
||||
new(
|
||||
nameof(IntArrayArrayList),
|
||||
IntArrayArrayList.GetAlgebraicType(registrar)
|
||||
),
|
||||
new(nameof(IntListListArray), IntListListArray.GetAlgebraicType(registrar)),
|
||||
new(
|
||||
nameof(StringArrayArrayList),
|
||||
StringArrayArrayList.GetAlgebraicType(registrar)
|
||||
),
|
||||
new(
|
||||
nameof(StringListListArray),
|
||||
StringListListArray.GetAlgebraicType(registrar)
|
||||
)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite<ContainsNestedLists>.GetAlgebraicType(
|
||||
SpacetimeDB.BSATN.ITypeRegistrar registrar
|
||||
) => GetAlgebraicType(registrar);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var ___hashIntList = 0;
|
||||
if (IntList != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < IntList.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = IntList[___i0];
|
||||
var ___out1 = ___tmp0.GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashIntList = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashStringList = 0;
|
||||
if (StringList != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < StringList.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = StringList[___i0];
|
||||
var ___out1 = ___tmp0 == null ? 0 : ___tmp0.GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashStringList = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashIntArray = 0;
|
||||
if (IntArray != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < IntArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = IntArray[___i0].GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashIntArray = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashStringArray = 0;
|
||||
if (StringArray != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < StringArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = StringArray[___i0] == null ? 0 : StringArray[___i0].GetHashCode();
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashStringArray = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashIntArrayArrayList = 0;
|
||||
if (IntArrayArrayList != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < IntArrayArrayList.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = IntArrayArrayList[___i0];
|
||||
var ___out1 = 0;
|
||||
if (___tmp0 != null)
|
||||
{
|
||||
var ___hc1 = new System.HashCode();
|
||||
for (int ___i1 = 0; ___i1 < ___tmp0.Length; ___i1++)
|
||||
{
|
||||
var ___out2 = 0;
|
||||
if (___tmp0[___i1] != null)
|
||||
{
|
||||
var ___hc2 = new System.HashCode();
|
||||
for (int ___i2 = 0; ___i2 < ___tmp0[___i1].Length; ___i2++)
|
||||
{
|
||||
var ___out3 = ___tmp0[___i1][___i2].GetHashCode();
|
||||
___hc2.Add(___out3);
|
||||
}
|
||||
___out2 = ___hc2.ToHashCode();
|
||||
}
|
||||
___hc1.Add(___out2);
|
||||
}
|
||||
___out1 = ___hc1.ToHashCode();
|
||||
}
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashIntArrayArrayList = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashIntListListArray = 0;
|
||||
if (IntListListArray != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < IntListListArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = 0;
|
||||
if (IntListListArray[___i0] != null)
|
||||
{
|
||||
var ___hc1 = new System.HashCode();
|
||||
for (int ___i1 = 0; ___i1 < IntListListArray[___i0].Count; ___i1++)
|
||||
{
|
||||
var ___tmp1 = IntListListArray[___i0][___i1];
|
||||
var ___out2 = 0;
|
||||
if (___tmp1 != null)
|
||||
{
|
||||
var ___hc2 = new System.HashCode();
|
||||
for (int ___i2 = 0; ___i2 < ___tmp1.Count; ___i2++)
|
||||
{
|
||||
var ___tmp2 = ___tmp1[___i2];
|
||||
var ___out3 = ___tmp2.GetHashCode();
|
||||
___hc2.Add(___out3);
|
||||
}
|
||||
___out2 = ___hc2.ToHashCode();
|
||||
}
|
||||
___hc1.Add(___out2);
|
||||
}
|
||||
___out1 = ___hc1.ToHashCode();
|
||||
}
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashIntListListArray = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashStringArrayArrayList = 0;
|
||||
if (StringArrayArrayList != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < StringArrayArrayList.Count; ___i0++)
|
||||
{
|
||||
var ___tmp0 = StringArrayArrayList[___i0];
|
||||
var ___out1 = 0;
|
||||
if (___tmp0 != null)
|
||||
{
|
||||
var ___hc1 = new System.HashCode();
|
||||
for (int ___i1 = 0; ___i1 < ___tmp0.Length; ___i1++)
|
||||
{
|
||||
var ___out2 = 0;
|
||||
if (___tmp0[___i1] != null)
|
||||
{
|
||||
var ___hc2 = new System.HashCode();
|
||||
for (int ___i2 = 0; ___i2 < ___tmp0[___i1].Length; ___i2++)
|
||||
{
|
||||
var ___out3 =
|
||||
___tmp0[___i1][___i2] == null
|
||||
? 0
|
||||
: ___tmp0[___i1][___i2].GetHashCode();
|
||||
___hc2.Add(___out3);
|
||||
}
|
||||
___out2 = ___hc2.ToHashCode();
|
||||
}
|
||||
___hc1.Add(___out2);
|
||||
}
|
||||
___out1 = ___hc1.ToHashCode();
|
||||
}
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashStringArrayArrayList = ___hc0.ToHashCode();
|
||||
}
|
||||
var ___hashStringListListArray = 0;
|
||||
if (StringListListArray != null)
|
||||
{
|
||||
var ___hc0 = new System.HashCode();
|
||||
for (int ___i0 = 0; ___i0 < StringListListArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = 0;
|
||||
if (StringListListArray[___i0] != null)
|
||||
{
|
||||
var ___hc1 = new System.HashCode();
|
||||
for (int ___i1 = 0; ___i1 < StringListListArray[___i0].Count; ___i1++)
|
||||
{
|
||||
var ___tmp1 = StringListListArray[___i0][___i1];
|
||||
var ___out2 = 0;
|
||||
if (___tmp1 != null)
|
||||
{
|
||||
var ___hc2 = new System.HashCode();
|
||||
for (int ___i2 = 0; ___i2 < ___tmp1.Count; ___i2++)
|
||||
{
|
||||
var ___tmp2 = ___tmp1[___i2];
|
||||
var ___out3 = ___tmp2 == null ? 0 : ___tmp2.GetHashCode();
|
||||
___hc2.Add(___out3);
|
||||
}
|
||||
___out2 = ___hc2.ToHashCode();
|
||||
}
|
||||
___hc1.Add(___out2);
|
||||
}
|
||||
___out1 = ___hc1.ToHashCode();
|
||||
}
|
||||
___hc0.Add(___out1);
|
||||
}
|
||||
___hashStringListListArray = ___hc0.ToHashCode();
|
||||
}
|
||||
return ___hashIntList
|
||||
^ ___hashStringList
|
||||
^ ___hashIntArray
|
||||
^ ___hashStringArray
|
||||
^ ___hashIntArrayArrayList
|
||||
^ ___hashIntListListArray
|
||||
^ ___hashStringArrayArrayList
|
||||
^ ___hashStringListListArray;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(ContainsNestedLists? that)
|
||||
{
|
||||
if (((object?)that) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var ___eqIntList = true;
|
||||
if (this.IntList == null || that.IntList == null)
|
||||
{
|
||||
___eqIntList = this.IntList == that.IntList;
|
||||
}
|
||||
else if (this.IntList.Count != that.IntList.Count)
|
||||
{
|
||||
___eqIntList = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.IntList.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.IntList[___i0];
|
||||
var ___tmpB0 = that.IntList[___i0];
|
||||
var ___out1 = ___tmpA0.Equals(___tmpB0);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqIntList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqStringList = true;
|
||||
if (this.StringList == null || that.StringList == null)
|
||||
{
|
||||
___eqStringList = this.StringList == that.StringList;
|
||||
}
|
||||
else if (this.StringList.Count != that.StringList.Count)
|
||||
{
|
||||
___eqStringList = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.StringList.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.StringList[___i0];
|
||||
var ___tmpB0 = that.StringList[___i0];
|
||||
var ___out1 = ___tmpA0 == null ? ___tmpB0 == null : ___tmpA0.Equals(___tmpB0);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqStringList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqIntArray = true;
|
||||
if (this.IntArray == null || that.IntArray == null)
|
||||
{
|
||||
___eqIntArray = this.IntArray == that.IntArray;
|
||||
}
|
||||
else if (this.IntArray.Length != that.IntArray.Length)
|
||||
{
|
||||
___eqIntArray = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.IntArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = this.IntArray[___i0].Equals(that.IntArray[___i0]);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqIntArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqStringArray = true;
|
||||
if (this.StringArray == null || that.StringArray == null)
|
||||
{
|
||||
___eqStringArray = this.StringArray == that.StringArray;
|
||||
}
|
||||
else if (this.StringArray.Length != that.StringArray.Length)
|
||||
{
|
||||
___eqStringArray = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.StringArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 =
|
||||
this.StringArray[___i0] == null
|
||||
? that.StringArray[___i0] == null
|
||||
: this.StringArray[___i0].Equals(that.StringArray[___i0]);
|
||||
if (!___out1)
|
||||
{
|
||||
___eqStringArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqIntArrayArrayList = true;
|
||||
if (this.IntArrayArrayList == null || that.IntArrayArrayList == null)
|
||||
{
|
||||
___eqIntArrayArrayList = this.IntArrayArrayList == that.IntArrayArrayList;
|
||||
}
|
||||
else if (this.IntArrayArrayList.Count != that.IntArrayArrayList.Count)
|
||||
{
|
||||
___eqIntArrayArrayList = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.IntArrayArrayList.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.IntArrayArrayList[___i0];
|
||||
var ___tmpB0 = that.IntArrayArrayList[___i0];
|
||||
var ___out1 = true;
|
||||
if (___tmpA0 == null || ___tmpB0 == null)
|
||||
{
|
||||
___out1 = ___tmpA0 == ___tmpB0;
|
||||
}
|
||||
else if (___tmpA0.Length != ___tmpB0.Length)
|
||||
{
|
||||
___out1 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i1 = 0; ___i1 < ___tmpA0.Length; ___i1++)
|
||||
{
|
||||
var ___out2 = true;
|
||||
if (___tmpA0[___i1] == null || ___tmpB0[___i1] == null)
|
||||
{
|
||||
___out2 = ___tmpA0[___i1] == ___tmpB0[___i1];
|
||||
}
|
||||
else if (___tmpA0[___i1].Length != ___tmpB0[___i1].Length)
|
||||
{
|
||||
___out2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i2 = 0; ___i2 < ___tmpA0[___i1].Length; ___i2++)
|
||||
{
|
||||
var ___out3 = ___tmpA0[___i1][___i2].Equals(___tmpB0[___i1][___i2]);
|
||||
if (!___out3)
|
||||
{
|
||||
___out2 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out2)
|
||||
{
|
||||
___out1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out1)
|
||||
{
|
||||
___eqIntArrayArrayList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqIntListListArray = true;
|
||||
if (this.IntListListArray == null || that.IntListListArray == null)
|
||||
{
|
||||
___eqIntListListArray = this.IntListListArray == that.IntListListArray;
|
||||
}
|
||||
else if (this.IntListListArray.Length != that.IntListListArray.Length)
|
||||
{
|
||||
___eqIntListListArray = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.IntListListArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = true;
|
||||
if (this.IntListListArray[___i0] == null || that.IntListListArray[___i0] == null)
|
||||
{
|
||||
___out1 = this.IntListListArray[___i0] == that.IntListListArray[___i0];
|
||||
}
|
||||
else if (this.IntListListArray[___i0].Count != that.IntListListArray[___i0].Count)
|
||||
{
|
||||
___out1 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i1 = 0; ___i1 < this.IntListListArray[___i0].Count; ___i1++)
|
||||
{
|
||||
var ___tmpA1 = this.IntListListArray[___i0][___i1];
|
||||
var ___tmpB1 = that.IntListListArray[___i0][___i1];
|
||||
var ___out2 = true;
|
||||
if (___tmpA1 == null || ___tmpB1 == null)
|
||||
{
|
||||
___out2 = ___tmpA1 == ___tmpB1;
|
||||
}
|
||||
else if (___tmpA1.Count != ___tmpB1.Count)
|
||||
{
|
||||
___out2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i2 = 0; ___i2 < ___tmpA1.Count; ___i2++)
|
||||
{
|
||||
var ___tmpA2 = ___tmpA1[___i2];
|
||||
var ___tmpB2 = ___tmpB1[___i2];
|
||||
var ___out3 = ___tmpA2.Equals(___tmpB2);
|
||||
if (!___out3)
|
||||
{
|
||||
___out2 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out2)
|
||||
{
|
||||
___out1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out1)
|
||||
{
|
||||
___eqIntListListArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqStringArrayArrayList = true;
|
||||
if (this.StringArrayArrayList == null || that.StringArrayArrayList == null)
|
||||
{
|
||||
___eqStringArrayArrayList = this.StringArrayArrayList == that.StringArrayArrayList;
|
||||
}
|
||||
else if (this.StringArrayArrayList.Count != that.StringArrayArrayList.Count)
|
||||
{
|
||||
___eqStringArrayArrayList = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.StringArrayArrayList.Count; ___i0++)
|
||||
{
|
||||
var ___tmpA0 = this.StringArrayArrayList[___i0];
|
||||
var ___tmpB0 = that.StringArrayArrayList[___i0];
|
||||
var ___out1 = true;
|
||||
if (___tmpA0 == null || ___tmpB0 == null)
|
||||
{
|
||||
___out1 = ___tmpA0 == ___tmpB0;
|
||||
}
|
||||
else if (___tmpA0.Length != ___tmpB0.Length)
|
||||
{
|
||||
___out1 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i1 = 0; ___i1 < ___tmpA0.Length; ___i1++)
|
||||
{
|
||||
var ___out2 = true;
|
||||
if (___tmpA0[___i1] == null || ___tmpB0[___i1] == null)
|
||||
{
|
||||
___out2 = ___tmpA0[___i1] == ___tmpB0[___i1];
|
||||
}
|
||||
else if (___tmpA0[___i1].Length != ___tmpB0[___i1].Length)
|
||||
{
|
||||
___out2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i2 = 0; ___i2 < ___tmpA0[___i1].Length; ___i2++)
|
||||
{
|
||||
var ___out3 =
|
||||
___tmpA0[___i1][___i2] == null
|
||||
? ___tmpB0[___i1][___i2] == null
|
||||
: ___tmpA0[___i1][___i2].Equals(___tmpB0[___i1][___i2]);
|
||||
if (!___out3)
|
||||
{
|
||||
___out2 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out2)
|
||||
{
|
||||
___out1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out1)
|
||||
{
|
||||
___eqStringArrayArrayList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var ___eqStringListListArray = true;
|
||||
if (this.StringListListArray == null || that.StringListListArray == null)
|
||||
{
|
||||
___eqStringListListArray = this.StringListListArray == that.StringListListArray;
|
||||
}
|
||||
else if (this.StringListListArray.Length != that.StringListListArray.Length)
|
||||
{
|
||||
___eqStringListListArray = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i0 = 0; ___i0 < this.StringListListArray.Length; ___i0++)
|
||||
{
|
||||
var ___out1 = true;
|
||||
if (
|
||||
this.StringListListArray[___i0] == null
|
||||
|| that.StringListListArray[___i0] == null
|
||||
)
|
||||
{
|
||||
___out1 = this.StringListListArray[___i0] == that.StringListListArray[___i0];
|
||||
}
|
||||
else if (
|
||||
this.StringListListArray[___i0].Count != that.StringListListArray[___i0].Count
|
||||
)
|
||||
{
|
||||
___out1 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i1 = 0; ___i1 < this.StringListListArray[___i0].Count; ___i1++)
|
||||
{
|
||||
var ___tmpA1 = this.StringListListArray[___i0][___i1];
|
||||
var ___tmpB1 = that.StringListListArray[___i0][___i1];
|
||||
var ___out2 = true;
|
||||
if (___tmpA1 == null || ___tmpB1 == null)
|
||||
{
|
||||
___out2 = ___tmpA1 == ___tmpB1;
|
||||
}
|
||||
else if (___tmpA1.Count != ___tmpB1.Count)
|
||||
{
|
||||
___out2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int ___i2 = 0; ___i2 < ___tmpA1.Count; ___i2++)
|
||||
{
|
||||
var ___tmpA2 = ___tmpA1[___i2];
|
||||
var ___tmpB2 = ___tmpB1[___i2];
|
||||
var ___out3 =
|
||||
___tmpA2 == null ? ___tmpB2 == null : ___tmpA2.Equals(___tmpB2);
|
||||
if (!___out3)
|
||||
{
|
||||
___out2 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out2)
|
||||
{
|
||||
___out1 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!___out1)
|
||||
{
|
||||
___eqStringListListArray = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ___eqIntList
|
||||
&& ___eqStringList
|
||||
&& ___eqIntArray
|
||||
&& ___eqStringArray
|
||||
&& ___eqIntArrayArrayList
|
||||
&& ___eqIntListListArray
|
||||
&& ___eqStringArrayArrayList
|
||||
&& ___eqStringListListArray;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
{
|
||||
if (that == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var that_ = that as ContainsNestedLists;
|
||||
if (((object?)that_) == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Equals(that_);
|
||||
}
|
||||
|
||||
public static bool operator ==(ContainsNestedLists? this_, ContainsNestedLists? that)
|
||||
{
|
||||
if (((object?)this_) == null || ((object?)that) == null)
|
||||
{
|
||||
return object.Equals(this_, that);
|
||||
}
|
||||
return this_.Equals(that);
|
||||
}
|
||||
|
||||
public static bool operator !=(ContainsNestedLists? this_, ContainsNestedLists? that)
|
||||
{
|
||||
if (((object?)this_) == null || ((object?)that) == null)
|
||||
{
|
||||
return !object.Equals(this_, that);
|
||||
}
|
||||
return !this_.Equals(that);
|
||||
}
|
||||
#nullable restore
|
||||
} // ContainsNestedLists
|
||||
+24
-12
@@ -67,10 +67,15 @@ partial class CustomClass : System.IEquatable<CustomClass>, SpacetimeDB.BSATN.IS
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IntField.GetHashCode()
|
||||
^ StringField.GetHashCode()
|
||||
^ NullableIntField.GetHashCode()
|
||||
^ (NullableStringField == null ? 0 : NullableStringField.GetHashCode());
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
var ___hashNullableIntField = NullableIntField.GetHashCode();
|
||||
var ___hashNullableStringField =
|
||||
NullableStringField == null ? 0 : NullableStringField.GetHashCode();
|
||||
return ___hashIntField
|
||||
^ ___hashStringField
|
||||
^ ___hashNullableIntField
|
||||
^ ___hashNullableStringField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
@@ -80,14 +85,21 @@ partial class CustomClass : System.IEquatable<CustomClass>, SpacetimeDB.BSATN.IS
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IntField.Equals(that.IntField)
|
||||
&& StringField.Equals(that.StringField)
|
||||
&& NullableIntField.Equals(that.NullableIntField)
|
||||
&& (
|
||||
NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: NullableStringField.Equals(that.NullableStringField)
|
||||
);
|
||||
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
var ___eqNullableIntField = this.NullableIntField.Equals(that.NullableIntField);
|
||||
var ___eqNullableStringField =
|
||||
this.NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: this.NullableStringField.Equals(that.NullableStringField);
|
||||
return ___eqIntField
|
||||
&& ___eqStringField
|
||||
&& ___eqNullableIntField
|
||||
&& ___eqNullableStringField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+55
-28
@@ -105,14 +105,26 @@ partial class CustomNestedClass
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return NestedClass.GetHashCode()
|
||||
^ (NestedNullableClass == null ? 0 : NestedNullableClass.GetHashCode())
|
||||
^ NestedEnum.GetHashCode()
|
||||
^ NestedNullableEnum.GetHashCode()
|
||||
^ NestedTaggedEnum.GetHashCode()
|
||||
^ (NestedNullableTaggedEnum == null ? 0 : NestedNullableTaggedEnum.GetHashCode())
|
||||
^ NestedCustomRecord.GetHashCode()
|
||||
^ (NestedNullableCustomRecord == null ? 0 : NestedNullableCustomRecord.GetHashCode());
|
||||
var ___hashNestedClass = NestedClass == null ? 0 : NestedClass.GetHashCode();
|
||||
var ___hashNestedNullableClass =
|
||||
NestedNullableClass == null ? 0 : NestedNullableClass.GetHashCode();
|
||||
var ___hashNestedEnum = NestedEnum.GetHashCode();
|
||||
var ___hashNestedNullableEnum = NestedNullableEnum.GetHashCode();
|
||||
var ___hashNestedTaggedEnum = NestedTaggedEnum == null ? 0 : NestedTaggedEnum.GetHashCode();
|
||||
var ___hashNestedNullableTaggedEnum =
|
||||
NestedNullableTaggedEnum == null ? 0 : NestedNullableTaggedEnum.GetHashCode();
|
||||
var ___hashNestedCustomRecord =
|
||||
NestedCustomRecord == null ? 0 : NestedCustomRecord.GetHashCode();
|
||||
var ___hashNestedNullableCustomRecord =
|
||||
NestedNullableCustomRecord == null ? 0 : NestedNullableCustomRecord.GetHashCode();
|
||||
return ___hashNestedClass
|
||||
^ ___hashNestedNullableClass
|
||||
^ ___hashNestedEnum
|
||||
^ ___hashNestedNullableEnum
|
||||
^ ___hashNestedTaggedEnum
|
||||
^ ___hashNestedNullableTaggedEnum
|
||||
^ ___hashNestedCustomRecord
|
||||
^ ___hashNestedNullableCustomRecord;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
@@ -122,26 +134,41 @@ partial class CustomNestedClass
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return NestedClass.Equals(that.NestedClass)
|
||||
&& (
|
||||
NestedNullableClass == null
|
||||
? that.NestedNullableClass == null
|
||||
: NestedNullableClass.Equals(that.NestedNullableClass)
|
||||
)
|
||||
&& NestedEnum.Equals(that.NestedEnum)
|
||||
&& NestedNullableEnum.Equals(that.NestedNullableEnum)
|
||||
&& NestedTaggedEnum.Equals(that.NestedTaggedEnum)
|
||||
&& (
|
||||
NestedNullableTaggedEnum == null
|
||||
? that.NestedNullableTaggedEnum == null
|
||||
: NestedNullableTaggedEnum.Equals(that.NestedNullableTaggedEnum)
|
||||
)
|
||||
&& NestedCustomRecord.Equals(that.NestedCustomRecord)
|
||||
&& (
|
||||
NestedNullableCustomRecord == null
|
||||
? that.NestedNullableCustomRecord == null
|
||||
: NestedNullableCustomRecord.Equals(that.NestedNullableCustomRecord)
|
||||
);
|
||||
|
||||
var ___eqNestedClass =
|
||||
this.NestedClass == null
|
||||
? that.NestedClass == null
|
||||
: this.NestedClass.Equals(that.NestedClass);
|
||||
var ___eqNestedNullableClass =
|
||||
this.NestedNullableClass == null
|
||||
? that.NestedNullableClass == null
|
||||
: this.NestedNullableClass.Equals(that.NestedNullableClass);
|
||||
var ___eqNestedEnum = this.NestedEnum.Equals(that.NestedEnum);
|
||||
var ___eqNestedNullableEnum = this.NestedNullableEnum.Equals(that.NestedNullableEnum);
|
||||
var ___eqNestedTaggedEnum =
|
||||
this.NestedTaggedEnum == null
|
||||
? that.NestedTaggedEnum == null
|
||||
: this.NestedTaggedEnum.Equals(that.NestedTaggedEnum);
|
||||
var ___eqNestedNullableTaggedEnum =
|
||||
this.NestedNullableTaggedEnum == null
|
||||
? that.NestedNullableTaggedEnum == null
|
||||
: this.NestedNullableTaggedEnum.Equals(that.NestedNullableTaggedEnum);
|
||||
var ___eqNestedCustomRecord =
|
||||
this.NestedCustomRecord == null
|
||||
? that.NestedCustomRecord == null
|
||||
: this.NestedCustomRecord.Equals(that.NestedCustomRecord);
|
||||
var ___eqNestedNullableCustomRecord =
|
||||
this.NestedNullableCustomRecord == null
|
||||
? that.NestedNullableCustomRecord == null
|
||||
: this.NestedNullableCustomRecord.Equals(that.NestedNullableCustomRecord);
|
||||
return ___eqNestedClass
|
||||
&& ___eqNestedNullableClass
|
||||
&& ___eqNestedEnum
|
||||
&& ___eqNestedNullableEnum
|
||||
&& ___eqNestedTaggedEnum
|
||||
&& ___eqNestedNullableTaggedEnum
|
||||
&& ___eqNestedCustomRecord
|
||||
&& ___eqNestedNullableCustomRecord;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+24
-12
@@ -67,10 +67,15 @@ partial class CustomRecord : System.IEquatable<CustomRecord>, SpacetimeDB.BSATN.
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IntField.GetHashCode()
|
||||
^ StringField.GetHashCode()
|
||||
^ NullableIntField.GetHashCode()
|
||||
^ (NullableStringField == null ? 0 : NullableStringField.GetHashCode());
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
var ___hashNullableIntField = NullableIntField.GetHashCode();
|
||||
var ___hashNullableStringField =
|
||||
NullableStringField == null ? 0 : NullableStringField.GetHashCode();
|
||||
return ___hashIntField
|
||||
^ ___hashStringField
|
||||
^ ___hashNullableIntField
|
||||
^ ___hashNullableStringField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
@@ -80,14 +85,21 @@ partial class CustomRecord : System.IEquatable<CustomRecord>, SpacetimeDB.BSATN.
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IntField.Equals(that.IntField)
|
||||
&& StringField.Equals(that.StringField)
|
||||
&& NullableIntField.Equals(that.NullableIntField)
|
||||
&& (
|
||||
NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: NullableStringField.Equals(that.NullableStringField)
|
||||
);
|
||||
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
var ___eqNullableIntField = this.NullableIntField.Equals(that.NullableIntField);
|
||||
var ___eqNullableStringField =
|
||||
this.NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: this.NullableStringField.Equals(that.NullableStringField);
|
||||
return ___eqIntField
|
||||
&& ___eqStringField
|
||||
&& ___eqNullableIntField
|
||||
&& ___eqNullableStringField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+23
-12
@@ -69,23 +69,34 @@ partial struct CustomStruct
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return IntField.GetHashCode()
|
||||
^ StringField.GetHashCode()
|
||||
^ NullableIntField.GetHashCode()
|
||||
^ (NullableStringField == null ? 0 : NullableStringField.GetHashCode());
|
||||
var ___hashIntField = IntField.GetHashCode();
|
||||
var ___hashStringField = StringField == null ? 0 : StringField.GetHashCode();
|
||||
var ___hashNullableIntField = NullableIntField.GetHashCode();
|
||||
var ___hashNullableStringField =
|
||||
NullableStringField == null ? 0 : NullableStringField.GetHashCode();
|
||||
return ___hashIntField
|
||||
^ ___hashStringField
|
||||
^ ___hashNullableIntField
|
||||
^ ___hashNullableStringField;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public bool Equals(CustomStruct that)
|
||||
{
|
||||
return IntField.Equals(that.IntField)
|
||||
&& StringField.Equals(that.StringField)
|
||||
&& NullableIntField.Equals(that.NullableIntField)
|
||||
&& (
|
||||
NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: NullableStringField.Equals(that.NullableStringField)
|
||||
);
|
||||
var ___eqIntField = this.IntField.Equals(that.IntField);
|
||||
var ___eqStringField =
|
||||
this.StringField == null
|
||||
? that.StringField == null
|
||||
: this.StringField.Equals(that.StringField);
|
||||
var ___eqNullableIntField = this.NullableIntField.Equals(that.NullableIntField);
|
||||
var ___eqNullableStringField =
|
||||
this.NullableStringField == null
|
||||
? that.NullableStringField == null
|
||||
: this.NullableStringField.Equals(that.NullableStringField);
|
||||
return ___eqIntField
|
||||
&& ___eqStringField
|
||||
&& ___eqNullableIntField
|
||||
&& ___eqNullableStringField;
|
||||
}
|
||||
|
||||
public override bool Equals(object? that)
|
||||
|
||||
+8
-4
@@ -115,13 +115,17 @@ partial record CustomTaggedEnum : System.IEquatable<CustomTaggedEnum>
|
||||
switch (this)
|
||||
{
|
||||
case IntVariant(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashIntVariant = inner.GetHashCode();
|
||||
return ___hashIntVariant;
|
||||
case StringVariant(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashStringVariant = inner == null ? 0 : inner.GetHashCode();
|
||||
return ___hashStringVariant;
|
||||
case NullableIntVariant(var inner):
|
||||
return inner.GetHashCode();
|
||||
var ___hashNullableIntVariant = inner.GetHashCode();
|
||||
return ___hashNullableIntVariant;
|
||||
case NullableStringVariant(var inner):
|
||||
return inner == null ? 0 : inner.GetHashCode();
|
||||
var ___hashNullableStringVariant = inner == null ? 0 : inner.GetHashCode();
|
||||
return ___hashNullableStringVariant;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ partial class EmptyClass : System.IEquatable<EmptyClass>, SpacetimeDB.BSATN.IStr
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,13 +169,18 @@ record TableView
|
||||
try
|
||||
{
|
||||
Scheduled = new(reducer, scheduledAtIndex);
|
||||
if (table.GetPrimaryKey(this) is not { } pk || table.Members[pk].Type != "ulong")
|
||||
if (
|
||||
table.GetPrimaryKey(this) is not { } pk
|
||||
|| table.Members[pk].Type.Name != "ulong"
|
||||
)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{Name} is a scheduled table but doesn't have a primary key of type `ulong`."
|
||||
);
|
||||
}
|
||||
if (table.Members[Scheduled.ScheduledAtColumn].Type != "SpacetimeDB.ScheduleAt")
|
||||
if (
|
||||
table.Members[Scheduled.ScheduledAtColumn].Type.Name != "SpacetimeDB.ScheduleAt"
|
||||
)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{Name}.{attr.ScheduledAt} is marked with `ScheduledAt`, but doesn't have the expected type `SpacetimeDB.ScheduleAt`."
|
||||
@@ -388,12 +393,12 @@ record TableDeclaration : BaseTypeDeclaration<ColumnDeclaration>
|
||||
}
|
||||
var standardIndexName = ct.ToIndex().StandardIndexName(view);
|
||||
yield return $$"""
|
||||
{{vis}} sealed class {{f.Name}}UniqueIndex : UniqueIndex<{{view.Name}}, {{globalName}}, {{f.Type}}, {{f.TypeInfo}}> {
|
||||
{{vis}} sealed class {{f.Name}}UniqueIndex : UniqueIndex<{{view.Name}}, {{globalName}}, {{f.Type.Name}}, {{f.Type.BSATNName}}> {
|
||||
internal {{f.Name}}UniqueIndex() : base("{{standardIndexName}}") {}
|
||||
// Important: don't move this to the base class.
|
||||
// C# generics don't play well with nullable types and can't accept both struct-type-based and class-type-based
|
||||
// `globalName` in one generic definition, leading to buggy `Row?` expansion for either one or another.
|
||||
public {{globalName}}? Find({{f.Type}} key) => DoFilter(key).Cast<{{globalName}}?>().SingleOrDefault();
|
||||
public {{globalName}}? Find({{f.Type.Name}} key) => DoFilter(key).Cast<{{globalName}}?>().SingleOrDefault();
|
||||
public {{globalName}} Update({{globalName}} row) => DoUpdate(row);
|
||||
}
|
||||
{{vis}} {{f.Name}}UniqueIndex {{f.Name}} => new();
|
||||
@@ -422,11 +427,11 @@ record TableDeclaration : BaseTypeDeclaration<ColumnDeclaration>
|
||||
{
|
||||
var types = string.Join(
|
||||
", ",
|
||||
members.Take(n + 1).Select(m => $"{m.Type}, {m.TypeInfo}")
|
||||
members.Take(n + 1).Select(m => $"{m.Type.Name}, {m.Type.BSATNName}")
|
||||
);
|
||||
var scalars = members.Take(n).Select(m => $"{m.Type} {m.Name}");
|
||||
var lastScalar = $"{members[n].Type} {members[n].Name}";
|
||||
var lastBounds = $"Bound<{members[n].Type}> {members[n].Name}";
|
||||
var scalars = members.Take(n).Select(m => $"{m.Type.Name} {m.Name}");
|
||||
var lastScalar = $"{members[n].Type.Name} {members[n].Name}";
|
||||
var lastBounds = $"Bound<{members[n].Type.Name}> {members[n].Name}";
|
||||
var argsScalar = string.Join(", ", scalars.Append(lastScalar));
|
||||
var argsBounds = string.Join(", ", scalars.Append(lastBounds));
|
||||
string argName;
|
||||
@@ -672,13 +677,13 @@ record ReducerDeclaration
|
||||
[System.Diagnostics.CodeAnalysis.Experimental("STDB_UNSTABLE")]
|
||||
public static void VolatileNonatomicScheduleImmediate{{Name}}({{string.Join(
|
||||
", ",
|
||||
Args.Select(a => $"{a.Type} {a.Name}")
|
||||
Args.Select(a => $"{a.Type.Name} {a.Name}")
|
||||
)}}) {
|
||||
using var stream = new MemoryStream();
|
||||
using var writer = new BinaryWriter(stream);
|
||||
{{string.Join(
|
||||
"\n",
|
||||
Args.Select(a => $"new {a.TypeInfo}().Write(writer, {a.Name});")
|
||||
Args.Select(a => $"new {a.Type.BSATNName}().Write(writer, {a.Name});")
|
||||
)}}
|
||||
SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate(nameof({{Name}}), stream);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user