public unsafe static void TestCommonTailOptimization() { var wr = new Writer.MetadataWriter(); wr.ScopeDefinitions.Add(BuildSimpleTestData()); var ms = new MemoryStream(); wr.Write(ms); fixed(byte *pBuffer = ms.ToArray()) { var rd = new Reader.MetadataReader((IntPtr)pBuffer, (int)ms.Length); Reader.ScopeDefinitionHandle scopeHandle = rd.ScopeDefinitions.Single(); Reader.ScopeDefinition systemRuntimeScope = scopeHandle.GetScopeDefinition(rd); Reader.NamespaceDefinition rootNamespace = systemRuntimeScope.RootNamespaceDefinition.GetNamespaceDefinition(rd); Reader.NamespaceDefinition systemNamespace = rootNamespace.NamespaceDefinitions.Single( ns => ns.GetNamespaceDefinition(rd).Name.StringEquals("System", rd) ).GetNamespaceDefinition(rd); // This validates the common tail optimization. // Since both System.Object and System.String define a default constructor and the // records are structurally equivalent, there should only be one metadata record // representing a default .ctor in the blob. Reader.TypeDefinition objectType = systemNamespace.TypeDefinitions.Single( t => t.GetTypeDefinition(rd).Name.StringEquals("Object", rd) ).GetTypeDefinition(rd); Reader.TypeDefinition stringType = systemNamespace.TypeDefinitions.Single( t => t.GetTypeDefinition(rd).Name.StringEquals("String", rd) ).GetTypeDefinition(rd); Reader.MethodHandle objectCtor = objectType.Methods.Single(); Reader.MethodHandle stringCtor = stringType.Methods.Single(); Assert.True(objectCtor.Equals(stringCtor)); } }
public unsafe static void TestSimpleRoundTripping() { var wr = new Writer.MetadataWriter(); wr.ScopeDefinitions.Add(BuildSimpleTestData()); var ms = new MemoryStream(); wr.Write(ms); fixed(byte *pBuffer = ms.ToArray()) { var rd = new Reader.MetadataReader((IntPtr)pBuffer, (int)ms.Length); // Validate the System.Runtime scope Reader.ScopeDefinitionHandle scopeHandle = rd.ScopeDefinitions.Single(); Reader.ScopeDefinition systemRuntimeScope = scopeHandle.GetScopeDefinition(rd); Assert.Equal(4, systemRuntimeScope.MajorVersion); Assert.Equal("System.Runtime", systemRuntimeScope.Name.GetConstantStringValue(rd).Value); // Validate the root namespace and <Module> type Reader.NamespaceDefinition rootNamespace = systemRuntimeScope.RootNamespaceDefinition.GetNamespaceDefinition(rd); Assert.Equal(1, rootNamespace.TypeDefinitions.Count()); Reader.TypeDefinition moduleType = rootNamespace.TypeDefinitions.Single().GetTypeDefinition(rd); Assert.Equal("<Module>", moduleType.Name.GetConstantStringValue(rd).Value); Assert.Equal(1, rootNamespace.NamespaceDefinitions.Count()); // Validate the System namespace Reader.NamespaceDefinition systemNamespace = rootNamespace.NamespaceDefinitions.Single().GetNamespaceDefinition(rd); Assert.Equal(4, systemNamespace.TypeDefinitions.Count()); foreach (var typeHandle in systemNamespace.TypeDefinitions) { Reader.TypeDefinition type = typeHandle.GetTypeDefinition(rd); string typeName = type.Name.GetConstantStringValue(rd).Value; string baseTypeName = null; if (!type.BaseType.IsNull(rd)) { baseTypeName = type.BaseType.ToTypeDefinitionHandle(rd).GetTypeDefinition(rd).Name.GetConstantStringValue(rd).Value; } switch (typeName) { case "Object": Assert.Null(baseTypeName); Assert.Equal(1, type.Methods.Count()); break; case "Void": Assert.Equal("ValueType", baseTypeName); Assert.Equal(0, type.Methods.Count()); break; case "String": Assert.Equal("Object", baseTypeName); Assert.Equal(1, type.Methods.Count()); break; case "ValueType": Assert.Equal("Object", baseTypeName); Assert.Equal(0, type.Methods.Count()); break; default: throw new NotImplementedException(); } } } }