From 9b82ce12fe576df8423aa70db2270135eac353f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6llner?= Date: Sun, 1 Mar 2020 13:18:55 +0100 Subject: [PATCH] made nullable behavior more consistent added serialization tests bug fixes --- .../Capnp.Net.Runtime.Tests.Core21.csproj | 1 + Capnp.Net.Runtime.Tests/SerializationTests.cs | 170 +++++++- Capnp.Net.Runtime/CapnpSerializable.cs | 5 +- Capnp.Net.Runtime/DeserializerState.cs | 82 ++-- Capnp.Net.Runtime/DynamicSerializerState.cs | 23 +- Capnp.Net.Runtime/EmptyListDeserializer.cs | 2 +- Capnp.Net.Runtime/ListDeserializer.cs | 6 +- .../ListOfPrimitivesDeserializer.cs | 2 - .../ListOfPrimitivesSerializer.cs | 20 +- Capnp.Net.Runtime/ListOfTextSerializer.cs | 8 +- Capnp.Net.Runtime/Rpc/TcpRpcClient.cs | 6 +- Capnp.Net.Runtime/SerializerState.cs | 56 +-- .../Embedded Resources/test.cs | 366 +++++++++--------- .../CodeGen/DomainClassSnippetGen.cs | 18 +- CapnpC.CSharp.Generator/CodeGen/GenNames.cs | 23 +- 15 files changed, 459 insertions(+), 329 deletions(-) diff --git a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj index 5eac70b..b72dab4 100644 --- a/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj +++ b/Capnp.Net.Runtime.Tests.Core21/Capnp.Net.Runtime.Tests.Core21.csproj @@ -8,6 +8,7 @@ Debug;Release + diff --git a/Capnp.Net.Runtime.Tests/SerializationTests.cs b/Capnp.Net.Runtime.Tests/SerializationTests.cs index 3ea4f63..75b1aa2 100644 --- a/Capnp.Net.Runtime.Tests/SerializationTests.cs +++ b/Capnp.Net.Runtime.Tests/SerializationTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static Capnproto_test.Capnp.Test.TestStructUnion; namespace Capnp.Net.Runtime.Tests { @@ -53,7 +54,7 @@ namespace Capnp.Net.Runtime.Tests Assert.IsTrue(list[129]); var list2 = b.CreateObject(); list2.Init(null); - list2.Init(list); + list2.Init(list.ToArray()); Assert.IsFalse(list2[0]); Assert.IsTrue(list2[63]); Assert.IsFalse(list2[64]); @@ -101,7 +102,7 @@ namespace Capnp.Net.Runtime.Tests var list2 = b.CreateObject>(); list2.Init(null); - list2.Init(list); + list2.Init(list.ToArray()); proxies = list2.Cast().ToArray(); Assert.IsTrue(proxies[0].IsNull); Assert.IsFalse(proxies[1].IsNull); @@ -124,5 +125,170 @@ namespace Capnp.Net.Runtime.Tests list3[4].Foo(123u, true).Wait(); Assert.AreEqual(6, c2.CallCount); } + + [TestMethod] + public void ListOfEmpty() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + Assert.ThrowsException(() => list.Init(-1)); + list.Init(987654321); + Assert.AreEqual(987654321, list.Count); + Assert.ThrowsException(() => list.Init(42)); + DeserializerState d = list; + int list2 = d.RequireList().CastVoid(); + Assert.AreEqual(987654321, list2); + } + + [TestMethod] + public void ListOfPointers() + { + var b = MessageBuilder.Create(); + b.InitCapTable(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = null; }); + list.Init(7); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(7, list.Count); + var c1 = new Counters(); + var cap1 = new TestInterfaceImpl(c1); + var obj1 = b.CreateObject(); + obj1.SetObject(cap1); + var obj2 = b.CreateObject(); + obj2.SetStruct(1, 1); + var lobs = b.CreateObject(); + lobs.Init(1); + var obj3 = lobs.Rewrap(); + list[1] = obj1; + list[2] = obj2; + list[3] = obj3; + Assert.IsNotNull(list[0]); + Assert.AreEqual(ObjectKind.Nil, list[0].Kind); + Assert.AreEqual(obj1, list[1]); + Assert.AreEqual(obj2, list[2]); + Assert.AreEqual(obj3, list[3]); + var list2 = list.ToArray(); + Assert.IsNotNull(list2[0]); + Assert.AreEqual(ObjectKind.Nil, list2[0].Kind); + Assert.AreEqual(obj1, list2[1]); + Assert.AreEqual(obj2, list2[2]); + Assert.AreEqual(obj3, list2[3]); + + DeserializerState d = list; + var list3 = d.RequireList().Cast(_ => _); + Assert.AreEqual(7, list3.Count); + Assert.IsNotNull(list3[0]); + Assert.AreEqual(ObjectKind.Nil, list3[0].Kind); + Assert.AreEqual(ObjectKind.Capability, list3[1].Kind); + Assert.AreEqual(ObjectKind.Struct, list3[2].Kind); + Assert.AreEqual(ObjectKind.ListOfBits, list3[3].Kind); + } + + [TestMethod] + public void ListOfPrimitives() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = 1.0f; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + list[0] = 0.0f; + list[1] = 1.0f; + list[2] = 2.0f; + list[3] = 3.0f; + Assert.AreEqual(0.0f, list[0]); + Assert.AreEqual(1.0f, list[1]); + Assert.AreEqual(2.0f, list[2]); + Assert.AreEqual(3.0f, list[3]); + + var list2 = b.CreateObject>(); + list2.Init(null); + list2.Init(list.ToArray()); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual(0.0f, list2[0]); + Assert.AreEqual(1.0f, list2[1]); + Assert.AreEqual(2.0f, list2[2]); + Assert.AreEqual(3.0f, list2[3]); + + DeserializerState d = list2; + var list3 = d.RequireList().CastFloat(); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual(0.0f, list3[0]); + Assert.AreEqual(1.0f, list3[1]); + Assert.AreEqual(2.0f, list3[2]); + Assert.AreEqual(3.0f, list3[3]); + } + + [TestMethod] + public void ListOfStructs() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject>(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + list[0].SomeText = "0"; + list[1].SomeText = "1"; + list[2].SomeText = "2"; + list[3].SomeText = "3"; + Assert.AreEqual("0", list[0].SomeText); + Assert.AreEqual("3", list[3].SomeText); + + var list2 = b.CreateObject>(); + list2.Init(list.ToArray(), (dst, src) => { dst.SomeText = src.SomeText; dst.MoreText = src.MoreText; }); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual("0", list2[0].SomeText); + Assert.AreEqual("3", list2[3].SomeText); + + DeserializerState d = list2; + var list3 = d.RequireList().Cast(_ => new SomeStruct.READER(_)); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual("0", list3[0].SomeText); + Assert.AreEqual("3", list3[3].SomeText); + } + + [TestMethod] + public void ListOfText() + { + var b = MessageBuilder.Create(); + var list = b.CreateObject(); + Assert.ThrowsException(() => list.Init(-1)); + Assert.ThrowsException(() => { var _ = list[0]; }); + Assert.ThrowsException(() => { list[0] = "foo"; }); + list.Init(4); + Assert.ThrowsException(() => list.Init(1)); + Assert.AreEqual(4, list.Count); + list[0] = "0"; + list[2] = null; + list[3] = "3"; + Assert.AreEqual("0", list[0]); + Assert.IsNull(list[1]); + Assert.IsNull(list[2]); + Assert.AreEqual("3", list[3]); + + var list2 = b.CreateObject(); + list2.Init(list.ToArray()); + Assert.AreEqual(4, list2.Count); + Assert.AreEqual("0", list2[0]); + Assert.IsNull(list2[1]); + Assert.IsNull(list2[2]); + Assert.AreEqual("3", list2[3]); + + DeserializerState d = list2; + var tmp = d.RequireList(); + var list3 = tmp.CastText2(); + Assert.AreEqual(4, list3.Count); + Assert.AreEqual("0", list3[0]); + Assert.IsNull(list3[1]); + Assert.IsNull(list3[2]); + Assert.AreEqual("3", list3[3]); + } } } diff --git a/Capnp.Net.Runtime/CapnpSerializable.cs b/Capnp.Net.Runtime/CapnpSerializable.cs index 81b86b6..631f869 100644 --- a/Capnp.Net.Runtime/CapnpSerializable.cs +++ b/Capnp.Net.Runtime/CapnpSerializable.cs @@ -163,9 +163,8 @@ namespace Capnp /// /// /// deserializer state to construct from - /// The domain object instance. Nullability note: The returned reference will be null if (and only if) is a capability interface and - /// represents the nil object (obtained from a null pointer). For all other types, when the state is nil, - /// the method still constructs a valid but "empty" object instance (such as domain object without any properties set, empty string, empty list etc.) + /// The domain object instance. Nullability note: The returned reference may be null if + /// represents the nil object. public static T? Create(DeserializerState state) where T: class { diff --git a/Capnp.Net.Runtime/DeserializerState.cs b/Capnp.Net.Runtime/DeserializerState.cs index 8dd7ce8..026b29e 100644 --- a/Capnp.Net.Runtime/DeserializerState.cs +++ b/Capnp.Net.Runtime/DeserializerState.cs @@ -158,7 +158,6 @@ namespace Capnp /// Memory span which represents this struct's data section (given this state actually represents a struct) /// public ReadOnlySpan StructDataSection => CurrentSegment.Slice(Offset, StructDataCount); - ReadOnlySpan StructPtrSection => CurrentSegment.Slice(Offset + StructDataCount, StructPtrCount); ReadOnlySpan GetRawBits() => CurrentSegment.Slice(Offset, (ListElementCount + 63) / 64); ReadOnlySpan GetRawBytes() => CurrentSegment.Slice(Offset, (ListElementCount + 7) / 8); @@ -172,26 +171,15 @@ namespace Capnp { get { - switch (Kind) + return Kind switch { - case ObjectKind.ListOfBits: - return GetRawBits(); - - case ObjectKind.ListOfBytes: - return GetRawBytes(); - - case ObjectKind.ListOfShorts: - return GetRawShorts(); - - case ObjectKind.ListOfInts: - return GetRawInts(); - - case ObjectKind.ListOfLongs: - return GetRawLongs(); - - default: - return default; - } + ObjectKind.ListOfBits => GetRawBits(), + ObjectKind.ListOfBytes => GetRawBytes(), + ObjectKind.ListOfShorts => GetRawShorts(), + ObjectKind.ListOfInts => GetRawInts(), + ObjectKind.ListOfLongs => GetRawLongs(), + _ => default, + }; } } @@ -513,38 +501,19 @@ namespace Capnp /// state does not represent a list public ListDeserializer RequireList() { - switch (Kind) + return Kind switch { - case ObjectKind.ListOfBits: - return new ListOfBitsDeserializer(ref this, false); - - case ObjectKind.ListOfBytes: - return new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfBytes); - - case ObjectKind.ListOfEmpty: - return new ListOfEmptyDeserializer(ref this); - - case ObjectKind.ListOfInts: - return new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfInts); - - case ObjectKind.ListOfLongs: - return new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfLongs); - - case ObjectKind.ListOfPointers: - return new ListOfPointersDeserializer(ref this); - - case ObjectKind.ListOfShorts: - return new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfShorts); - - case ObjectKind.ListOfStructs: - return new ListOfStructsDeserializer(ref this); - - case ObjectKind.Nil: - return new EmptyListDeserializer(); - - default: - throw new DeserializationException("Cannot deserialize this object as list"); - } + ObjectKind.ListOfBits => new ListOfBitsDeserializer(ref this, false), + ObjectKind.ListOfBytes => new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfBytes), + ObjectKind.ListOfEmpty => new ListOfEmptyDeserializer(ref this), + ObjectKind.ListOfInts => new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfInts), + ObjectKind.ListOfLongs => new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfLongs), + ObjectKind.ListOfPointers => new ListOfPointersDeserializer(ref this), + ObjectKind.ListOfShorts => new ListOfPrimitivesDeserializer(ref this, ListKind.ListOfShorts), + ObjectKind.ListOfStructs => new ListOfStructsDeserializer(ref this), + ObjectKind.Nil => new EmptyListDeserializer(), + _ => throw new DeserializationException("Cannot deserialize this object as list"), + }; } /// @@ -554,14 +523,11 @@ namespace Capnp /// state does not represent a list of pointers public ListOfCapsDeserializer RequireCapList() where T: class { - switch (Kind) + return Kind switch { - case ObjectKind.ListOfPointers: - return new ListOfCapsDeserializer(ref this); - - default: - throw new DeserializationException("Cannot deserialize this object as capability list"); - } + ObjectKind.ListOfPointers => new ListOfCapsDeserializer(ref this), + _ => throw new DeserializationException("Cannot deserialize this object as capability list"), + }; } /// diff --git a/Capnp.Net.Runtime/DynamicSerializerState.cs b/Capnp.Net.Runtime/DynamicSerializerState.cs index 679a59f..77e615d 100644 --- a/Capnp.Net.Runtime/DynamicSerializerState.cs +++ b/Capnp.Net.Runtime/DynamicSerializerState.cs @@ -121,27 +121,16 @@ namespace Capnp /// Object representation. Must be one of the following: /// /// An instance implementing - /// null - /// A - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// A ]]> - /// Another - /// Another + /// null, + /// IReadOnlyList<byte>, IReadOnlyList<sbyte>, IReadOnlyList<ushort>, IReadOnlyList<short> + /// IReadOnlyList<int>, IReadOnlyList<uint>, IReadOnlyList<long>, IReadOnlyList<ulong> + /// IReadOnlyList<float>, IReadOnlyList<double>, IReadOnlyList<bool>, IReadOnlyList<string> + /// Another or /// Low-level capability object () /// Proxy object () /// Skeleton object () /// Capability interface implementation - /// A ]]> whereby each list item is one of the things listed here. + /// IReadOnlyList<object>, whereby each list item is one of the things listed here. /// /// public void SetObject(object? obj) diff --git a/Capnp.Net.Runtime/EmptyListDeserializer.cs b/Capnp.Net.Runtime/EmptyListDeserializer.cs index 76ee7d1..255f233 100644 --- a/Capnp.Net.Runtime/EmptyListDeserializer.cs +++ b/Capnp.Net.Runtime/EmptyListDeserializer.cs @@ -68,7 +68,7 @@ namespace Capnp /// /// Returns an empty string. /// - public override string CastText() => string.Empty; + public override string? CastText() => null; /// /// Returns an empty ]]>. diff --git a/Capnp.Net.Runtime/ListDeserializer.cs b/Capnp.Net.Runtime/ListDeserializer.cs index 67d65c4..6d28ab9 100644 --- a/Capnp.Net.Runtime/ListDeserializer.cs +++ b/Capnp.Net.Runtime/ListDeserializer.cs @@ -26,7 +26,7 @@ namespace Capnp GenericCasts>.CastFunc = _ => _.CastULong(); GenericCasts>.CastFunc = _ => _.CastFloat(); GenericCasts>.CastFunc = _ => _.CastDouble(); - GenericCasts.CastFunc = _ => _.CastText(); + GenericCasts.CastFunc = _ => _.CastText()!; // it *may* return null, but how to express this syntactically correct? } /// @@ -269,7 +269,7 @@ namespace Capnp /// /// The desired representation /// If this list cannot be represented in the desired manner. - public IReadOnlyList CastText2() => CastList().LazyListSelect(ld => ld.CastText()); + public IReadOnlyList CastText2() => CastList().LazyListSelect(ld => ld.CastText()); /// /// Represents this list as Text. For representing it as List(Text), use . @@ -285,7 +285,7 @@ namespace Capnp /// /// The decoded text /// If this list cannot be represented in the desired manner. - public virtual string CastText() + public virtual string? CastText() { throw new NotSupportedException("This kind of list does not represent text"); } diff --git a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs index 1cb357a..aa47218 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesDeserializer.cs @@ -77,8 +77,6 @@ namespace Capnp base(ref state) { _kind = kind; - - var binCoder = PrimitiveCoder.Get(); } /// diff --git a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs index b70a3a9..7f53839 100644 --- a/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs +++ b/Capnp.Net.Runtime/ListOfPrimitivesSerializer.cs @@ -37,8 +37,16 @@ namespace Capnp /// Element value public T this[int index] { - get => Data[index]; - set => Data[index] = value; + get + { + ListSerializerHelper.EnsureAllocated(this); + return Data[index]; + } + set + { + ListSerializerHelper.EnsureAllocated(this); + Data[index] = value; + } } /// @@ -84,11 +92,17 @@ namespace Capnp } } + IEnumerable Enumerate() + { + for (int i = 0; i < Data.Length; i++) + yield return Data[i]; + } + /// /// Implements . /// /// - public IEnumerator GetEnumerator() => (IEnumerator)Data.ToArray().GetEnumerator(); + public IEnumerator GetEnumerator() => Enumerate().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => Data.ToArray().GetEnumerator(); } diff --git a/Capnp.Net.Runtime/ListOfTextSerializer.cs b/Capnp.Net.Runtime/ListOfTextSerializer.cs index 5bd63e7..c1dabbf 100644 --- a/Capnp.Net.Runtime/ListOfTextSerializer.cs +++ b/Capnp.Net.Runtime/ListOfTextSerializer.cs @@ -22,8 +22,7 @@ namespace Capnp { get { - if (!IsAllocated) - throw new InvalidOperationException("Not initialized"); + ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -32,8 +31,7 @@ namespace Capnp } set { - if (!IsAllocated) - throw new InvalidOperationException("Not initialized"); + ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); @@ -53,7 +51,7 @@ namespace Capnp for (int i = 0; i < count; i++) { - yield return TryGetPointer(i)?.ListReadAsText(); + yield return this[i]; } } diff --git a/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs b/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs index 02a975d..6b872fd 100644 --- a/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs +++ b/Capnp.Net.Runtime/Rpc/TcpRpcClient.cs @@ -19,12 +19,10 @@ namespace Capnp.Rpc class OutboundTcpEndpoint : IEndpoint { - readonly TcpRpcClient _client; readonly FramePump _pump; - public OutboundTcpEndpoint(TcpRpcClient client, FramePump pump) + public OutboundTcpEndpoint(FramePump pump) { - _client = client; _pump = pump; } @@ -84,7 +82,7 @@ namespace Capnp.Rpc var stream = _createLayers(_client.GetStream()); _pump = new FramePump(stream); _attachTracerAction?.Invoke(); - _outboundEndpoint = new OutboundTcpEndpoint(this, _pump); + _outboundEndpoint = new OutboundTcpEndpoint(_pump); _inboundEndpoint = _rpcEngine.AddEndpoint(_outboundEndpoint); _pumpThread = new Thread(() => { diff --git a/Capnp.Net.Runtime/SerializerState.cs b/Capnp.Net.Runtime/SerializerState.cs index 4490ada..9824afc 100644 --- a/Capnp.Net.Runtime/SerializerState.cs +++ b/Capnp.Net.Runtime/SerializerState.cs @@ -39,7 +39,6 @@ namespace Capnp internal int ListElementCount { get; set; } internal ushort StructDataCount { get; set; } internal ushort StructPtrCount { get; set; } - internal ObjectKind Kind { get; set; } internal uint CapabilityIndex { get; set; } SerializerState[]? _linkedStates; @@ -93,7 +92,7 @@ namespace Capnp if (Kind != ObjectKind.Nil) { - InvalidOperationException InvalidWrap() => + static InvalidOperationException InvalidWrap() => new InvalidOperationException("Incompatible cast"); switch (ts.Kind) @@ -165,6 +164,11 @@ namespace Capnp /// public Span RawData => SegmentSpan.Slice(Offset, (int)WordsAllocated); + /// + /// The kind of object this state currently represents. + /// + public ObjectKind Kind { get; internal set; } + void AllocateWords(uint count) { if (count == 0) @@ -286,7 +290,7 @@ namespace Capnp Allocate(); } - WirePointer targetPtr = default(WirePointer); + WirePointer targetPtr = default; switch (target.Kind) { @@ -539,38 +543,16 @@ namespace Capnp /// negative or exceeding 2^29-1 protected void SetListOfValues(byte bitsPerElement, int totalCount) { - ObjectKind kind; - - switch (bitsPerElement) + var kind = bitsPerElement switch { - case 0: - kind = ObjectKind.ListOfEmpty; - break; - - case 1: - kind = ObjectKind.ListOfBits; - break; - - case 8: - kind = ObjectKind.ListOfBytes; - break; - - case 16: - kind = ObjectKind.ListOfShorts; - break; - - case 32: - kind = ObjectKind.ListOfInts; - break; - - case 64: - kind = ObjectKind.ListOfLongs; - break; - - default: - throw new ArgumentOutOfRangeException(nameof(bitsPerElement)); - } - + 0 => ObjectKind.ListOfEmpty, + 1 => ObjectKind.ListOfBits, + 8 => ObjectKind.ListOfBytes, + 16 => ObjectKind.ListOfShorts, + 32 => ObjectKind.ListOfInts, + 64 => ObjectKind.ListOfLongs, + _ => throw new ArgumentOutOfRangeException(nameof(bitsPerElement)), + }; if (Kind == ObjectKind.Nil) { if (totalCount < 0) @@ -702,8 +684,6 @@ namespace Capnp if (relBitOffset + bitCount > 64) throw new ArgumentOutOfRangeException(nameof(bitCount)); - ulong word = data[index]; - if (bitCount == 64) { data[index] = value; @@ -875,14 +855,14 @@ namespace Capnp /// If the underlying object is a struct: index into the struct's pointer section. /// If the underlying object is a list of pointers: Element index /// Text to encode - /// Default text of > is null + /// Default text if > is null /// Both and are null /// /// The underlying object was not determined to be a struct or list of pointers. /// Object at given position was already set. /// /// is out of bounds. - public void WriteText(int index, string? text, string defaultText) + public void WriteText(int index, string? text, string? defaultText) { BuildPointer(index).WriteText(text ?? defaultText); } diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs index 3a90610..e96c18b 100644 --- a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs +++ b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs @@ -321,7 +321,7 @@ namespace Capnproto_test.Capnp.Test public ulong UInt64Field => ctx.ReadDataULong(192UL, 0UL); public float Float32Field => ctx.ReadDataFloat(256UL, 0F); public double Float64Field => ctx.ReadDataDouble(320UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); public IReadOnlyList DataField => ctx.ReadList(1).CastByte(); public Capnproto_test.Capnp.Test.TestAllTypes.READER StructField => ctx.ReadStruct(2, Capnproto_test.Capnp.Test.TestAllTypes.READER.create); public Capnproto_test.Capnp.Test.TestEnum EnumField => (Capnproto_test.Capnp.Test.TestEnum)ctx.ReadDataUShort(288UL, (ushort)0); @@ -419,8 +419,8 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfPrimitivesSerializer DataField @@ -1373,15 +1373,15 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Qux => ctx.ReadText(0, ""); - public string Grault => ctx.ReadText(1, ""); - public string Bar => ctx.ReadText(2, ""); - public string Foo => ctx.ReadText(3, ""); - public string Corge => ctx.ReadText(4, ""); - public string Waldo => ctx.ReadText(5, ""); - public string Quux => ctx.ReadText(6, ""); - public string Garply => ctx.ReadText(7, ""); - public string Baz => ctx.ReadText(8, ""); + public string Qux => ctx.ReadText(0, null); + public string Grault => ctx.ReadText(1, null); + public string Bar => ctx.ReadText(2, null); + public string Foo => ctx.ReadText(3, null); + public string Corge => ctx.ReadText(4, null); + public string Waldo => ctx.ReadText(5, null); + public string Quux => ctx.ReadText(6, null); + public string Garply => ctx.ReadText(7, null); + public string Baz => ctx.ReadText(8, null); } public class WRITER : SerializerState @@ -1393,56 +1393,56 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Grault { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Bar { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Foo { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Corge { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } public string Waldo { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } public string Quux { - get => this.ReadText(6, ""); - set => this.WriteText(6, value, ""); + get => this.ReadText(6, null); + set => this.WriteText(6, value, null); } public string Garply { - get => this.ReadText(7, ""); - set => this.WriteText(7, value, ""); + get => this.ReadText(7, null); + set => this.WriteText(7, value, null); } public string Baz { - get => this.ReadText(8, ""); - set => this.WriteText(8, value, ""); + get => this.ReadText(8, null); + set => this.WriteText(8, value, null); } } } @@ -1992,13 +1992,13 @@ namespace Capnproto_test.Capnp.Test public short U0f0s16 => which == WHICH.U0f0s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f0s32 => which == WHICH.U0f0s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f0s64 => which == WHICH.U0f0s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, "") : default; + public string U0f0sp => which == WHICH.U0f0sp ? ctx.ReadText(0, null) : default; public bool U0f1s1 => which == WHICH.U0f1s1 ? ctx.ReadDataBool(64UL, false) : default; public sbyte U0f1s8 => which == WHICH.U0f1s8 ? ctx.ReadDataSByte(64UL, (sbyte)0) : default; public short U0f1s16 => which == WHICH.U0f1s16 ? ctx.ReadDataShort(64UL, (short)0) : default; public int U0f1s32 => which == WHICH.U0f1s32 ? ctx.ReadDataInt(64UL, 0) : default; public long U0f1s64 => which == WHICH.U0f1s64 ? ctx.ReadDataLong(64UL, 0L) : default; - public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, "") : default; + public string U0f1sp => which == WHICH.U0f1sp ? ctx.ReadText(0, null) : default; } public class WRITER : SerializerState @@ -2045,8 +2045,8 @@ namespace Capnproto_test.Capnp.Test public string U0f0sp { - get => which == WHICH.U0f0sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f0sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } public bool U0f1s1 @@ -2081,8 +2081,8 @@ namespace Capnproto_test.Capnp.Test public string U0f1sp { - get => which == WHICH.U0f1sp ? this.ReadText(0, "") : default; - set => this.WriteText(0, value, ""); + get => which == WHICH.U0f1sp ? this.ReadText(0, null) : default; + set => this.WriteText(0, value, null); } } } @@ -2537,14 +2537,14 @@ namespace Capnproto_test.Capnp.Test public int U1f1s32 => which == WHICH.U1f1s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f0s64 => which == WHICH.U1f0s64 ? ctx.ReadDataLong(192UL, 0L) : default; public long U1f1s64 => which == WHICH.U1f1s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, "") : default; - public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, "") : default; + public string U1f0sp => which == WHICH.U1f0sp ? ctx.ReadText(1, null) : default; + public string U1f1sp => which == WHICH.U1f1sp ? ctx.ReadText(1, null) : default; public bool U1f2s1 => which == WHICH.U1f2s1 ? ctx.ReadDataBool(129UL, false) : default; public sbyte U1f2s8 => which == WHICH.U1f2s8 ? ctx.ReadDataSByte(136UL, (sbyte)0) : default; public short U1f2s16 => which == WHICH.U1f2s16 ? ctx.ReadDataShort(144UL, (short)0) : default; public int U1f2s32 => which == WHICH.U1f2s32 ? ctx.ReadDataInt(160UL, 0) : default; public long U1f2s64 => which == WHICH.U1f2s64 ? ctx.ReadDataLong(192UL, 0L) : default; - public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, "") : default; + public string U1f2sp => which == WHICH.U1f2sp ? ctx.ReadText(1, null) : default; } public class WRITER : SerializerState @@ -2621,14 +2621,14 @@ namespace Capnproto_test.Capnp.Test public string U1f0sp { - get => which == WHICH.U1f0sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f0sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public string U1f1sp { - get => which == WHICH.U1f1sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f1sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public bool U1f2s1 @@ -2663,8 +2663,8 @@ namespace Capnproto_test.Capnp.Test public string U1f2sp { - get => which == WHICH.U1f2sp ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.U1f2sp ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } } } @@ -3229,11 +3229,11 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(32U, (ushort)0); - public string Before => ctx.ReadText(0, ""); + public string Before => ctx.ReadText(0, null); public ushort Foo => which == WHICH.Foo ? ctx.ReadDataUShort(0UL, (ushort)0) : default; public ushort Middle => ctx.ReadDataUShort(16UL, (ushort)0); public uint Bar => which == WHICH.Bar ? ctx.ReadDataUInt(64UL, 0U) : default; - public string After => ctx.ReadText(1, ""); + public string After => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -3251,8 +3251,8 @@ namespace Capnproto_test.Capnp.Test public string Before { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ushort Foo @@ -3275,8 +3275,8 @@ namespace Capnproto_test.Capnp.Test public string After { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } @@ -3882,7 +3882,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); public long Grault => ctx.ReadDataLong(64UL, 0L); - public string Garply => ctx.ReadText(0, ""); + public string Garply => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -3905,8 +3905,8 @@ namespace Capnproto_test.Capnp.Test public string Garply { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -3970,8 +3970,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); - public string Garply => ctx.ReadText(1, ""); + public string Grault => ctx.ReadText(0, null); + public string Garply => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -3988,14 +3988,14 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Garply { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } @@ -4059,7 +4059,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Corge => ctx.ReadDataInt(0UL, 0); - public string Grault => ctx.ReadText(0, ""); + public string Grault => ctx.ReadText(0, null); public long Garply => ctx.ReadDataLong(64UL, 0L); } @@ -4077,8 +4077,8 @@ namespace Capnproto_test.Capnp.Test public string Grault { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public long Garply @@ -4316,8 +4316,8 @@ namespace Capnproto_test.Capnp.Test public ulong Bar => ctx.ReadDataULong(64UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(192UL, (ushort)0) : default; public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(0, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(2, "") : default; + public string Waldo => ctx.ReadText(0, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(2, null) : default; } public class WRITER : SerializerState @@ -4357,14 +4357,14 @@ namespace Capnproto_test.Capnp.Test public string Waldo { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Fred ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } } @@ -4436,8 +4436,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(256UL, 0UL); public ushort Garply => ctx.ReadDataUShort(192UL, (ushort)0); - public string Plugh => ctx.ReadText(2, ""); - public string Xyzzy => ctx.ReadText(4, ""); + public string Plugh => ctx.ReadText(2, null); + public string Xyzzy => ctx.ReadText(4, null); } public class WRITER : SerializerState @@ -4460,14 +4460,14 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(2, ""); - set => this.WriteText(2, value, ""); + get => this.ReadText(2, null); + set => this.WriteText(2, value, null); } public string Xyzzy { - get => this.ReadText(4, ""); - set => this.WriteText(4, value, ""); + get => this.ReadText(4, null); + set => this.WriteText(4, value, null); } } } @@ -4626,8 +4626,8 @@ namespace Capnproto_test.Capnp.Test public ulong Bar => ctx.ReadDataULong(128UL, 0UL); public ushort Qux => which == WHICH.Qux ? ctx.ReadDataUShort(208UL, (ushort)0) : default; public corge.READER Corge => which == WHICH.Corge ? new corge.READER(ctx) : default; - public string Waldo => ctx.ReadText(1, ""); - public string Fred => which == WHICH.Fred ? ctx.ReadText(3, "") : default; + public string Waldo => ctx.ReadText(1, null); + public string Fred => which == WHICH.Fred ? ctx.ReadText(3, null) : default; } public class WRITER : SerializerState @@ -4667,14 +4667,14 @@ namespace Capnproto_test.Capnp.Test public string Waldo { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } public string Fred { - get => which == WHICH.Fred ? this.ReadText(3, "") : default; - set => this.WriteText(3, value, ""); + get => which == WHICH.Fred ? this.ReadText(3, null) : default; + set => this.WriteText(3, value, null); } } @@ -4746,8 +4746,8 @@ namespace Capnproto_test.Capnp.Test public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong Grault => ctx.ReadDataULong(320UL, 0UL); public ushort Garply => ctx.ReadDataUShort(208UL, (ushort)0); - public string Plugh => ctx.ReadText(3, ""); - public string Xyzzy => ctx.ReadText(5, ""); + public string Plugh => ctx.ReadText(3, null); + public string Xyzzy => ctx.ReadText(5, null); } public class WRITER : SerializerState @@ -4770,14 +4770,14 @@ namespace Capnproto_test.Capnp.Test public string Plugh { - get => this.ReadText(3, ""); - set => this.WriteText(3, value, ""); + get => this.ReadText(3, null); + set => this.WriteText(3, value, null); } public string Xyzzy { - get => this.ReadText(5, ""); - set => this.WriteText(5, value, ""); + get => this.ReadText(5, null); + set => this.WriteText(5, value, null); } } } @@ -5747,7 +5747,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5759,8 +5759,8 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -5807,7 +5807,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5819,8 +5819,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -5876,7 +5876,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public bool F => ctx.ReadDataBool(0UL, false); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5894,8 +5894,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -5951,7 +5951,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public byte F => ctx.ReadDataByte(0UL, (byte)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -5969,8 +5969,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -6026,7 +6026,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ushort F => ctx.ReadDataUShort(0UL, (ushort)0); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6044,8 +6044,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -6101,7 +6101,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint F => ctx.ReadDataUInt(0UL, 0U); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6119,8 +6119,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -6176,7 +6176,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public ulong F => ctx.ReadDataULong(0UL, 0UL); - public string Pad => ctx.ReadText(0, ""); + public string Pad => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -6194,8 +6194,8 @@ namespace Capnproto_test.Capnp.Test public string Pad { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -6250,7 +6250,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string F => ctx.ReadText(0, ""); + public string F => ctx.ReadText(0, null); public ulong Pad => ctx.ReadDataULong(0UL, 0UL); } @@ -6263,8 +6263,8 @@ namespace Capnproto_test.Capnp.Test public string F { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ulong Pad @@ -6527,7 +6527,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Foo => ctx.ReadDataInt(0UL, 0); - public string Bar => ctx.ReadText(0, ""); + public string Bar => ctx.ReadText(0, null); public short Baz => ctx.ReadDataShort(32UL, (short)0); public theUnion.READER TheUnion => new theUnion.READER(ctx); public anotherUnion.READER AnotherUnion => new anotherUnion.READER(ctx); @@ -6548,8 +6548,8 @@ namespace Capnproto_test.Capnp.Test public string Bar { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public short Baz @@ -6693,7 +6693,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(48U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(1, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(1, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(1).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(64UL, 0F) : default; } @@ -6712,8 +6712,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(1, "") : default; - set => this.WriteText(1, value, ""); + get => which == WHICH.Qux ? this.ReadText(1, null) : default; + set => this.WriteText(1, value, null); } public ListOfPrimitivesSerializer Corge @@ -6854,7 +6854,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public WHICH which => (WHICH)ctx.ReadDataUShort(96U, (ushort)0); - public string Qux => which == WHICH.Qux ? ctx.ReadText(2, "") : default; + public string Qux => which == WHICH.Qux ? ctx.ReadText(2, null) : default; public IReadOnlyList Corge => which == WHICH.Corge ? ctx.ReadList(2).CastInt() : default; public float Grault => which == WHICH.Grault ? ctx.ReadDataFloat(128UL, 0F) : default; } @@ -6873,8 +6873,8 @@ namespace Capnproto_test.Capnp.Test public string Qux { - get => which == WHICH.Qux ? this.ReadText(2, "") : default; - set => this.WriteText(2, value, ""); + get => which == WHICH.Qux ? this.ReadText(2, null) : default; + set => this.WriteText(2, value, null); } public ListOfPrimitivesSerializer Corge @@ -6951,7 +6951,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestOldVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestOldVersion.READER.create); } @@ -6970,8 +6970,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestOldVersion.WRITER Old3 @@ -7059,7 +7059,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public long Old1 => ctx.ReadDataLong(0UL, 0L); - public string Old2 => ctx.ReadText(0, ""); + public string Old2 => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestNewVersion.READER Old3 => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestNewVersion.READER.create); public long New1 => ctx.ReadDataLong(64UL, 987L); public string New2 => ctx.ReadText(2, "baz"); @@ -7080,8 +7080,8 @@ namespace Capnproto_test.Capnp.Test public string Old2 { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestNewVersion.WRITER Old3 @@ -7711,8 +7711,8 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); - public string MoreText => ctx.ReadText(1, ""); + public string SomeText => ctx.ReadText(0, null); + public string MoreText => ctx.ReadText(1, null); } public class WRITER : SerializerState @@ -7724,14 +7724,14 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string MoreText { - get => this.ReadText(1, ""); - set => this.WriteText(1, value, ""); + get => this.ReadText(1, null); + set => this.WriteText(1, value, null); } } } @@ -7787,7 +7787,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string SomeText => ctx.ReadText(0, ""); + public string SomeText => ctx.ReadText(0, null); public IReadOnlyList StructList => ctx.ReadList(1).Cast(Capnproto_test.Capnp.Test.TestPrintInlineStructs.InlineStruct.READER.create); } @@ -7800,8 +7800,8 @@ namespace Capnproto_test.Capnp.Test public string SomeText { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public ListOfStructsSerializer StructList @@ -7862,7 +7862,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int Int32Field => ctx.ReadDataInt(0UL, 0); - public string TextField => ctx.ReadText(0, ""); + public string TextField => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -7880,8 +7880,8 @@ namespace Capnproto_test.Capnp.Test public string TextField { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -10214,7 +10214,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string X => ctx.ReadText(0, ""); + public string X => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -10226,8 +10226,8 @@ namespace Capnproto_test.Capnp.Test public string X { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -11147,7 +11147,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.Box.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.Box.READER.create); } @@ -11160,8 +11160,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.Box.WRITER OutBox @@ -11432,7 +11432,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER OutBox => ctx.ReadStruct(1, Capnproto_test.Capnp.Test.TestPipeline.AnyBox.READER.create); } @@ -11445,8 +11445,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.TestPipeline.AnyBox.WRITER OutBox @@ -11731,7 +11731,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public uint I => ctx.ReadDataUInt(0UL, 0U); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestCallOrder C => ctx.ReadCap(1); } @@ -11750,8 +11750,8 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestCallOrder C @@ -11813,7 +11813,7 @@ namespace Capnproto_test.Capnp.Test public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); public int I => ctx.ReadDataInt(0UL, 0); - public string T => ctx.ReadText(0, ""); + public string T => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -11831,8 +11831,8 @@ namespace Capnproto_test.Capnp.Test public string T { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -12448,7 +12448,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12460,8 +12460,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -12568,7 +12568,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12580,8 +12580,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -12898,7 +12898,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string S => ctx.ReadText(0, ""); + public string S => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -12910,8 +12910,8 @@ namespace Capnproto_test.Capnp.Test public string S { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -13306,7 +13306,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public uint B => ctx.ReadDataUInt(0UL, 123U); public string C => ctx.ReadText(1, "foo"); } @@ -13320,8 +13320,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public uint B @@ -13389,7 +13389,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string D => ctx.ReadText(0, ""); + public string D => ctx.ReadText(0, null); public string E => ctx.ReadText(1, "bar"); } @@ -13402,8 +13402,8 @@ namespace Capnproto_test.Capnp.Test public string D { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public string E @@ -13711,7 +13711,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Str => ctx.ReadText(0, ""); + public string Str => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -13723,8 +13723,8 @@ namespace Capnproto_test.Capnp.Test public string Str { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -13779,7 +13779,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string A => ctx.ReadText(0, ""); + public string A => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface B => ctx.ReadCap(1); } @@ -13792,8 +13792,8 @@ namespace Capnproto_test.Capnp.Test public string A { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface B @@ -14197,7 +14197,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -14209,8 +14209,8 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } @@ -14865,7 +14865,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Text => ctx.ReadText(0, ""); + public string Text => ctx.ReadText(0, null); public Capnproto_test.Capnp.Test.ITestInterface Cap => ctx.ReadCap(1); } @@ -14878,8 +14878,8 @@ namespace Capnproto_test.Capnp.Test public string Text { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } public Capnproto_test.Capnp.Test.ITestInterface Cap @@ -15619,7 +15619,7 @@ namespace Capnproto_test.Capnp.Test public static READER create(DeserializerState ctx) => new READER(ctx); public static implicit operator DeserializerState(READER reader) => reader.ctx; public static implicit operator READER(DeserializerState ctx) => new READER(ctx); - public string Host => ctx.ReadText(0, ""); + public string Host => ctx.ReadText(0, null); } public class WRITER : SerializerState @@ -15631,8 +15631,8 @@ namespace Capnproto_test.Capnp.Test public string Host { - get => this.ReadText(0, ""); - set => this.WriteText(0, value, ""); + get => this.ReadText(0, null); + set => this.WriteText(0, value, null); } } } diff --git a/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs b/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs index 17af353..fe7ba90 100644 --- a/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs +++ b/CapnpC.CSharp.Generator/CodeGen/DomainClassSnippetGen.cs @@ -284,7 +284,8 @@ namespace CapnpC.CSharp.Generator.CodeGen value.Decode(); return ArrayCreationExpression(ArrayType( - _names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClass, Nullability.NullableRef)) + _names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClass, + _names.GetDefaultElementTypeNullability(value.Type.ElementType))) .WithRankSpecifiers( SingletonList( ArrayRankSpecifier( @@ -619,13 +620,14 @@ namespace CapnpC.CSharp.Generator.CodeGen IdentifierName(nameof(Capnp.ReadOnlyListExtensions.ToReadOnlyList)))) .AddArgumentListArguments(Argument( SimpleLambdaExpression(Parameter(Identifier("_")), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(nameof(Capnp.CapnpSerializable)), - GenericName(nameof(Capnp.CapnpSerializable.Create)) - .AddTypeArgumentListArguments(MakeNonNullableType(elementType)))) - .AddArgumentListArguments(Argument(IdentifierName("_"))))))); + _names.SuppressNullableWarning( + InvocationExpression( + MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + IdentifierName(nameof(Capnp.CapnpSerializable)), + GenericName(nameof(Capnp.CapnpSerializable.Create)) + .AddTypeArgumentListArguments(MakeNonNullableType(elementType)))) + .AddArgumentListArguments(Argument(IdentifierName("_")))))))); } ExpressionSyntax MakeStructListConversion(ExpressionSyntax context, TypeSyntax elementType, int rank) diff --git a/CapnpC.CSharp.Generator/CodeGen/GenNames.cs b/CapnpC.CSharp.Generator/CodeGen/GenNames.cs index b16ff99..afcdf19 100644 --- a/CapnpC.CSharp.Generator/CodeGen/GenNames.cs +++ b/CapnpC.CSharp.Generator/CodeGen/GenNames.cs @@ -387,6 +387,23 @@ namespace CapnpC.CSharp.Generator.CodeGen } } + public Nullability GetDefaultElementTypeNullability(Model.Type type) + { + switch (type.Tag) + { + case TypeTag.Data: + case TypeTag.Text: + case TypeTag.Interface: + case TypeTag.List: + case TypeTag.ListPointer: + case TypeTag.StructPointer: + return Nullability.NullableRef; + + default: + return Nullability.NonNullable; + } + } + public TypeSyntax MakeTypeSyntax(Model.Type type, TypeDefinition scope, TypeUsage usage, Nullability nullability) { switch (type.Tag) @@ -483,11 +500,13 @@ namespace CapnpC.CSharp.Generator.CodeGen case TypeUsage.Reader: return MaybeNullableRefType(GenericName(Identifier("IReadOnlyList")) - .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.Reader, Nullability.NonNullable)), nullability); + .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.Reader, + GetDefaultElementTypeNullability(type.ElementType))), nullability); case TypeUsage.DomainClass: return MaybeNullableRefType(GenericName(Identifier("IReadOnlyList")) - .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.DomainClass, Nullability.NullableRef)), nullability); + .AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.DomainClass, + GetDefaultElementTypeNullability(type.ElementType))), nullability); default: throw new NotImplementedException();