예제 #1
0
 private static void WriteCustomType(IBinaryWriter writer, CustomTypeInfo customTypeInfo, object value)
 {
     writer.WriteByte(customTypeInfo.Code);
     byte[] buffer = customTypeInfo.SerializeFunction(value);
     writer.WriteInt16((short)buffer.Length);
     writer.WriteBytes(buffer);
 }
예제 #2
0
파일: TupleTests.cs 프로젝트: belav/roslyn
        public void Literal()
        {
            var source =
                @"class C
{
    static void M()
    {
        (int, int) o;
    }
}";
            var comp = CreateCompilationWithMscorlib40(
                source,
                new[] { ValueTupleRef, SystemRuntimeFacadeRef },
                options: TestOptions.DebugDll
                );

            WithRuntimeInstance(
                comp,
                new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef },
                runtime =>
            {
                var context  = CreateMethodContext(runtime, "C.M");
                var testData = new CompilationTestData();
                string error;
                var result = context.CompileExpression("(A: 1, B: 2)", out error, testData);
                Assert.Null(error);
                ReadOnlyCollection <byte> customTypeInfo;
                var customTypeInfoId = result.GetCustomTypeInfo(out customTypeInfo);
                ReadOnlyCollection <byte> dynamicFlags;
                ReadOnlyCollection <string> tupleElementNames;
                CustomTypeInfo.Decode(
                    customTypeInfoId,
                    customTypeInfo,
                    out dynamicFlags,
                    out tupleElementNames
                    );
                Assert.Equal(new[] { "A", "B" }, tupleElementNames);
                var methodData = testData.GetMethodData("<>x.<>m0");
                var method     = (MethodSymbol)methodData.Method;
                Assert.True(method.ReturnType.IsTupleType);
                CheckAttribute(
                    result.Assembly,
                    method,
                    AttributeDescription.TupleElementNamesAttribute,
                    expected: true
                    );
                methodData.VerifyIL(
                    @"{
  // Code size        8 (0x8)
  .maxstack  2
  .locals init (System.ValueTuple<int, int> V_0) //o
  IL_0000:  ldc.i4.1
  IL_0001:  ldc.i4.2
  IL_0002:  newobj     ""System.ValueTuple<int, int>..ctor(int, int)""
  IL_0007:  ret
}"
                    );
            }
                );
        }
        public void EncodeAndDecode()
        {
            var encoded = CustomTypeInfo.Encode(null, null);

            Assert.Null(encoded);

            var bytes = GetBytesInRange(0, 256);

            encoded = CustomTypeInfo.Encode(bytes, null);
            Assert.Null(encoded);

            bytes   = GetBytesInRange(0, 255);
            encoded = CustomTypeInfo.Encode(bytes, null);
            Assert.Equal(256, encoded.Count);
            Assert.Equal(255, encoded[0]);
            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(CustomTypeInfo.PayloadTypeId, encoded, out dynamicFlags, out tupleElementNames);
            Assert.Equal(bytes, dynamicFlags);
            Assert.Null(tupleElementNames);

            var names = new ReadOnlyCollection <string>(new[] { null, "A", null, "B" });

            encoded = CustomTypeInfo.Encode(bytes, names);
            Assert.Equal(255, encoded[0]);
            CustomTypeInfo.Decode(CustomTypeInfo.PayloadTypeId, encoded, out dynamicFlags, out tupleElementNames);
            Assert.Equal(bytes, dynamicFlags);
            Assert.Equal(names, tupleElementNames);

            encoded = CustomTypeInfo.Encode(null, names);
            CustomTypeInfo.Decode(CustomTypeInfo.PayloadTypeId, encoded, out dynamicFlags, out tupleElementNames);
            Assert.Null(dynamicFlags);
            Assert.Equal(names, tupleElementNames);
        }
        private static void ValidateCustomTypeInfo(params byte[] payload)
        {
            Assert.NotNull(payload);

            var dkmClrCustomTypeInfo = CustomTypeInfo.Create(
                new ReadOnlyCollection <byte>(payload),
                null
                );

            Assert.Equal(CustomTypeInfo.PayloadTypeId, dkmClrCustomTypeInfo.PayloadTypeId);
            Assert.NotNull(dkmClrCustomTypeInfo.Payload);

            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(
                dkmClrCustomTypeInfo.PayloadTypeId,
                dkmClrCustomTypeInfo.Payload,
                out dynamicFlags,
                out tupleElementNames
                );

            ValidateBytes(dynamicFlags, payload);
            Assert.Null(tupleElementNames);
        }
        internal static LocalSymbol Create(
            TypeNameDecoder <PEModuleSymbol, TypeSymbol> typeNameDecoder,
            MethodSymbol containingMethod,
            AssemblySymbol sourceAssembly,
            Alias alias)
        {
            var typeName = alias.Type;

            Debug.Assert(typeName.Length > 0);

            var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName);

            Debug.Assert((object)type != null);

            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(alias.CustomTypeInfoId, alias.CustomTypeInfo, out dynamicFlags, out tupleElementNames);

            if (dynamicFlags != null)
            {
                type = DecodeDynamicTypes(type, sourceAssembly, dynamicFlags);
            }

            if (tupleElementNames != null)
            {
                type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, sourceAssembly, tupleElementNames.AsImmutable());
            }

            var name        = alias.FullName;
            var displayName = alias.Name;

            switch (alias.Kind)
            {
            case DkmClrAliasKind.Exception:
                return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName));

            case DkmClrAliasKind.StowedException:
                return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName));

            case DkmClrAliasKind.ReturnValue:
            {
                int index;
                PseudoVariableUtilities.TryParseReturnValueIndex(name, out index);
                Debug.Assert(index >= 0);
                return(new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index));
            }

            case DkmClrAliasKind.ObjectId:
                return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: false));

            case DkmClrAliasKind.Variable:
                return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true));

            default:
                throw ExceptionUtilities.UnexpectedValue(alias.Kind);
            }
        }
예제 #6
0
 public PropertyInfo(
     string name, DisplayText description, bool reserved = false,
     MSBuildValueKind valueKind = MSBuildValueKind.Unknown,
     CustomTypeInfo customType  = null, string defaultValue        = null,
     bool isDeprecated          = false, string deprecationMessage = null)
     : base(name, description, valueKind, customType, defaultValue, isDeprecated, deprecationMessage)
 {
     Reserved = reserved;
 }
예제 #7
0
 internal static ReadOnlyCollection <byte> GetCustomTypeInfoPayload(
     this CSharpCompilation compilation,
     TypeSymbol type,
     int customModifiersCount,
     RefKind refKind)
 {
     return(CustomTypeInfo.Encode(
                GetDynamicTransforms(compilation, type, customModifiersCount, refKind),
                GetTupleElementNames(compilation, type)));
 }
예제 #8
0
 private static void WriteCustomType(Stream stream, CustomTypeInfo customTypeInfo, object value, bool writeType)
 {
     if (writeType)
     {
         stream.WriteByte(0x63);
     }
     stream.WriteByte(customTypeInfo.Code);
     byte[] buffer = customTypeInfo.SerializeFunction(value);
     WriteIntLength(stream, buffer.Length);
     stream.Write(buffer, 0, buffer.Length);
 }
예제 #9
0
        internal static ReadOnlyCollection <byte> ToBytes(this ImmutableArray <bool> dynamicFlags)
        {
            Debug.Assert(!dynamicFlags.IsDefaultOrEmpty);

            var builder = ArrayBuilder <bool> .GetInstance(dynamicFlags.Length);

            builder.AddRange(dynamicFlags);
            var bytes = DynamicFlagsCustomTypeInfo.ToBytes(builder);

            builder.Free();
            return(CustomTypeInfo.Encode(bytes, null));
        }
예제 #10
0
 private static void WriteCustomTypeArray(Stream stream, CustomTypeInfo customTypeInfo, IList list)
 {
     stream.WriteByte(0xe3);
     WriteIntLength(stream, (short)list.Count);
     stream.WriteByte(customTypeInfo.Code);
     foreach (object obj2 in list)
     {
         byte[] buffer = customTypeInfo.SerializeFunction(obj2);
         WriteIntLength(stream, buffer.Length);
         stream.Write(buffer, 0, buffer.Length);
     }
 }
예제 #11
0
 private static void WriteCustomTypeArray(IBinaryWriter writer, CustomTypeInfo customTypeInfo, IList list)
 {
     writer.WriteInt16((short)list.Count);
     writer.WriteByte(0x63);
     writer.WriteByte(customTypeInfo.Code);
     foreach (object obj2 in list)
     {
         byte[] buffer = customTypeInfo.SerializeFunction(obj2);
         writer.WriteInt16((short)buffer.Length);
         writer.WriteBytes(buffer);
     }
 }
        public void CustomTypeInfoConstructor_OtherGuid()
        {
            var customTypeInfo = DkmClrCustomTypeInfo.Create(Guid.NewGuid(), new ReadOnlyCollection <byte>(new byte[] { 0x01 }));
            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(
                customTypeInfo.PayloadTypeId,
                customTypeInfo.Payload,
                out dynamicFlags,
                out tupleElementNames);
            Assert.Null(dynamicFlags);
            Assert.Null(tupleElementNames);
        }
예제 #13
0
        public void Constant()
        {
            var source =
                @"class A<T>
{
     internal class B<U>
    {
    }
}
class C
{
    static (object, object) F;
    static void M()
    {
        const A<(int, int A)>.B<(object B, object)>[] c = null;
    }
}";
            var comp = CreateCompilationWithMscorlib40(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);

            WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime =>
            {
                var context  = CreateMethodContext(runtime, "C.M");
                var testData = new CompilationTestData();
                var locals   = ArrayBuilder <LocalAndMethod> .GetInstance();
                string typeName;
                var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
                Assert.Equal(1, locals.Count);
                ReadOnlyCollection <byte> customTypeInfo;
                var customTypeInfoId = locals[0].GetCustomTypeInfo(out customTypeInfo);
                ReadOnlyCollection <byte> dynamicFlags;
                ReadOnlyCollection <string> tupleElementNames;
                CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames);
                Assert.Equal(new[] { null, "A", "B", null }, tupleElementNames);
                var method = (MethodSymbol)testData.GetExplicitlyDeclaredMethods().Single().Value.Method;
                CheckAttribute(assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: true);
                var returnType = method.ReturnType;
                Assert.False(returnType.IsTupleType);
                Assert.True(returnType.ContainsTuple());
                VerifyLocal(testData, typeName, locals[0], "<>m0", "c", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
                            @"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldnull
  IL_0001:  ret
}");
                locals.Free();
            });
        }
예제 #14
0
        public void Local()
        {
            var source =
                @"class C
{
    static void M()
    {
        (int A\u1234, int \u1234B) o = (1, 2);
    }
}";
            var comp = CreateCompilationWithMscorlib40(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);

            WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime =>
            {
                var context  = CreateMethodContext(runtime, "C.M");
                var testData = new CompilationTestData();
                var locals   = ArrayBuilder <LocalAndMethod> .GetInstance();
                string typeName;
                var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
                Assert.Equal(1, locals.Count);
                ReadOnlyCollection <byte> customTypeInfo;
                var customTypeInfoId = locals[0].GetCustomTypeInfo(out customTypeInfo);
                ReadOnlyCollection <byte> dynamicFlags;
                ReadOnlyCollection <string> tupleElementNames;
                CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames);
                Assert.Equal(new[] { "A\u1234", "\u1234B" }, tupleElementNames);
                var method = (MethodSymbol)testData.GetExplicitlyDeclaredMethods().Single().Value.Method;
                CheckAttribute(assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: true);
                Assert.True(method.ReturnType.IsTupleType);
                VerifyLocal(testData, typeName, locals[0], "<>m0", "o", expectedILOpt:
                            string.Format(@"{{
  // Code size        2 (0x2)
  .maxstack  1
  .locals init (System.ValueTuple<int, int> V_0) //o
  IL_0000:  ldloc.0
  IL_0001:  ret
}}", '\u1234'));
                locals.Free();
            });
        }
예제 #15
0
        internal static LocalSymbol Create(
            TypeNameDecoder <PEModuleSymbol, TypeSymbol> typeNameDecoder,
            MethodSymbol containingMethod,
            AssemblySymbol sourceAssembly,
            Alias alias)
        {
            var typeName = alias.Type;

            Debug.Assert(typeName.Length > 0);

            var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName);

            Debug.Assert((object)type != null);

            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(alias.CustomTypeInfoId, alias.CustomTypeInfo, out dynamicFlags, out tupleElementNames);

            // Preserve tuple element names. See https://github.com/dotnet/roslyn/issues/13589.
            if (dynamicFlags != null)
            {
                var flagsBuilder = ArrayBuilder <bool> .GetInstance();

                DynamicFlagsCustomTypeInfo.CopyTo(dynamicFlags, flagsBuilder);
                var dynamicType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(
                    type,
                    sourceAssembly,
                    RefKind.None,
                    flagsBuilder.ToImmutableAndFree(),
                    checkLength: false);
                Debug.Assert(dynamicType != null);
                Debug.Assert(dynamicType != type);
                type = dynamicType;
            }

            var name        = alias.FullName;
            var displayName = alias.Name;

            switch (alias.Kind)
            {
            case DkmClrAliasKind.Exception:
                return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName));

            case DkmClrAliasKind.StowedException:
                return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName));

            case DkmClrAliasKind.ReturnValue:
            {
                int index;
                PseudoVariableUtilities.TryParseReturnValueIndex(name, out index);
                Debug.Assert(index >= 0);
                return(new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index));
            }

            case DkmClrAliasKind.ObjectId:
                return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: false));

            case DkmClrAliasKind.Variable:
                return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true));

            default:
                throw ExceptionUtilities.UnexpectedValue(alias.Kind);
            }
        }
예제 #16
0
 private static void VerifyCustomTypeInfo(CustomTypeInfo customTypeInfo, byte[] expectedBytes)
 {
     Assert.Equal(DynamicFlagsCustomTypeInfo.PayloadTypeId, customTypeInfo.PayloadTypeId);
     Assert.Equal(expectedBytes, customTypeInfo.Payload);
 }
예제 #17
0
        public void AliasElement()
        {
            var source =
                @"class C
{
    static (int, int) F;
    static void M()
    {
    }
}";
            var comp = CreateCompilationWithMscorlib40(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);

            WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime =>
            {
                var context = CreateMethodContext(
                    runtime,
                    "C.M");
                // (int A, (int, int D) B)[] t;
                var aliasElementNames = new ReadOnlyCollection <string>(new[] { "A", "B", null, "D" });
                var alias             = new Alias(
                    DkmClrAliasKind.Variable,
                    "t",
                    "t",
                    "System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]][], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51",
                    CustomTypeInfo.PayloadTypeId,
                    CustomTypeInfo.Encode(null, aliasElementNames));
                var locals = ArrayBuilder <LocalAndMethod> .GetInstance();
                string typeName;
                var diagnostics = DiagnosticBag.GetInstance();
                var testData    = new CompilationTestData();
                var assembly    = context.CompileGetLocals(
                    locals,
                    argumentsOnly: false,
                    aliases: ImmutableArray.Create(alias),
                    diagnostics: diagnostics,
                    typeName: out typeName,
                    testData: testData);
                diagnostics.Verify();
                diagnostics.Free();
                Assert.Equal(1, locals.Count);
                ReadOnlyCollection <byte> customTypeInfo;
                var customTypeInfoId = locals[0].GetCustomTypeInfo(out customTypeInfo);
                ReadOnlyCollection <byte> dynamicFlags;
                ReadOnlyCollection <string> tupleElementNames;
                CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames);
                Assert.Equal(aliasElementNames, tupleElementNames);
                var method = (MethodSymbol)testData.GetExplicitlyDeclaredMethods().Single().Value.Method;
                CheckAttribute(assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: true);
                var returnType = (TypeSymbol)method.ReturnType;
                Assert.False(returnType.IsTupleType);
                Assert.True(((ArrayTypeSymbol)returnType).ElementType.IsTupleType);
                VerifyLocal(testData, typeName, locals[0], "<>m0", "t", expectedILOpt:
                            @"{
  // Code size       16 (0x10)
  .maxstack  1
  IL_0000:  ldstr      ""t""
  IL_0005:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
  IL_000a:  castclass  ""System.ValueTuple<int, System.ValueTuple<int, int>>[]""
  IL_000f:  ret
}");
                locals.Free();
            });
        }
예제 #18
0
        public void DeclareLocal()
        {
            var source =
                @"class C
{
    static void M()
    {
        var x = (1, 2);
    }
}";
            var comp = CreateCompilationWithMscorlib40(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);

            WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime =>
            {
                var context  = CreateMethodContext(runtime, "C.M");
                var testData = new CompilationTestData();
                string error;
                ResultProperties resultProperties;
                ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                var result = context.CompileExpression(
                    "(int A, int B) y = x;",
                    DkmEvaluationFlags.None,
                    NoAliases,
                    DebuggerDiagnosticFormatter.Instance,
                    out resultProperties,
                    out error,
                    out missingAssemblyIdentities,
                    EnsureEnglishUICulture.PreferredOrNull,
                    testData);
                Assert.Null(error);
                Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult);
                ReadOnlyCollection <byte> customTypeInfo;
                var customTypeInfoId = result.GetCustomTypeInfo(out customTypeInfo);
                ReadOnlyCollection <byte> dynamicFlags;
                ReadOnlyCollection <string> tupleElementNames;
                CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames);
                Assert.Null(tupleElementNames);
                var methodData = testData.GetMethodData("<>x.<>m0");
                var method     = (MethodSymbol)methodData.Method;
                CheckAttribute(result.Assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: false);
                methodData.VerifyIL(
                    @"{
  // Code size       64 (0x40)
  .maxstack  6
  .locals init (System.ValueTuple<int, int> V_0) //x
  IL_0000:  ldtoken    ""System.ValueTuple<int, int>""
  IL_0005:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_000a:  ldstr      ""y""
  IL_000f:  ldstr      ""108766ce-df68-46ee-b761-0dcb7ac805f1""
  IL_0014:  newobj     ""System.Guid..ctor(string)""
  IL_0019:  ldc.i4.5
  IL_001a:  newarr     ""byte""
  IL_001f:  dup
  IL_0020:  ldtoken    ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=5 <PrivateImplementationDetails>.845151BC3876B3B783409FD71AF3665D783D8036161B4A2D2ACD27E1A0FCEDF7""
  IL_0025:  call       ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)""
  IL_002a:  call       ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])""
  IL_002f:  ldstr      ""y""
  IL_0034:  call       ""System.ValueTuple<int, int> Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<System.ValueTuple<int, int>>(string)""
  IL_0039:  ldloc.0
  IL_003a:  stobj      ""System.ValueTuple<int, int>""
  IL_003f:  ret
}");
            });
        }
예제 #19
0
 internal void SetParent(CustomTypeInfo parent) => CustomType = parent;
        public void EncodeAndDecode()
        {
            var encoded = CustomTypeInfo.Encode(null, null);

            Assert.Null(encoded);

            ReadOnlyCollection <byte>   bytes;
            ReadOnlyCollection <string> names;

            // Exceed max bytes.
            bytes   = GetBytesInRange(0, 256);
            encoded = CustomTypeInfo.Encode(bytes, null);
            Assert.Null(encoded);

            // Max bytes.
            bytes   = GetBytesInRange(0, 255);
            encoded = CustomTypeInfo.Encode(bytes, null);
            Assert.Equal(256, encoded.Count);
            Assert.Equal(255, encoded[0]);
            ReadOnlyCollection <byte>   dynamicFlags;
            ReadOnlyCollection <string> tupleElementNames;

            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Equal(bytes, dynamicFlags);
            Assert.Null(tupleElementNames);

            // Empty dynamic flags collection
            bytes = new ReadOnlyCollection <byte>(new byte[0]);
            // ... with names.
            names   = new ReadOnlyCollection <string>(new[] { "A" });
            encoded = CustomTypeInfo.Encode(bytes, names);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Null(dynamicFlags);
            Assert.Equal(names, tupleElementNames);
            // ... without names.
            encoded = CustomTypeInfo.Encode(bytes, null);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Null(dynamicFlags);
            Assert.Null(tupleElementNames);

            // Empty names collection
            names = new ReadOnlyCollection <string>(new string[0]);
            // ... with dynamic flags.
            bytes   = GetBytesInRange(0, 255);
            encoded = CustomTypeInfo.Encode(bytes, names);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Equal(bytes, dynamicFlags);
            Assert.Null(tupleElementNames);
            // ... without dynamic flags.
            encoded = CustomTypeInfo.Encode(null, names);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Null(dynamicFlags);
            Assert.Null(tupleElementNames);

            // Single null name
            names = new ReadOnlyCollection <string>(new string[] { null });
            // ... with dynamic flags.
            bytes   = GetBytesInRange(0, 255);
            encoded = CustomTypeInfo.Encode(bytes, names);
            Assert.Equal(255, encoded[0]);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Equal(bytes, dynamicFlags);
            Assert.Equal(names, tupleElementNames);
            // ... without dynamic flags.
            encoded = CustomTypeInfo.Encode(null, names);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Null(dynamicFlags);
            Assert.Equal(names, tupleElementNames);

            // Multiple names
            names = new ReadOnlyCollection <string>(new[] { null, "A", null, "B" });
            // ... with dynamic flags.
            bytes   = GetBytesInRange(0, 255);
            encoded = CustomTypeInfo.Encode(bytes, names);
            Assert.Equal(255, encoded[0]);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Equal(bytes, dynamicFlags);
            Assert.Equal(names, tupleElementNames);
            // ... without dynamic flags.
            encoded = CustomTypeInfo.Encode(null, names);
            CustomTypeInfo.Decode(
                CustomTypeInfo.PayloadTypeId,
                encoded,
                out dynamicFlags,
                out tupleElementNames
                );
            Assert.Null(dynamicFlags);
            Assert.Equal(names, tupleElementNames);
        }
 internal static Alias Alias(DkmClrAliasKind kind, string name, string fullName, string type, CustomTypeInfo customTypeInfo)
 {
     return(new Alias(kind, name, fullName, type, customTypeInfo));
 }