Ejemplo n.º 1
0
        /// <summary>
        /// Converts the .NET type into the custom Code Gen type
        /// </summary>
        /// <param name="asmType"></param>
        /// <param name="valueTypeOnly">
        /// Will only export Fields and Properties whose base type extends System.ValueType
        /// </param>
        /// <param name="resolveDependencies">
        /// Switch to have the IL of the type parsed and all dependent calls Metadata tokens added.
        /// </param>
        /// <returns></returns>
        public static CgType GetCgOfType(this Type asmType, bool valueTypeOnly, bool resolveDependencies = false)
        {
            var cgType = new CgType();

            if (asmType == null || NfReflect.IsIgnoreType(asmType) || NfReflect.IsClrGeneratedType(asmType))
            {
                return(null);
            }

            //use the logic in TypeName to get the namespace and class name so its not tied to having the assembly
            var cgTypeName = new NfTypeName(asmType.AssemblyQualifiedName);

            //make sure there is always some kind of namespace
            cgType.Namespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace)
                ? asmType.Assembly.GetName().Name
                : cgTypeName.Namespace;
            cgType.IsContrivedNamespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace);
            cgType.Name = cgTypeName.ClassName;
            cgType.AssemblyQualifiedName = asmType.AssemblyQualifiedName;
            cgType.IsEnum = NfReflect.IsEnumType(asmType);

            var cgTypesInterfaces = asmType.GetInterfaces();

            cgType.MetadataToken = asmType.MetadataToken;

            Func <CgType, string, bool> alreadyPresentHerein =
                (cg, nextName) =>
                (cg.Properties.FirstOrDefault(
                     cgP => string.Equals(cgP.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null
                 ||
                 cg.Fields.FirstOrDefault(
                     cgF => string.Equals(cgF.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null
                 ||
                 cg.Events.FirstOrDefault(
                     cgE => string.Equals(cgE.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null)
            ;

            //have events go first since they tend to be speard across fields and properties
            foreach (
                var evtInfo in
                asmType.GetEvents(Shared.Core.NfSettings.DefaultFlags))
            {
                var evtHandlerType = evtInfo.NfEventHandlerType().ToString();

                var cgMem = new CgMember
                {
                    Name          = evtInfo.Name,
                    TypeName      = evtHandlerType,
                    MetadataToken = evtInfo.MetadataToken
                };
                cgType.Events.Add(cgMem);
            }

            var asmMembers =
                asmType.GetMembers(Shared.Core.NfSettings.DefaultFlags);

            foreach (var mi in asmMembers)
            {
                if (alreadyPresentHerein(cgType, mi.Name))
                {
                    continue;
                }

                try
                {
                    if (mi.MemberType == MemberTypes.Property)
                    {
                        var pi = mi as PropertyInfo;

                        var cgm = GetAsCgMember(pi, valueTypeOnly, cgType.EnumValueDictionary);
                        if (cgm == null)
                        {
                            continue;
                        }
                        if (resolveDependencies)
                        {
                            var propMi = NfReflect.GetMethodsForProperty(pi, asmType);
                            foreach (var pim in propMi)
                            {
                                cgm.opCodeCallsAndCallvirtsMetadatTokens.AddRange(Asm.GetCallsMetadataTokens(pim));
                            }
                        }
                        cgType.Properties.Add(cgm);
                    }
                }
                catch (Exception ex)
                {
                    Asm.AddLoaderExceptionToLog(null, ex);

                    if (!Settings.IgnoreReflectionMissingAsmError)
                    {
                        throw;
                    }

                    cgType.Properties.Add(new CgMember
                    {
                        Name      = mi.Name,
                        TypeName  = DF_TYPE_NAME,
                        HasGetter = true,
                        HasSetter = true,
                        SkipIt    = true
                    });
                }

                try
                {
                    if (mi.MemberType == MemberTypes.Event)
                    {
                        continue;//these have already been handled
                    }
                }
                catch (Exception ex)
                {
                    Asm.AddLoaderExceptionToLog(null, ex);
                    continue;
                }

                try
                {
                    if (mi.MemberType == MemberTypes.Field)
                    {
                        var fi  = mi as FieldInfo;
                        var cgm = GetAsCgMember(fi, valueTypeOnly, cgType.EnumValueDictionary);

                        if (cgm == null)
                        {
                            continue;
                        }
                        cgType.Fields.Add(cgm);
                    }
                }
                catch (Exception ex)
                {
                    Asm.AddLoaderExceptionToLog(null, ex);
                    if (!Settings.IgnoreReflectionMissingAsmError)
                    {
                        throw;
                    }

                    cgType.Fields.Add(new CgMember
                    {
                        Name     = mi.Name,
                        TypeName = DF_TYPE_NAME,
                        SkipIt   = true
                    });
                }
                try
                {
                    if (!valueTypeOnly && mi.MemberType == MemberTypes.Method)
                    {
                        var mti = mi as MethodInfo;
                        var cgm = GetAsCgMember(mti, resolveDependencies);

                        if (cgm == null)
                        {
                            continue;
                        }
                        cgm.IsInterfaceImpl = IsInterfaceImpl(mti, cgTypesInterfaces);
                        cgType.Methods.Add(cgm);
                    }

                    if (!valueTypeOnly && mi.MemberType == MemberTypes.Constructor)
                    {
                        var ci = mi as ConstructorInfo;
                        var tn = (string.IsNullOrWhiteSpace(cgTypeName.Namespace)
                            ? cgTypeName.ClassName
                            : $"{cgTypeName.Namespace}.{cgTypeName.ClassName}");

                        var cgm = GetAsCgMember(ci, tn, resolveDependencies);

                        if (cgm == null)
                        {
                            continue;
                        }
                        cgType.Methods.Add(cgm);
                    }
                }
                catch (Exception ex)
                {
                    Asm.AddLoaderExceptionToLog(null, ex);
                    if (!Settings.IgnoreReflectionMissingAsmError)
                    {
                        throw;
                    }

                    cgType.Methods.Add(new CgMember
                    {
                        Name     = mi.Name,
                        TypeName = DF_TYPE_NAME,
                        SkipIt   = true
                    });
                }
            }

            if (resolveDependencies)
            {
                ResolveAllMetadataTokens(cgType, asmType.Assembly.ManifestModule);
            }

            return(cgType);
        }