示例#1
0
        public static TypeReference GetChildrenType(this ModuleDefinition module, TypeReference type)
        {
            if (type.IsArray)
                return type.GetElementType();

            var getIEnumerableInterfaceChild = new Func<TypeReference, TypeReference>(typeReference =>
            {
                if (typeReference.IsGenericInstance)
                {
                    var genericType = typeReference as GenericInstanceType;

                    if (genericType != null)
                    {
                        var genericInstances = genericType.GetGenericInstances();

                        // We have to make some exceptions to dictionaries
                        var ienumerableInterface = genericInstances.FirstOrDefault(x => x.FullName.StartsWith("System.Collections.Generic.IDictionary`2<"));

                        // If we have more than 1 generic argument then we try to get a IEnumerable<>
                        // interface otherwise we just return the last argument in the list
                        if (ienumerableInterface == null)
                            ienumerableInterface = genericInstances.FirstOrDefault(x => x.FullName.StartsWith("System.Collections.Generic.IEnumerable`1<"));

                        // We just don't know :(
                        if (ienumerableInterface == null)
                            return module.ImportReference(typeof(object));

                        return (ienumerableInterface as GenericInstanceType).GenericArguments[0];
                    }
                }

                return null;
            });

            var result = getIEnumerableInterfaceChild(type);

            if (result != null)
                return result;

            // This might be a type that inherits from list<> or something... lets find out
            if (type.BetterResolve().GetInterfaces().Any(x => x.FullName == "System.Collections.Generic.IEnumerable`1"))
            {
                // if this is the case we will dig until we find a generic instance type
                var baseType = type.BetterResolve().BaseType;

                while (baseType != null)
                {
                    result = getIEnumerableInterfaceChild(baseType);

                    if (result != null)
                        return result;

                    baseType = baseType.BetterResolve().BaseType;
                };
            }

            return module.ImportReference(typeof(object));
        }
示例#2
0
        private static IEnumerable <TypeReference> GetGenericInstances(this TypeReference type, string[] genericArgumentNames, TypeReference[] genericArgumentsOfCurrentType)
        {
            var resolvedBase = type.BetterResolve();

            if (resolvedBase.HasGenericParameters)
            {
                var genericArguments = new List <TypeReference>();

                foreach (var arg in (type as GenericInstanceType).GenericArguments)
                {
                    var t = genericArgumentNames.FirstOrDefault(x => x == arg.FullName);

                    if (t == null)
                    {
                        genericArguments.Add(arg);
                    }
                    else
                    {
                        genericArguments.Add(genericArgumentsOfCurrentType[Array.IndexOf(genericArgumentNames, t)]);
                    }
                }

                var genericType = resolvedBase.MakeGenericInstanceType(genericArguments.ToArray());
                return(genericType.GetGenericInstances());
            }

            return(new TypeReference[0]);
        }
示例#3
0
 internal BuilderType(BuilderType builderType, TypeReference typeReference) : base(builderType)
 {
     this.IsByReference  = typeReference.IsByReference;
     this.typeReference  = typeReference;
     this.typeDefinition = typeReference.BetterResolve();
     this.Builder        = builderType.Builder;
 }
示例#4
0
        public static IEnumerable<TypeReference> GetInterfaces(this TypeReference type)
        {
            var typeDef = type.BetterResolve();
            var result = new List<TypeReference>();

            while (true)
            {
                if (typeDef == null)
                    break;

                try
                {
                    if (typeDef.BaseType == null && (typeDef.Interfaces == null || typeDef.Interfaces.Count == 0))
                        break;

                    if (typeDef.Interfaces != null && typeDef.Interfaces.Count > 0)
                        result.AddRange(type.Recursive(x => x.BetterResolve().Interfaces.Select(y => y.InterfaceType)).Select(x => x.ResolveType(type)));

                    type = typeDef.BaseType;

                    typeDef = type?.BetterResolve();
                }
                catch
                {
                    break;
                }
            };

            return result;
        }
示例#5
0
        private static void GetMethodReferences(TypeReference typeToInspect, List <MethodReference> result, bool byInterfaces)
        {
            if (typeToInspect == null)
            {
                return;
            }

            if (typeToInspect.IsGenericInstance)
            {
                var genericType = typeToInspect as GenericInstanceType;
                if (genericType != null)
                {
                    var instances = genericType.GetGenericInstances().Where(x => (!x.BetterResolve().IsInterface || byInterfaces));
                    foreach (var item in instances)
                    {
                        var methods = item.BetterResolve().Methods.Select(x => x.MakeHostInstanceGeneric((item as GenericInstanceType).GenericArguments.ToArray()));

                        if (methods != null || methods.Any())
                        {
                            result.AddRange(methods);
                        }
                    }
                }
            }
            else
            {
                var methods = typeToInspect.BetterResolve().Methods;
                if (methods != null || methods.Count > 0)
                {
                    result.AddRange(methods);
                }
            }

            var typeReference = typeToInspect.BetterResolve();

            if (byInterfaces)
            {
                for (int i = 0; i < typeReference.Interfaces.Count; i++)
                {
                    GetMethodReferences(typeReference.Interfaces[i].InterfaceType, result, true);
                }
            }
            else if (typeReference.BaseType != null)
            {
                GetMethodReferences(typeReference.BaseType, result, false);
            }
        }
示例#6
0
        public static IEnumerable<TypeReference> GetBaseClasses(this TypeReference type)
        {
            var typeDef = type.BetterResolve();

            if (typeDef != null && typeDef.BaseType != null)
            {
                yield return typeDef.BaseType;
                foreach (var item in GetBaseClasses(typeDef.BaseType))
                    yield return item;
            }
        }
示例#7
0
        public static MethodReference GetMethodReference(this TypeReference type, string methodName, Type[] parameterTypes)
        {
            var definition = type.BetterResolve();
            var result = definition
                .Methods
                .FirstOrDefault(x => x.Name == methodName && parameterTypes.Select(y => y.FullName).SequenceEqual(x.Parameters.Select(y => y.ParameterType.FullName)));

            if (result != null)
                return result;

            throw new Exception($"Unable to proceed. The type '{type.FullName}' does not contain a method '{methodName}'");
        }
示例#8
0
        public static MethodReference GetMethodReference(this TypeReference type, string methodName, int parameterCount)
        {
            var definition = type.BetterResolve();
            var result = definition
                .Methods
                .FirstOrDefault(x => x.Name == methodName && x.Parameters.Count == parameterCount);

            if (result != null)
                return result;

            throw new Exception($"Unable to proceed. The type '{type.FullName}' does not contain a method '{methodName}'");
        }
示例#9
0
        public static IEnumerable<TypeReference> GetNestedTypes(this TypeReference type)
        {
            var typeDef = type.BetterResolve();

            if (typeDef == null)
                return new TypeReference[0];

            if (typeDef.NestedTypes != null && typeDef.NestedTypes.Count > 0)
                return type.Recursive(x => x.BetterResolve().NestedTypes).Select(x => x.ResolveType(type));

            if (typeDef.BaseType != null)
                return GetNestedTypes(typeDef.BaseType);

            return new TypeReference[0];
        }
示例#10
0
 internal static bool IsDelegate(this TypeReference typeReference) => typeReference.BetterResolve().IsDelegate();
示例#11
0
 public static bool IsAssignableFrom(this TypeReference target, TypeReference source) =>
 target == source ||
 target == source ||
 source.IsSubclassOf(target) ||
 target.BetterResolve().IsInterface&& source.GetBaseClasses().Any(x => x.Implements(target.FullName));
示例#12
0
        private static IEnumerable <TypeDeclaringType> GetTypeReference(TypeReference typeReference)
        {
            var typeDefinition = typeReference.BetterResolve() ?? typeReference as TypeDefinition;

            yield return(new TypeDeclaringType(typeReference, typeReference));

            foreach (var item in typeDefinition.CustomAttributes)
            {
                yield return(new TypeDeclaringType(typeReference, item.AttributeType));
            }

            foreach (var field in typeDefinition.Fields)
            {
                foreach (var item in field.CustomAttributes)
                {
                    yield return(new TypeDeclaringType(typeReference, item.AttributeType));
                }

                yield return(new TypeDeclaringType(typeReference, field.FieldType));
            }

            foreach (var property in typeDefinition.Properties)
            {
                foreach (var item in property.CustomAttributes)
                {
                    yield return(new TypeDeclaringType(typeReference, item.AttributeType));
                }

                yield return(new TypeDeclaringType(typeReference, property.PropertyType));
            }

            foreach (var method in typeDefinition.Methods)
            {
                foreach (var item in method.CustomAttributes)
                {
                    yield return(new TypeDeclaringType(typeReference, item.AttributeType));

                    foreach (var @param in item.ConstructorArguments.Where(x => x.Value is TypeReference))
                    {
                        yield return(new TypeDeclaringType(typeReference, param.Value as TypeReference));
                    }

                    foreach (var @param in item.Fields.Where(x => x.Argument.Value is TypeReference))
                    {
                        yield return(new TypeDeclaringType(typeReference, param.Argument.Value as TypeReference));
                    }

                    foreach (var @param in item.Properties.Where(x => x.Argument.Value is TypeReference))
                    {
                        yield return(new TypeDeclaringType(typeReference, param.Argument.Value as TypeReference));
                    }
                }

                if (method.ReturnType.FullName != "System.Void")
                {
                    yield return(new TypeDeclaringType(typeReference, method.ReturnType));
                }

                foreach (var item in method.Parameters)
                {
                    yield return(new TypeDeclaringType(typeReference, item.ParameterType));
                }

                foreach (var item in method.GenericParameters)
                {
                    yield return(new TypeDeclaringType(typeReference, item));
                }
            }

            foreach (var @event in typeDefinition.Events)
            {
                foreach (var item in @event.CustomAttributes)
                {
                    yield return(new TypeDeclaringType(typeReference, item.AttributeType));
                }

                yield return(new TypeDeclaringType(typeReference, @event.EventType));
            }
        }
示例#13
0
        public static bool IsUsed(TypeReference typeReference)
        {
            var declaringType = typeReference.BetterResolve();

            return
                (Types
                 .Any(x =>
            {
                if (x.declaringType.AreEqual(typeReference))
                {
                    return false;
                }

                if (x.typeReference.AreEqual(typeReference))
                {
                    if (declaringType.HasNestedTypes && x.declaringType.IsNested)
                    {
                        return false;
                    }

                    return true;
                }

                return false;
            })
                 ||
                 declaringType
                 .Methods
                 .SelectMany(methodDefinition => Bucket
                             .Where(x =>
            {
                if (x == null)
                {
                    return false;
                }

                if (methodDefinition == null)
                {
                    return false;
                }

                if (x.instruction.OpCode != OpCodes.Call && x.instruction.OpCode != OpCodes.Callvirt && x.instruction.OpCode == OpCodes.Newobj)
                {
                    return false;
                }

                if (x.instruction.Operand == null)
                {
                    return false;
                }

                if (x.method.DeclaringType.AreEqual(typeReference))
                {
                    return false;
                }

                var value = (x.instruction.Operand as MethodReference)?.BetterResolve();

                if (value == null)
                {
                    return false;
                }

                return value.AreEqual(methodDefinition);
            }))
                 .Any());
        }