Beispiel #1
0
        /// <summary>
        /// Gets the <see cref="FieldInfo"/> as a code gen member (<see cref="CgMember"/>)
        /// </summary>
        /// <param name="fi"></param>
        /// <param name="valueTypeOnly"></param>
        /// <param name="enumValueDictionary"></param>
        /// <returns></returns>
        public static CgMember GetAsCgMember(FieldInfo fi, bool valueTypeOnly,
                                             Dictionary <string, string[]> enumValueDictionary)
        {
            if (fi == null)
            {
                return(null);
            }

            if (NfReflect.IsClrGeneratedType(fi.Name))
            {
                return(null);
            }

            var fiType = fi.NfFieldType();

            if (valueTypeOnly && fiType.NfBaseType() != null && fiType.NfBaseType().Name != VALUE_TYPE)
            {
                return(null);
            }

            var cgMem = new CgMember
            {
                TypeName         = Settings.LangStyle.TransformClrTypeSyntax(fiType),
                IsEnumerableType = NfReflect.IsEnumerableReturnType(fiType),
                Name             = fi.Name,
                IsStatic         = fi.IsStatic,
                MetadataToken    = fi.MetadataToken
            };

            string[] enumVals;
            if (NfReflect.IsEnumType(fiType, out enumVals) && enumValueDictionary != null)
            {
                cgMem.IsEnum = true;
                var clearName = NfReflect.GetLastTypeNameFromArrayAndGeneric(cgMem.TypeName, "<");
                if (!enumValueDictionary.ContainsKey(clearName))
                {
                    enumValueDictionary.Add(clearName, enumVals);
                }
            }
            return(cgMem);
        }
Beispiel #2
0
        /// <summary>
        /// Gets a method as a code gen member type
        /// </summary>
        /// <param name="mti"></param>
        /// <param name="getCallvirtMetadataTokens"></param>
        /// <returns></returns>
        public static CgMember GetAsCgMember(MethodInfo mti, bool getCallvirtMetadataTokens = false)
        {
            if (mti == null)
            {
                return(null);
            }
            if (NfReflect.IsClrMethodForProperty(mti.Name, out _))
            {
                return(null);
            }
            if (NfReflect.IsClrGeneratedType(mti.Name))
            {
                //these appear as '<SomeNameOfMethodAlreadyAdded>b__kifkj(...)'
                return(null);
            }

            var miReturnType = mti.NfReturnType();

            var cgMem = new CgMember
            {
                Name             = mti.Name,
                TypeName         = Settings.LangStyle.TransformClrTypeSyntax(miReturnType),
                IsStatic         = mti.IsStatic,
                IsGeneric        = mti.IsGenericMethod,
                IsEnumerableType = NfReflect.IsEnumerableReturnType(miReturnType),
                IsMethod         = true,
                MetadataToken    = mti.MetadataToken
            };

            if (mti.IsAssembly)
            {
                cgMem.AccessModifier = CgAccessModifier.Assembly;
            }
            if (mti.IsFamily)
            {
                cgMem.AccessModifier = CgAccessModifier.Family;
            }
            if (mti.IsFamilyAndAssembly)
            {
                cgMem.AccessModifier = CgAccessModifier.FamilyAssembly;
            }
            if (mti.IsPrivate)
            {
                cgMem.AccessModifier = CgAccessModifier.Private;
            }
            if (mti.IsPublic)
            {
                cgMem.AccessModifier = CgAccessModifier.Public;
            }

            foreach (var parameterInfo in mti.GetParameters())
            {
                var paramType = parameterInfo.NfParameterType();
                var cgArg     = new CgArg
                {
                    ArgName = parameterInfo.Name,
                    ArgType = Settings.LangStyle.TransformClrTypeSyntax(paramType)
                };

                cgMem.Args.Add(cgArg);
            }
            cgMem.MethodBodyIL = Convert.ToBase64String(Asm.GetMethodBody(mti));

            if (!getCallvirtMetadataTokens)
            {
                return(cgMem);
            }

            cgMem.opCodeCallsAndCallvirtsMetadatTokens.AddRange(Asm.GetCallsMetadataTokens(mti));
            return(cgMem);
        }
Beispiel #3
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);
        }