[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/tlecomte/ClearScript/master/ClearScript/Util/AssemblyHelpers.cs [Back]  [Original]

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Microsoft.ClearScript.Util
{
    internal static partial class AssemblyHelpers
    {
        public static string GetFullAssemblyName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                return name;
            }

            if (MiscHelpers.Try(out var assembly, () => Assembly.Load(name)))
            {
                return assembly.FullName;
            }

            var fileName = name;
            if (!string.Equals(Path.GetExtension(fileName), ".dll", StringComparison.OrdinalIgnoreCase))
            {
                fileName = Path.ChangeExtension(fileName + '.', "dll");
            }

            if (MiscHelpers.Try(out var assemblyName, () => AssemblyName.GetAssemblyName(fileName)))
            {
                return assemblyName.FullName;
            }

            var dirPath = Path.GetDirectoryName(typeof(string).Assembly.Location);
            if (!string.IsNullOrWhiteSpace(dirPath))
            {
                // ReSharper disable AccessToModifiedClosure

                var path = Path.Combine(dirPath, fileName);
                if (File.Exists(path) && MiscHelpers.Try(out assemblyName, () => AssemblyName.GetAssemblyName(path)))
                {
                    return assemblyName.FullName;
                }

                if (MiscHelpers.Try(out var subDirPaths, () => Directory.EnumerateDirectories(dirPath, "*", SearchOption.AllDirectories)))
                {
                    foreach (var subDirPath in subDirPaths)
                    {
                        path = Path.Combine(subDirPath, fileName);
                        if (File.Exists(path) && MiscHelpers.Try(out assemblyName, () => AssemblyName.GetAssemblyName(path)))
                        {
                            return assemblyName.FullName;
                        }
                    }
                }

                // ReSharper restore AccessToModifiedClosure
            }

            return name;
        }

        public static Assembly TryLoad(AssemblyName name)
        {
            if (MiscHelpers.Try(out var assembly, () => Assembly.Load(name)))
            {
                return assembly;
            }

            return null;
        }

        public static T GetAttribute(this Assembly assembly, bool inherit) where T : Attribute
        {
            return Attribute.GetCustomAttributes(assembly, typeof(T), inherit).SingleOrDefault() as T;
        }

        public static IEnumerable GetAttributes(this Assembly assembly, bool inherit) where T : Attribute
        {
            return Attribute.GetCustomAttributes(assembly, typeof(T), inherit).OfType();
        }

        public static bool IsFriendOf(this Assembly thisAssembly, Assembly thatAssembly)
        {
            if (thatAssembly == thisAssembly)
            {
                return true;
            }

            var thisName = thisAssembly.GetName();
            foreach (var attribute in thatAssembly.GetAttributes(false))
            {
                var thatName = new AssemblyName(attribute.AssemblyName);
                if (AssemblyName.ReferenceMatchesDefinition(thatName, thisName))
                {
                    return true;
                }
            }

            return false;
        }

        public static IEnumerable GetReferencedEnums(this Assembly assembly)
        {
            var processedTypes = new HashSet();
            return assembly.GetAllTypes().SelectMany(type => GetReferencedEnums(assembly, type, processedTypes));
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, Type type, HashSet processedTypes)
        {
            if ((type == null) || !type.IsVisible || type.ContainsGenericParameters || processedTypes.Contains(type))
            {
                yield break;
            }

            processedTypes.Add(type);

            if (type.IsEnum)
            {
                yield return type;
                yield break;
            }

            foreach (var enumType in GetReferencedEnums(assembly, type.GetElementType(), processedTypes))
            {
                yield return enumType;
            }

            foreach (var enumType in type.GetGenericArguments().SelectMany(argType => GetReferencedEnums(assembly, argType, processedTypes)))
            {
                yield return enumType;
            }

            foreach (var enumType in GetReferencedEnums(assembly, type.BaseType, processedTypes))
            {
                yield return enumType;
            }

            foreach (var enumType in type.GetInterfaces().SelectMany(interfaceType => GetReferencedEnums(assembly, interfaceType, processedTypes)))
            {
                yield return enumType;
            }

            if (type.Assembly == assembly)
            {
                foreach (var enumType in type.GetMembers().SelectMany(member => GetReferencedEnums(assembly, member, processedTypes)))
                {
                    yield return enumType;
                }
            }
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, MemberInfo member, HashSet processedTypes)
        {
            if (member == null)
            {
                return Enumerable.Empty();
            }

            if (member.MemberType == MemberTypes.Field)
            {
                return GetReferencedEnums(assembly, (FieldInfo)member, processedTypes);
            }

            if (member.MemberType == MemberTypes.Property)
            {
                return GetReferencedEnums(assembly, (PropertyInfo)member, processedTypes);
            }

            if (member.MemberType == MemberTypes.Method)
            {
                return GetReferencedEnums(assembly, (MethodInfo)member, processedTypes);
            }

            if (member.MemberType == MemberTypes.NestedType)
            {
                return GetReferencedEnums(assembly, (Type)member, processedTypes);
            }

            return Enumerable.Empty();
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, FieldInfo field, HashSet processedTypes)
        {
            if (field == null)
            {
                return Enumerable.Empty();
            }

            return GetReferencedEnums(assembly, field.FieldType, processedTypes);
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, PropertyInfo property, HashSet processedTypes)
        {
            if (property == null)
            {
                yield break;
            }

            foreach (var enumType in GetReferencedEnums(assembly, property.PropertyType, processedTypes))
            {
                yield return enumType;
            }

            foreach (var enumType in GetReferencedEnums(assembly, property.GetMethod, processedTypes))
            {
                yield return enumType;
            }

            foreach (var enumType in GetReferencedEnums(assembly, property.SetMethod, processedTypes))
            {
                yield return enumType;
            }
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, MethodInfo method, HashSet processedTypes)
        {
            if (method == null)
            {
                yield break;
            }

            foreach (var enumType in GetReferencedEnums(assembly, method.ReturnParameter, processedTypes))
            {
                yield return enumType;
            }

            foreach (var enumType in method.GetParameters().SelectMany(param => GetReferencedEnums(assembly, param, processedTypes)))
            {
                yield return enumType;
            }
        }

        private static IEnumerable GetReferencedEnums(Assembly assembly, ParameterInfo param, HashSet processedTypes)
        {
            if (param == null)
            {
                return Enumerable.Empty();
            }

            return GetReferencedEnums(assembly, param.ParameterType, processedTypes);
        }
    }
}

Web Proxy Viewer  |  New URL  |  Original Page