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

            var piType = pi.NfPropertyType();

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

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

            if (pi.CanRead)
            {
                cgMem.HasGetter = true;
                if (pi.NfGetGetMethod() != null)
                {
                    cgMem.IsStatic = pi.NfGetGetMethod().IsStatic;
                }
            }

            if (pi.CanWrite)
            {
                cgMem.HasSetter = true;
                if (pi.NfGetSetMethod() != null)
                {
                    cgMem.IsStatic = pi.NfGetSetMethod().IsStatic;
                }
            }

            string[] enumVals;
            if (NfReflect.IsEnumType(piType, 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 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 #3
0
        public AsmDiagram(Assembly asm, bool withNamespaceSubGraphs = false)
        {
            if (asm == null)
            {
                throw new ArgumentNullException(nameof(asm));
            }

            _targetedNs = asm.GetName().Name;

            _withNsSubgraphs = withNamespaceSubGraphs;
            _asmName         = NfString.SafeDotNetIdentifier(asm.GetName().Name);
            foreach (
                var asmType in
                asm.NfGetExportedTypes()
                .Where(x => !string.IsNullOrWhiteSpace(x.Namespace) &&
                       AssemblyName.ReferenceMatchesDefinition(asm.GetName(), x.Assembly.GetName())))
            {
                var item1 = new FlattenedItem(asmType)
                {
                    FlName = asmType.Name
                };
                if (item1.IsTerminalNode || NfReflect.IsEnumType(asmType))
                {
                    continue;
                }

                foreach (
                    var p in
                    asmType.NfGetProperties(NfSettings.DefaultFlags, false)
                    .Where(
                        x => x != null &&
                        !string.IsNullOrWhiteSpace(x.NfPropertyType(false)?.Namespace) &&
                        AssemblyName.ReferenceMatchesDefinition(x.NfPropertyType(false)?.Assembly.GetName(), asm.GetName()))
                    )
                {
                    if (NfReflect.IsEnumType(p.PropertyType))
                    {
                        continue;
                    }
                    var item2 = new FlattenedItem(p.PropertyType)
                    {
                        FlName = p.Name
                    };
                    if (item2.IsTerminalNode)
                    {
                        continue;
                    }
                    var tupleOfItems = new Tuple <FlattenedItem, FlattenedItem>(item1, item2);
                    var itemEv       = new AsmDiagramEdge(tupleOfItems);
                    if (Edges.Any(x => x.AreSame(itemEv)))
                    {
                        continue;
                    }
                    Edges.Add(itemEv);
                }
            }

            Edges = RemoveDuplicates(Edges);

            var names   = Edges.SelectMany(x => x.NodeName).ToList();
            var uqNames = names.Distinct().OrderBy(x => x).ToList();

            _nodes = uqNames.Select(x => new AsmDiagramNode(x, GetCountOfEdgesOn(x))).ToList();

            if (_withNsSubgraphs)
            {
                var uqNamespaces = _nodes.Select(x => x.NodeNamespace).Distinct().ToList();
                foreach (var ns in uqNamespaces)
                {
                    _nsSubGraphs.Add(new AsmDiagramSubGraph(ns, _nodes));
                }
            }
        }
Beispiel #4
0
        //[EditorBrowsable(EditorBrowsableState.Never)]
        public static List <FlattenedLine> FlattenType(Assembly assembly, string typeFullName,
                                                       ref int currentDepth, int maxDepth, string limitOnValueType, bool displayEnums, Stack <FlattenedItem> fiValueTypes, Stack typeStack)
        {
            var printList = new List <FlattenedLine>();

            if (string.IsNullOrWhiteSpace(typeFullName))
            {
                return(printList);
            }

            Func <PropertyInfo, string, bool> limitOnPi =
                (info, s) =>
                string.IsNullOrWhiteSpace(s) ||
                string.Equals($"{info.PropertyType}", s, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(NfReflect.GetLastTypeNameFromArrayAndGeneric(info.PropertyType), s,
                              StringComparison.OrdinalIgnoreCase) ||
                (s == Constants.ENUM && NfReflect.IsEnumType(info.PropertyType));

            var currentType = assembly.NfGetType(typeFullName);

            if (currentType == null)
            {
                return(printList);
            }

            //top frame of recursive calls will perform this
            if (fiValueTypes == null)
            {
                if (maxDepth <= 0)
                {
                    maxDepth = 16;
                }
                typeStack = new Stack();
                typeStack.Push(typeFullName);
                fiValueTypes = new Stack <FlattenedItem>();
                fiValueTypes.Push(new FlattenedItem(currentType)
                {
                    FlName = NfReflect.GetTypeNameWithoutNamespace(typeFullName)
                });
            }

            var typeNamesList =
                currentType.GetProperties(NfSettings.DefaultFlags)
                .Where(
                    x =>
                    (NfReflect.IsValueTypeProperty(x) && limitOnPi(x, limitOnValueType) ||
                     (limitOnValueType == Constants.ENUM && limitOnPi(x, limitOnValueType)))
                    //more limbo branching for enums
                    )
                .Select(p => new Tuple <Type, string>(p.PropertyType, p.Name))
                .ToList();


            foreach (var typeNamePair in typeNamesList)
            {
                var pVtype = typeNamePair.Item1;
                var pVname = typeNamePair.Item2;

                fiValueTypes.Push(new FlattenedItem(pVtype)
                {
                    FlName = pVname
                });
                var fiItems = fiValueTypes.ToList();
                fiItems.Reverse();
                printList.Add(new FlattenedLine(fiItems.Distinct(new FlattenedItemComparer()).ToList())
                {
                    ValueType = $"{typeNamePair.Item1}"
                });
                fiValueTypes.Pop();
            }

            //then recurse the object types
            foreach (
                var p in
                currentType.GetProperties(NfSettings.DefaultFlags)
                .Where(x => !NfReflect.IsValueTypeProperty(x)))
            {
                currentDepth += 1;

                //time to go
                if (currentDepth >= maxDepth)
                {
                    return(printList);
                }

                var typeIn = NfReflect.GetLastTypeNameFromArrayAndGeneric(p.PropertyType);

                if (typeIn == null || typeStack.Contains(typeIn))
                {
                    continue;
                }

                var fi = new FlattenedItem(p.PropertyType)
                {
                    FlName = p.Name
                };
                if (fiValueTypes.ToList().Any(x => x.FlType == p.PropertyType))
                {
                    continue;
                }

                fiValueTypes.Push(fi);
                typeStack.Push(typeIn);

                //enum types being handled as limbo between value type and ref type
                string[] enumVals;
                if (displayEnums && NfReflect.IsEnumType(p.PropertyType, out enumVals))
                {
                    foreach (var ev in enumVals)
                    {
                        fiValueTypes.Push(new FlattenedItem(typeof(Enum))
                        {
                            FlName = ev
                        });
                        var fiItems = fiValueTypes.ToList();
                        fiItems.Reverse();
                        printList.Add(new FlattenedLine(fiItems.Distinct(new FlattenedItemComparer()).ToList())
                        {
                            ValueType = String.Empty
                        });
                        fiValueTypes.Pop();
                    }
                }
                else
                {
                    printList.AddRange(FlattenType(assembly, fi.TypeFullName, ref currentDepth, maxDepth,
                                                   limitOnValueType, displayEnums, fiValueTypes, typeStack));
                }

                fiValueTypes.Pop();
                typeStack.Pop();
                currentDepth -= 1;
            }
            return(printList);
        }
Beispiel #5
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);
        }