|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Buffers.Binary;
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace System.Xml.Serialization
{
internal sealed class Compiler
{
private readonly StringWriter _writer = new StringWriter(CultureInfo.InvariantCulture);
// SxS: This method does not take any resource name and does not expose any resources to the caller.
// It's OK to suppress the SxS warning.
[RequiresUnreferencedCode("Reflects against input Type DeclaringType")]
internal static void AddImport(Type? type, Hashtable types)
{
if (type == null)
return;
if (TypeScope.IsKnownType(type))
return;
if (types[type] != null)
return;
types[type] = type;
Type? baseType = type.BaseType;
if (baseType != null)
AddImport(baseType, types);
Type? declaringType = type.DeclaringType;
if (declaringType != null)
AddImport(declaringType, types);
foreach (Type intf in type.GetInterfaces())
AddImport(intf, types);
ConstructorInfo[] ctors = type.GetConstructors();
for (int i = 0; i < ctors.Length; i++)
{
ParameterInfo[] parms = ctors[i].GetParameters();
for (int j = 0; j < parms.Length; j++)
{
AddImport(parms[j].ParameterType, types);
}
}
if (type.IsGenericType)
{
Type[] arguments = type.GetGenericArguments();
for (int i = 0; i < arguments.Length; i++)
{
AddImport(arguments[i], types);
}
}
Module module = type.Module;
Assembly assembly = module.Assembly;
if (DynamicAssemblies.IsTypeDynamic(type))
{
DynamicAssemblies.Add(assembly);
return;
}
object[] typeForwardedFromAttribute = type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false);
if (typeForwardedFromAttribute.Length > 0)
{
TypeForwardedFromAttribute? originalAssemblyInfo = typeForwardedFromAttribute[0] as TypeForwardedFromAttribute;
Debug.Assert(originalAssemblyInfo != null);
Assembly.Load(new AssemblyName(originalAssemblyInfo.AssemblyFullName));
}
}
internal TextWriter Source
{
get { return _writer; }
}
internal static string GetTempAssemblyName(AssemblyName parent, string? ns)
{
return string.IsNullOrEmpty(ns) ?
$"{parent.Name}.XmlSerializers" :
$"{parent.Name}.XmlSerializers.{GetPersistentHashCode(ns)}";
}
private static uint GetPersistentHashCode(string value)
{
byte[] valueBytes = Encoding.UTF8.GetBytes(value);
byte[] hash = SHA512.HashData(valueBytes);
return BinaryPrimitives.ReadUInt32BigEndian(hash);
}
}
}
|