/// <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); }