private bool Equals(TypeInstance <T> other)
        {
            if (ReferenceEquals(null, other))
            {
                return(false);
            }

            if (ReferenceEquals(this, other))
            {
                return(true);
            }

            return(Equals(Type, other.Type) && GenericArguments.SequenceEqual(other.GenericArguments) &&
                   Equals(IsArray, other.IsArray) && ArrayDimensions.SequenceEqual(other.ArrayDimensions));
        }
Example #2
0
        private ITypeInstance <IType> CreateTypeFromTypeReference(TypeReference typeReference, bool isStub)
        {
            if (typeReference.IsGenericParameter)
            {
                var genericParameter      = (Mono.Cecil.GenericParameter)typeReference;
                var declarerIsMethod      = genericParameter.Type == GenericParameterType.Method;
                var declaringTypeFullName = declarerIsMethod
                    ? genericParameter.DeclaringMethod.BuildFullName()
                    : genericParameter.DeclaringType.BuildFullName();

                return(new TypeInstance <GenericParameter>(CreateGenericParameter(genericParameter,
                                                                                  declaringTypeFullName,
                                                                                  declarerIsMethod)));
            }

            if (typeReference.IsArray)
            {
                var dimensions = new List <int>();
                do
                {
                    var arrayType = (ArrayType)typeReference;
                    dimensions.Add(arrayType.Rank);
                    typeReference = arrayType.ElementType;
                } while (typeReference.IsArray);

                var elementTypeInstance = GetOrCreateStubTypeInstanceFromTypeReference(typeReference);
                switch (elementTypeInstance.Type)
                {
                case Interface intf:
                    return(new TypeInstance <Interface>(intf, elementTypeInstance.GenericArguments, dimensions));

                case Attribute att:
                    return(new TypeInstance <Attribute>(att, elementTypeInstance.GenericArguments, dimensions));

                case Class cls:
                    return(new TypeInstance <Class>(cls, elementTypeInstance.GenericArguments, dimensions));

                default:
                    return(new TypeInstance <IType>(elementTypeInstance.Type, elementTypeInstance.GenericArguments,
                                                    dimensions));
                }
            }

            if (typeReference.IsGenericInstance)
            {
                var elementType      = GetOrCreateStubTypeInstanceFromTypeReference(typeReference.GetElementType()).Type;
                var genericInstance  = (GenericInstanceType)typeReference;
                var genericArguments = genericInstance.GenericArguments
                                       .Select(CreateGenericArgumentFromTypeReference)
                                       .Where(argument => !argument.Type.IsCompilerGenerated);
                switch (elementType)
                {
                case Interface intf:
                    return(new TypeInstance <Interface>(intf, genericArguments));

                case Attribute att:
                    return(new TypeInstance <Attribute>(att, genericArguments));

                case Class cls:
                    return(new TypeInstance <Class>(cls, genericArguments));

                default:
                    return(new TypeInstance <IType>(elementType, genericArguments));
                }
            }


            TypeDefinition typeDefinition;

            try
            {
                typeDefinition = typeReference.Resolve();
            }
            catch (AssemblyResolutionException)
            {
                typeDefinition = null;
            }

            var typeName         = typeReference.BuildFullName();
            var currentNamespace = _namespaceRegistry.GetOrCreateNamespace(typeReference.IsNested
                ? typeReference.DeclaringType.Namespace
                : typeReference.Namespace);
            var currentAssembly = _assemblyRegistry.GetOrCreateAssembly(typeReference.Module.Assembly.Name.FullName,
                                                                        typeReference.Module.Assembly.FullName, true);

            Type type;
            bool isCompilerGenerated, isNested, isGeneric;

            if (typeDefinition == null)
            {
                isCompilerGenerated = typeReference.IsCompilerGenerated();
                isNested            = typeReference.IsNested;
                isGeneric           = typeReference.HasGenericParameters;
                type = new Type(typeName, typeReference.Name, currentAssembly, currentNamespace, NotAccessible,
                                isNested, isGeneric, true, isCompilerGenerated);

                return(new TypeInstance <Class>(new Class(type)));
            }

            var visibility = typeDefinition.GetVisibility();

            isCompilerGenerated = typeDefinition.IsCompilerGenerated();
            isNested            = typeDefinition.IsNested;
            isGeneric           = typeDefinition.HasGenericParameters;
            type = new Type(typeName, typeReference.Name, currentAssembly, currentNamespace, visibility, isNested,
                            isGeneric, isStub, isCompilerGenerated);

            var genericParameters = GetGenericParameters(typeDefinition);

            type.GenericParameters.AddRange(genericParameters);

            ITypeInstance <IType> createdTypeInstance;
            var isInterface = typeDefinition.IsInterface;

            if (typeDefinition.IsInterface)
            {
                createdTypeInstance = new TypeInstance <Interface>(new Interface(type));
            }
            else
            {
                if (typeDefinition.IsAttribute())
                {
                    createdTypeInstance =
                        new TypeInstance <Attribute>(new Attribute(type, typeDefinition.IsAbstract,
                                                                   typeDefinition.IsSealed));
                }
                else
                {
                    createdTypeInstance = new TypeInstance <Class>(new Class(type, typeDefinition.IsAbstract,
                                                                             typeDefinition.IsSealed, typeDefinition.IsValueType, typeDefinition.IsEnum));
                }
            }

            if (!isStub && !isCompilerGenerated)
            {
                if (!isInterface)
                {
                    LoadBaseTask((Class)createdTypeInstance.Type, type, typeDefinition);
                }

                LoadNonBaseTasks(createdTypeInstance.Type, type, typeDefinition);
            }

            return(createdTypeInstance);
        }