public FlattenedItem(Type flType) { FlType = flType; IsEnumerable = NfReflect.IsEnumerableReturnType(flType); TypeFullName = NfReflect.GetLastTypeNameFromArrayAndGeneric(flType); MetadataToken = flType?.MetadataToken ?? 0; }
/// <summary> /// Returns string specific to graph-viz (ver. 2.38+) /// see [http://www.graphviz.org/] /// </summary> /// <returns></returns> public static string ToGraphVizString(this CgMember cgMem) { var graphViz = new StringBuilder(); graphViz.Append("<tr><td align=\"left\">"); graphViz.Append(cgMem.Name); graphViz.Append(" "); var typeColor = Etc.ValueTypesList.Contains(NfReflect.GetLastTypeNameFromArrayAndGeneric(cgMem.TypeName.Trim(), "<")) ? "blue" : "grey"; if (cgMem.HasGetter || cgMem.HasSetter) { graphViz.Append("("); graphViz.Append(string.Join(", ", cgMem.Args.Select(x => x.ToGraphVizString()))); graphViz.Append(")"); } graphViz.Append(": <font color=\""); graphViz.Append(typeColor); graphViz.Append("\">"); graphViz.Append(NfReflect.GetLastTypeNameFromArrayAndGeneric(cgMem.TypeName, "<")); if (cgMem.IsEnumerableType) { graphViz.Append("[*]"); } graphViz.Append("</font></td></tr>"); return(graphViz.ToString()); }
/// <summary> /// Returns edge definitions specific to graph-viz (ver. 2.38+) /// see [http://www.graphviz.org/] /// </summary> /// <returns></returns> public static string ToGraphVizEdge(this CgType cgType) { var graphViz = new StringBuilder(); var myName = NfString.SafeDotNetIdentifier(cgType.FullName); var edges = new List <string>(); foreach ( var property in cgType.Properties.Where( x => !Etc.ValueTypesList.Contains(NfReflect.GetLastTypeNameFromArrayAndGeneric(x.TypeName, "<"))) ) { var toName = NfString.SafeDotNetIdentifier(NfReflect.GetLastTypeNameFromArrayAndGeneric(property.TypeName, "<")); var edg = new StringBuilder(); edg.AppendFormat("{0} -> {1}", myName, toName); edg.Append(property.IsEnumerableType ? " [arrowhead=odiamond]" : " [arrowhead=vee]"); edg.Append(";"); if (!edges.Contains(edg.ToString())) { edges.Add(edg.ToString()); } } foreach (var edge in edges) { graphViz.AppendLine(edge); } return(graphViz.ToString()); }
/// <summary> /// Returns the field's names of the <see cref="enumTypeName"/> /// being that such an enum was encountered while reflecting the type. /// </summary> /// <param name="enumTypeName"></param> /// <returns></returns> public string[] EnumsValues(string enumTypeName) { if (string.IsNullOrWhiteSpace(enumTypeName)) { return(null); } var vals = EnumValueDictionary.ContainsKey(enumTypeName) ? EnumValueDictionary[enumTypeName] : null; if (vals != null) { return(vals); } var clearName = NfReflect.GetLastTypeNameFromArrayAndGeneric(enumTypeName); vals = EnumValueDictionary.ContainsKey(clearName) ? EnumValueDictionary[clearName] : null; if (vals != null) { return(vals); } //try one last time for cs style generics clearName = NfReflect.GetLastTypeNameFromArrayAndGeneric(enumTypeName, "<"); vals = EnumValueDictionary.ContainsKey(clearName) ? EnumValueDictionary[clearName] : null; return(vals); }
public void TestGetTypeNameFromArrayAndGeneric() { var testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("int[]"); Assert.AreEqual("int", testResult); testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("System.Collections.Generic.List`1[System.String]"); Assert.AreEqual("System.String", testResult); testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("System.Tuple`2[System.Int32,System.String]"); Assert.AreEqual("System.Int32", testResult); testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("System.Tuple`2[System.Collections.Generic.List`1[SomeNamespace.AType],System.String]"); Assert.AreEqual("SomeNamespace.AType", testResult); //test C# style testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric( "System.Collections.Generic.List<System.String>", "<"); Assert.AreEqual("System.String", testResult); testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("System.Tuple<System.Int32, System.String>", "<"); Assert.AreEqual("System.Int32", testResult); testResult = NfReflect.GetLastTypeNameFromArrayAndGeneric("System.Tuple<System.Collections.Generic.List<SomeNamespace.AType>,System.String>", "<"); Assert.AreEqual("SomeNamespace.AType", testResult); var testResults = NfReflect.GetTypeNamesFromGeneric( "System.Tuple`3[System.Collections.Generic.List`1[System.String], System.String, System.Tuple`2[System.Int32, System.String]]"); Console.WriteLine(string.Join(" | ", testResults)); }
/// <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); }
/// <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); }
public void CopyFrom(System.Data.DataColumn col) { if (!string.IsNullOrWhiteSpace(col.ColumnName)) { column_name = col.ColumnName; } if (col.Ordinal > 0) { column_ordinal = col.Ordinal; } if (col.DataType != null && !string.IsNullOrWhiteSpace(col.DataType.FullName)) { data_type = NfReflect.GetLastTypeNameFromArrayAndGeneric(col.DataType.FullName); if (data_type == "System.String") { string_length = Globals.MSSQL_MAX_VARCHAR; } } is_auto_increment = col.AutoIncrement; is_nullable = col.AllowDBNull; }
/// <summary> /// Assigns property values on the <see cref="rtInstance"/> from /// the x-ref data source. /// </summary> /// <param name="elem"></param> /// <param name="rtInstance"></param> public static void SetTypeXrefValue(XmlElement elem, object rtInstance) { var nameAttr = elem.Attributes[NAME]; if (string.IsNullOrWhiteSpace(nameAttr?.Value)) { return; } if (rtInstance == null) { return; } var propertyName = nameAttr.Value; var pi = rtInstance.GetType().GetProperty(propertyName); if (pi == null || !pi.CanWrite) { return; } var valueAttr = elem.Attributes[VALUE]; if (!string.IsNullOrWhiteSpace(valueAttr?.Value)) { pi.SetValue(rtInstance, valueAttr.Value, null); return; } if (!elem.HasChildNodes || pi == null) { return; } var piType = pi.PropertyType; var propertyInstance = Activator.CreateInstance(piType); //expecting the type to have a getter and setter of generic List<T> if (NfReflect.IsEnumerableReturnType(piType)) { var addMi = piType.GetMethod("Add"); if (addMi == null) { return; } var enumerableTypeName = NfReflect.GetLastTypeNameFromArrayAndGeneric(piType); if (string.IsNullOrWhiteSpace(enumerableTypeName)) { return; } var asm = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetType(enumerableTypeName) != null); if (asm == null) { return; } var enumerableType = asm.GetType(enumerableTypeName); if (enumerableType == null) { return; } var enumerableInstance = Activator.CreateInstance(enumerableType); foreach (var cNode in elem.ChildNodes) { var cElem = cNode as XmlElement; if (cElem == null) { continue; } SetTypeXrefValue(cElem, enumerableInstance); } addMi.Invoke(propertyInstance, new[] { enumerableInstance }); } else//no generic type { foreach (var cNode in elem.ChildNodes) { var cElem = cNode as XmlElement; if (cElem == null) { continue; } SetTypeXrefValue(cElem, propertyInstance); } } pi.SetValue(rtInstance, propertyInstance, null); }
/// <summary> /// Dumps an entire assembly into a list of <see cref="FlattenedLine"/> /// </summary> /// <param name="fla"></param> /// <param name="writeProgress">Optional handler to write progress for the calling assembly.</param> /// <returns></returns> public static FlattenAssembly GetFlattenedAssembly(FlattenLineArgs fla, Action <ProgressMessage> writeProgress = null) { if (fla == null) { throw new ArgumentNullException(nameof(fla)); } if (fla.Assembly == null) { throw new ArgumentException("The Assembly reference must be passed in " + "with the FlattenLineArgs"); } writeProgress?.Invoke(new ProgressMessage { Activity = "Getting all types from assembly", ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = 1, Status = "OK" }); var allTypeNames = fla.Assembly.NfGetTypes().Select(x => x.FullName).ToList(); var allLines = new List <FlattenedLine>(); var counter = 0; var total = allTypeNames.Count; foreach (var t in allTypeNames) { writeProgress?.Invoke(new ProgressMessage { Activity = t, ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Working Type Names" }); var flattenArgs = new FlattenTypeArgs { Assembly = fla.Assembly, TypeFullName = t, Depth = fla.Depth, Separator = fla.Separator, UseTypeNames = fla.UseTypeNames, LimitOnThisType = fla.LimitOnThisType }; var flattenedType = FlattenType(flattenArgs); foreach (var line in flattenedType.Lines.Where(x => !string.IsNullOrWhiteSpace(x.ValueType))) { //if there is a limit on some type and this line is that type in any form then continue if (!string.IsNullOrWhiteSpace(fla.LimitOnThisType) && !string.Equals(fla.LimitOnThisType, line.ValueType, StringComparison.OrdinalIgnoreCase) && !string.Equals(fla.LimitOnThisType, NfReflect.GetLastTypeNameFromArrayAndGeneric(line.ValueType), StringComparison.OrdinalIgnoreCase)) { continue; } if (allLines.Any(x => x.Equals(line))) { continue; } allLines.Add(line); } counter += 1; } return(new FlattenAssembly { AllLines = allLines, AssemblyName = fla.Assembly.GetName().FullName }); }
//[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); }