// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
namespace Roslyn.Utilities
{
///
/// This type contains the light up scenarios for various platform and runtimes. Any function
/// in this type can, and is expected to, fail on various platforms. These are light up scenarios
/// only.
///
internal static class CorLightup
{
internal static class Desktop
{
private static class _CultureInfo
{
internal static readonly Type Type = typeof(CultureInfo);
internal static readonly PropertyInfo CultureTypes = Type
.GetTypeInfo()
.GetDeclaredProperty(nameof(CultureTypes));
}
private static class CultureTypes
{
internal const int UserCustomCulture = 8;
}
internal static bool? IsUserCustomCulture(CultureInfo cultureInfo)
{
if (_CultureInfo.CultureTypes == null)
{
return null;
}
try
{
var value = (int)_CultureInfo.CultureTypes.GetValue(cultureInfo);
return (value & CultureTypes.UserCustomCulture) != 0;
}
catch (Exception ex)
{
Debug.Assert(false, ex.Message);
return null;
}
}
private static class _Assembly
{
internal static readonly Type Type = typeof(Assembly);
internal static readonly Func Load_bytes = Type
.GetTypeInfo()
.GetDeclaredMethod("Load", typeof(byte[]))
.CreateDelegate>();
internal static readonly Func LoadFile = Type
.GetTypeInfo()
.GetDeclaredMethod("LoadFile", typeof(string))
.CreateDelegate>();
internal static readonly Func get_Location = Type
.GetTypeInfo()
.GetDeclaredMethod("get_Location")
.CreateDelegate>();
internal static readonly Func get_GlobalAssemblyCache = Type
.GetTypeInfo()
.GetDeclaredMethod("get_GlobalAssemblyCache")
.CreateDelegate>();
}
private static class _Module
{
internal static readonly Type Type = typeof(Module);
internal static readonly Func get_ModuleVersionId = Type
.GetTypeInfo()
.GetDeclaredMethod("get_ModuleVersionId")
.CreateDelegate>();
}
private static class _ResolveEventArgs
{
internal static readonly Type Type = ReflectionUtilities.TryGetType("System.ResolveEventArgs");
internal static readonly MethodInfo get_Name = Type
.GetTypeInfo()
.GetDeclaredMethod("get_Name");
internal static readonly MethodInfo get_RequestingAssembly = Type
.GetTypeInfo()
.GetDeclaredMethod("get_RequestingAssembly");
}
private static class _AppDomain
{
internal static readonly Type Type = ReflectionUtilities.TryGetType("System.AppDomain");
internal static readonly Type ResolveEventHandlerType = ReflectionUtilities.TryGetType("System.ResolveEventHandler");
internal static readonly MethodInfo get_CurrentDomain = Type
.GetTypeInfo()
.GetDeclaredMethod("get_CurrentDomain");
internal static readonly MethodInfo add_AssemblyResolve = Type
.GetTypeInfo()
.GetDeclaredMethod("add_AssemblyResolve", ResolveEventHandlerType);
internal static readonly MethodInfo remove_AssemblyResolve = Type
.GetTypeInfo()
.GetDeclaredMethod("remove_AssemblyResolve", ResolveEventHandlerType);
}
internal static Assembly LoadAssembly(byte[] peImage)
{
if (_Assembly.Load_bytes == null)
{
throw new PlatformNotSupportedException();
}
return _Assembly.Load_bytes(peImage);
}
internal static Assembly LoadAssembly(string path)
{
if (_Assembly.LoadFile == null)
{
throw new PlatformNotSupportedException();
}
return _Assembly.LoadFile(path);
}
internal static string GetAssemblyLocation(Assembly assembly)
{
if (_Assembly.get_Location == null)
{
throw new PlatformNotSupportedException();
}
return _Assembly.get_Location(assembly);
}
internal static Guid GetModuleVersionId(Module module)
{
return _Module.get_ModuleVersionId(module);
}
internal static bool IsAssemblyFromGlobalAssemblyCache(Assembly assembly)
{
if (_Assembly.get_GlobalAssemblyCache == null)
{
throw new PlatformNotSupportedException();
}
return _Assembly.get_GlobalAssemblyCache(assembly);
}
private sealed class AssemblyResolveWrapper
{
private readonly Func _handler;
private static readonly MethodInfo s_stubInfo = typeof(AssemblyResolveWrapper).GetTypeInfo().GetDeclaredMethod("Stub");
public AssemblyResolveWrapper(Func handler)
{
_handler = handler;
}
private Assembly Stub(object sender, object resolveEventArgs)
{
var name = (string)_ResolveEventArgs.get_Name.Invoke(resolveEventArgs, Array.Empty