diff --git a/Cargo.lock b/Cargo.lock index 78d877eb29e..655f2fe8e04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5157,9 +5157,9 @@ dependencies = [ "itertools 0.12.1", "lazy_static", "petgraph", - "pretty_assertions", "proptest", "serde_json", + "serial_test", "smallvec", "spacetimedb-cli", "spacetimedb-data-structures", diff --git a/crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj b/crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj index 6edb39ed2d5..647cb6c273e 100644 --- a/crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj +++ b/crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj @@ -2,7 +2,7 @@ SpacetimeDB.BSATN.Codegen - 1.0.0-rc1-hotfix1 + 1.0.0-rc2 SpacetimeDB BSATN Codegen The SpacetimeDB BSATN Codegen implements the Roslyn incremental generators for BSATN serialization/deserialization in C#. diff --git a/crates/bindings-csharp/BSATN.Codegen/Diag.cs b/crates/bindings-csharp/BSATN.Codegen/Diag.cs index 7a60a2a8c68..2ae3b2513ba 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Diag.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Diag.cs @@ -91,10 +91,41 @@ Func toLocation ) : this(group, title, interpolate, ctx => toLocation(ctx).Locations.FirstOrDefault()) { } + public ErrorDescriptor( + ErrorDescriptorGroup group, + string title, + Expression> interpolate, + Func toLocation + ) + : this( + group, + title, + interpolate, + ctx => + toLocation(ctx).ApplicationSyntaxReference is { } r + ? r.SyntaxTree.GetLocation(r.Span) + : null + ) { } + public Diagnostic ToDiag(TContext ctx) => Diagnostic.Create(descriptor, toLocation(ctx), makeFormatArgs(ctx)); } +/// +/// No-op error descriptor placeholder. +/// +/// Error descriptors must have strong ID to avoid breaking semver, since they are used for diagnostic suppression by users. +/// To ensure this, we cannot reorder to delete unused diagnostics - instead, we need to put some placeholders where they used to be. +/// This class serves that purpose - it's a no-op error descriptor that you can instantiate just to reserve said ID. +/// +public sealed class UnusedErrorDescriptor +{ + public UnusedErrorDescriptor(ErrorDescriptorGroup group) + { + group.NextId(); + } +} + internal static class ErrorDescriptor { private static readonly ErrorDescriptorGroup group = new("BSATN", "SpacetimeDB.BSATN"); diff --git a/crates/bindings-csharp/BSATN.Codegen/Type.cs b/crates/bindings-csharp/BSATN.Codegen/Type.cs index 73197c86b44..44f662f0d7f 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Type.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Type.cs @@ -234,10 +234,13 @@ public void Write(System.IO.BinaryWriter writer, {{FullName}} value) { {{write}} } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType(SpacetimeDB.BSATN.ITypeRegistrar registrar) => registrar.RegisterType<{{FullName}}>(_ => new SpacetimeDB.BSATN.AlgebraicType.{{Kind}}(new SpacetimeDB.BSATN.AggregateElement[] { {{MemberDeclaration.GenerateDefs(Members)}} })); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite<{{FullName}}>.GetAlgebraicType(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + GetAlgebraicType(registrar); } """ ); diff --git a/crates/bindings-csharp/BSATN.Codegen/Utils.cs b/crates/bindings-csharp/BSATN.Codegen/Utils.cs index 5f7ee915af6..7c9964b7a01 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Utils.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Utils.cs @@ -313,7 +313,11 @@ public override string ToString() sb.Append(" : ").AppendJoin(", ", BaseTypes); } - sb.Append(typeScope.Constraints).AppendLine(" {"); + if (typeScope.Constraints.Length > 0) + { + sb.Append(' ').Append(typeScope.Constraints); + } + sb.AppendLine(" {"); } sb.AppendLine(); diff --git a/crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj b/crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj index 5b795237723..0cc0841f96b 100644 --- a/crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj +++ b/crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj @@ -2,7 +2,7 @@ SpacetimeDB.BSATN.Runtime - 1.0.0-rc1-hotfix1 + 1.0.0-rc2 SpacetimeDB BSATN Runtime The SpacetimeDB BSATN Runtime implements APIs for BSATN serialization/deserialization in C#. diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomClass.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomClass.verified.cs index f1c7727c41d..9493914333f 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomClass.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomClass.verified.cs @@ -29,7 +29,7 @@ public void Write(System.IO.BinaryWriter writer, CustomClass value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -39,5 +39,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringField), StringField.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomClass diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomStruct.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomStruct.verified.cs index 855a5757c9c..95a910c8f01 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomStruct.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomStruct.verified.cs @@ -29,7 +29,7 @@ public void Write(System.IO.BinaryWriter writer, CustomStruct value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -39,5 +39,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringField), StringField.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomStruct diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomTaggedEnum.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomTaggedEnum.verified.cs index 66edf6ee00d..d9be5d8eb86 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomTaggedEnum.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#CustomTaggedEnum.verified.cs @@ -48,7 +48,7 @@ public void Write(System.IO.BinaryWriter writer, CustomTaggedEnum value) } } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Sum( @@ -58,5 +58,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringVariant), StringVariant.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomTaggedEnum diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#PublicTable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#PublicTable.verified.cs index 3a47ce3009f..e993d0875c6 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#PublicTable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/client/snapshots/Type#PublicTable.verified.cs @@ -105,7 +105,7 @@ public void Write(System.IO.BinaryWriter writer, PublicTable value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -144,5 +144,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar ) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // PublicTable diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs index 61423e76db3..8b485188a7f 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/Lib.cs @@ -361,20 +361,6 @@ public static partial class InAnotherNamespace public partial struct TestDuplicateTableName { } } -[SpacetimeDB.Table( - Name = "TestIncompatibleSchedule1", - Scheduled = nameof(TestIncompatibleScheduleReducer) -)] -[SpacetimeDB.Table(Name = "TestIncompatibleSchedule2")] -public partial struct TestIncompatibleSchedule -{ - [SpacetimeDB.Reducer] - public static void TestIncompatibleScheduleReducer( - ReducerContext ctx, - TestIncompatibleSchedule table - ) { } -} - [SpacetimeDB.Table] [SpacetimeDB.Index] public partial struct TestIndexWithoutColumns { } @@ -382,3 +368,35 @@ public partial struct TestIndexWithoutColumns { } [SpacetimeDB.Table] [SpacetimeDB.Index(BTree = [])] public partial struct TestIndexWithEmptyColumns { } + +[SpacetimeDB.Table( + Name = "TestScheduleWithoutPrimaryKey", + Scheduled = "DummyScheduledReducer", + ScheduledAt = nameof(ScheduleAtCorrectType) +)] +[SpacetimeDB.Table( + Name = "TestScheduleWithWrongPrimaryKeyType", + Scheduled = "DummyScheduledReducer", + ScheduledAt = nameof(ScheduleAtCorrectType) +)] +[SpacetimeDB.Table(Name = "TestScheduleWithoutScheduleAt", Scheduled = "DummyScheduledReducer")] +[SpacetimeDB.Table( + Name = "TestScheduleWithWrongScheduleAtType", + Scheduled = "DummyScheduledReducer", + ScheduledAt = nameof(ScheduleAtWrongType) +)] +public partial struct TestScheduleIssues +{ + [SpacetimeDB.PrimaryKey(Table = "TestScheduleWithWrongPrimaryKeyType")] + public string IdWrongType; + + [SpacetimeDB.PrimaryKey(Table = "TestScheduleWithoutScheduleAt")] + [SpacetimeDB.PrimaryKey(Table = "TestScheduleWithWrongScheduleAtType")] + public int IdCorrectType; + + public int ScheduleAtWrongType; + public ScheduleAt ScheduleAtCorrectType; + + [SpacetimeDB.Reducer] + public static void DummyScheduledReducer(ReducerContext ctx, TestScheduleIssues table) { } +} diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt index 50427f075b2..465227b1cc9 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/ExtraCompilationErrors.verified.txt @@ -184,18 +184,18 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor } }, {/* - - public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_UniqueField_idx_btree") {} +} +public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { + ^^^^^^^^^^^^^^^^^^^ + static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { */ - Message: Partial declarations of 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' must not specify different base classes, + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0263, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0263), - MessageFormat: Partial declarations of '{0}' must not specify different base classes, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -207,18 +207,18 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor } }, {/* - public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_UniqueField_idx_btree") {} - ^^^^ - // Important: don't move this to the base class. +} +public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { + ^^^^^^^^^^^^^^^^^^^ + static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { */ - Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0122, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), - MessageFormat: '{0}' is inaccessible due to its protection level, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -230,18 +230,18 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor } }, {/* - // `globalName` in one generic definition, leading to buggy `Row?` expansion for either one or another. - public global::TestUniqueNotEquatable? Find(int? key) => DoFilter(key).Cast().SingleOrDefault(); - ^^^^^^^^ - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); +public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { + static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ - Message: The name 'DoFilter' does not exist in the current context, + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0103, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), - MessageFormat: The name '{0}' does not exist in the current context, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -253,18 +253,18 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor } }, {/* - public global::TestUniqueNotEquatable? Find(int? key) => DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); - ^^^^^^^^ -} +public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { + static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ - Message: The name 'DoUpdate' does not exist in the current context, + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0103, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), - MessageFormat: The name '{0}' does not exist in the current context, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -276,18 +276,18 @@ internal static readonly SpacetimeDB.BSATN.IReadWrite Unsuppor } }, {/* -} -public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); - ^^^^^^^^^ -public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Name: nameof(TestTableTaggedEnum), */ - Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0121, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), - MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -299,18 +299,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex new(this); -public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Name: nameof(TestTableTaggedEnum), */ - Message: The type 'TestUniqueNotEquatable' already contains a definition for 'TestUniqueNotEquatableUniqueIndex', + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0102, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0102), - MessageFormat: The type '{0}' already contains a definition for '{1}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -322,18 +322,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // Important: don't move this to the base class. + + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); */ - Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'TestUniqueNotEquatableUniqueIndex' with the same parameter types, + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0111, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), - MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -345,18 +345,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} - ^^^^ - // Important: don't move this to the base class. + + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); */ - Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0122, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), - MessageFormat: '{0}' is inaccessible due to its protection level, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -368,18 +368,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex DoFilter(key).Cast().SingleOrDefault(); - ^^^^^^^^ - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); */ - Message: The name 'DoFilter' does not exist in the current context, + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0103, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), - MessageFormat: The name '{0}' does not exist in the current context, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -391,18 +391,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); - ^^^^^^ -} + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); */ - Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'Update' with the same parameter types, + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0111, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), - MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -414,18 +414,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); - ^^^^^^^^ -} + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); */ - Message: The name 'DoUpdate' does not exist in the current context, + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { - Id: CS0103, + Id: CS0311, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), - MessageFormat: The name '{0}' does not exist in the current context, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -437,18 +437,18 @@ public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex new(this); - ^^^^^^^^^ -} + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); */ - Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS0121, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), - MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -460,18 +460,41 @@ public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); } }, {/* - public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.TestReducerWithoutContext((SpacetimeDB.ReducerContext)ctx); - ^^^^^^^^^^^^^^^^^^^^^^^^^ + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*/ + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., + Severity: Error, + Descriptor: { + Id: CS0311, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), + MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] } + }, + {/* + public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ - Message: No overload for method 'TestReducerWithoutContext' takes 1 arguments, + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', Severity: Error, Descriptor: { - Id: CS1501, + Id: CS0310, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS1501), - MessageFormat: No overload for method '{0}' takes {1} arguments, + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), + MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -483,18 +506,18 @@ public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); } }, {/* -SpacetimeDB.Internal.Module.RegisterTable(); -SpacetimeDB.Internal.Module.RegisterTable(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -SpacetimeDB.Internal.Module.RegisterTable(); + + public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_UniqueField_idx_btree") {} */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'Module.RegisterTable()'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: Partial declarations of 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' must not specify different base classes, Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0263, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0263), + MessageFormat: Partial declarations of '{0}' must not specify different base classes, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -506,18 +529,18 @@ SpacetimeDB.Internal.Module.RegisterTable(); } }, {/* -SpacetimeDB.Internal.Module.RegisterTable(); -SpacetimeDB.Internal.Module.RegisterTable(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -SpacetimeDB.Internal.Module.RegisterTable(); + public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_UniqueField_idx_btree") {} + ^^^^ + // Important: don't move this to the base class. */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Module.RegisterTable()', + Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, Severity: Error, Descriptor: { - Id: CS0310, + Id: CS0122, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + 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, @@ -529,18 +552,41 @@ SpacetimeDB.Internal.Module.RegisterTable(); } }, {/* + // `globalName` in one generic definition, leading to buggy `Row?` expansion for either one or another. + public global::TestUniqueNotEquatable? Find(int? key) => DoFilter(key).Cast().SingleOrDefault(); + ^^^^^^^^ + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); +*/ + Message: The name 'DoFilter' does not exist in the current context, + Severity: Error, + Descriptor: { + Id: CS0103, + Title: , + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, + Category: Compiler, + DefaultSeverity: Error, + IsEnabledByDefault: true, + CustomTags: [ + Compiler, + Telemetry, + NotConfigurable + ] + } + }, + {/* + public global::TestUniqueNotEquatable? Find(int? key) => DoFilter(key).Cast().SingleOrDefault(); + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.UniqueField, row); + ^^^^^^^^ } -public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - ^^^^^^^^^^^^^^^^^^^ - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: The name 'DoUpdate' does not exist in the current context, Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0103, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -553,17 +599,17 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - ^^^^^^^^^^^^^^^^^^^ - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { +public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); + ^^^^^^^^^ +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', Severity: Error, Descriptor: { - Id: CS0310, + Id: CS0121, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), + MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -575,18 +621,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: The type 'TestUniqueNotEquatable' already contains a definition for 'TestUniqueNotEquatableUniqueIndex', Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0102, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0102), + MessageFormat: The type '{0}' already contains a definition for '{1}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -598,18 +644,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + // Important: don't move this to the base class. */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'TestUniqueNotEquatableUniqueIndex' with the same parameter types, Severity: Error, Descriptor: { - Id: CS0310, + Id: CS0111, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), + MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -621,18 +667,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoCount(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); +public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { + internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} + ^^^^ + // Important: don't move this to the base class. */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0122, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + 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, @@ -644,18 +690,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoCount(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); + // `globalName` in one generic definition, leading to buggy `Row?` expansion for either one or another. + public global::TestUniqueNotEquatable? Find(TestEnumWithExplicitValues key) => DoFilter(key).Cast().SingleOrDefault(); + ^^^^^^^^ + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: The name 'DoFilter' does not exist in the current context, Severity: Error, Descriptor: { - Id: CS0310, + Id: CS0103, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -667,18 +713,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoCount(); - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public global::TestUniqueNotEquatable? Find(TestEnumWithExplicitValues key) => DoFilter(key).Cast().SingleOrDefault(); + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); + ^^^^^^ +} */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'Update' with the same parameter types, Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0111, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0111), + MessageFormat: Type '{1}' already defines a member called '{0}' with the same parameter types, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -690,18 +736,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoCount(); - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); + public global::TestUniqueNotEquatable? Find(TestEnumWithExplicitValues key) => DoFilter(key).Cast().SingleOrDefault(); + public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); + ^^^^^^^^ +} */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: The name 'DoUpdate' does not exist in the current context, Severity: Error, Descriptor: { - Id: CS0310, + Id: CS0103, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0103), + MessageFormat: The name '{0}' does not exist in the current context, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -713,18 +759,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.DoIter(); - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); +} +public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); + ^^^^^^^^^ +} */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', Severity: Error, Descriptor: { - Id: CS0311, + Id: CS0121, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0311), - MessageFormat: The type '{3}' cannot be used as type parameter '{2}' in the generic type or method '{0}'. There is no implicit reference conversion from '{3}' to '{1}'., + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0121), + MessageFormat: The call is ambiguous between the following methods or properties: '{0}' and '{1}', Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -736,18 +782,18 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView Iter() => SpacetimeDB.Internal.ITableView.DoIter(); - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoInsert(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); + public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { + Reducers.TestReducerWithoutContext((SpacetimeDB.ReducerContext)ctx); + ^^^^^^^^^^^^^^^^^^^^^^^^^ + } */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: No overload for method 'TestReducerWithoutContext' takes 1 arguments, Severity: Error, Descriptor: { - Id: CS0310, + Id: CS1501, Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0310), - MessageFormat: '{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}', + HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS1501), + MessageFormat: No overload for method '{0}' takes {1} arguments, Category: Compiler, DefaultSeverity: Error, IsEnabledByDefault: true, @@ -759,12 +805,12 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoInsert(row); - public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +SpacetimeDB.Internal.Module.RegisterTable(); +SpacetimeDB.Internal.Module.RegisterTable(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +SpacetimeDB.Internal.Module.RegisterTable(); */ - Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'ITableView'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.Internal.ITable'., + Message: The type 'TestTableTaggedEnum' cannot be used as type parameter 'T' in the generic type or method 'Module.RegisterTable()'. There is no implicit reference conversion from 'TestTableTaggedEnum' to 'SpacetimeDB.BSATN.IStructuralReadWrite'., Severity: Error, Descriptor: { Id: CS0311, @@ -782,12 +828,12 @@ public readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView SpacetimeDB.Internal.ITableView.DoInsert(row); - public bool Delete(global::TestTableTaggedEnum row) => SpacetimeDB.Internal.ITableView.DoDelete(row); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +SpacetimeDB.Internal.Module.RegisterTable(); +SpacetimeDB.Internal.Module.RegisterTable(); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +SpacetimeDB.Internal.Module.RegisterTable(); */ - Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ITableView', + Message: 'TestTableTaggedEnum' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Module.RegisterTable()', Severity: Error, Descriptor: { Id: CS0310, diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs index 294d986eb8f..a3c89ede44e 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs @@ -54,6 +54,46 @@ public readonly struct TestAutoIncNotInteger return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestAutoIncNotInteger), + ProductTypeRef: (uint) + new global::TestAutoIncNotInteger.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: + [ + new( + Name: null, + AccessorName: "IdentityField", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.MakeUniqueConstraint(1) + ], + Sequences: + [ + SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.MakeSequence(0), + SpacetimeDB.Internal.ITableView< + TestAutoIncNotInteger, + global::TestAutoIncNotInteger + >.MakeSequence(1) + ], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< TestAutoIncNotInteger, @@ -116,6 +156,23 @@ public readonly struct TestDuplicateTableName return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestDuplicateTableName, + global::TestDuplicateTableName + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestDuplicateTableName), + ProductTypeRef: (uint) + new global::TestDuplicateTableName.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: [], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< TestDuplicateTableName, @@ -141,140 +198,352 @@ public bool Delete(global::TestDuplicateTableName row) => >.DoDelete(row); } - public readonly struct TestIncompatibleSchedule1 + public readonly struct TestScheduleWithoutPrimaryKey : SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues > { - static global::TestIncompatibleSchedule SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule - >.ReadGenFields(System.IO.BinaryReader reader, global::TestIncompatibleSchedule row) + static global::TestScheduleIssues SpacetimeDB.Internal.ITableView< + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues + >.ReadGenFields(System.IO.BinaryReader reader, global::TestScheduleIssues row) { - if (row.ScheduledId == default) - { - row.ScheduledId = global::TestIncompatibleSchedule.BSATN.ScheduledId.Read( - reader - ); - } return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestScheduleWithoutPrimaryKey), + ProductTypeRef: (uint) + new global::TestScheduleIssues.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: [], + Constraints: [], + Sequences: [], + Schedule: SpacetimeDB.Internal.ITableView< + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues + >.MakeSchedule("DummyScheduledReducer", 3), + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues >.DoCount(); - public IEnumerable Iter() => + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues >.DoIter(); - public global::TestIncompatibleSchedule Insert(global::TestIncompatibleSchedule row) => + public global::TestScheduleIssues Insert(global::TestScheduleIssues row) => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues >.DoInsert(row); - public bool Delete(global::TestIncompatibleSchedule row) => + public bool Delete(global::TestScheduleIssues row) => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule + TestScheduleWithoutPrimaryKey, + global::TestScheduleIssues >.DoDelete(row); + } - public sealed class TestIncompatibleSchedule1UniqueIndex + public readonly struct TestScheduleWithoutScheduleAt + : SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + > + { + static global::TestScheduleIssues SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.ReadGenFields(System.IO.BinaryReader reader, global::TestScheduleIssues row) + { + return row; + } + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestScheduleWithoutScheduleAt), + ProductTypeRef: (uint) + new global::TestScheduleIssues.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [1], + Indexes: + [ + new( + Name: null, + AccessorName: "IdCorrectType", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.MakeUniqueConstraint(1) + ], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.DoIter(); + + public global::TestScheduleIssues Insert(global::TestScheduleIssues row) => + SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.DoInsert(row); + + public bool Delete(global::TestScheduleIssues row) => + SpacetimeDB.Internal.ITableView< + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues + >.DoDelete(row); + + public sealed class TestScheduleWithoutScheduleAtUniqueIndex : UniqueIndex< - TestIncompatibleSchedule1, - global::TestIncompatibleSchedule, - ulong, - SpacetimeDB.BSATN.U64 + TestScheduleWithoutScheduleAt, + global::TestScheduleIssues, + int, + SpacetimeDB.BSATN.I32 > { - internal TestIncompatibleSchedule1UniqueIndex(TestIncompatibleSchedule1 handle) - : base(handle, "TestIncompatibleSchedule1_ScheduledId_idx_btree") { } + internal TestScheduleWithoutScheduleAtUniqueIndex( + TestScheduleWithoutScheduleAt handle + ) + : base(handle, "TestScheduleWithoutScheduleAt_IdCorrectType_idx_btree") { } // 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 global::TestIncompatibleSchedule? Find(ulong key) => - DoFilter(key).Cast().SingleOrDefault(); + public global::TestScheduleIssues? Find(int key) => + DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestIncompatibleSchedule row) => - DoUpdate(row.ScheduledId, row); + public bool Update(global::TestScheduleIssues row) => + DoUpdate(row.IdCorrectType, row); } - public TestIncompatibleSchedule1UniqueIndex ScheduledId => new(this); + public TestScheduleWithoutScheduleAtUniqueIndex IdCorrectType => new(this); } - public readonly struct TestIncompatibleSchedule2 + public readonly struct TestScheduleWithWrongPrimaryKeyType : SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues > { - static global::TestIncompatibleSchedule SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule - >.ReadGenFields(System.IO.BinaryReader reader, global::TestIncompatibleSchedule row) + static global::TestScheduleIssues SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues + >.ReadGenFields(System.IO.BinaryReader reader, global::TestScheduleIssues row) { - if (row.ScheduledId == default) - { - row.ScheduledId = global::TestIncompatibleSchedule.BSATN.ScheduledId.Read( - reader - ); - } return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestScheduleWithWrongPrimaryKeyType), + ProductTypeRef: (uint) + new global::TestScheduleIssues.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [0], + Indexes: + [ + new( + Name: null, + AccessorName: "IdWrongType", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues + >.MakeUniqueConstraint(0) + ], + Sequences: [], + Schedule: SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues + >.MakeSchedule("DummyScheduledReducer", 3), + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues >.DoCount(); - public IEnumerable Iter() => + public IEnumerable Iter() => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues >.DoIter(); - public global::TestIncompatibleSchedule Insert(global::TestIncompatibleSchedule row) => + public global::TestScheduleIssues Insert(global::TestScheduleIssues row) => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues >.DoInsert(row); - public bool Delete(global::TestIncompatibleSchedule row) => + public bool Delete(global::TestScheduleIssues row) => SpacetimeDB.Internal.ITableView< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues >.DoDelete(row); - public sealed class TestIncompatibleSchedule2UniqueIndex + public sealed class TestScheduleWithWrongPrimaryKeyTypeUniqueIndex : UniqueIndex< - TestIncompatibleSchedule2, - global::TestIncompatibleSchedule, - ulong, - SpacetimeDB.BSATN.U64 + TestScheduleWithWrongPrimaryKeyType, + global::TestScheduleIssues, + string, + SpacetimeDB.BSATN.String > { - internal TestIncompatibleSchedule2UniqueIndex(TestIncompatibleSchedule2 handle) - : base(handle, "TestIncompatibleSchedule2_ScheduledId_idx_btree") { } + internal TestScheduleWithWrongPrimaryKeyTypeUniqueIndex( + TestScheduleWithWrongPrimaryKeyType handle + ) + : base(handle, "TestScheduleWithWrongPrimaryKeyType_IdWrongType_idx_btree") { } // 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 global::TestIncompatibleSchedule? Find(ulong key) => - DoFilter(key).Cast().SingleOrDefault(); + public global::TestScheduleIssues? Find(string key) => + DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestIncompatibleSchedule row) => - DoUpdate(row.ScheduledId, row); + public bool Update(global::TestScheduleIssues row) => + DoUpdate(row.IdWrongType, row); } - public TestIncompatibleSchedule2UniqueIndex ScheduledId => new(this); + public TestScheduleWithWrongPrimaryKeyTypeUniqueIndex IdWrongType => new(this); + } + + public readonly struct TestScheduleWithWrongScheduleAtType + : SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + > + { + static global::TestScheduleIssues SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.ReadGenFields(System.IO.BinaryReader reader, global::TestScheduleIssues row) + { + return row; + } + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestScheduleWithWrongScheduleAtType), + ProductTypeRef: (uint) + new global::TestScheduleIssues.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [1], + Indexes: + [ + new( + Name: null, + AccessorName: "IdCorrectType", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.MakeUniqueConstraint(1) + ], + Sequences: [], + Schedule: SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.MakeSchedule("DummyScheduledReducer", 2), + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.DoIter(); + + public global::TestScheduleIssues Insert(global::TestScheduleIssues row) => + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.DoInsert(row); + + public bool Delete(global::TestScheduleIssues row) => + SpacetimeDB.Internal.ITableView< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues + >.DoDelete(row); + + public sealed class TestScheduleWithWrongScheduleAtTypeUniqueIndex + : UniqueIndex< + TestScheduleWithWrongScheduleAtType, + global::TestScheduleIssues, + int, + SpacetimeDB.BSATN.I32 + > + { + internal TestScheduleWithWrongScheduleAtTypeUniqueIndex( + TestScheduleWithWrongScheduleAtType handle + ) + : base(handle, "TestScheduleWithWrongScheduleAtType_IdCorrectType_idx_btree") + { } + + // 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 global::TestScheduleIssues? Find(int key) => + DoFilter(key).Cast().SingleOrDefault(); + + public bool Update(global::TestScheduleIssues row) => + DoUpdate(row.IdCorrectType, row); + } + + public TestScheduleWithWrongScheduleAtTypeUniqueIndex IdCorrectType => new(this); } public readonly struct TestTableTaggedEnum @@ -288,6 +557,23 @@ public readonly struct TestTableTaggedEnum return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestTableTaggedEnum, + global::TestTableTaggedEnum + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestTableTaggedEnum), + ProductTypeRef: (uint) + new global::TestTableTaggedEnum.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: [], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< TestTableTaggedEnum, @@ -327,6 +613,45 @@ public readonly struct TestUniqueNotEquatable return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestUniqueNotEquatable), + ProductTypeRef: (uint) + new global::TestUniqueNotEquatable.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [1], + Indexes: + [ + new( + Name: null, + AccessorName: "UniqueField", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ), + new( + Name: null, + AccessorName: "PrimaryKeyField", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable + >.MakeUniqueConstraint(0), + SpacetimeDB.Internal.ITableView< + TestUniqueNotEquatable, + global::TestUniqueNotEquatable + >.MakeUniqueConstraint(1) + ], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< TestUniqueNotEquatable, @@ -403,8 +728,14 @@ public sealed class Local { public Internal.TableHandles.TestAutoIncNotInteger TestAutoIncNotInteger => new(); public Internal.TableHandles.TestDuplicateTableName TestDuplicateTableName => new(); - public Internal.TableHandles.TestIncompatibleSchedule1 TestIncompatibleSchedule1 => new(); - public Internal.TableHandles.TestIncompatibleSchedule2 TestIncompatibleSchedule2 => new(); + public Internal.TableHandles.TestScheduleWithoutPrimaryKey TestScheduleWithoutPrimaryKey => + new(); + public Internal.TableHandles.TestScheduleWithoutScheduleAt TestScheduleWithoutScheduleAt => + new(); + public Internal.TableHandles.TestScheduleWithWrongPrimaryKeyType TestScheduleWithWrongPrimaryKeyType => + new(); + public Internal.TableHandles.TestScheduleWithWrongScheduleAtType TestScheduleWithWrongScheduleAtType => + new(); public Internal.TableHandles.TestTableTaggedEnum TestTableTaggedEnum => new(); public Internal.TableHandles.TestUniqueNotEquatable TestUniqueNotEquatable => new(); } @@ -412,35 +743,45 @@ public sealed class Local static class ModuleRegistration { - class TestDuplicateReducerKind1 : SpacetimeDB.Internal.IReducer + class __ReducerWithReservedPrefix : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("__init__", []); + ) => new(nameof(__ReducerWithReservedPrefix), [], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.TestDuplicateReducerKind1((SpacetimeDB.ReducerContext)ctx); + Reducers.__ReducerWithReservedPrefix((SpacetimeDB.ReducerContext)ctx); } } - class __ReducerWithReservedPrefix : SpacetimeDB.Internal.IReducer + class DummyScheduledReducer : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + private static readonly TestScheduleIssues.BSATN table = new(); + + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("__ReducerWithReservedPrefix", []); + ) => + new( + nameof(DummyScheduledReducer), + [new(nameof(table), table.GetAlgebraicType(registrar))], + null + ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.__ReducerWithReservedPrefix((SpacetimeDB.ReducerContext)ctx); + TestScheduleIssues.DummyScheduledReducer( + (SpacetimeDB.ReducerContext)ctx, + table.Read(reader) + ); } } class OnReducerWithReservedPrefix : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("OnReducerWithReservedPrefix", []); + ) => new(nameof(OnReducerWithReservedPrefix), [], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -448,44 +789,47 @@ public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx } } - class TestDuplicateReducerName : SpacetimeDB.Internal.IReducer + class TestDuplicateReducerKind1 : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("TestDuplicateReducerName", []); + ) => new(nameof(TestDuplicateReducerKind1), [], SpacetimeDB.Internal.Lifecycle.Init); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.TestDuplicateReducerName((SpacetimeDB.ReducerContext)ctx); + Reducers.TestDuplicateReducerKind1((SpacetimeDB.ReducerContext)ctx); } } - class TestIncompatibleScheduleReducer : SpacetimeDB.Internal.IReducer + class TestDuplicateReducerKind2 : SpacetimeDB.Internal.IReducer { - private static readonly TestIncompatibleSchedule.BSATN table = new(); + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => new(nameof(TestDuplicateReducerKind2), [], SpacetimeDB.Internal.Lifecycle.Init); + + public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) + { + Reducers.TestDuplicateReducerKind2((SpacetimeDB.ReducerContext)ctx); + } + } - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + class TestDuplicateReducerName : SpacetimeDB.Internal.IReducer + { + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - new( - "TestIncompatibleScheduleReducer", - [new(nameof(table), table.GetAlgebraicType(registrar))] - ); + ) => new(nameof(TestDuplicateReducerName), [], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - TestIncompatibleSchedule.TestIncompatibleScheduleReducer( - (SpacetimeDB.ReducerContext)ctx, - table.Read(reader) - ); + Reducers.TestDuplicateReducerName((SpacetimeDB.ReducerContext)ctx); } } class TestReducerReturnType : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("TestReducerReturnType", []); + ) => new(nameof(TestReducerReturnType), [], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -495,9 +839,9 @@ public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx class TestReducerWithoutContext : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("TestReducerWithoutContext", []); + ) => new(nameof(TestReducerWithoutContext), [], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -523,18 +867,46 @@ public static void Main() new SpacetimeDB.ReducerContext(identity, address, random, time) ); - SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer<__ReducerWithReservedPrefix>(); + SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); + SpacetimeDB.Internal.Module.RegisterReducer(); + SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); - SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestAutoIncNotInteger, + SpacetimeDB.Internal.TableHandles.TestAutoIncNotInteger + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestDuplicateTableName, + SpacetimeDB.Internal.TableHandles.TestDuplicateTableName + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestScheduleIssues, + SpacetimeDB.Internal.TableHandles.TestScheduleWithoutPrimaryKey + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestScheduleIssues, + SpacetimeDB.Internal.TableHandles.TestScheduleWithoutScheduleAt + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestScheduleIssues, + SpacetimeDB.Internal.TableHandles.TestScheduleWithWrongPrimaryKeyType + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestScheduleIssues, + SpacetimeDB.Internal.TableHandles.TestScheduleWithWrongScheduleAtType + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestTableTaggedEnum, + SpacetimeDB.Internal.TableHandles.TestTableTaggedEnum + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestUniqueNotEquatable, + SpacetimeDB.Internal.TableHandles.TestUniqueNotEquatable + >(); } // Exports only work from the main assembly, so we need to generate forwarding methods. diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#InAnotherNamespace.TestDuplicateTableName.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#InAnotherNamespace.TestDuplicateTableName.verified.cs index 4c8719683c7..130e8da0694 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#InAnotherNamespace.TestDuplicateTableName.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#InAnotherNamespace.TestDuplicateTableName.verified.cs @@ -4,7 +4,7 @@ partial class InAnotherNamespace { - partial struct TestDuplicateTableName : SpacetimeDB.Internal.ITable + partial struct TestDuplicateTableName : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { } @@ -26,7 +26,7 @@ InAnotherNamespace.TestDuplicateTableName value value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -34,31 +34,10 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new SpacetimeDB.BSATN.AggregateElement[] { } ) ); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.TestDuplicateTableName), - Columns: [], - Indexes: [], - Constraints: [], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref) - new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // TestDuplicateTableName } // InAnotherNamespace diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.InAnotherNamespace.TestDuplicateReducerName.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.InAnotherNamespace.TestDuplicateReducerName.verified.cs index 79f324641ec..d3235595557 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.InAnotherNamespace.TestDuplicateReducerName.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.InAnotherNamespace.TestDuplicateReducerName.verified.cs @@ -13,7 +13,7 @@ public static void VolatileNonatomicScheduleImmediateTestDuplicateReducerName() using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "TestDuplicateReducerName", + nameof(TestDuplicateReducerName), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.OnReducerWithReservedPrefix.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.OnReducerWithReservedPrefix.verified.cs index e1bb60b457e..058b95c0c43 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.OnReducerWithReservedPrefix.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.OnReducerWithReservedPrefix.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediateOnReducerWithReservedPrefix using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "OnReducerWithReservedPrefix", + nameof(OnReducerWithReservedPrefix), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind1.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind1.verified.cs index 26dcf01debd..a7ad2e1574d 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind1.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind1.verified.cs @@ -10,6 +10,9 @@ public static void VolatileNonatomicScheduleImmediateTestDuplicateReducerKind1() using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("__init__", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(TestDuplicateReducerKind1), + stream + ); } } // Reducers diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind2.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind2.verified.cs index ed109522242..2d0fa1d5c40 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind2.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerKind2.verified.cs @@ -10,6 +10,9 @@ public static void VolatileNonatomicScheduleImmediateTestDuplicateReducerKind2() using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("__init__", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(TestDuplicateReducerKind2), + stream + ); } } // Reducers diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerName.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerName.verified.cs index 8de882954d2..2bd8ae447b7 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerName.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestDuplicateReducerName.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediateTestDuplicateReducerName() using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "TestDuplicateReducerName", + nameof(TestDuplicateReducerName), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerReturnType.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerReturnType.verified.cs index 78ecae225fe..3e4c6571395 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerReturnType.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerReturnType.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediateTestReducerReturnType() using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "TestReducerReturnType", + nameof(TestReducerReturnType), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerWithoutContext.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerWithoutContext.verified.cs index f05edb4fd5c..be30e5b7e5b 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerWithoutContext.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.TestReducerWithoutContext.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediateTestReducerWithoutContext() using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "TestReducerWithoutContext", + nameof(TestReducerWithoutContext), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.__ReducerWithReservedPrefix.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.__ReducerWithReservedPrefix.verified.cs index e7cbe63e389..78e0e7bcff5 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.__ReducerWithReservedPrefix.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#Reducers.__ReducerWithReservedPrefix.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediate__ReducerWithReservedPrefix using var writer = new BinaryWriter(stream); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "__ReducerWithReservedPrefix", + nameof(__ReducerWithReservedPrefix), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs index bd8dfba24cc..02975bc53bd 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestAutoIncNotInteger.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct TestAutoIncNotInteger : SpacetimeDB.Internal.ITable +partial struct TestAutoIncNotInteger : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -29,7 +29,7 @@ public void Write(System.IO.BinaryWriter writer, TestAutoIncNotInteger value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -41,45 +41,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.TestAutoIncNotInteger), - Columns: - [ - new(nameof(AutoIncField), BSATN.AutoIncField.GetAlgebraicType(registrar)), - new(nameof(IdentityField), BSATN.IdentityField.GetAlgebraicType(registrar)) - ], - Indexes: [], - Constraints: - [ - new( - "TestAutoIncNotInteger_AutoIncField", - (byte)SpacetimeDB.Internal.ColumnAttrs.AutoInc, - [0] - ), - new( - "TestAutoIncNotInteger_IdentityField", - (byte)SpacetimeDB.Internal.ColumnAttrs.Identity, - [1] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // TestAutoIncNotInteger diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestDuplicateTableName.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestDuplicateTableName.verified.cs index 0cf0b34c9f6..4c9b674dbb7 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestDuplicateTableName.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestDuplicateTableName.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct TestDuplicateTableName : SpacetimeDB.Internal.ITable +partial struct TestDuplicateTableName : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { } @@ -18,7 +18,7 @@ public void Write(System.IO.BinaryWriter writer, TestDuplicateTableName value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -26,29 +26,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new SpacetimeDB.BSATN.AggregateElement[] { } ) ); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.TestDuplicateTableName), - Columns: [], - Indexes: [], - Constraints: [], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // TestDuplicateTableName diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.TestIncompatibleScheduleReducer.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.TestIncompatibleScheduleReducer.verified.cs deleted file mode 100644 index 226f5a450a7..00000000000 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.TestIncompatibleScheduleReducer.verified.cs +++ /dev/null @@ -1,20 +0,0 @@ -//HintName: TestIncompatibleSchedule.TestIncompatibleScheduleReducer.cs -// -#nullable enable - -partial struct TestIncompatibleSchedule -{ - [System.Diagnostics.CodeAnalysis.Experimental("STDB_UNSTABLE")] - public static void VolatileNonatomicScheduleImmediateTestIncompatibleScheduleReducer( - TestIncompatibleSchedule table - ) - { - using var stream = new MemoryStream(); - using var writer = new BinaryWriter(stream); - new TestIncompatibleSchedule.BSATN().Write(writer, table); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "TestIncompatibleScheduleReducer", - stream - ); - } -} // TestIncompatibleSchedule diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs deleted file mode 100644 index b19217b5193..00000000000 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIncompatibleSchedule.verified.cs +++ /dev/null @@ -1,113 +0,0 @@ -//HintName: TestIncompatibleSchedule.cs -// -#nullable enable - -[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Auto)] -partial struct TestIncompatibleSchedule : SpacetimeDB.Internal.ITable -{ - public void ReadFields(System.IO.BinaryReader reader) - { - ScheduledId = BSATN.ScheduledId.Read(reader); - ScheduledAt = BSATN.ScheduledAt.Read(reader); - } - - public void WriteFields(System.IO.BinaryWriter writer) - { - BSATN.ScheduledId.Write(writer, ScheduledId); - BSATN.ScheduledAt.Write(writer, ScheduledAt); - } - - public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite - { - internal static readonly SpacetimeDB.BSATN.U64 ScheduledId = new(); - internal static readonly SpacetimeDB.ScheduleAt.BSATN ScheduledAt = new(); - - public TestIncompatibleSchedule Read(System.IO.BinaryReader reader) => - SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); - - public void Write(System.IO.BinaryWriter writer, TestIncompatibleSchedule value) - { - value.WriteFields(writer); - } - - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - registrar.RegisterType( - _ => new SpacetimeDB.BSATN.AlgebraicType.Product( - new SpacetimeDB.BSATN.AggregateElement[] - { - new(nameof(ScheduledId), ScheduledId.GetAlgebraicType(registrar)), - new(nameof(ScheduledAt), ScheduledAt.GetAlgebraicType(registrar)) - } - ) - ); - } - - public ulong ScheduledId; - public SpacetimeDB.ScheduleAt ScheduledAt; - - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.TestIncompatibleSchedule1), - Columns: - [ - new(nameof(ScheduledId), BSATN.ScheduledId.GetAlgebraicType(registrar)), - new(nameof(ScheduledAt), BSATN.ScheduledAt.GetAlgebraicType(registrar)) - ], - Indexes: [], - Constraints: - [ - new( - "TestIncompatibleSchedule1_ScheduledId", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, - [0] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: "TestIncompatibleScheduleReducer" - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - new( - new( - TableName: nameof(SpacetimeDB.Local.TestIncompatibleSchedule2), - Columns: - [ - new(nameof(ScheduledId), BSATN.ScheduledId.GetAlgebraicType(registrar)), - new(nameof(ScheduledAt), BSATN.ScheduledAt.GetAlgebraicType(registrar)) - ], - Indexes: [], - Constraints: - [ - new( - "TestIncompatibleSchedule2_ScheduledId", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, - [0] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; -} // TestIncompatibleSchedule diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.DummyScheduledReducer.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.DummyScheduledReducer.verified.cs new file mode 100644 index 00000000000..c5f5137dc91 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.DummyScheduledReducer.verified.cs @@ -0,0 +1,20 @@ +//HintName: TestScheduleIssues.DummyScheduledReducer.cs +// +#nullable enable + +partial struct TestScheduleIssues +{ + [System.Diagnostics.CodeAnalysis.Experimental("STDB_UNSTABLE")] + public static void VolatileNonatomicScheduleImmediateDummyScheduledReducer( + TestScheduleIssues table + ) + { + using var stream = new MemoryStream(); + using var writer = new BinaryWriter(stream); + new TestScheduleIssues.BSATN().Write(writer, table); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(DummyScheduledReducer), + stream + ); + } +} // TestScheduleIssues diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.verified.cs new file mode 100644 index 00000000000..72612e1c0e9 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestScheduleIssues.verified.cs @@ -0,0 +1,63 @@ +//HintName: TestScheduleIssues.cs +// +#nullable enable + +partial struct TestScheduleIssues : SpacetimeDB.BSATN.IStructuralReadWrite +{ + public void ReadFields(System.IO.BinaryReader reader) + { + IdWrongType = BSATN.IdWrongType.Read(reader); + IdCorrectType = BSATN.IdCorrectType.Read(reader); + ScheduleAtWrongType = BSATN.ScheduleAtWrongType.Read(reader); + ScheduleAtCorrectType = BSATN.ScheduleAtCorrectType.Read(reader); + } + + public void WriteFields(System.IO.BinaryWriter writer) + { + BSATN.IdWrongType.Write(writer, IdWrongType); + BSATN.IdCorrectType.Write(writer, IdCorrectType); + BSATN.ScheduleAtWrongType.Write(writer, ScheduleAtWrongType); + BSATN.ScheduleAtCorrectType.Write(writer, ScheduleAtCorrectType); + } + + public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite + { + internal static readonly SpacetimeDB.BSATN.String IdWrongType = new(); + internal static readonly SpacetimeDB.BSATN.I32 IdCorrectType = new(); + internal static readonly SpacetimeDB.BSATN.I32 ScheduleAtWrongType = new(); + internal static readonly SpacetimeDB.ScheduleAt.BSATN ScheduleAtCorrectType = new(); + + public TestScheduleIssues Read(System.IO.BinaryReader reader) => + SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); + + public void Write(System.IO.BinaryWriter writer, TestScheduleIssues value) + { + value.WriteFields(writer); + } + + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => + registrar.RegisterType( + _ => new SpacetimeDB.BSATN.AlgebraicType.Product( + new SpacetimeDB.BSATN.AggregateElement[] + { + new(nameof(IdWrongType), IdWrongType.GetAlgebraicType(registrar)), + new(nameof(IdCorrectType), IdCorrectType.GetAlgebraicType(registrar)), + new( + nameof(ScheduleAtWrongType), + ScheduleAtWrongType.GetAlgebraicType(registrar) + ), + new( + nameof(ScheduleAtCorrectType), + ScheduleAtCorrectType.GetAlgebraicType(registrar) + ) + } + ) + ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } +} // TestScheduleIssues diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestTableTaggedEnum.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestTableTaggedEnum.verified.cs index 4155c7f93b8..468a7596ae2 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestTableTaggedEnum.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestTableTaggedEnum.verified.cs @@ -48,7 +48,7 @@ public void Write(System.IO.BinaryWriter writer, TestTableTaggedEnum value) } } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -60,5 +60,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // TestTableTaggedEnum diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs index 57201dbbffc..063e824eb1b 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestUniqueNotEquatable.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct TestUniqueNotEquatable : SpacetimeDB.Internal.ITable +partial struct TestUniqueNotEquatable : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -33,7 +33,7 @@ public void Write(System.IO.BinaryWriter writer, TestUniqueNotEquatable value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -45,48 +45,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.TestUniqueNotEquatable), - Columns: - [ - new(nameof(UniqueField), BSATN.UniqueField.GetAlgebraicType(registrar)), - new( - nameof(PrimaryKeyField), - BSATN.PrimaryKeyField.GetAlgebraicType(registrar) - ) - ], - Indexes: [], - Constraints: - [ - new( - "TestUniqueNotEquatable_UniqueField", - (byte)SpacetimeDB.Internal.ColumnAttrs.Unique, - [0] - ), - new( - "TestUniqueNotEquatable_PrimaryKeyField", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKey, - [1] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // TestUniqueNotEquatable diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt index d81c1380582..f68a8506792 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module.verified.txt @@ -87,31 +87,6 @@ public partial record TestTableTaggedEnum : SpacetimeDB.TaggedEnum<(int X, int Y }, {/* -[SpacetimeDB.Table( -^^^^^^^^^^^^^^^^^^^ - Name = "TestIncompatibleSchedule1", -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Scheduled = nameof(TestIncompatibleScheduleReducer) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -)] -^^ -[SpacetimeDB.Table(Name = "TestIncompatibleSchedule2")] -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -public partial struct TestIncompatibleSchedule -*/ - Message: Schedule adds extra fields to the row type. Either all `[Table]` attributes should have a `Schedule`, or none of them., - Severity: Error, - Descriptor: { - Id: STDB0010, - Title: Incompatible `[Table(Schedule)]` attributes, - MessageFormat: Schedule adds extra fields to the row type. Either all `[Table]` attributes should have a `Schedule`, or none of them., - Category: SpacetimeDB, - DefaultSeverity: Error, - IsEnabledByDefault: true - } - }, - {/* - [SpacetimeDB.Table] ^^^^^^^^^^^^^^^^^^^ [SpacetimeDB.Index] @@ -153,6 +128,98 @@ public partial struct TestIndexWithEmptyColumns { } } }, {/* + +[SpacetimeDB.Table( + ^^^^^^^^^^^^^^^^^^ + Name = "TestScheduleWithoutPrimaryKey", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Scheduled = "DummyScheduledReducer", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ScheduledAt = nameof(ScheduleAtCorrectType) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +)] +^ +[SpacetimeDB.Table( +*/ + Message: TestScheduleWithoutPrimaryKey is a scheduled table but doesn't have a primary key of type `ulong`., + Severity: Error, + Descriptor: { + Id: STDB0012, + Title: Invalid scheduled table declaration, + MessageFormat: {0}, + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* +)] +[SpacetimeDB.Table( + ^^^^^^^^^^^^^^^^^^ + Name = "TestScheduleWithWrongPrimaryKeyType", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Scheduled = "DummyScheduledReducer", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ScheduledAt = nameof(ScheduleAtCorrectType) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +)] +^ +[SpacetimeDB.Table(Name = "TestScheduleWithoutScheduleAt", Scheduled = "DummyScheduledReducer")] +*/ + Message: TestScheduleWithWrongPrimaryKeyType is a scheduled table but doesn't have a primary key of type `ulong`., + Severity: Error, + Descriptor: { + Id: STDB0012, + Title: Invalid scheduled table declaration, + MessageFormat: {0}, + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* +)] +[SpacetimeDB.Table(Name = "TestScheduleWithoutScheduleAt", Scheduled = "DummyScheduledReducer")] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +[SpacetimeDB.Table( +*/ + Message: Item ScheduledAt not found., + Severity: Error, + Descriptor: { + Id: STDB0012, + Title: Invalid scheduled table declaration, + MessageFormat: {0}, + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* +[SpacetimeDB.Table(Name = "TestScheduleWithoutScheduleAt", Scheduled = "DummyScheduledReducer")] +[SpacetimeDB.Table( + ^^^^^^^^^^^^^^^^^^ + Name = "TestScheduleWithWrongScheduleAtType", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Scheduled = "DummyScheduledReducer", +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ScheduledAt = nameof(ScheduleAtWrongType) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +)] +^ +public partial struct TestScheduleIssues +*/ + Message: TestScheduleWithWrongScheduleAtType is a scheduled table but doesn't have a primary key of type `ulong`., + Severity: Error, + Descriptor: { + Id: STDB0012, + Title: Invalid scheduled table declaration, + MessageFormat: {0}, + Category: SpacetimeDB, + DefaultSeverity: Error, + IsEnabledByDefault: true + } + }, + {/* [SpacetimeDB.Reducer] public static int TestReducerReturnType(ReducerContext ctx) => 0; ^^^ @@ -222,12 +289,12 @@ public partial struct TestIndexWithEmptyColumns { } }, { Location: , - Message: Reducer with the same export name __init__ is registered in multiple places: Reducers.TestDuplicateReducerKind1, Reducers.TestDuplicateReducerKind2, + Message: Several reducers are assigned to the same lifecycle kind Init: Reducers.TestDuplicateReducerKind1, Reducers.TestDuplicateReducerKind2, Severity: Error, Descriptor: { - Id: STDB0007, - Title: Duplicate exports, - MessageFormat: {0} with the same export name {1} is registered in multiple places: {2}, + Id: STDB0011, + Title: Multiple reducers of the same kind, + MessageFormat: Several reducers are assigned to the same lifecycle kind {0}: {1}, Category: SpacetimeDB, DefaultSeverity: Error, IsEnabledByDefault: true diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumField.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumField.verified.cs index 9ba09be963b..c41d3f73e36 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumField.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumField.verified.cs @@ -48,7 +48,7 @@ public void Write(System.IO.BinaryWriter writer, TestTaggedEnumField value) } } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -60,5 +60,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // TestTaggedEnumField diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumInlineTuple.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumInlineTuple.verified.cs index 26a7b2bb2bf..f09264af234 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumInlineTuple.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTaggedEnumInlineTuple.verified.cs @@ -39,7 +39,7 @@ public void Write(System.IO.BinaryWriter writer, TestTaggedEnumInlineTuple value } } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -50,5 +50,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // TestTaggedEnumInlineTuple diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTypeParams_T_.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTypeParams_T_.verified.cs index dcd36118901..ae8f0904f75 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTypeParams_T_.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestTypeParams_T_.verified.cs @@ -26,7 +26,7 @@ public void Write(System.IO.BinaryWriter writer, TestTypeParams value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType>( @@ -37,5 +37,10 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite< + TestTypeParams + >.GetAlgebraicType(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + GetAlgebraicType(registrar); } } // TestTypeParams diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestUnsupportedType.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestUnsupportedType.verified.cs index 90568e958d8..8b8e392fe6c 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestUnsupportedType.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type#TestUnsupportedType.verified.cs @@ -38,7 +38,7 @@ public void Write(System.IO.BinaryWriter writer, TestUnsupportedType value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -58,5 +58,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // TestUnsupportedType diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs index 84b699424a5..5938e293834 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/Lib.cs @@ -118,6 +118,10 @@ public static partial class Timers [SpacetimeDB.Table(Scheduled = nameof(SendScheduledMessage))] public partial struct SendMessageTimer { + [PrimaryKey] + [AutoInc] + public ulong ScheduledId; + public ScheduleAt ScheduledAt; public string Text; } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs index 2305175ef95..751475f930a 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeMultiColumn.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct BTreeMultiColumn : SpacetimeDB.Internal.ITable +partial struct BTreeMultiColumn : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -32,7 +32,7 @@ public void Write(System.IO.BinaryWriter writer, BTreeMultiColumn value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( @@ -45,42 +45,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar } ) ); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.BTreeMultiColumn), - Columns: - [ - new(nameof(X), BSATN.X.GetAlgebraicType(registrar)), - new(nameof(Y), BSATN.Y.GetAlgebraicType(registrar)), - new(nameof(Z), BSATN.Z.GetAlgebraicType(registrar)) - ], - Indexes: - [ - new( - "BTreeMultiColumn_X_Y_Z_idx_btree", - false, - SpacetimeDB.Internal.IndexType.BTree, - [0, 1, 2] - ) - ], - Constraints: [], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // BTreeMultiColumn diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs index 2dfdbaa2f4d..1542246942c 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#BTreeViews.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct BTreeViews : SpacetimeDB.Internal.ITable +partial struct BTreeViews : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -35,7 +35,7 @@ public void Write(System.IO.BinaryWriter writer, BTreeViews value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -47,52 +47,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(Faction), Faction.GetAlgebraicType(registrar)) } )); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.BTreeViews), - Columns: - [ - new(nameof(Id), BSATN.Id.GetAlgebraicType(registrar)), - new(nameof(X), BSATN.X.GetAlgebraicType(registrar)), - new(nameof(Y), BSATN.Y.GetAlgebraicType(registrar)), - new(nameof(Faction), BSATN.Faction.GetAlgebraicType(registrar)) - ], - Indexes: - [ - new( - "BTreeViews_X_Y_idx_btree", - false, - SpacetimeDB.Internal.IndexType.BTree, - [1, 2] - ), - new( - "BTreeViews_Faction_idx_btree", - false, - SpacetimeDB.Internal.IndexType.BTree, - [3] - ) - ], - Constraints: - [ - new("BTreeViews_Id", (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKey, [0]) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // BTreeViews diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs index 24248c8e66e..97b9b5cfd12 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs @@ -42,6 +42,30 @@ internal readonly struct BTreeMultiColumn return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + BTreeMultiColumn, + global::BTreeMultiColumn + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(BTreeMultiColumn), + ProductTypeRef: (uint) + new global::BTreeMultiColumn.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: + [ + new( + Name: null, + AccessorName: "Location", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0, 1, 2]) + ) + ], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< BTreeMultiColumn, @@ -196,6 +220,46 @@ internal readonly struct BTreeViews return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + BTreeViews, + global::BTreeViews + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(BTreeViews), + ProductTypeRef: (uint) + new global::BTreeViews.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [0], + Indexes: + [ + new( + Name: null, + AccessorName: "Id", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ), + new( + Name: null, + AccessorName: "Location", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1, 2]) + ), + new( + Name: null, + AccessorName: "Faction", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([3]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + BTreeViews, + global::BTreeViews + >.MakeUniqueConstraint(0) + ], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); @@ -346,6 +410,47 @@ public readonly struct MultiTable1 return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + MultiTable1, + global::MultiTableRow + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(MultiTable1), + ProductTypeRef: (uint) + new global::MultiTableRow.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [1], + Indexes: + [ + new( + Name: null, + AccessorName: "Foo", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([1]) + ), + new( + Name: null, + AccessorName: "Name", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + MultiTable1, + global::MultiTableRow + >.MakeUniqueConstraint(1) + ], + Sequences: + [ + SpacetimeDB.Internal.ITableView< + MultiTable1, + global::MultiTableRow + >.MakeSequence(1) + ], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Public + ); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); @@ -427,6 +532,42 @@ public readonly struct MultiTable2 return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + MultiTable2, + global::MultiTableRow + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(MultiTable2), + ProductTypeRef: (uint) + new global::MultiTableRow.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: + [ + new( + Name: null, + AccessorName: "Bar", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([2]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + MultiTable2, + global::MultiTableRow + >.MakeUniqueConstraint(2) + ], + Sequences: + [ + SpacetimeDB.Internal.ITableView< + MultiTable2, + global::MultiTableRow + >.MakeSequence(1) + ], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); @@ -468,6 +609,23 @@ public readonly struct PrivateTable return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + PrivateTable, + global::PrivateTable + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(PrivateTable), + ProductTypeRef: (uint) + new global::PrivateTable.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [], + Indexes: [], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); @@ -496,6 +654,42 @@ public readonly struct PublicTable return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + PublicTable, + global::PublicTable + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(PublicTable), + ProductTypeRef: (uint) + new global::PublicTable.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [0], + Indexes: + [ + new( + Name: null, + AccessorName: "Id", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + PublicTable, + global::PublicTable + >.MakeUniqueConstraint(0) + ], + Sequences: + [ + SpacetimeDB.Internal.ITableView< + PublicTable, + global::PublicTable + >.MakeSequence(0) + ], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); @@ -543,6 +737,47 @@ public readonly struct SendMessageTimer return row; } + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(SendMessageTimer), + ProductTypeRef: (uint) + new global::Timers.SendMessageTimer.BSATN() + .GetAlgebraicType(registrar) + .Ref_, + PrimaryKey: [0], + Indexes: + [ + new( + Name: null, + AccessorName: "ScheduledId", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([0]) + ) + ], + Constraints: + [ + SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.MakeUniqueConstraint(0) + ], + Sequences: + [ + SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.MakeSequence(0) + ], + Schedule: SpacetimeDB.Internal.ITableView< + SendMessageTimer, + global::Timers.SendMessageTimer + >.MakeSchedule("SendScheduledMessage", 1), + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + public ulong Count => SpacetimeDB.Internal.ITableView< SendMessageTimer, @@ -608,9 +843,9 @@ static class ModuleRegistration { class Init : SpacetimeDB.Internal.IReducer { - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("__init__", []); + ) => new(nameof(Init), [], SpacetimeDB.Internal.Lifecycle.Init); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -622,9 +857,9 @@ class InsertData : SpacetimeDB.Internal.IReducer { private static readonly PublicTable.BSATN data = new(); - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("InsertData", [new(nameof(data), data.GetAlgebraicType(registrar))]); + ) => new(nameof(InsertData), [new(nameof(data), data.GetAlgebraicType(registrar))], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -636,9 +871,9 @@ class InsertData2 : SpacetimeDB.Internal.IReducer { private static readonly PublicTable.BSATN data = new(); - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("InsertData2", [new(nameof(data), data.GetAlgebraicType(registrar))]); + ) => new(nameof(InsertData2), [new(nameof(data), data.GetAlgebraicType(registrar))], null); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -653,9 +888,14 @@ class InsertMultiData : SpacetimeDB.Internal.IReducer { private static readonly MultiTableRow.BSATN data = new(); - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("InsertMultiData", [new(nameof(data), data.GetAlgebraicType(registrar))]); + ) => + new( + nameof(InsertMultiData), + [new(nameof(data), data.GetAlgebraicType(registrar))], + null + ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -667,9 +907,14 @@ class ScheduleImmediate : SpacetimeDB.Internal.IReducer { private static readonly PublicTable.BSATN data = new(); - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("ScheduleImmediate", [new(nameof(data), data.GetAlgebraicType(registrar))]); + ) => + new( + nameof(ScheduleImmediate), + [new(nameof(data), data.GetAlgebraicType(registrar))], + null + ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -681,9 +926,14 @@ class SendScheduledMessage : SpacetimeDB.Internal.IReducer { private static readonly Timers.SendMessageTimer.BSATN arg = new(); - public SpacetimeDB.Internal.ReducerDef MakeReducerDef( + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef( SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => new("SendScheduledMessage", [new(nameof(arg), arg.GetAlgebraicType(registrar))]); + ) => + new( + nameof(SendScheduledMessage), + [new(nameof(arg), arg.GetAlgebraicType(registrar))], + null + ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -715,12 +965,34 @@ public static void Main() SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); SpacetimeDB.Internal.Module.RegisterReducer(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); - SpacetimeDB.Internal.Module.RegisterTable(); + SpacetimeDB.Internal.Module.RegisterTable< + global::BTreeMultiColumn, + SpacetimeDB.Internal.TableHandles.BTreeMultiColumn + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::BTreeViews, + SpacetimeDB.Internal.TableHandles.BTreeViews + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::MultiTableRow, + SpacetimeDB.Internal.TableHandles.MultiTable1 + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::MultiTableRow, + SpacetimeDB.Internal.TableHandles.MultiTable2 + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::PrivateTable, + SpacetimeDB.Internal.TableHandles.PrivateTable + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::PublicTable, + SpacetimeDB.Internal.TableHandles.PublicTable + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::Timers.SendMessageTimer, + SpacetimeDB.Internal.TableHandles.SendMessageTimer + >(); } // Exports only work from the main assembly, so we need to generate forwarding methods. diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.InsertMultiData.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.InsertMultiData.verified.cs index 6641f96fd4c..585bd32efb2 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.InsertMultiData.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.InsertMultiData.verified.cs @@ -10,6 +10,9 @@ public static void VolatileNonatomicScheduleImmediateInsertMultiData(MultiTableR using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); new MultiTableRow.BSATN().Write(writer, data); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("InsertMultiData", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(InsertMultiData), + stream + ); } } // MultiTableRow diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs index 4c9f25ee84b..9bf0b374617 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#MultiTableRow.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct MultiTableRow : SpacetimeDB.Internal.ITable +partial struct MultiTableRow : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -32,7 +32,7 @@ public void Write(System.IO.BinaryWriter writer, MultiTableRow value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -43,76 +43,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(Bar), Bar.GetAlgebraicType(registrar)) } )); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.MultiTable1), - Columns: - [ - new(nameof(Name), BSATN.Name.GetAlgebraicType(registrar)), - new(nameof(Foo), BSATN.Foo.GetAlgebraicType(registrar)), - new(nameof(Bar), BSATN.Bar.GetAlgebraicType(registrar)) - ], - Indexes: - [ - new( - "MultiTable1_Name_idx_btree", - false, - SpacetimeDB.Internal.IndexType.BTree, - [0] - ) - ], - Constraints: - [ - new( - "MultiTable1_Foo", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, - [1] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "public", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - new( - new( - TableName: nameof(SpacetimeDB.Local.MultiTable2), - Columns: - [ - new(nameof(Name), BSATN.Name.GetAlgebraicType(registrar)), - new(nameof(Foo), BSATN.Foo.GetAlgebraicType(registrar)), - new(nameof(Bar), BSATN.Bar.GetAlgebraicType(registrar)) - ], - Indexes: [], - Constraints: - [ - new("MultiTable2_Foo", (byte)SpacetimeDB.Internal.ColumnAttrs.AutoInc, [1]), - new("MultiTable2_Bar", (byte)SpacetimeDB.Internal.ColumnAttrs.Unique, [2]) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // MultiTableRow diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PrivateTable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PrivateTable.verified.cs index 9b3c3632c0c..1480f14170b 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PrivateTable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PrivateTable.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial class PrivateTable : SpacetimeDB.Internal.ITable +partial class PrivateTable : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { } @@ -18,35 +18,15 @@ public void Write(System.IO.BinaryWriter writer, PrivateTable value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( new SpacetimeDB.BSATN.AggregateElement[] { } )); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.PrivateTable), - Columns: [], - Indexes: [], - Constraints: [], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // PrivateTable diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs index 1e1882c7ea4..7b61dabf5ff 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#PublicTable.verified.cs @@ -2,7 +2,7 @@ // #nullable enable -partial struct PublicTable : SpacetimeDB.Internal.ITable +partial struct PublicTable : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { @@ -114,7 +114,7 @@ public void Write(System.IO.BinaryWriter writer, PublicTable value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -156,84 +156,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar ) } )); - } - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.PublicTable), - Columns: - [ - new(nameof(Id), BSATN.Id.GetAlgebraicType(registrar)), - new(nameof(ByteField), BSATN.ByteField.GetAlgebraicType(registrar)), - new(nameof(UshortField), BSATN.UshortField.GetAlgebraicType(registrar)), - new(nameof(UintField), BSATN.UintField.GetAlgebraicType(registrar)), - new(nameof(UlongField), BSATN.UlongField.GetAlgebraicType(registrar)), - new(nameof(UInt128Field), BSATN.UInt128Field.GetAlgebraicType(registrar)), - new(nameof(U128Field), BSATN.U128Field.GetAlgebraicType(registrar)), - new(nameof(U256Field), BSATN.U256Field.GetAlgebraicType(registrar)), - new(nameof(SbyteField), BSATN.SbyteField.GetAlgebraicType(registrar)), - new(nameof(ShortField), BSATN.ShortField.GetAlgebraicType(registrar)), - new(nameof(IntField), BSATN.IntField.GetAlgebraicType(registrar)), - new(nameof(LongField), BSATN.LongField.GetAlgebraicType(registrar)), - new(nameof(Int128Field), BSATN.Int128Field.GetAlgebraicType(registrar)), - new(nameof(I128Field), BSATN.I128Field.GetAlgebraicType(registrar)), - new(nameof(I256Field), BSATN.I256Field.GetAlgebraicType(registrar)), - new(nameof(BoolField), BSATN.BoolField.GetAlgebraicType(registrar)), - new(nameof(FloatField), BSATN.FloatField.GetAlgebraicType(registrar)), - new(nameof(DoubleField), BSATN.DoubleField.GetAlgebraicType(registrar)), - new(nameof(StringField), BSATN.StringField.GetAlgebraicType(registrar)), - new(nameof(IdentityField), BSATN.IdentityField.GetAlgebraicType(registrar)), - new(nameof(AddressField), BSATN.AddressField.GetAlgebraicType(registrar)), - new( - nameof(CustomStructField), - BSATN.CustomStructField.GetAlgebraicType(registrar) - ), - new( - nameof(CustomClassField), - BSATN.CustomClassField.GetAlgebraicType(registrar) - ), - new( - nameof(CustomEnumField), - BSATN.CustomEnumField.GetAlgebraicType(registrar) - ), - new( - nameof(CustomTaggedEnumField), - BSATN.CustomTaggedEnumField.GetAlgebraicType(registrar) - ), - new(nameof(ListField), BSATN.ListField.GetAlgebraicType(registrar)), - new( - nameof(NullableValueField), - BSATN.NullableValueField.GetAlgebraicType(registrar) - ), - new( - nameof(NullableReferenceField), - BSATN.NullableReferenceField.GetAlgebraicType(registrar) - ) - ], - Indexes: [], - Constraints: - [ - new( - "PublicTable_Id", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, - [0] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: null - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref)new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // PublicTable diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.InsertData.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.InsertData.verified.cs index 4be5a0da72a..2eedf2f9e83 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.InsertData.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.InsertData.verified.cs @@ -10,6 +10,9 @@ public static void VolatileNonatomicScheduleImmediateInsertData(PublicTable data using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); new PublicTable.BSATN().Write(writer, data); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("InsertData", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(InsertData), + stream + ); } } // Reducers diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.ScheduleImmediate.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.ScheduleImmediate.verified.cs index aa20a22ef0b..e49abc9114a 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.ScheduleImmediate.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Reducers.ScheduleImmediate.verified.cs @@ -11,7 +11,7 @@ public static void VolatileNonatomicScheduleImmediateScheduleImmediate(PublicTab using var writer = new BinaryWriter(stream); new PublicTable.BSATN().Write(writer, data); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "ScheduleImmediate", + nameof(ScheduleImmediate), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Test.NestingNamespaces.AndClasses.InsertData2.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Test.NestingNamespaces.AndClasses.InsertData2.verified.cs index b46447f3d07..88134251166 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Test.NestingNamespaces.AndClasses.InsertData2.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Test.NestingNamespaces.AndClasses.InsertData2.verified.cs @@ -12,7 +12,10 @@ public static void VolatileNonatomicScheduleImmediateInsertData2(PublicTable dat using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); new PublicTable.BSATN().Write(writer, data); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("InsertData2", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( + nameof(InsertData2), + stream + ); } } // AndClasses } // namespace diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.Init.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.Init.verified.cs index 7cb0c5b60e9..61efa0d598b 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.Init.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.Init.verified.cs @@ -10,6 +10,6 @@ public static void VolatileNonatomicScheduleImmediateInit() using var stream = new MemoryStream(); using var writer = new BinaryWriter(stream); - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("__init__", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate(nameof(Init), stream); } } // Timers diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs index 94c5a2f8e6b..4ada75d4420 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendMessageTimer.verified.cs @@ -4,28 +4,27 @@ partial class Timers { - [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Auto)] - partial struct SendMessageTimer : SpacetimeDB.Internal.ITable + partial struct SendMessageTimer : SpacetimeDB.BSATN.IStructuralReadWrite { public void ReadFields(System.IO.BinaryReader reader) { - Text = BSATN.Text.Read(reader); ScheduledId = BSATN.ScheduledId.Read(reader); ScheduledAt = BSATN.ScheduledAt.Read(reader); + Text = BSATN.Text.Read(reader); } public void WriteFields(System.IO.BinaryWriter writer) { - BSATN.Text.Write(writer, Text); BSATN.ScheduledId.Write(writer, ScheduledId); BSATN.ScheduledAt.Write(writer, ScheduledAt); + BSATN.Text.Write(writer, Text); } public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite { - internal static readonly SpacetimeDB.BSATN.String Text = new(); internal static readonly SpacetimeDB.BSATN.U64 ScheduledId = new(); internal static readonly SpacetimeDB.ScheduleAt.BSATN ScheduledAt = new(); + internal static readonly SpacetimeDB.BSATN.String Text = new(); public Timers.SendMessageTimer Read(System.IO.BinaryReader reader) => SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); @@ -35,59 +34,23 @@ public void Write(System.IO.BinaryWriter writer, Timers.SendMessageTimer value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType( _ => new SpacetimeDB.BSATN.AlgebraicType.Product( new SpacetimeDB.BSATN.AggregateElement[] { - new(nameof(Text), Text.GetAlgebraicType(registrar)), new(nameof(ScheduledId), ScheduledId.GetAlgebraicType(registrar)), - new(nameof(ScheduledAt), ScheduledAt.GetAlgebraicType(registrar)) + new(nameof(ScheduledAt), ScheduledAt.GetAlgebraicType(registrar)), + new(nameof(Text), Text.GetAlgebraicType(registrar)) } ) ); - } - - public ulong ScheduledId; - public SpacetimeDB.ScheduleAt ScheduledAt; - static IEnumerable SpacetimeDB.Internal.ITable.MakeTableDesc( - SpacetimeDB.BSATN.ITypeRegistrar registrar - ) => - [ - new( - new( - TableName: nameof(SpacetimeDB.Local.SendMessageTimer), - Columns: - [ - new(nameof(Text), BSATN.Text.GetAlgebraicType(registrar)), - new(nameof(ScheduledId), BSATN.ScheduledId.GetAlgebraicType(registrar)), - new(nameof(ScheduledAt), BSATN.ScheduledAt.GetAlgebraicType(registrar)) - ], - Indexes: [], - Constraints: - [ - new( - "SendMessageTimer_ScheduledId", - (byte)SpacetimeDB.Internal.ColumnAttrs.PrimaryKeyAuto, - [1] - ) - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "private", - Scheduled: "SendScheduledMessage" - ), - (uint) - ( - (SpacetimeDB.BSATN.AlgebraicType.Ref) - new BSATN().GetAlgebraicType(registrar) - ).Ref_ - ), - ]; + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } } // SendMessageTimer } // Timers diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendScheduledMessage.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendScheduledMessage.verified.cs index eefbfb2a669..282ad91ff48 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendScheduledMessage.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#Timers.SendScheduledMessage.verified.cs @@ -13,7 +13,7 @@ Timers.SendMessageTimer arg using var writer = new BinaryWriter(stream); new Timers.SendMessageTimer.BSATN().Write(writer, arg); SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate( - "SendScheduledMessage", + nameof(SendScheduledMessage), stream ); } diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomClass.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomClass.verified.cs index 1ac96f3d0dd..44d38f11143 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomClass.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomClass.verified.cs @@ -29,7 +29,7 @@ public void Write(System.IO.BinaryWriter writer, CustomClass value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -39,5 +39,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringField), StringField.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomClass diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomStruct.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomStruct.verified.cs index 855a5757c9c..95a910c8f01 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomStruct.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomStruct.verified.cs @@ -29,7 +29,7 @@ public void Write(System.IO.BinaryWriter writer, CustomStruct value) value.WriteFields(writer); } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Product( @@ -39,5 +39,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringField), StringField.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomStruct diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomTaggedEnum.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomTaggedEnum.verified.cs index 66edf6ee00d..d9be5d8eb86 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomTaggedEnum.verified.cs +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Type#CustomTaggedEnum.verified.cs @@ -48,7 +48,7 @@ public void Write(System.IO.BinaryWriter writer, CustomTaggedEnum value) } } - public SpacetimeDB.BSATN.AlgebraicType GetAlgebraicType( + public SpacetimeDB.BSATN.AlgebraicType.Ref GetAlgebraicType( SpacetimeDB.BSATN.ITypeRegistrar registrar ) => registrar.RegisterType(_ => new SpacetimeDB.BSATN.AlgebraicType.Sum( @@ -58,5 +58,9 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar new(nameof(StringVariant), StringVariant.GetAlgebraicType(registrar)) } )); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); } } // CustomTaggedEnum diff --git a/crates/bindings-csharp/Codegen/Codegen.csproj b/crates/bindings-csharp/Codegen/Codegen.csproj index a0ceb9ec7b0..5c0bce86693 100644 --- a/crates/bindings-csharp/Codegen/Codegen.csproj +++ b/crates/bindings-csharp/Codegen/Codegen.csproj @@ -2,7 +2,7 @@ SpacetimeDB.Codegen - 1.0.0-rc1-hotfix1 + 1.0.0-rc2 SpacetimeDB Module Codegen The SpacetimeDB Codegen implements the Roslyn incremental generators for writing SpacetimeDB modules in C#. diff --git a/crates/bindings-csharp/Codegen/Diag.cs b/crates/bindings-csharp/Codegen/Diag.cs index c0c052ce965..1635bc0b161 100644 --- a/crates/bindings-csharp/Codegen/Diag.cs +++ b/crates/bindings-csharp/Codegen/Diag.cs @@ -92,12 +92,23 @@ string prefix ctx => ctx.method.Identifier ); - public static readonly ErrorDescriptor IncompatibleTableSchedule = + public static readonly UnusedErrorDescriptor IncompatibleTableSchedule = new(group); + + public static readonly ErrorDescriptor<( + ReducerKind kind, + IEnumerable fullNames + )> DuplicateSpecialReducer = new( group, - "Incompatible `[Table(Schedule)]` attributes", - table => - $"Schedule adds extra fields to the row type. Either all `[Table]` attributes should have a `Schedule`, or none of them.", - table => table.SyntaxTree.GetLocation(table.AttributeLists.Span) + "Multiple reducers of the same kind", + ctx => + $"Several reducers are assigned to the same lifecycle kind {ctx.kind}: {string.Join(", ", ctx.fullNames)}", + ctx => Location.None ); + + public static readonly ErrorDescriptor<( + AttributeData attr, + string message + )> InvalidScheduledDeclaration = + new(group, "Invalid scheduled table declaration", ctx => $"{ctx.message}", ctx => ctx.attr); } diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index 6ee9fed69a1..018094c7d0c 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -7,6 +7,25 @@ namespace SpacetimeDB.Codegen; using SpacetimeDB.Internal; using static Utils; +static class IndexOfExt +{ + // A LINQ helper to find the index of the first element equal to `searchItem`. + public static int IndexOf(this IEnumerable source, T searchItem) + where T : IEquatable + { + var i = 0; + foreach (var item in source) + { + if (searchItem.Equals(item)) + { + return i; + } + i++; + } + throw new InvalidOperationException($"Item {searchItem} not found."); + } +} + readonly record struct ColumnAttr(ColumnAttrs Mask, string? Table = null) { private static readonly ImmutableDictionary AttrTypes = ImmutableArray @@ -119,114 +138,140 @@ or SpecialType.System_Int64 } } - public ColumnAttrs GetAttrs(string tableName) => - CombineColumnAttrs(Attrs.Where(x => x.Table == null || x.Table == tableName)); + public ColumnAttrs GetAttrs(TableView view) => + CombineColumnAttrs(Attrs.Where(x => x.Table == null || x.Table == view.Name)); // For the `TableDesc` constructor. public string GenerateColumnDef() => $"new (nameof({Name}), BSATN.{Name}.GetAlgebraicType(registrar))"; } +record Scheduled(string ReducerName, int ScheduledAtColumn); + record TableView { public readonly string Name; public readonly bool IsPublic; - public readonly string? Scheduled; + public readonly Scheduled? Scheduled; - public TableView(TableDeclaration table, AttributeData data) + public TableView(TableDeclaration table, AttributeData data, DiagReporter diag) { var attr = data.ParseAs(); Name = attr.Name ?? table.ShortName; IsPublic = attr.Public; - Scheduled = attr.Scheduled; + if (attr.Scheduled is { } reducer) + { + try + { + Scheduled = new( + reducer, + table.Members.Select(m => m.Name).IndexOf(attr.ScheduledAt) + ); + if (table.GetPrimaryKey(this) is not { } pk || table.Members[pk].Type != "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") + { + throw new InvalidOperationException( + $"{Name}.{attr.ScheduledAt} is marked with `ScheduledAt`, but doesn't have the expected type `SpacetimeDB.ScheduleAt`." + ); + } + } + catch (Exception e) + { + diag.Report(ErrorDescriptor.InvalidScheduledDeclaration, (data, e.Message)); + } + } } } -abstract record ViewIndex +enum ViewIndexType +{ + BTree, +} + +record ViewIndex { - public EquatableArray Columns; - public string? Table; - public string Name; + public readonly EquatableArray Columns; + public readonly string? Table; + public readonly string AccessorName; + public readonly ViewIndexType Type; - protected abstract string Type { get; } + // See: bindings_sys::index_id_from_name for documentation of this format. + // Guaranteed not to contain quotes, so does not need to be escaped when embedded in a string. + private readonly string StandardNameSuffix; - public ViewIndex(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) + private ViewIndex(string? accessorName, string[] columns, ViewIndexType type) { - var attr = data.ParseAs(); - Columns = new((attr.BTree ?? []).ToImmutableArray()); - Table = attr.Table; - Name = attr.Name ?? string.Join("", Columns); + AccessorName = accessorName ?? string.Join("_", columns); + Columns = new(columns.ToImmutableArray()); + Type = type; + StandardNameSuffix = $"_{string.Join("_", Columns)}_idx_{Type.ToString().ToLower()}"; + } + public ViewIndex(ColumnDeclaration col) + : this( + null, + [col.Name], + ViewIndexType.BTree // this might become hash in the future + ) { } + + private ViewIndex(IndexAttribute attr, TypeDeclarationSyntax decl, DiagReporter diag) + : this( + attr.Name, + // TODO: check other properties when we support types other than BTree. + // Then make sure we don't allow multiple index types on the same attribute via diagnostics. + attr.BTree ?? [], + ViewIndexType.BTree + ) + { + Table = attr.Table; if (Columns.Length == 0) { diag.Report(ErrorDescriptor.EmptyIndexColumns, decl); } } - public string GenerateIndexDef(string viewName, IEnumerable columns) + public ViewIndex(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) + : this(data.ParseAs(), decl, diag) { } + + public string GenerateIndexDef(IEnumerable allColumns) { - var cols = Columns.Select(c => - columns.Select((c, i) => (c, i)).First(cd => cd.c.Name == c) - ); - var colIndices = cols.Select(col => col.i); - var colNames = cols.Select(col => col.c.Name); + var colIndices = Columns.Select(c => allColumns.Select(cd => cd.Name).IndexOf(c)); - // Note: when updating to v9, you could optionally just pass `null` instead of this string. - // The same name will be auto-generated on the host. - var standardIndexName = StandardIndexName("btree", viewName, colNames); - return $"new(\"{standardIndexName}\", false, SpacetimeDB.Internal.IndexType.{Type}, [{string.Join(", ", colIndices)}])"; + return $$""" + new( + Name: null, + AccessorName: {{(AccessorName is not null ? $"\"{AccessorName}\"" : "null")}}, + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.{{Type}}([{{string.Join( + ", ", + colIndices + )}}]) + ) + """; } - // See: bindings_sys::index_id_from_name for documentation of this format. - // Guaranteed not to contain quotes, so does not need to be escaped when embedded in a string. - public static string StandardIndexName( - string type, - string tableName, - IEnumerable columnNames - ) => $"{tableName}_{string.Join("_", columnNames)}_idx_{type.ToLower()}"; -} - -record ViewBTree : ViewIndex -{ - public ViewBTree(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) - : base(data, decl, diag) { } - - protected override string Type => "BTree"; + public string StandardIndexName(TableView view) => view.Name + StandardNameSuffix; } record TableDeclaration : BaseTypeDeclaration { public readonly Accessibility Visibility; public readonly EquatableArray Views; - public readonly EquatableArray BTrees; - - private static ColumnDeclaration[] ScheduledColumns(string tableName) => - [ - new( - tableName, - "ScheduledId", - "ulong", - "SpacetimeDB.BSATN.U64", - ColumnAttrs.PrimaryKeyAuto, - true - ), - new( - tableName, - "ScheduledAt", - "SpacetimeDB.ScheduleAt", - "SpacetimeDB.ScheduleAt.BSATN", - ColumnAttrs.UnSet, - false - ), - ]; + public readonly EquatableArray Indexes; public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter diag) : base(context, diag) { + var typeSyntax = (TypeDeclarationSyntax)context.TargetNode; + if (Kind is TypeKind.Sum) { - diag.Report(ErrorDescriptor.TableTaggedEnum, (TypeDeclarationSyntax)context.TargetNode); + diag.Report(ErrorDescriptor.TableTaggedEnum, typeSyntax); } var container = context.TargetSymbol; @@ -245,10 +290,7 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di } break; default: - diag.Report( - ErrorDescriptor.InvalidTableVisibility, - (TypeDeclarationSyntax)context.TargetNode - ); + diag.Report(ErrorDescriptor.InvalidTableVisibility, typeSyntax); throw new Exception( "Table row type visibility must be public or internal, including containing types." ); @@ -257,88 +299,52 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di container = container.ContainingType; } - Views = new(context.Attributes.Select(a => new TableView(this, a)).ToImmutableArray()); - BTrees = new( + Views = new( + context.Attributes.Select(a => new TableView(this, a, diag)).ToImmutableArray() + ); + Indexes = new( context .TargetSymbol.GetAttributes() .Where(a => a.AttributeClass?.ToString() == typeof(IndexAttribute).FullName) - .Select(a => new ViewBTree(a, (TypeDeclarationSyntax)context.TargetNode, diag)) + .Select(a => new ViewIndex(a, typeSyntax, diag)) .ToImmutableArray() ); - - var hasScheduled = Views.Select(t => t.Scheduled is not null).Distinct(); - - if (hasScheduled.Count() != 1) - { - diag.Report( - ErrorDescriptor.IncompatibleTableSchedule, - (TypeDeclarationSyntax)context.TargetNode - ); - } - - if (hasScheduled.Any(has => has)) - { - // For scheduled tables, we append extra fields early in the pipeline, - // both to the type itself and to the BSATN information, as if they - // were part of the original declaration. - Members = new(Members.Concat(ScheduledColumns(FullName)).ToImmutableArray()); - } } protected override ColumnDeclaration ConvertMember(IFieldSymbol field, DiagReporter diag) => new(FullName, field, diag); - public IEnumerable GenerateViewFilters(string viewName) + public IEnumerable GenerateViewFilters(TableView view) { var vis = SyntaxFacts.GetText(Visibility); var globalName = $"global::{FullName}"; - foreach ( - var ct in GetConstraints(viewName) - .Where(tuple => tuple.attr.HasFlag(ColumnAttrs.Unique)) - ) + foreach (var ct in GetConstraints(view, ColumnAttrs.Unique)) { var f = ct.col; - if (f.GetAttrs(viewName).HasFlag(ColumnAttrs.Unique)) - { - var iUniqueIndex = $""; - - var standardIndexName = ViewIndex.StandardIndexName( - "btree", - viewName, - [ct.col.Name] - ); - yield return $$""" - {{vis}} sealed class {{viewName}}UniqueIndex : UniqueIndex<{{viewName}}, {{globalName}}, {{f.Type}}, {{f.TypeInfo}}> { - internal {{viewName}}UniqueIndex({{viewName}} handle) : base(handle, "{{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 bool Update({{globalName}} row) => DoUpdate(row.{{f.Name}}, row); - } - {{vis}} {{viewName}}UniqueIndex {{f.Name}} => new(this); - """; - } + var standardIndexName = new ViewIndex(ct.col).StandardIndexName(view); + yield return $$""" + {{vis}} sealed class {{view.Name}}UniqueIndex : UniqueIndex<{{view.Name}}, {{globalName}}, {{f.Type}}, {{f.TypeInfo}}> { + internal {{view.Name}}UniqueIndex({{view.Name}} handle) : base(handle, "{{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 bool Update({{globalName}} row) => DoUpdate(row.{{f.Name}}, row); + } + {{vis}} {{view.Name}}UniqueIndex {{f.Name}} => new(this); + """; } - foreach (var btree in BTrees) + foreach (var index in GetIndexes(view)) { - if (btree.Table != null && btree.Table != viewName) - { - continue; - } + var members = index.Columns.Select(s => Members.First(x => x.Name == s)).ToArray(); - var members = btree.Columns.Select(s => Members.First(x => x.Name == s)).ToArray(); - - var standardIndexName = ViewIndex.StandardIndexName( - "btree", - viewName, - members.Select(x => x.Name) - ); + var standardIndexName = index.StandardIndexName(view); + var name = index.AccessorName ?? standardIndexName; yield return $$""" - {{vis}} sealed class {{btree.Name}}Index() : SpacetimeDB.Internal.IndexBase<{{globalName}}>("{{standardIndexName}}") { + {{vis}} sealed class {{name}}Index() : SpacetimeDB.Internal.IndexBase<{{globalName}}>("{{standardIndexName}}") { """; for (var n = 0; n < members.Length; n++) @@ -380,7 +386,7 @@ public ulong Delete({{argsBounds}}) => """; } - yield return $"}}\n {vis} {btree.Name}Index {btree.Name} => new();\n"; + yield return $"}}\n {vis} {name}Index {name} => new();\n"; } } @@ -391,7 +397,7 @@ public IEnumerable GenerateViews() foreach (var v in Views) { var autoIncFields = Members - .Where(f => f.GetAttrs(v.Name).HasFlag(ColumnAttrs.AutoInc)) + .Where(f => f.GetAttrs(v).HasFlag(ColumnAttrs.AutoInc)) .Select(f => f.Name); var globalName = $"global::{FullName}"; @@ -416,12 +422,36 @@ public IEnumerable GenerateViews() return row; } + static SpacetimeDB.Internal.RawTableDefV9 {{iTable}}.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( + Name: nameof({{v.Name}}), + ProductTypeRef: (uint) new {{globalName}}.BSATN().GetAlgebraicType(registrar).Ref_, + PrimaryKey: [{{GetPrimaryKey(v)?.ToString() ?? ""}}], + Indexes: [ + {{string.Join( + ",\n", + GetConstraints(v, ColumnAttrs.Unique) + .Select(c => new ViewIndex(c.col)) + .Concat(GetIndexes(v)) + .Select(b => b.GenerateIndexDef(Members)) + )}} + ], + Constraints: {{GenConstraintList(v, ColumnAttrs.Unique, $"{iTable}.MakeUniqueConstraint")}}, + Sequences: {{GenConstraintList(v, ColumnAttrs.AutoInc, $"{iTable}.MakeSequence")}}, + Schedule: {{( + v.Scheduled is {} scheduled + ? $"{iTable}.MakeSchedule(\"{scheduled.ReducerName}\", {scheduled.ScheduledAtColumn})" + : "null" + )}}, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.{{(v.IsPublic ? "Public" : "Private")}} + ); + public ulong Count => {{iTable}}.DoCount(); public IEnumerable<{{globalName}}> Iter() => {{iTable}}.DoIter(); public {{globalName}} Insert({{globalName}} row) => {{iTable}}.DoInsert(row); public bool Delete({{globalName}} row) => {{iTable}}.DoDelete(row); - {{string.Join("\n", GenerateViewFilters(v.Name))}} + {{string.Join("\n", GenerateViewFilters(v))}} } """, $"{SyntaxFacts.GetText(Visibility)} Internal.TableHandles.{v.Name} {v.Name} => new();" @@ -431,99 +461,44 @@ public IEnumerable GenerateViews() public record struct Constraint(ColumnDeclaration col, int pos, ColumnAttrs attr); - public IEnumerable GetConstraints(string viewName) => + public IEnumerable GetConstraints( + TableView view, + ColumnAttrs filterByAttr = ~ColumnAttrs.UnSet + ) => Members // Important: the position must be stored here, before filtering. - .Select((col, pos) => new Constraint(col, pos, col.GetAttrs(viewName))) - .Where(c => c.attr != ColumnAttrs.UnSet); - - public override Scope.Extensions ToExtensions() - { - var extensions = base.ToExtensions(); - - if (Views.Any(v => v.Scheduled is not null)) - { - // For scheduled tables we're adding extra fields to the type source. - extensions.Contents.Append( - $$""" - public ulong ScheduledId; - public SpacetimeDB.ScheduleAt ScheduledAt; - """ - ); - - // When doing so, the compiler will warn about undefined ordering between partial declarations. - // We don't care about ordering as we generate BSATN ourselves and don't use those structs in FFI, - // so we can safely suppress the warning by saying "yes, we're okay with an auto/arbitrary layout". - extensions.ExtraAttrs.Add( - "[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Auto)]" - ); - } - - // If it's a tagged enum, then attempting to generate table methods will result in more noisy errors than it's worth. - // We already reported useful diagnostic while parsing, and we generated what we could (type-level methods), so let's stop here. - if (Kind is TypeKind.Sum) - { - return extensions; - } - - var iTable = $"SpacetimeDB.Internal.ITable<{ShortName}>"; - - // ITable inherits IStructuralReadWrite, so we can replace the base type instead of appending another one. - extensions.BaseTypes.Clear(); - extensions.BaseTypes.Add(iTable); - - extensions.Contents.Append( - $$""" - static IEnumerable {{iTable}}.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => [ - {{string.Join("\n", Views.Select(v => $$""" - new ( - new ( - TableName: nameof(SpacetimeDB.Local.{{v.Name}}), - Columns: [ - {{string.Join(",\n", Members.Select(m => m.GenerateColumnDef()))}} - ], - Indexes: [ - {{string.Join(",\n", BTrees - .Where(b => b.Table == null || b.Table == v.Name) - .Select(b => b.GenerateIndexDef(v.Name, Members)) - )}} - ],Constraints: [ - {{string.Join( - ",\n", - GetConstraints(v.Name) - .Select(ct => - $$""" - new( - "{{v.Name}}_{{ct.col.Name}}", - (byte)SpacetimeDB.Internal.ColumnAttrs.{{ct.attr}}, - [{{ct.pos}}] - ) - """ - ) - )}} - ], - Sequences: [], - // "system" | "user" - TableType: "user", - // "public" | "private" - TableAccess: "{{(v.IsPublic ? "public" : "private")}}", - Scheduled: {{(v.Scheduled is not null ? $"\"{v.Scheduled}\"" : "null")}} - ), - (uint) ((SpacetimeDB.BSATN.AlgebraicType.Ref) new BSATN().GetAlgebraicType(registrar)).Ref_ - ), - """))}} - ]; - """ - ); - - return extensions; - } + .Select((col, pos) => new Constraint(col, pos, col.GetAttrs(view))) + .Where(c => c.attr.HasFlag(filterByAttr)); + + public IEnumerable GetIndexes(TableView view) => + Indexes.Where(i => i.Table == null || i.Table == view.Name); + + // Reimplementation of V8 -> V9 constraint conversion in Rust. + // See https://github.com/clockworklabs/SpacetimeDB/blob/13a800e9f88cbe885b98eab9e45b0fcfd3ab7014/crates/schema/src/def/validate/v8.rs#L74-L78 + // and https://github.com/clockworklabs/SpacetimeDB/blob/13a800e9f88cbe885b98eab9e45b0fcfd3ab7014/crates/lib/src/db/raw_def/v8.rs#L460-L510 + private string GenConstraintList( + TableView view, + ColumnAttrs filterByAttr, + string makeConstraintFn + ) => + $$""" + [ + {{string.Join( + ",\n", + GetConstraints(view, filterByAttr) + .Select(pair => $"{makeConstraintFn}({pair.pos})") + )}} + ] + """; + + internal int? GetPrimaryKey(TableView view) => + GetConstraints(view, ColumnAttrs.PrimaryKey).Select(c => (int?)c.pos).SingleOrDefault(); } record ReducerDeclaration { public readonly string Name; - public readonly string ExportName; + public readonly ReducerKind Kind; public readonly string FullName; public readonly EquatableArray Args; public readonly Scope Scope; @@ -557,13 +532,7 @@ public ReducerDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter } } - ExportName = attr.Kind switch - { - ReducerKind.Init => "__init__", - ReducerKind.ClientConnected => "__identity_connected__", - ReducerKind.ClientDisconnected => "__identity_disconnected__", - _ => Name, - }; + Kind = attr.Kind; FullName = SymbolToName(method); Args = new( method @@ -584,9 +553,15 @@ public string GenerateClass() class {{Name}}: SpacetimeDB.Internal.IReducer { {{MemberDeclaration.GenerateBsatnFields(Accessibility.Private, Args)}} - public SpacetimeDB.Internal.ReducerDef MakeReducerDef(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( - "{{ExportName}}", - [{{MemberDeclaration.GenerateDefs(Args)}}] + public SpacetimeDB.Internal.RawReducerDefV9 MakeReducerDef(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( + nameof({{Name}}), + [{{MemberDeclaration.GenerateDefs(Args)}}], + {{Kind switch { + ReducerKind.Init => "SpacetimeDB.Internal.Lifecycle.Init", + ReducerKind.ClientConnected => "SpacetimeDB.Internal.Lifecycle.OnConnect", + ReducerKind.ClientDisconnected => "SpacetimeDB.Internal.Lifecycle.OnDisconnect", + _ => "null" + }}} ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { @@ -617,7 +592,7 @@ public Scope.Extensions GenerateSchedule() "\n", Args.Select(a => $"new {a.TypeInfo}().Write(writer, {a.Name});") )}} - SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate("{{ExportName}}", stream); + SpacetimeDB.Internal.IReducer.VolatileNonatomicScheduleImmediate(nameof({{Name}}), stream); } """ ); @@ -719,13 +694,31 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .WithTrackingName("SpacetimeDB.Reducer.GenerateSchedule") .RegisterSourceOutputs(context); + context.RegisterSourceOutput( + reducers + .Where(r => r.Kind != ReducerKind.UserDefined) + .Collect() + .SelectMany( + (reducers, ct) => + reducers + .GroupBy(r => r.Kind) + .Where(group => group.Count() > 1) + .Select(group => + ErrorDescriptor.DuplicateSpecialReducer.ToDiag( + (group.Key, group.Select(r => r.FullName)) + ) + ) + ), + (ctx, diag) => ctx.ReportDiagnostic(diag) + ); + var addReducers = CollectDistinct( "Reducer", context, reducers - .Select((r, ct) => (r.Name, r.ExportName, r.FullName, Class: r.GenerateClass())) + .Select((r, ct) => (r.Name, r.FullName, Class: r.GenerateClass())) .WithTrackingName("SpacetimeDB.Reducer.GenerateClass"), - r => r.ExportName, + r => r.Name, r => r.FullName ); @@ -805,7 +798,7 @@ public static void Main() { )}} {{string.Join( "\n", - tableViews.Select(t => $"SpacetimeDB.Internal.Module.RegisterTable<{t.tableName}>();").Distinct() + tableViews.Select(t => $"SpacetimeDB.Internal.Module.RegisterTable<{t.tableName}, SpacetimeDB.Internal.TableHandles.{t.viewName}>();") )}} } diff --git a/crates/bindings-csharp/Runtime/Attrs.cs b/crates/bindings-csharp/Runtime/Attrs.cs index 86db7eeb46f..a3390fb3436 100644 --- a/crates/bindings-csharp/Runtime/Attrs.cs +++ b/crates/bindings-csharp/Runtime/Attrs.cs @@ -14,7 +14,7 @@ public enum ColumnAttrs : byte PrimaryKeyAuto = PrimaryKey | AutoInc, } - [AttributeUsage(AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] public abstract class ColumnAttribute : Attribute { public string? Table { get; init; } @@ -48,7 +48,17 @@ public sealed class TableAttribute : Attribute /// public bool Public { get; init; } = false; + /// + /// If set, the name of the reducer that will be invoked when the scheduled time is reached. + /// public string? Scheduled { get; init; } + + /// + /// The name of the column that will be used to store the scheduled time. + /// + /// Defaults to ScheduledAt. + /// + public string ScheduledAt { get; init; } = "ScheduledAt"; } [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)] diff --git a/crates/bindings-csharp/Runtime/Internal/IIndex.cs b/crates/bindings-csharp/Runtime/Internal/IIndex.cs index 6f87c3bacb2..5abc12620e4 100644 --- a/crates/bindings-csharp/Runtime/Internal/IIndex.cs +++ b/crates/bindings-csharp/Runtime/Internal/IIndex.cs @@ -1,9 +1,10 @@ namespace SpacetimeDB.Internal; using System; +using SpacetimeDB.BSATN; public abstract class IndexBase - where Row : ITable, new() + where Row : IStructuralReadWrite, new() { private readonly FFI.IndexId indexId; @@ -60,8 +61,7 @@ out var out_ return out_; } - private class RawTableIter(FFI.IndexId indexId, Bounds bounds) - : ITable.RawTableIterBase + private class RawTableIter(FFI.IndexId indexId, Bounds bounds) : RawTableIterBase where Bounds : IBTreeIndexBounds { protected override void IterStart(out FFI.RowIter handle) @@ -85,7 +85,7 @@ out handle public abstract class UniqueIndex(Handle table, string name) : IndexBase(name) where Handle : ITableView - where Row : ITable, new() + where Row : IStructuralReadWrite, new() where T : IEquatable where RW : struct, BSATN.IReadWrite { diff --git a/crates/bindings-csharp/Runtime/Internal/IReducer.cs b/crates/bindings-csharp/Runtime/Internal/IReducer.cs index 0a4f6fe75c8..052dda3c630 100644 --- a/crates/bindings-csharp/Runtime/Internal/IReducer.cs +++ b/crates/bindings-csharp/Runtime/Internal/IReducer.cs @@ -7,7 +7,7 @@ public interface IReducerContext { } public interface IReducer { - ReducerDef MakeReducerDef(ITypeRegistrar registrar); + RawReducerDefV9 MakeReducerDef(ITypeRegistrar registrar); // This one is not static because we need to be able to store IReducer in a list. void Invoke(BinaryReader reader, IReducerContext args); diff --git a/crates/bindings-csharp/Runtime/Internal/ITable.cs b/crates/bindings-csharp/Runtime/Internal/ITable.cs index 8b688646ea5..7a1bca01a1e 100644 --- a/crates/bindings-csharp/Runtime/Internal/ITable.cs +++ b/crates/bindings-csharp/Runtime/Internal/ITable.cs @@ -2,97 +2,91 @@ namespace SpacetimeDB.Internal; using SpacetimeDB.BSATN; -public interface ITable : IStructuralReadWrite - where T : ITable, new() +internal abstract class RawTableIterBase + where T : IStructuralReadWrite, new() { - // These are the methods that codegen needs to implement. - static abstract IEnumerable MakeTableDesc(ITypeRegistrar registrar); - - internal abstract class RawTableIterBase + public sealed class Enumerator(FFI.RowIter handle) : IDisposable { - public sealed class Enumerator(FFI.RowIter handle) : IDisposable - { - byte[] buffer = new byte[0x20_000]; - public byte[] Current { get; private set; } = []; + byte[] buffer = new byte[0x20_000]; + public byte[] Current { get; private set; } = []; - public bool MoveNext() + public bool MoveNext() + { + if (handle == FFI.RowIter.INVALID) { - if (handle == FFI.RowIter.INVALID) - { - return false; - } - - uint buffer_len; - while (true) - { - buffer_len = (uint)buffer.Length; - var ret = FFI.row_iter_bsatn_advance(handle, buffer, ref buffer_len); - if (ret == Errno.EXHAUSTED) - { - handle = FFI.RowIter.INVALID; - } - // On success, the only way `buffer_len == 0` is for the iterator to be exhausted. - // This happens when the host iterator was empty from the start. - System.Diagnostics.Debug.Assert(!(ret == Errno.OK && buffer_len == 0)); - switch (ret) - { - // Iterator advanced and may also be `EXHAUSTED`. - // When `OK`, we'll need to advance the iterator in the next call to `MoveNext`. - // In both cases, copy over the row data to `Current` from the scratch `buffer`. - case Errno.EXHAUSTED - or Errno.OK: - Current = new byte[buffer_len]; - Array.Copy(buffer, 0, Current, 0, buffer_len); - return buffer_len != 0; - // Couldn't find the iterator, error! - case Errno.NO_SUCH_ITER: - throw new NoSuchIterException(); - // The scratch `buffer` is too small to fit a row / chunk. - // Grow `buffer` and try again. - // The `buffer_len` will have been updated with the necessary size. - case Errno.BUFFER_TOO_SMALL: - buffer = new byte[buffer_len]; - continue; - default: - throw new UnknownException(ret); - } - } + return false; } - public void Dispose() + uint buffer_len; + while (true) { - if (handle != FFI.RowIter.INVALID) + buffer_len = (uint)buffer.Length; + var ret = FFI.row_iter_bsatn_advance(handle, buffer, ref buffer_len); + if (ret == Errno.EXHAUSTED) { - FFI.row_iter_bsatn_close(handle); handle = FFI.RowIter.INVALID; } + // On success, the only way `buffer_len == 0` is for the iterator to be exhausted. + // This happens when the host iterator was empty from the start. + System.Diagnostics.Debug.Assert(!(ret == Errno.OK && buffer_len == 0)); + switch (ret) + { + // Iterator advanced and may also be `EXHAUSTED`. + // When `OK`, we'll need to advance the iterator in the next call to `MoveNext`. + // In both cases, copy over the row data to `Current` from the scratch `buffer`. + case Errno.EXHAUSTED + or Errno.OK: + Current = new byte[buffer_len]; + Array.Copy(buffer, 0, Current, 0, buffer_len); + return buffer_len != 0; + // Couldn't find the iterator, error! + case Errno.NO_SUCH_ITER: + throw new NoSuchIterException(); + // The scratch `buffer` is too small to fit a row / chunk. + // Grow `buffer` and try again. + // The `buffer_len` will have been updated with the necessary size. + case Errno.BUFFER_TOO_SMALL: + buffer = new byte[buffer_len]; + continue; + default: + throw new UnknownException(ret); + } } + } - public void Reset() + public void Dispose() + { + if (handle != FFI.RowIter.INVALID) { - throw new NotImplementedException(); + FFI.row_iter_bsatn_close(handle); + handle = FFI.RowIter.INVALID; } } - protected abstract void IterStart(out FFI.RowIter handle); - - // Note: using the GetEnumerator() duck-typing protocol instead of IEnumerable to avoid extra boxing. - public Enumerator GetEnumerator() + public void Reset() { - IterStart(out var handle); - return new(handle); + throw new NotImplementedException(); } + } - public IEnumerable Parse() + protected abstract void IterStart(out FFI.RowIter handle); + + // Note: using the GetEnumerator() duck-typing protocol instead of IEnumerable to avoid extra boxing. + public Enumerator GetEnumerator() + { + IterStart(out var handle); + return new(handle); + } + + public IEnumerable Parse() + { + foreach (var chunk in this) { - foreach (var chunk in this) + using var stream = new MemoryStream(chunk); + using var reader = new BinaryReader(stream); + while (stream.Position < stream.Length) { - using var stream = new MemoryStream(chunk); - using var reader = new BinaryReader(stream); - while (stream.Position < stream.Length) - { - yield return Read(reader); - } + yield return IStructuralReadWrite.Read(reader); } } } @@ -100,23 +94,28 @@ public IEnumerable Parse() public interface ITableView where View : ITableView - where T : ITable, new() + where T : IStructuralReadWrite, new() { + // These are the methods that codegen needs to implement. + static abstract RawTableDefV9 MakeTableDesc(ITypeRegistrar registrar); + static abstract T ReadGenFields(BinaryReader reader, T row); // These are static helpers that codegen can use. - private class RawTableIter(FFI.TableId tableId) : ITable.RawTableIterBase + private class RawTableIter(FFI.TableId tableId) : RawTableIterBase { protected override void IterStart(out FFI.RowIter handle) => FFI.datastore_table_scan_bsatn(tableId, out handle); } + private static readonly string tableName = typeof(View).Name; + // Note: this must be Lazy to ensure that we don't try to get the tableId during startup, before the module is initialized. private static readonly Lazy tableId_ = new(() => { - var name_bytes = System.Text.Encoding.UTF8.GetBytes(typeof(View).Name); + var name_bytes = System.Text.Encoding.UTF8.GetBytes(tableName); FFI.table_id_from_name(name_bytes, (uint)name_bytes.Length, out var out_); return out_; }); @@ -158,4 +157,20 @@ protected static bool DoDelete(T row) FFI.datastore_delete_all_by_eq_bsatn(tableId, bytes, (uint)bytes.Length, out var out_); return out_ > 0; } + + protected static RawScheduleDefV9 MakeSchedule(string reducerName, ushort colIndex) => + new(Name: $"{tableName}_sched", ReducerName: reducerName, ScheduledAtColumn: colIndex); + + protected static RawSequenceDefV9 MakeSequence(ushort colIndex) => + new( + Name: null, + Column: colIndex, + Start: null, + MinValue: null, + MaxValue: null, + Increment: 1 + ); + + protected static RawConstraintDefV9 MakeUniqueConstraint(ushort colIndex) => + new(Name: null, Data: new RawConstraintDataV9.Unique(new([colIndex]))); } diff --git a/crates/bindings-csharp/Runtime/Internal/Module.cs b/crates/bindings-csharp/Runtime/Internal/Module.cs index e912a106129..9d62a2e14b1 100644 --- a/crates/bindings-csharp/Runtime/Internal/Module.cs +++ b/crates/bindings-csharp/Runtime/Internal/Module.cs @@ -5,7 +5,7 @@ namespace SpacetimeDB.Internal; using SpacetimeDB; using SpacetimeDB.BSATN; -partial class RawModuleDefV8 +partial class RawModuleDefV9 { // Note: this intends to generate a valid identifier, but it's not guaranteed to be unique as it's not proper mangling. // Fix it up to a different mangling scheme if it causes problems. @@ -16,9 +16,8 @@ private static string GetFriendlyName(Type type) => private void RegisterTypeName(AlgebraicType.Ref typeRef) { - MiscExports.Add( - new MiscModuleExport.TypeAlias(new(GetFriendlyName(typeof(T)), (uint)typeRef.Ref_)) - ); + var scopedName = new RawScopedTypeNameV9([], GetFriendlyName(typeof(T))); + Types.Add(new(scopedName, (uint)typeRef.Ref_, CustomOrdering: true)); } internal AlgebraicType.Ref RegisterType(Func makeType) @@ -33,14 +32,14 @@ internal AlgebraicType.Ref RegisterType(Func Reducers.Add(reducer); + internal void RegisterReducer(RawReducerDefV9 reducer) => Reducers.Add(reducer); - internal void RegisterTable(TableDesc table) => Tables.Add(table); + internal void RegisterTable(RawTableDefV9 table) => Tables.Add(table); } public static class Module { - private static readonly RawModuleDefV8 moduleDef = new(); + private static readonly RawModuleDefV9 moduleDef = new(); private static readonly List reducers = []; private static Func? newContext = @@ -89,13 +88,11 @@ public static void RegisterReducer() moduleDef.RegisterReducer(reducer.MakeReducerDef(typeRegistrar)); } - public static void RegisterTable() - where T : ITable, new() + public static void RegisterTable() + where T : IStructuralReadWrite, new() + where View : ITableView, new() { - foreach (var t in T.MakeTableDesc(typeRegistrar)) - { - moduleDef.RegisterTable(t); - } + moduleDef.RegisterTable(View.MakeTableDesc(typeRegistrar)); } private static byte[] Consume(this BytesSource source) @@ -154,12 +151,10 @@ private static void Write(this BytesSink sink, byte[] bytes) public static void __describe_module__(BytesSink description) { - // replace `module` with a temporary internal module that will register RawModuleDefV8, AlgebraicType and other internal types - // during the RawModuleDefV8.GetSatsTypeInfo() instead of exposing them via user's module. try { // We need this explicit cast here to make `ToBytes` understand the types correctly. - RawModuleDef versioned = new RawModuleDef.V8BackCompat(moduleDef); + RawModuleDef versioned = new RawModuleDef.V9(moduleDef); var moduleBytes = IStructuralReadWrite.ToBytes(new RawModuleDef.BSATN(), versioned); description.Write(moduleBytes); } diff --git a/crates/bindings-csharp/Runtime/Runtime.csproj b/crates/bindings-csharp/Runtime/Runtime.csproj index 011a41b3961..f9534147600 100644 --- a/crates/bindings-csharp/Runtime/Runtime.csproj +++ b/crates/bindings-csharp/Runtime/Runtime.csproj @@ -2,7 +2,7 @@ SpacetimeDB.Runtime - 1.0.0-rc1-hotfix1 + 1.0.0-rc2 SpacetimeDB Module Runtime The SpacetimeDB Runtime implements the database runtime bindings for writing SpacetimeDB modules in C#. diff --git a/crates/sats/src/lib.rs b/crates/sats/src/lib.rs index 948992ef749..63e92d75678 100644 --- a/crates/sats/src/lib.rs +++ b/crates/sats/src/lib.rs @@ -234,3 +234,8 @@ where macro_rules! __make_register_reftype { ($ty:ty, $name:literal) => {}; } + +/// A helper for prettier Debug implementation, without extra indirection around Some("name"). +fn dbg_aggregate_name(opt: &Option>) -> &dyn std::fmt::Debug { + opt.as_ref().map_or(opt, |s| s) +} diff --git a/crates/sats/src/product_type.rs b/crates/sats/src/product_type.rs index 30bc21d464b..4f1699f10da 100644 --- a/crates/sats/src/product_type.rs +++ b/crates/sats/src/product_type.rs @@ -35,7 +35,7 @@ pub const ADDRESS_TAG: &str = "__address__"; /// so for example, `values({ A: U64, B: Bool }) = values(U64) * values(Bool)`. /// /// [structural]: https://en.wikipedia.org/wiki/Structural_type_system -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, SpacetimeType)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, SpacetimeType)] #[sats(crate = crate)] pub struct ProductType { /// The factors of the product type. @@ -45,6 +45,19 @@ pub struct ProductType { pub elements: Box<[ProductTypeElement]>, } +impl std::fmt::Debug for ProductType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("ProductType ")?; + f.debug_map() + .entries( + self.elements + .iter() + .map(|elem| (crate::dbg_aggregate_name(&elem.name), &elem.algebraic_type)), + ) + .finish() + } +} + impl ProductType { /// Returns a product type with the given `elements` as its factors. pub const fn new(elements: Box<[ProductTypeElement]>) -> Self { diff --git a/crates/sats/src/sum_type.rs b/crates/sats/src/sum_type.rs index 378bae85888..7c7a4dc2a12 100644 --- a/crates/sats/src/sum_type.rs +++ b/crates/sats/src/sum_type.rs @@ -37,7 +37,7 @@ pub const OPTION_NONE_TAG: &str = "none"; /// See also: https://ncatlab.org/nlab/show/sum+type. /// /// [structural]: https://en.wikipedia.org/wiki/Structural_type_system -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, SpacetimeType)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, SpacetimeType)] #[sats(crate = crate)] pub struct SumType { /// The possible variants of the sum type. @@ -46,6 +46,19 @@ pub struct SumType { pub variants: Box<[SumTypeVariant]>, } +impl std::fmt::Debug for SumType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("SumType ")?; + f.debug_map() + .entries( + self.variants + .iter() + .map(|variant| (crate::dbg_aggregate_name(&variant.name), &variant.algebraic_type)), + ) + .finish() + } +} + impl SumType { /// Returns a sum type with these possible `variants`. pub const fn new(variants: Box<[SumTypeVariant]>) -> Self { diff --git a/crates/sats/src/typespace.rs b/crates/sats/src/typespace.rs index 61184fc1998..cbddf79620a 100644 --- a/crates/sats/src/typespace.rs +++ b/crates/sats/src/typespace.rs @@ -35,7 +35,7 @@ pub enum TypeRefError { /// where `&0` is the type reference at index `0`. /// /// [System F]: https://en.wikipedia.org/wiki/System_F -#[derive(Debug, Clone, SpacetimeType)] +#[derive(Clone, SpacetimeType)] #[cfg_attr(feature = "test", derive(PartialEq, Eq, PartialOrd, Ord))] #[sats(crate = crate)] pub struct Typespace { @@ -43,6 +43,13 @@ pub struct Typespace { pub types: Vec, } +impl std::fmt::Debug for Typespace { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("Typespace ")?; + f.debug_list().entries(&self.types).finish() + } +} + impl Default for Typespace { fn default() -> Self { Self::new(Vec::new()) diff --git a/crates/schema/Cargo.toml b/crates/schema/Cargo.toml index 952d1a3b284..82fda50506e 100644 --- a/crates/schema/Cargo.toml +++ b/crates/schema/Cargo.toml @@ -35,5 +35,5 @@ spacetimedb-lib = { workspace = true, features = ["test"] } spacetimedb-testing = { path = "../testing" } spacetimedb-cli.workspace = true -pretty_assertions.workspace = true proptest.workspace = true +serial_test.workspace = true diff --git a/crates/schema/tests/ensure_same_schema.rs b/crates/schema/tests/ensure_same_schema.rs new file mode 100644 index 00000000000..3cf932a28cc --- /dev/null +++ b/crates/schema/tests/ensure_same_schema.rs @@ -0,0 +1,50 @@ +use serial_test::serial; +use spacetimedb_cli::generate::extract_descriptions; +use spacetimedb_schema::auto_migrate::{ponder_auto_migrate, AutoMigrateStep}; +use spacetimedb_schema::def::ModuleDef; +use spacetimedb_testing::modules::{CompilationMode, CompiledModule}; + +fn get_normalized_schema(module_name: &str) -> ModuleDef { + let module = CompiledModule::compile(module_name, CompilationMode::Debug); + extract_descriptions(module.path()) + .expect("failed to extract module descriptions") + .try_into() + .expect("failed to convert raw module def to module def") +} + +fn assert_identical_modules(module_name_prefix: &str) { + let rs = get_normalized_schema(module_name_prefix); + let cs = get_normalized_schema(&format!("{module_name_prefix}-cs")); + let diff = ponder_auto_migrate(&cs, &rs) + .expect("could not compute a diff between Rust and C#") + .steps; + + // Ignore RLS steps for now, as they are not yet implemented in C#. + // TODO: remove this when C#-friendly RLS is implemented. + let mut diff = diff; + diff.retain(|step| !matches!(step, AutoMigrateStep::AddRowLevelSecurity(_))); + + assert!( + diff.is_empty(), + "Rust and C# modules are not identical. Here are the steps to migrate from C# to Rust: {diff:#?}" + ); +} + +macro_rules! declare_tests { + ($($name:ident => $path:literal,)*) => { + $( + #[test] + #[serial] + fn $name() { + assert_identical_modules($path); + } + )* + } +} + +declare_tests! { + spacetimedb_quickstart => "spacetimedb-quickstart", + sdk_test_connect_disconnect => "sdk-test-connect-disconnect", + sdk_test => "sdk-test", + benchmarks => "benchmarks", +} diff --git a/crates/schema/tests/validate_integration.rs b/crates/schema/tests/validate_integration.rs deleted file mode 100644 index 13e6c2c68e1..00000000000 --- a/crates/schema/tests/validate_integration.rs +++ /dev/null @@ -1,74 +0,0 @@ -//! Test that our module validation succeeds with the existing v8 modules in-codebase. - -//! Validate a module. -//! The name should refer to a path in the `modules` directory of this repo. - -use spacetimedb_cli::generate::extract_descriptions; -use spacetimedb_lib::{db::raw_def::v9::RawModuleDefV9, ser::serde::SerializeWrapper, RawModuleDef}; -use spacetimedb_primitives::TableId; -use spacetimedb_schema::{ - def::{ModuleDef, TableDef}, - identifier::Identifier, - schema::{Schema, TableSchema}, -}; -use spacetimedb_testing::modules::{CompilationMode, CompiledModule}; - -const TEST_TABLE_ID: TableId = TableId(1337); - -#[allow(clippy::disallowed_macros)] // LET ME PRINTLN >:( -fn validate_module(module_name: &str) { - let module = CompiledModule::compile(module_name, CompilationMode::Debug); - let raw_module_def: RawModuleDef = - extract_descriptions(module.path()).expect("failed to extract module descriptions"); - let RawModuleDef::V8BackCompat(raw_module_def) = raw_module_def else { - panic!("no more v8 - rewrite to v9") - }; - - // v8 -> ModuleDef - let result = ModuleDef::try_from(raw_module_def.clone()); - - // we don't use `expect` here because we want to format via `Display`, not `Debug`. - let result = match result { - Ok(result) => result, - Err(err) => panic!("Module {} is invalid: \n{}", module_name, err), - }; - - // (ModuleDef -> v9 -> ModuleDef) == noop - let result_as_raw: RawModuleDefV9 = result.clone().into(); - let result_from_raw = ModuleDef::try_from(result_as_raw).expect("failed to convert back to ModuleDef"); - assert_identical(result.clone(), result_from_raw); - - // Check that all tables in the module are valid according to the old validation rules, too. - for table in raw_module_def.tables.into_iter() { - let name = Identifier::new(table.schema.table_name.clone()).expect("already validated"); - let new_def: &TableDef = result.lookup(&name).expect("already validated"); - - let mut schema_new_path = TableSchema::from_module_def(&result, new_def, (), TEST_TABLE_ID); - - schema_new_path.janky_fix_column_defs(&result); - schema_new_path.normalize(); - schema_new_path.validated().expect("TableSchema is invalid"); - } -} - -/// Assert that two ModuleDefs are identical. -/// TODO: implement better ModuleDef comparison. This just checks that their serialized forms are the same, -/// which is fine for this test, but we need a more relaxed comparison in general. -/// Allowing typespace permutations, etc. -fn assert_identical(module_def_1: ModuleDef, module_def_2: ModuleDef) { - let module_def_1: RawModuleDefV9 = module_def_1.into(); - let module_def_2: RawModuleDefV9 = module_def_2.into(); - let s1 = serde_json::to_string_pretty(&SerializeWrapper::new(&module_def_1)).unwrap(); - let s2 = serde_json::to_string_pretty(&SerializeWrapper::new(&module_def_2)).unwrap(); - assert_eq!(s1, s2, "{}", pretty_assertions::StrComparison::new(&s1, &s2)); -} - -#[test] -fn validate_cs_modules() { - // These need to be called in sequence because running them in parallel locks the codegen DLLs - // which causes a compilation failure. Thanks, .NET - validate_module("sdk-test-cs"); - validate_module("sdk-test-connect-disconnect-cs"); - validate_module("spacetimedb-quickstart-cs"); - validate_module("benchmarks-cs"); -} diff --git a/modules/Directory.Build.props b/modules/Directory.Build.props index d9f53d99b49..a03bac5df3a 100644 --- a/modules/Directory.Build.props +++ b/modules/Directory.Build.props @@ -2,8 +2,16 @@ - + StdbModule + net8.0 + wasi-wasm + enable + enable + + false + + $(NoWarn);CS8981;IDE1006 diff --git a/modules/benchmarks-cs/benchmarks-cs.csproj b/modules/benchmarks-cs/benchmarks-cs.csproj index 78bed9e34c0..d4caede5ffa 100644 --- a/modules/benchmarks-cs/benchmarks-cs.csproj +++ b/modules/benchmarks-cs/benchmarks-cs.csproj @@ -1,15 +1,5 @@ - - StdbModule - net8.0 - wasi-wasm - enable - enable - - $(NoWarn);CS8981;IDE1006 - -