CorLightup.cs 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// 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
{
    /// <summary>
    /// This type contains the light up scenarios for various platform and runtimes.  Any function
C
Charles Stoner 已提交
12
    /// in this type can, and is expected to, fail on various platforms.  These are light up scenarios
13 14 15 16 17 18
    /// only.
    /// </summary>
    internal static class CorLightup
    {
        internal static class Desktop
        {
T
Tomas Matousek 已提交
19
            private static class _CultureInfo
20
            {
T
Tomas Matousek 已提交
21
                internal static readonly Type Type = typeof(CultureInfo);
22 23 24 25 26 27 28 29 30 31 32

                internal static readonly PropertyInfo CultureTypes = Type
                    .GetTypeInfo()
                    .GetDeclaredProperty(nameof(CultureTypes));
            }

            private static class CultureTypes
            {
                internal const int UserCustomCulture = 8;
            }

T
Tomas Matousek 已提交
33
            internal static bool? IsUserCustomCulture(CultureInfo cultureInfo)
34
            {
T
Tomas Matousek 已提交
35
                if (_CultureInfo.CultureTypes == null)
36 37 38 39 40 41
                {
                    return null;
                }

                try
                {
T
Tomas Matousek 已提交
42
                    var value = (int)_CultureInfo.CultureTypes.GetValue(cultureInfo);
43 44 45 46 47 48 49 50
                    return (value & CultureTypes.UserCustomCulture) != 0;
                }
                catch (Exception ex)
                {
                    Debug.Assert(false, ex.Message);
                    return null;
                }
            }
T
Tomas Matousek 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

            private static class _Assembly
            {
                internal static readonly Type Type = typeof(Assembly);

                internal static readonly Func<byte[], Assembly> Load_bytes = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("Load", typeof(byte[]))
                    .CreateDelegate<Func<byte[], Assembly>>();

                internal static readonly Func<string, Assembly> LoadFile = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("LoadFile", typeof(string))
                    .CreateDelegate<Func<string, Assembly>>();

                internal static readonly Func<Assembly, string> get_Location = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("get_Location")
                    .CreateDelegate<Func<Assembly, string>>();

                internal static readonly Func<Assembly, bool> get_GlobalAssemblyCache = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("get_GlobalAssemblyCache")
                    .CreateDelegate<Func<Assembly, bool>>();
            }

77 78 79 80 81 82 83 84 85 86
            private static class _Module
            {
                internal static readonly Type Type = typeof(Module);

                internal static readonly Func<Module, Guid> get_ModuleVersionId = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("get_ModuleVersionId")
                    .CreateDelegate<Func<Module, Guid>>();
            }

T
Tomas Matousek 已提交
87 88
            private static class _ResolveEventArgs
            {
89
                internal static readonly Type Type = ReflectionUtilities.TryGetType("System.ResolveEventArgs");
T
Tomas Matousek 已提交
90 91 92 93 94 95 96 97 98 99 100 101

                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
            {
102 103
                internal static readonly Type Type = ReflectionUtilities.TryGetType("System.AppDomain");
                internal static readonly Type ResolveEventHandlerType = ReflectionUtilities.TryGetType("System.ResolveEventHandler");
T
Tomas Matousek 已提交
104 105 106 107 108 109 110 111

                internal static readonly MethodInfo get_CurrentDomain = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("get_CurrentDomain");

                internal static readonly MethodInfo add_AssemblyResolve = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("add_AssemblyResolve", ResolveEventHandlerType);
112 113 114 115

                internal static readonly MethodInfo remove_AssemblyResolve = Type
                    .GetTypeInfo()
                    .GetDeclaredMethod("remove_AssemblyResolve", ResolveEventHandlerType);
T
Tomas Matousek 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
            }

            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);
            }
147 148 149 150 151

            internal static Guid GetModuleVersionId(Module module)
            {
                return _Module.get_ModuleVersionId(module);
            }
T
Tomas Matousek 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165

            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<string, Assembly, Assembly> _handler;
J
Jared Parsons 已提交
166
                private static readonly MethodInfo s_stubInfo = typeof(AssemblyResolveWrapper).GetTypeInfo().GetDeclaredMethod("Stub");
T
Tomas Matousek 已提交
167 168 169 170 171 172 173 174

                public AssemblyResolveWrapper(Func<string, Assembly, Assembly> handler)
                {
                    _handler = handler;
                }

                private Assembly Stub(object sender, object resolveEventArgs)
                {
175 176
                    var name = (string)_ResolveEventArgs.get_Name.Invoke(resolveEventArgs, Array.Empty<object>());
                    var requestingAssembly = (Assembly)_ResolveEventArgs.get_RequestingAssembly.Invoke(resolveEventArgs, Array.Empty<object>());
T
Tomas Matousek 已提交
177 178 179 180 181 182

                    return _handler(name, requestingAssembly);
                }

                public object GetHandler()
                {
J
Jared Parsons 已提交
183
                    return s_stubInfo.CreateDelegate(_AppDomain.ResolveEventHandlerType, this);
T
Tomas Matousek 已提交
184 185 186
                }
            }

187
            internal static object GetCurrentAppDomain()
T
Tomas Matousek 已提交
188 189 190 191 192 193 194 195 196
            {
                if (_AppDomain.get_CurrentDomain == null ||
                    _AppDomain.add_AssemblyResolve == null ||
                    _ResolveEventArgs.get_Name == null ||
                    _ResolveEventArgs.get_RequestingAssembly == null)
                {
                    throw new PlatformNotSupportedException();
                }

197
                return _AppDomain.get_CurrentDomain.Invoke(null, Array.Empty<object>());
198 199 200 201 202 203 204 205 206 207
            }

            internal static void GetOrRemoveAssemblyResolveHandler(Func<string, Assembly, Assembly> handler, MethodInfo handlerOperation)
            {
                if (_AppDomain.add_AssemblyResolve == null)
                {
                    throw new PlatformNotSupportedException();
                }

                object currentAppDomain = GetCurrentAppDomain();
T
Tomas Matousek 已提交
208 209
                object resolveEventHandler = new AssemblyResolveWrapper(handler).GetHandler();

210 211 212 213 214 215 216 217 218 219 220
                handlerOperation.Invoke(currentAppDomain, new[] { resolveEventHandler });
            }

            internal static void AddAssemblyResolveHandler(Func<string, Assembly, Assembly> handler)
            {
                GetOrRemoveAssemblyResolveHandler(handler, _AppDomain.add_AssemblyResolve);
            }

            internal static void RemoveAssemblyResolveHandler(Func<string, Assembly, Assembly> handler)
            {
                GetOrRemoveAssemblyResolveHandler(handler, _AppDomain.remove_AssemblyResolve);
T
Tomas Matousek 已提交
221
            }
222 223 224
        }
    }
}