diff --git a/src/Compilers/Core/CodeAnalysisTest/ObjectSerializationTests.cs b/src/Compilers/Core/CodeAnalysisTest/ObjectSerializationTests.cs index e397a96b843491787f4059d91df889f5e72b1a76..301f5c681952c9e6ce8009727808cd58a4b9a229 100644 --- a/src/Compilers/Core/CodeAnalysisTest/ObjectSerializationTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/ObjectSerializationTests.cs @@ -1032,6 +1032,24 @@ private void TestRoundTripChar(Char ch) TestRoundTrip(ch, (w, v) => w.WriteChar(v), r => r.ReadChar()); } + [Fact] + public void TestRoundTripGuid() + { + TestRoundTripGuid(Guid.Empty); + TestRoundTripGuid(new Guid(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)); + TestRoundTripGuid(new Guid(0b10000000000000000000000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)); + TestRoundTripGuid(new Guid(0b10000000000000000000000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + for (int i = 0; i < 10; i++) + { + TestRoundTripGuid(Guid.NewGuid()); + } + } + + private void TestRoundTripGuid(Guid guid) + { + TestRoundTrip(guid, (w, v) => w.WriteGuid(v), r => r.ReadGuid()); + } + [Fact] public void TestRoundTripStringCharacters() { diff --git a/src/Compilers/Core/Portable/Serialization/ObjectReader.cs b/src/Compilers/Core/Portable/Serialization/ObjectReader.cs index e4cafd01701865e542f5691625f61835eb393c0a..15672b682bfa34794dd74287d8fe5a1e6f8aadd4 100644 --- a/src/Compilers/Core/Portable/Serialization/ObjectReader.cs +++ b/src/Compilers/Core/Portable/Serialization/ObjectReader.cs @@ -124,6 +124,17 @@ public void Dispose() public ushort ReadUInt16() => _reader.ReadUInt16(); public string ReadString() => ReadStringValue(); + public Guid ReadGuid() + { + var accessor = new ObjectWriter.GuidAccessor + { + Low64 = ReadInt64(), + High64 = ReadInt64() + }; + + return accessor.Guid; + } + public object ReadValue() { var oldDepth = _recursionDepth; diff --git a/src/Compilers/Core/Portable/Serialization/ObjectWriter.cs b/src/Compilers/Core/Portable/Serialization/ObjectWriter.cs index 428f51026f7e920c712b52edc569847f4a7c36cf..36b49d1554f238cdcad50eef9c575611617759a8 100644 --- a/src/Compilers/Core/Portable/Serialization/ObjectWriter.cs +++ b/src/Compilers/Core/Portable/Serialization/ObjectWriter.cs @@ -119,6 +119,28 @@ public void Dispose() public void WriteUInt16(ushort value) => _writer.Write(value); public void WriteString(string value) => WriteStringValue(value); + /// + /// Used so we can easily grab the low/high 64bits of a guid for serialization. + /// + [StructLayout(LayoutKind.Explicit)] + internal struct GuidAccessor + { + [FieldOffset(0)] + public Guid Guid; + + [FieldOffset(0)] + public long Low64; + [FieldOffset(8)] + public long High64; + } + + public void WriteGuid(Guid guid) + { + var accessor = new GuidAccessor { Guid = guid }; + WriteInt64(accessor.Low64); + WriteInt64(accessor.High64); + } + public void WriteValue(object value) { Debug.Assert(value == null || !value.GetType().GetTypeInfo().IsEnum, "Enum should not be written with WriteValue. Write them as ints instead."); diff --git a/src/Workspaces/Core/Portable/Execution/AbstractReferenceSerializationService.cs b/src/Workspaces/Core/Portable/Execution/AbstractReferenceSerializationService.cs index 88eb69639f5185a4b754b63e177d39dd71d62aaf..fe285615c793bed71934290bde887eb7ea19e02b 100644 --- a/src/Workspaces/Core/Portable/Execution/AbstractReferenceSerializationService.cs +++ b/src/Workspaces/Core/Portable/Execution/AbstractReferenceSerializationService.cs @@ -234,7 +234,7 @@ private void WriteAnalyzerFileReferenceMvid(AnalyzerFileReference reference, Obj var mvidHandle = metadataReader.GetModuleDefinition().Mvid; var guid = metadataReader.GetGuid(mvidHandle); - writer.WriteValue(guid.ToByteArray()); + writer.WriteGuid(guid); } } catch @@ -312,7 +312,7 @@ private void WriteMvidTo(ModuleMetadata metadata, ObjectWriter writer, Cancellat var mvidHandle = metadataReader.GetModuleDefinition().Mvid; var guid = metadataReader.GetGuid(mvidHandle); - writer.WriteValue(guid.ToByteArray()); + writer.WriteGuid(guid); } private void WritePortableExecutableReferenceTo( diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentId.cs b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentId.cs index 64a5d020a183d8eee6c2204aa4b93d4c825c94d8..3053a7c7496c51904bbd9e1667501530926a6b54 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/DocumentId.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/DocumentId.cs @@ -102,7 +102,7 @@ void IObjectWritable.WriteTo(ObjectWriter writer) { ProjectId.WriteTo(writer); - writer.WriteValue(Id.ToByteArray()); + writer.WriteGuid(Id); writer.WriteString(DebugName); } @@ -110,7 +110,7 @@ internal static DocumentId ReadFrom(ObjectReader reader) { var projectId = ProjectId.ReadFrom(reader); - var guid = new Guid((byte[])reader.ReadValue()); + var guid = reader.ReadGuid(); var debugName = reader.ReadString(); return CreateFromSerialized(projectId, guid, debugName); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectId.cs b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectId.cs index fd1eec299a0c67dd0812060b1cade5d8b587cfc2..b5d167495869ae64a1713fb987ba37355d51d1be 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectId.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectId.cs @@ -86,13 +86,13 @@ public override int GetHashCode() void IObjectWritable.WriteTo(ObjectWriter writer) { - writer.WriteValue(Id.ToByteArray()); + writer.WriteGuid(Id); writer.WriteString(DebugName); } internal static ProjectId ReadFrom(ObjectReader reader) { - var guid = new Guid((byte[])reader.ReadValue()); + var guid = reader.ReadGuid(); var debugName = reader.ReadString(); return CreateFromSerialized(guid, debugName); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionId.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionId.cs index 486f3074ba03fcf3441d9aae037cc6fbb4548e2d..3175c4b604cddd81541bab011e55e0536c234d09 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionId.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionId.cs @@ -83,13 +83,13 @@ public override int GetHashCode() void IObjectWritable.WriteTo(ObjectWriter writer) { - writer.WriteValue(Id.ToByteArray()); + writer.WriteGuid(Id); writer.WriteString(DebugName); } internal static SolutionId ReadFrom(ObjectReader reader) { - var guid = new Guid((byte[])reader.ReadValue()); + var guid = reader.ReadGuid(); var debugName = reader.ReadString(); return CreateFromSerialized(guid, debugName);