diff --git a/crates/bindings-csharp/BSATN.Codegen/Type.cs b/crates/bindings-csharp/BSATN.Codegen/Type.cs index 44f662f0d7f..faa978eb244 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Type.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Type.cs @@ -15,11 +15,18 @@ public MemberDeclaration(ISymbol member, ITypeSymbol type, DiagReporter diag) { TypeInfo = GetTypeInfo(type); } + catch (UnresolvedTypeException) + { + // If it's an unresolved type, this error will have been already highlighted by .NET itself, no need to add noise. + // Just add some dummy type to avoid further errors. + // Note that we just use `object` here because emitting the unresolved type's name again would produce more of said noise. + TypeInfo = "SpacetimeDB.BSATN.Unsupported"; + } catch (Exception e) { diag.Report(ErrorDescriptor.UnsupportedType, (member, type, e)); - // dummy type; can't instantiate an interface, but at least it will produce fewer noisy errors - TypeInfo = $"SpacetimeDB.BSATN.IReadWrite<{Type}>"; + // dummy BSATN implementation to produce fewer noisy errors + TypeInfo = $"SpacetimeDB.BSATN.Unsupported<{Type}>"; } } diff --git a/crates/bindings-csharp/BSATN.Codegen/Utils.cs b/crates/bindings-csharp/BSATN.Codegen/Utils.cs index 7c9964b7a01..33b8b38db1a 100644 --- a/crates/bindings-csharp/BSATN.Codegen/Utils.cs +++ b/crates/bindings-csharp/BSATN.Codegen/Utils.cs @@ -72,6 +72,9 @@ IncrementalGeneratorInitializationContext context public static string MakeRwTypeParam(string typeParam) => typeParam + "RW"; + public class UnresolvedTypeException(INamedTypeSymbol type) + : InvalidOperationException($"Could not resolve type {type}") { } + public static string GetTypeInfo(ITypeSymbol type) { // We need to distinguish handle nullable reference types specially: @@ -120,7 +123,7 @@ static string GetTypeInfoForNamedType(INamedTypeSymbol type) { if (type.TypeKind == Microsoft.CodeAnalysis.TypeKind.Error) { - throw new InvalidOperationException($"Could not resolve type {type}"); + throw new UnresolvedTypeException(type); } if (type.TypeKind == Microsoft.CodeAnalysis.TypeKind.Enum) { diff --git a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs index 65dfa519133..c3c137a5f22 100644 --- a/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs +++ b/crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs @@ -438,3 +438,17 @@ public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => enumerable.GetAlgebraicType(registrar); } + +// This is a dummy type, mainly used by codegen as a diagnostics placeholder to +// reduce amount of noisy compilation errors when a used type is not supported by BSATN. +public readonly struct Unsupported : IReadWrite +{ + private static readonly NotSupportedException Exception = + new($"Type {typeof(T)} is not supported by BSATN."); + + public T Read(BinaryReader reader) => throw Exception; + + public void Write(BinaryWriter writer, T value) => throw Exception; + + public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) => throw Exception; +} 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 465227b1cc9..102787918af 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 @@ -23,29 +23,6 @@ } }, {/* -[SpacetimeDB.Table] -[SpacetimeDB.Index] - ^^^^^^^^^^^^^^^^^ -public partial struct TestIndexWithoutColumns { } -*/ - Message: Required member 'IndexAttribute.BTree' must be set in the object initializer or attribute constructor., - Severity: Error, - Descriptor: { - Id: CS9035, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS9035), - MessageFormat: Required member '{0}' must be set in the object initializer or attribute constructor., - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* { internal static readonly TRW Field = new(); ^^^ @@ -67,787 +44,5 @@ public partial struct TestIndexWithoutColumns { } NotConfigurable ] } - }, - {/* - internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSpecialType = new(); -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSystemType = new(); - ^^^^^ -internal static readonly SpacetimeDB.BSATN.IReadWrite UnresolvedType = new(); -*/ - Message: Cannot create an instance of the abstract type or interface 'IReadWrite', - Severity: Error, - Descriptor: { - Id: CS0144, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0144), - MessageFormat: Cannot create an instance of the abstract type or interface '{0}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSystemType = new(); -internal static readonly SpacetimeDB.BSATN.IReadWrite UnresolvedType = new(); - ^^^^^^^^^^^^^^ -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedEnum = new(); -*/ - Message: The type or namespace name 'UnresolvedType' could not be found (are you missing a using directive or an assembly reference?), - Severity: Error, - Descriptor: { - Id: CS0246, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0246), - MessageFormat: The type or namespace name '{0}' could not be found (are you missing a using directive or an assembly reference?), - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSystemType = new(); -internal static readonly SpacetimeDB.BSATN.IReadWrite UnresolvedType = new(); - ^^^^^ -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedEnum = new(); -*/ - Message: Cannot create an instance of the abstract type or interface 'IReadWrite', - Severity: Error, - Descriptor: { - Id: CS0144, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0144), - MessageFormat: Cannot create an instance of the abstract type or interface '{0}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -internal static readonly SpacetimeDB.BSATN.IReadWrite UnresolvedType = new(); -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedEnum = new(); - ^^^^^ - -*/ - Message: Cannot create an instance of the abstract type or interface 'IReadWrite', - Severity: Error, - Descriptor: { - Id: CS0144, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0144), - MessageFormat: Cannot create an instance of the abstract type or interface '{0}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -{ - internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSpecialType = new(); - ^^^^^ -internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSystemType = new(); -*/ - Message: Cannot create an instance of the abstract type or interface 'IReadWrite', - Severity: Error, - Descriptor: { - Id: CS0144, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0144), - MessageFormat: Cannot create an instance of the abstract type or interface '{0}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -} -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.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 readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - ^^^^^^^^^^^^^^^^^^^ - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum 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', - Severity: Error, - Descriptor: { - Id: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -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.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 readonly struct TestTableTaggedEnum : SpacetimeDB.Internal.ITableView { - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum 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', - Severity: Error, - Descriptor: { - Id: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - - static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Name: nameof(TestTableTaggedEnum), -*/ - 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 - ] - } - }, - {/* - - static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => new ( - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Name: nameof(TestTableTaggedEnum), -*/ - 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: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - - public ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); -*/ - 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 ulong Count => SpacetimeDB.Internal.ITableView.DoCount(); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - public IEnumerable Iter() => SpacetimeDB.Internal.ITableView.DoIter(); -*/ - 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: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - 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 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 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: '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: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - 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 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 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: '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: CS0310, - 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}', - 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: 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: '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: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - - public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_UniqueField_idx_btree") {} -*/ - Message: Partial declarations of 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' must not specify different base classes, - Severity: Error, - Descriptor: { - Id: CS0263, - 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, - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - 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: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, - Severity: Error, - Descriptor: { - Id: CS0122, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), - MessageFormat: '{0}' is inaccessible due to its protection level, - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - // `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); - ^^^^^^^^ -} -*/ - Message: The name 'DoUpdate' 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 TestUniqueNotEquatableUniqueIndex UniqueField => new(this); - ^^^^^^^^^ -public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { -*/ - Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', - Severity: Error, - Descriptor: { - Id: CS0121, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); -public sealed class TestUniqueNotEquatableUniqueIndex : UniqueIndex> { - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_idx_btree") {} -*/ - Message: The type 'TestUniqueNotEquatable' already contains a definition for 'TestUniqueNotEquatableUniqueIndex', - Severity: Error, - Descriptor: { - Id: CS0102, - Title: , - 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, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -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: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'TestUniqueNotEquatableUniqueIndex' with the same parameter types, - Severity: Error, - Descriptor: { - Id: CS0111, - 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, - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -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: 'UniqueIndex>.UniqueIndex(TestUniqueNotEquatable, string)' is inaccessible due to its protection level, - Severity: Error, - Descriptor: { - Id: CS0122, - Title: , - HelpLink: https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS0122), - MessageFormat: '{0}' is inaccessible due to its protection level, - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - // `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: 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(TestEnumWithExplicitValues key) => DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); - ^^^^^^ -} -*/ - Message: Type 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex' already defines a member called 'Update' with the same parameter types, - Severity: Error, - Descriptor: { - Id: CS0111, - 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, - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - public global::TestUniqueNotEquatable? Find(TestEnumWithExplicitValues key) => DoFilter(key).Cast().SingleOrDefault(); - public bool Update(global::TestUniqueNotEquatable row) => DoUpdate(row.PrimaryKeyField, row); - ^^^^^^^^ -} -*/ - Message: The name 'DoUpdate' 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 TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); - ^^^^^^^^^ -} -*/ - Message: The call is ambiguous between the following methods or properties: 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)' and 'TestUniqueNotEquatable.TestUniqueNotEquatableUniqueIndex.TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable)', - Severity: Error, - Descriptor: { - Id: CS0121, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* - public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.TestReducerWithoutContext((SpacetimeDB.ReducerContext)ctx); - ^^^^^^^^^^^^^^^^^^^^^^^^^ - } -*/ - Message: No overload for method 'TestReducerWithoutContext' takes 1 arguments, - Severity: Error, - Descriptor: { - Id: CS1501, - Title: , - 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, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } - }, - {/* -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 'Module.RegisterTable()'. 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 - ] - } - }, - {/* -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 'Module.RegisterTable()', - Severity: Error, - Descriptor: { - Id: CS0310, - 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}', - Category: Compiler, - DefaultSeverity: Error, - IsEnabledByDefault: true, - CustomTags: [ - Compiler, - Telemetry, - NotConfigurable - ] - } } ] \ No newline at end of file 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 a3c89ede44e..cc36a57e2e2 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 @@ -198,6 +198,138 @@ public bool Delete(global::TestDuplicateTableName row) => >.DoDelete(row); } + public readonly struct TestIndexWithEmptyColumns + : SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + > + { + static global::TestIndexWithEmptyColumns SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.ReadGenFields(System.IO.BinaryReader reader, global::TestIndexWithEmptyColumns row) + { + return row; + } + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestIndexWithEmptyColumns), + ProductTypeRef: (uint) + new global::TestIndexWithEmptyColumns.BSATN() + .GetAlgebraicType(registrar) + .Ref_, + PrimaryKey: [], + Indexes: + [ + new( + Name: null, + AccessorName: "", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([]) + ) + ], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.DoIter(); + + public global::TestIndexWithEmptyColumns Insert( + global::TestIndexWithEmptyColumns row + ) => + SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.DoInsert(row); + + public bool Delete(global::TestIndexWithEmptyColumns row) => + SpacetimeDB.Internal.ITableView< + TestIndexWithEmptyColumns, + global::TestIndexWithEmptyColumns + >.DoDelete(row); + } + + public readonly struct TestIndexWithoutColumns + : SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + > + { + static global::TestIndexWithoutColumns SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.ReadGenFields(System.IO.BinaryReader reader, global::TestIndexWithoutColumns row) + { + return row; + } + + static SpacetimeDB.Internal.RawTableDefV9 SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.MakeTableDesc(SpacetimeDB.BSATN.ITypeRegistrar registrar) => + new( + Name: nameof(TestIndexWithoutColumns), + ProductTypeRef: (uint) + new global::TestIndexWithoutColumns.BSATN() + .GetAlgebraicType(registrar) + .Ref_, + PrimaryKey: [], + Indexes: + [ + new( + Name: null, + AccessorName: "", + Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.BTree([]) + ) + ], + Constraints: [], + Sequences: [], + Schedule: null, + TableType: SpacetimeDB.Internal.TableType.User, + TableAccess: SpacetimeDB.Internal.TableAccess.Private + ); + + public ulong Count => + SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.DoCount(); + + public IEnumerable Iter() => + SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.DoIter(); + + public global::TestIndexWithoutColumns Insert(global::TestIndexWithoutColumns row) => + SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.DoInsert(row); + + public bool Delete(global::TestIndexWithoutColumns row) => + SpacetimeDB.Internal.ITableView< + TestIndexWithoutColumns, + global::TestIndexWithoutColumns + >.DoDelete(row); + } + public readonly struct TestScheduleWithoutPrimaryKey : SpacetimeDB.Internal.ITableView< TestScheduleWithoutPrimaryKey, @@ -546,59 +678,6 @@ public bool Update(global::TestScheduleIssues row) => public TestScheduleWithWrongScheduleAtTypeUniqueIndex IdCorrectType => new(this); } - public readonly struct TestTableTaggedEnum - : SpacetimeDB.Internal.ITableView - { - static global::TestTableTaggedEnum SpacetimeDB.Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.ReadGenFields(System.IO.BinaryReader reader, global::TestTableTaggedEnum row) - { - 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, - global::TestTableTaggedEnum - >.DoCount(); - - public IEnumerable Iter() => - SpacetimeDB.Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.DoIter(); - - public global::TestTableTaggedEnum Insert(global::TestTableTaggedEnum row) => - SpacetimeDB.Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.DoInsert(row); - - public bool Delete(global::TestTableTaggedEnum row) => - SpacetimeDB.Internal.ITableView< - TestTableTaggedEnum, - global::TestTableTaggedEnum - >.DoDelete(row); - } - public readonly struct TestUniqueNotEquatable : SpacetimeDB.Internal.ITableView< TestUniqueNotEquatable, @@ -675,52 +754,6 @@ public bool Delete(global::TestUniqueNotEquatable row) => TestUniqueNotEquatable, global::TestUniqueNotEquatable >.DoDelete(row); - - public sealed class TestUniqueNotEquatableUniqueIndex - : UniqueIndex< - TestUniqueNotEquatable, - global::TestUniqueNotEquatable, - int?, - SpacetimeDB.BSATN.ValueOption - > - { - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) - : base(handle, "TestUniqueNotEquatable_UniqueField_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::TestUniqueNotEquatable? Find(int? key) => - DoFilter(key).Cast().SingleOrDefault(); - - public bool Update(global::TestUniqueNotEquatable row) => - DoUpdate(row.UniqueField, row); - } - - public TestUniqueNotEquatableUniqueIndex UniqueField => new(this); - - public sealed class TestUniqueNotEquatableUniqueIndex - : UniqueIndex< - TestUniqueNotEquatable, - global::TestUniqueNotEquatable, - TestEnumWithExplicitValues, - SpacetimeDB.BSATN.Enum - > - { - internal TestUniqueNotEquatableUniqueIndex(TestUniqueNotEquatable handle) - : base(handle, "TestUniqueNotEquatable_PrimaryKeyField_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::TestUniqueNotEquatable? Find(TestEnumWithExplicitValues key) => - DoFilter(key).Cast().SingleOrDefault(); - - public bool Update(global::TestUniqueNotEquatable row) => - DoUpdate(row.PrimaryKeyField, row); - } - - public TestUniqueNotEquatableUniqueIndex PrimaryKeyField => new(this); } } @@ -728,6 +761,8 @@ public sealed class Local { public Internal.TableHandles.TestAutoIncNotInteger TestAutoIncNotInteger => new(); public Internal.TableHandles.TestDuplicateTableName TestDuplicateTableName => new(); + public Internal.TableHandles.TestIndexWithEmptyColumns TestIndexWithEmptyColumns => new(); + public Internal.TableHandles.TestIndexWithoutColumns TestIndexWithoutColumns => new(); public Internal.TableHandles.TestScheduleWithoutPrimaryKey TestScheduleWithoutPrimaryKey => new(); public Internal.TableHandles.TestScheduleWithoutScheduleAt TestScheduleWithoutScheduleAt => @@ -736,7 +771,6 @@ public sealed class Local new(); public Internal.TableHandles.TestScheduleWithWrongScheduleAtType TestScheduleWithWrongScheduleAtType => new(); - public Internal.TableHandles.TestTableTaggedEnum TestTableTaggedEnum => new(); public Internal.TableHandles.TestUniqueNotEquatable TestUniqueNotEquatable => new(); } } @@ -845,7 +879,7 @@ SpacetimeDB.BSATN.ITypeRegistrar registrar public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - Reducers.TestReducerWithoutContext((SpacetimeDB.ReducerContext)ctx); + throw new System.InvalidOperationException(); } } @@ -883,6 +917,14 @@ public static void Main() global::TestDuplicateTableName, SpacetimeDB.Internal.TableHandles.TestDuplicateTableName >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestIndexWithEmptyColumns, + SpacetimeDB.Internal.TableHandles.TestIndexWithEmptyColumns + >(); + SpacetimeDB.Internal.Module.RegisterTable< + global::TestIndexWithoutColumns, + SpacetimeDB.Internal.TableHandles.TestIndexWithoutColumns + >(); SpacetimeDB.Internal.Module.RegisterTable< global::TestScheduleIssues, SpacetimeDB.Internal.TableHandles.TestScheduleWithoutPrimaryKey @@ -899,10 +941,6 @@ public static void Main() 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 diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithEmptyColumns.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithEmptyColumns.verified.cs new file mode 100644 index 00000000000..0d35229b2d6 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithEmptyColumns.verified.cs @@ -0,0 +1,34 @@ +//HintName: TestIndexWithEmptyColumns.cs +// +#nullable enable + +partial struct TestIndexWithEmptyColumns : SpacetimeDB.BSATN.IStructuralReadWrite +{ + public void ReadFields(System.IO.BinaryReader reader) { } + + public void WriteFields(System.IO.BinaryWriter writer) { } + + public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite + { + public TestIndexWithEmptyColumns Read(System.IO.BinaryReader reader) => + SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); + + public void Write(System.IO.BinaryWriter writer, TestIndexWithEmptyColumns 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[] { } + ) + ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } +} // TestIndexWithEmptyColumns diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithoutColumns.verified.cs b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithoutColumns.verified.cs new file mode 100644 index 00000000000..738fad2ab98 --- /dev/null +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#TestIndexWithoutColumns.verified.cs @@ -0,0 +1,34 @@ +//HintName: TestIndexWithoutColumns.cs +// +#nullable enable + +partial struct TestIndexWithoutColumns : SpacetimeDB.BSATN.IStructuralReadWrite +{ + public void ReadFields(System.IO.BinaryReader reader) { } + + public void WriteFields(System.IO.BinaryWriter writer) { } + + public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite + { + public TestIndexWithoutColumns Read(System.IO.BinaryReader reader) => + SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); + + public void Write(System.IO.BinaryWriter writer, TestIndexWithoutColumns 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[] { } + ) + ); + + SpacetimeDB.BSATN.AlgebraicType SpacetimeDB.BSATN.IReadWrite.GetAlgebraicType( + SpacetimeDB.BSATN.ITypeRegistrar registrar + ) => GetAlgebraicType(registrar); + } +} // TestIndexWithoutColumns 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 f68a8506792..66b9718f4ba 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 @@ -86,43 +86,35 @@ public partial record TestTableTaggedEnum : SpacetimeDB.TaggedEnum<(int X, int Y } }, {/* - [SpacetimeDB.Table] -^^^^^^^^^^^^^^^^^^^ [SpacetimeDB.Index] -^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^^^^^^ public partial struct TestIndexWithoutColumns { } -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - Message: An internal error occurred during codegen: Object reference not set to an instance of an object., + Message: Index has an Index.BTree attribute, but no columns., Severity: Error, Descriptor: { - Id: STDBINT0001, - Title: Internal SpacetimeDB codegen error, - MessageFormat: An internal error occurred during codegen: {0}, - Category: SpacetimeDB.Internal, + Id: STDB0004, + Title: Index attribute must specify columns., + MessageFormat: {0} has an Index.BTree attribute, but no columns., + Category: SpacetimeDB, DefaultSeverity: Error, IsEnabledByDefault: true } }, {/* - [SpacetimeDB.Table] -^^^^^^^^^^^^^^^^^^^ [SpacetimeDB.Index(BTree = [])] -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ public partial struct TestIndexWithEmptyColumns { } -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - */ - Message: An internal error occurred during codegen: Object reference not set to an instance of an object., + Message: Index has an Index.BTree attribute, but no columns., Severity: Error, Descriptor: { - Id: STDBINT0001, - Title: Internal SpacetimeDB codegen error, - MessageFormat: An internal error occurred during codegen: {0}, - Category: SpacetimeDB.Internal, + Id: STDB0004, + Title: Index attribute must specify columns., + MessageFormat: {0} has an Index.BTree attribute, but no columns., + Category: SpacetimeDB, DefaultSeverity: Error, IsEnabledByDefault: true } 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 8b8e392fe6c..72955e717f2 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 @@ -22,13 +22,12 @@ public void WriteFields(System.IO.BinaryWriter writer) public readonly partial struct BSATN : SpacetimeDB.BSATN.IReadWrite { - internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSpecialType = + internal static readonly SpacetimeDB.BSATN.Unsupported UnsupportedSpecialType = new(); - internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedSystemType = + internal static readonly SpacetimeDB.BSATN.Unsupported UnsupportedSystemType = new(); - internal static readonly SpacetimeDB.BSATN.IReadWrite UnresolvedType = - new(); - internal static readonly SpacetimeDB.BSATN.IReadWrite UnsupportedEnum = new(); + internal static readonly SpacetimeDB.BSATN.Unsupported UnresolvedType = new(); + internal static readonly SpacetimeDB.BSATN.Unsupported UnsupportedEnum = new(); public TestUnsupportedType Read(System.IO.BinaryReader reader) => SpacetimeDB.BSATN.IStructuralReadWrite.Read(reader); diff --git a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type.verified.txt b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type.verified.txt index a707dbe2847..55f132a7a0c 100644 --- a/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type.verified.txt +++ b/crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Type.verified.txt @@ -86,23 +86,6 @@ } }, {/* - public Exception UnsupportedSystemType; - public UnresolvedType UnresolvedType; - ^^^^^^^^^^^^^^ - public LocalEnum UnsupportedEnum; -*/ - Message: BSATN implementation for UnresolvedType is not found: Could not resolve type UnresolvedType, - Severity: Error, - Descriptor: { - Id: BSATN0001, - Title: Unsupported type, - MessageFormat: BSATN implementation for {0} is not found: {1}, - Category: SpacetimeDB.BSATN, - DefaultSeverity: Error, - IsEnabledByDefault: true - } - }, - {/* public UnresolvedType UnresolvedType; public LocalEnum UnsupportedEnum; ^^^^^^^^^^^^^^^ diff --git a/crates/bindings-csharp/Codegen/Diag.cs b/crates/bindings-csharp/Codegen/Diag.cs index 1635bc0b161..2ab9a9a830d 100644 --- a/crates/bindings-csharp/Codegen/Diag.cs +++ b/crates/bindings-csharp/Codegen/Diag.cs @@ -34,12 +34,16 @@ internal static class ErrorDescriptor field => field ); - public static readonly ErrorDescriptor EmptyIndexColumns = + public static readonly ErrorDescriptor<( + ViewIndex index, + AttributeData attr + )> EmptyIndexColumns = new( group, - "Index attribute must specify index Columns.", - table => $"Table {table.Identifier} has an Index.BTree attribute, but no columns.", - table => table.BaseList! + "Index attribute must specify columns.", + ctx => + $"{(ctx.index.AccessorName != "" ? ctx.index.AccessorName : "Index")} has an Index.BTree attribute, but no columns.", + ctx => ctx.attr ); public static readonly ErrorDescriptor InvalidTableVisibility = @@ -47,7 +51,7 @@ internal static class ErrorDescriptor group, "Table row visibility must be public or internal, including container types.", table => $"Table {table.Identifier} and its parent types must be public or internal.", - table => table.BaseList! + table => table.Identifier ); public static readonly ErrorDescriptor TableTaggedEnum = diff --git a/crates/bindings-csharp/Codegen/Module.cs b/crates/bindings-csharp/Codegen/Module.cs index 018094c7d0c..df982a66220 100644 --- a/crates/bindings-csharp/Codegen/Module.cs +++ b/crates/bindings-csharp/Codegen/Module.cs @@ -220,25 +220,27 @@ public ViewIndex(ColumnDeclaration col) ViewIndexType.BTree // this might become hash in the future ) { } - private ViewIndex(IndexAttribute attr, TypeDeclarationSyntax decl, DiagReporter diag) + private ViewIndex(IndexAttribute attr) : this( - attr.Name, + attr.Name == "" ? null : 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 ?? [], + attr.BTree, ViewIndexType.BTree ) { Table = attr.Table; + } + + public ViewIndex(AttributeData data, DiagReporter diag) + : this(data.ParseAs()) + { if (Columns.Length == 0) { - diag.Report(ErrorDescriptor.EmptyIndexColumns, decl); + diag.Report(ErrorDescriptor.EmptyIndexColumns, (this, data)); } } - public ViewIndex(AttributeData data, TypeDeclarationSyntax decl, DiagReporter diag) - : this(data.ParseAs(), decl, diag) { } - public string GenerateIndexDef(IEnumerable allColumns) { var colIndices = Columns.Select(c => allColumns.Select(cd => cd.Name).IndexOf(c)); @@ -246,7 +248,7 @@ public string GenerateIndexDef(IEnumerable allColumns) return $$""" new( Name: null, - AccessorName: {{(AccessorName is not null ? $"\"{AccessorName}\"" : "null")}}, + AccessorName: "{{AccessorName}}", Algorithm: new SpacetimeDB.Internal.RawIndexAlgorithm.{{Type}}([{{string.Join( ", ", colIndices @@ -306,7 +308,7 @@ public TableDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter di context .TargetSymbol.GetAttributes() .Where(a => a.AttributeClass?.ToString() == typeof(IndexAttribute).FullName) - .Select(a => new ViewIndex(a, typeSyntax, diag)) + .Select(a => new ViewIndex(a, diag)) .ToImmutableArray() ); } @@ -322,6 +324,12 @@ public IEnumerable GenerateViewFilters(TableView view) foreach (var ct in GetConstraints(view, ColumnAttrs.Unique)) { var f = ct.col; + if (!f.IsEquatable) + { + // Skip - we already emitted diagnostic for this during parsing, and generated code would + // only produce a lot of noisy typechecking errors. + continue; + } var standardIndexName = new ViewIndex(ct.col).StandardIndexName(view); yield return $$""" {{vis}} sealed class {{view.Name}}UniqueIndex : UniqueIndex<{{view.Name}}, {{globalName}}, {{f.Type}}, {{f.TypeInfo}}> { @@ -338,10 +346,17 @@ public IEnumerable GenerateViewFilters(TableView view) foreach (var index in GetIndexes(view)) { - var members = index.Columns.Select(s => Members.First(x => x.Name == s)).ToArray(); + var name = index.AccessorName; + // Skip bad declarations. Empty name means no columns, which we have already reported with a meaningful error. + // Emitting this will result in further compilation errors due to missing property name. + if (name == "") + { + continue; + } + + var members = index.Columns.Select(s => Members.First(x => x.Name == s)).ToArray(); var standardIndexName = index.StandardIndexName(view); - var name = index.AccessorName ?? standardIndexName; yield return $$""" {{vis}} sealed class {{name}}Index() : SpacetimeDB.Internal.IndexBase<{{globalName}}>("{{standardIndexName}}") { @@ -394,6 +409,12 @@ public record struct View(string viewName, string tableName, string view, string public IEnumerable GenerateViews() { + // Don't try to generate views if this table is a sum type. + // We already emitted a diagnostic, and attempting to generate views will only result in more noisy errors. + if (Kind is TypeKind.Sum) + { + yield break; + } foreach (var v in Views) { var autoIncFields = Members @@ -502,6 +523,7 @@ record ReducerDeclaration public readonly string FullName; public readonly EquatableArray Args; public readonly Scope Scope; + private readonly bool HasWrongSignature; public ReducerDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter diag) { @@ -520,6 +542,7 @@ public ReducerDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter ) { diag.Report(ErrorDescriptor.ReducerContextParam, methodSyntax); + HasWrongSignature = true; } Name = method.Name; @@ -545,10 +568,13 @@ public ReducerDeclaration(GeneratorAttributeSyntaxContext context, DiagReporter public string GenerateClass() { - var args = string.Join( - ", ", - Args.Select(a => $"{a.Name}.Read(reader)").Prepend("(SpacetimeDB.ReducerContext)ctx") - ); + var invocation = HasWrongSignature + ? "throw new System.InvalidOperationException()" + : $"{FullName}({string.Join( + ", ", + Args.Select(a => $"{a.Name}.Read(reader)").Prepend("(SpacetimeDB.ReducerContext)ctx") + )})"; + return $$""" class {{Name}}: SpacetimeDB.Internal.IReducer { {{MemberDeclaration.GenerateBsatnFields(Accessibility.Private, Args)}} @@ -565,7 +591,7 @@ class {{Name}}: SpacetimeDB.Internal.IReducer { ); public void Invoke(BinaryReader reader, SpacetimeDB.Internal.IReducerContext ctx) { - {{FullName}}({{args}}); + {{invocation}}; } } """; diff --git a/crates/bindings-csharp/Runtime/Attrs.cs b/crates/bindings-csharp/Runtime/Attrs.cs index a3390fb3436..ffa6ea94ffa 100644 --- a/crates/bindings-csharp/Runtime/Attrs.cs +++ b/crates/bindings-csharp/Runtime/Attrs.cs @@ -68,7 +68,7 @@ public sealed class IndexAttribute : Attribute public string? Name { get; init; } - public required string[] BTree { get; init; } + public string[] BTree { get; init; } = []; } public sealed class AutoIncAttribute : Internal.ColumnAttribute