public static string Description(this MemberInfo member, bool addTypeDescription = true) { if (member == null) { Compute.RecordWarning("Cannot query the description of a null member info object. An empty string will be returned instead."); return(""); } DescriptionAttribute descriptionAttribute = member.GetCustomAttribute <DescriptionAttribute>(); InputClassificationAttribute classification = member.GetCustomAttribute <InputClassificationAttribute>(); string desc = ""; if (descriptionAttribute != null && !string.IsNullOrWhiteSpace(descriptionAttribute.Description)) { desc = descriptionAttribute.Description + Environment.NewLine; } if (addTypeDescription && member is PropertyInfo && (typeof(IObject).IsAssignableFrom(((PropertyInfo)member).PropertyType))) { desc += ((PropertyInfo)member).PropertyType.Description(classification) + Environment.NewLine; } return(desc); }
/***************************************************/ public static Dictionary <string, object> PropertyDictionary(this CustomObject obj) { if (obj == null) { Compute.RecordWarning("Cannot query the property dictionary of a null custom object. An empty dictionary will be returned."); return(new Dictionary <string, object>()); } Dictionary <string, object> dic = new Dictionary <string, object>(obj.CustomData); if (!dic.ContainsKey("Name")) { dic["Name"] = obj.Name; } if (!dic.ContainsKey("BHoM_Guid")) { dic["BHoM_Guid"] = obj.BHoM_Guid; } if (!dic.ContainsKey("Tags")) { dic["Tags"] = obj.Tags; } return(dic); }
public static object PropertyValue(this object obj, string propName) { if (obj == null || propName == null) { return(null); } if (propName.Contains(".")) { string[] props = propName.Split('.'); foreach (string innerProp in props) { obj = obj.PropertyValue(innerProp); if (obj == null) { break; } } return(obj); } System.Reflection.PropertyInfo prop = obj.GetType().GetProperty(propName); if (prop != null) { return(prop.GetValue(obj)); } else if (obj is IBHoMObject) { IBHoMObject bhom = obj as IBHoMObject; if (bhom.CustomData.ContainsKey(propName)) { Compute.RecordNote($"{propName} is stored in CustomData"); return(bhom.CustomData[propName]); } else { Compute.RecordWarning($"{bhom} does not contain a property: {propName}, or: CustomData[{propName}]"); return(null); } } else if (obj is IDictionary) { IDictionary dic = obj as IDictionary; if (dic.Contains(propName)) { return(dic[propName]); } else { Compute.RecordWarning($"{dic} does not contain the key: {propName}"); return(null); } } else { Compute.RecordWarning($"This instance of {obj.GetType()} does not contain the property: {propName}"); return(null); } }
/***************************************************/ public static List <Type> PropertyTypes(this Type type, bool goDeep = false) { if (type == null) { Compute.RecordWarning("Cannot query the property types of a null type. An empty list of types will be returned."); return(new List <Type>()); } HashSet <Type> properties = new HashSet <Type>(); foreach (var prop in type.GetProperties()) { if (!prop.CanRead || prop.GetMethod.GetParameters().Count() > 0) { continue; } properties.Add(prop.PropertyType); if (goDeep) { foreach (Type t in prop.PropertyType.PropertyObjects(true)) { properties.Add(t); } } } return(properties.ToList()); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <string> SplitByIndices(string text, List <int> indices) { if (text == null) { Compute.RecordError("Cannot split a null string."); return(new List <string>()); } if (indices == null) { Compute.RecordWarning("The 'indices' input is null and was replaced by an empty list"); indices = new List <int>(); } int previousIndex = 0; List <string> result = new List <string>(); foreach (int index in indices.OrderBy(x => x)) { result.Add(text.Substring(previousIndex, index - previousIndex)); previousIndex = index + 1; } result.Add(text.Substring(previousIndex)); return(result); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static Dictionary <string, object> PropertyDictionary(this object obj) { if (obj == null) { Compute.RecordWarning("Cannot query the property dictionary of a null object. An empty dictionary will be returned."); return(new Dictionary <string, object>()); } if (obj is CustomObject) { return(PropertyDictionary(obj as CustomObject)); } Dictionary <string, object> dic = new Dictionary <string, object>(); foreach (var prop in obj.GetType().GetProperties()) { if (!prop.CanRead || prop.GetMethod.GetParameters().Count() > 0) { continue; } var value = prop.GetValue(obj, null); dic[prop.Name] = value; } return(dic); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static string ToText(this MethodBase method, bool includePath = false, string paramStart = "(", string paramSeparator = ", ", string paramEnd = ")", bool removeIForInterface = true) { string name = (method is ConstructorInfo) ? method.DeclaringType.ToText(false, true) : method.Name; if (removeIForInterface && Query.IsInterfaceMethod(method)) { name = name.Substring(1); } string text = name + paramStart; try { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length > 0) { text += parameters.Select(x => x.ParameterType.ToText()).Aggregate((x, y) => x + paramSeparator + y); } } catch (Exception e) { Compute.RecordWarning("Method " + name + " failed to load its paramters.\nError: " + e.ToString()); text += "?"; } text += paramEnd; if (includePath) { string path = method.Path(); text = path + '.' + text; } return(text); }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static void ExtractAllMethods() { Compute.LoadAllAssemblies(); m_BHoMMethodList = new List <MethodInfo>(); m_AllMethodList = new List <MethodBase>(); m_EngineTypeList = new List <Type>(); BindingFlags bindingBHoM = BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static; foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { try { // Save BHoM objects only string name = asm.GetName().Name; if (name.EndsWith("_Engine")) { foreach (Type type in asm.GetTypes()) { // Get only the BHoM methods if (!type.IsInterface && type.IsAbstract) { MethodInfo[] typeMethods = type.GetMethods(bindingBHoM); m_BHoMMethodList.AddRange(typeMethods.Where(x => x.IsLegal())); } if (type.Name == "External") { MethodInfo getExternalMethods = type.GetMethod("Methods"); if (getExternalMethods != null) { m_ExternalMethodList.AddRange((List <MethodInfo>)getExternalMethods.Invoke(null, null)); } MethodInfo getExternalCtor = type.GetMethod("Constructors"); if (getExternalCtor != null) { m_ExternalMethodList.AddRange((List <ConstructorInfo>)getExternalCtor.Invoke(null, null)); } } // Get everything StoreAllMethods(type); } } else if (name.EndsWith("oM") || name.EndsWith("_Adapter") || name.EndsWith("_UI") || name.EndsWith("_Test")) { foreach (Type type in asm.GetTypes()) { StoreAllMethods(type); } } } catch (Exception) { Compute.RecordWarning("Cannot load types from assembly " + asm.GetName().Name); } } }
/***************************************************/ public static string ToText(this MethodBase method, bool includePath = false, string paramStart = "(", string paramSeparator = ", ", string paramEnd = ")", bool removeIForInterface = true, bool includeParamNames = true, int maxParams = 5, int maxChars = 40, bool includeParamPaths = false) { string name = (method is ConstructorInfo) ? method.DeclaringType.ToText(false, true) : method.Name; if (removeIForInterface && Query.IsInterfaceMethod(method)) { name = name.Substring(1); } string text = name + paramStart; try { ParameterInfo[] parameters = method.GetParameters(); string paramText = ""; if (parameters.Length > 0) { // Collect parameters text for (int i = 0; i < parameters.Count(); i++) { string singleParamText = includeParamNames ? parameters[i].ParameterType.ToText(includeParamPaths) + " " + parameters[i].Name : parameters[i].ParameterType.ToText(includeParamPaths); if (i == 0) { paramText = singleParamText; continue; } if (i > maxParams || string.Join(paramText, singleParamText).Length > maxChars) { paramText += $", and {parameters.Length - i} more inputs"; break; } paramText += ", " + singleParamText; } } text += paramText; } catch (Exception e) { Compute.RecordWarning("Method " + name + " failed to load its paramters.\nError: " + e.ToString()); text += "?"; } text += paramEnd; if (includePath) { string path = method.Path(); text = path + '.' + text; } return(text); }
/***************************************************/ public static List <string> UsedNamespaces(this Type type, bool onlyBHoM = false, int maxDepth = 10) { if (type == null) { Compute.RecordWarning("Cannot query the used namespaces of a null type. An empty list will be returned as the list of used namespaces."); return(new List <string>()); } return(type.UsedTypes(onlyBHoM).Select(x => ClipNamespace(x.Namespace, maxDepth)).Distinct().ToList()); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <Type> PropertyTypes(this object obj, bool goDeep = false) { if (obj == null) { Compute.RecordWarning("Cannot query the property types of a null object. An empty list of types will be returned."); return(new List <Type>()); } return(obj.GetType().PropertyTypes(goDeep)); }
public static string Description(this QuantityAttribute quantity) { if (quantity == null) { Compute.RecordWarning("Cannot query the description of a null quantity attribute. An empty string will be returned isntead."); return(""); } return("This is a " + quantity.GetType().Name + " [" + quantity.SIUnit + "]"); }
/***************************************************/ public static IEnumerable <T> EnumValues <T>(this Type enumType) { if (enumType == null) { Compute.RecordWarning("Cannot get the enum values of a null type. Returning an empty list instead."); return(new List <T>()); } return(Enum.GetValues(enumType).Cast <T>()); }
/*************************************/ /**** Public Methods ****/ /*************************************/ public static MethodInfo MethodInfo(this Type declaringType, string methodName, List <Type> paramTypes) { if (declaringType == null) { Compute.RecordError("Cannot create a method info from a null type."); return(null); } if (methodName == null) { Compute.RecordError("Cannot create a method info from a null method name."); return(null); } if (paramTypes == null) { Compute.RecordWarning("The 'paramTypes' input is null and was replaced by an empty list"); paramTypes = new List <Type>(); } MethodInfo foundMethod = null; List <MethodInfo> methods = declaringType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).ToList(); for (int k = 0; k < methods.Count; k++) { MethodInfo method = methods[k]; if (method.Name == methodName) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == paramTypes.Count) { if (method.ContainsGenericParameters) { Type[] generics = method.GetGenericArguments().Select(x => x.MakeFromGeneric()).ToArray(); method = method.MakeGenericMethod(generics); parameters = method.GetParameters(); } bool matching = true; for (int i = 0; i < paramTypes.Count; i++) { matching &= (paramTypes[i] == null || parameters[i].ParameterType == paramTypes[i]); } if (matching) { foundMethod = method; break; } } } } return(foundMethod); }
/***************************************************/ private static object GetValue <T>(this Dictionary <string, T> dic, string propName) { if (dic.ContainsKey(propName)) { return(dic[propName]); } else { Compute.RecordWarning($"{dic} does not contain the key: {propName}"); return(null); } }
/***************************************************/ private static object GetValue(this IDictionary obj, string propName) { IDictionary dic = obj as IDictionary; if (dic.Contains(propName)) { return(dic[propName]); } else { Compute.RecordWarning($"{dic} does not contain the key: {propName}"); return(null); } }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static bool SetValue(this IBHoMObject obj, string propName, object value) { if (obj == null) { return(false); } if (!obj.CustomData.ContainsKey(propName)) { Compute.RecordWarning("The objects does not contain any property with the name " + propName + ". The value is being set as custom data"); } obj.CustomData[propName] = value; return(true); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <string> PropertyNames(this object obj) { if (obj == null) { Compute.RecordWarning("Cannot query the property names of a null object. An empty list of names will be returned."); return(new List <string>()); } if (obj is CustomObject) { return(PropertyNames(obj as CustomObject)); } else { return(obj.GetType().PropertyNames()); } }
public static Dictionary <string, string> InputDescriptions(this MethodBase method) { if (method == null) { Compute.RecordWarning("Cannot query the input descriptions of a null method. Returning an empty dictionary instead."); return(new Dictionary <string, string>()); } Dictionary <string, string> descriptions = new Dictionary <string, string>(); foreach (ParameterInfo info in method.GetParameters()) { descriptions[info.Name] = info.Description(); } return(descriptions); }
public static string Description(this ParameterInfo parameter, bool addTypeDescription = true) { if (parameter == null) { Compute.RecordWarning("Cannot query the description of a null parameter object. An empty string will be returned instead."); return(""); } IEnumerable <InputAttribute> inputDesc = parameter.Member.GetCustomAttributes <InputAttribute>().Where(x => x.Name == parameter.Name); InputClassificationAttribute classification = null; string desc = ""; if (inputDesc.Count() > 0) { desc = inputDesc.First().Description + Environment.NewLine; classification = inputDesc.First().Classification; } else { //If no input descs are found, check if inputFromProperty descs can be found IEnumerable <InputFromProperty> inputFromPropDesc = parameter.Member.GetCustomAttributes <InputFromProperty>().Where(x => x.InputName == parameter.Name); //Only valid for engine type methods MethodInfo methodInfo = parameter.Member as MethodInfo; if (inputFromPropDesc.Count() > 0 && methodInfo != null && methodInfo.DeclaringType != null) { Type returnType = methodInfo.ReturnType.UnderlyingType().Type; if (returnType != null) { //Try to find matching proeprty type, matching both name and type PropertyInfo prop = returnType.GetProperty(inputFromPropDesc.First().PropertyName, parameter.ParameterType); //If found return description of property if (prop != null) { return(prop.Description()); } } } } if (addTypeDescription && parameter.ParameterType != null) { desc += parameter.ParameterType.Description(classification); } return(desc); }
/***************************************************/ public static bool SetPropertyValue(this List <IBHoMObject> objects, Type objectType, string propName, object value) { PropertyInfo propInfo = objectType.GetProperty(propName); if (propInfo == null) { Compute.RecordWarning("No property with the provided name found. The value is being set as custom data"); foreach (IBHoMObject obj in objects) { obj.CustomData[propName] = value; } return(true); } else { Action <object, object> setProp = (Action <object, object>)Delegate.CreateDelegate(typeof(Action <object, object>), propInfo.GetSetMethod()); if (value is IList && value.GetType() != propInfo.PropertyType) { IList values = ((IList)value); // Check that the two lists are of equal length if (objects.Count != values.Count) { return(false); } // Set their property for (int i = 0; i < values.Count; i++) { setProp(objects[i], values[i]); } } else { // Set the same property to all objects foreach (object obj in objects) { setProp(obj, value); } } return(true); } }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static object GetValue(this IBHoMObject obj, string propName) { IBHoMObject bhom = obj as IBHoMObject; if (bhom.CustomData.ContainsKey(propName)) { if (!(bhom is CustomObject)) { Compute.RecordNote($"{propName} is stored in CustomData"); } return(bhom.CustomData[propName]); } else { Compute.RecordWarning($"{bhom} does not contain a property: {propName}, or: CustomData[{propName}]"); return(null); } }
public static List <MethodInfo> SortExtensionMethods(this IEnumerable <MethodInfo> methods, Type type) { if (methods == null || methods.Count() == 0) { return(new List <MethodInfo>()); } if (type == null) { Compute.RecordWarning("Cannot sort methods based on a null type. The original list will be returned."); return(methods.ToList()); } List <List <Type> > hierarchy = type.InheritanceHierarchy(); IEnumerable <int> levels = methods.Select(x => hierarchy.InheritanceLevel(x.GetParameters()[0].ParameterType)); return(methods.Zip(levels, (m, l) => new { m, l }).Where(x => x.l != -1).OrderBy(x => x.l).Select(x => x.m).ToList()); }
/***************************************************/ public static List <string> PropertyNames(this Type type) { if (type == null) { Compute.RecordWarning("Cannot query the property names of a null type. An empty list of names will be returned."); return(new List <string>()); } List <string> names = new List <string>(); foreach (var prop in type.GetProperties()) { if (!prop.CanRead) { continue; } names.Add(prop.Name); } return(names); }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <MethodInfo> NestedMethods(this Type type) { if (type == null) { Compute.RecordWarning("Cannot query the nested methods of a null type. An empty list of methods will be returned."); return(new List <MethodInfo>()); } List <MethodInfo> methods = type.GetMethods().ToList(); Type[] nestedTypes = type.GetNestedTypes(); while (nestedTypes.Length > 0) { methods.AddRange(nestedTypes.SelectMany(x => x.GetMethods())); nestedTypes = nestedTypes.SelectMany(x => x.GetNestedTypes()).ToArray(); } return(methods); }
/***************************************************/ public static bool SetPropertyValue(this object obj, string propName, object value) { System.Reflection.PropertyInfo prop = obj.GetType().GetProperty(propName); if (prop != null) { if (value.GetType() != prop.PropertyType && value.GetType().GenericTypeArguments.Length > 0 && prop.PropertyType.GenericTypeArguments.Length > 0) { value = Modify.CastGeneric(value as dynamic, prop.PropertyType.GenericTypeArguments[0]); } if (value.GetType() != prop.PropertyType) { ConstructorInfo constructor = prop.PropertyType.GetConstructor(new Type[] { value.GetType() }); if (constructor != null) { value = constructor.Invoke(new object[] { value }); } } prop.SetValue(obj, value); return(true); } else if (obj is IBHoMObject) { IBHoMObject bhomObj = obj as IBHoMObject; if (bhomObj == null) { return(false); } if (!(bhomObj is CustomObject)) { Compute.RecordWarning("The objects does not contain any property with the name " + propName + ". The value is being set as custom data"); } bhomObj.CustomData[propName] = value; return(true); } return(false); }
public static List <string> UsedAssemblies(List <string> assemblyNames, bool onlyBHoM = false, bool goDeep = false) { if (assemblyNames == null) { Compute.RecordWarning("The list of assmeblyNames is null. An empty list will be returned as the list of used assemblies."); return(new List <string>()); } AllAssemblyList(); Dictionary <string, Assembly> dic = onlyBHoM ? m_BHoMAssemblies : m_AllAssemblies; List <Assembly> assemblies = assemblyNames.Where(x => dic.ContainsKey(x)).Select(x => dic[x]).ToList(); if (goDeep) { return(DeepDependencies(assemblies, onlyBHoM).Select(x => x.Location).ToList()); } else { return(assemblies.SelectMany(x => x.UsedAssemblies(onlyBHoM)).Select(x => x.Location).Distinct().ToList()); } }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static object Item <T>(this List <T> list, int index) { if (list == null) { Compute.RecordWarning("Cannot access item of a null list. A null value is returned."); return(null); } if (index < 0) { Compute.RecordWarning("Cannot access item with negative index. A null value is returned."); return(null); } if (index > list.Count) { Compute.RecordWarning("Cannot access item with index outside the range of the list. A null value is returned."); return(null); } return(list[index]); }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static object GetValue(this IBHoMObject obj, string propName) { IBHoMObject bhom = obj as IBHoMObject; if (obj == null || propName == null) { return(null); } if (bhom.CustomData.ContainsKey(propName)) { if (!(bhom is CustomObject)) { Compute.RecordNote($"{propName} is stored in CustomData"); } return(bhom.CustomData[propName]); } else { IFragment fragment = null; Type fragmentType = Create.Type(propName, true); if (fragmentType != null) { List <IFragment> matches = bhom.Fragments.Where(fr => fragmentType.IsAssignableFrom(fr.GetType())).ToList(); if (matches.Count > 1) { Compute.RecordWarning($"{bhom} contains more than one fragment of type {fragmentType.IToText()}. The first one will be returned."); } fragment = matches.FirstOrDefault(); } if (fragment == null) { Compute.RecordWarning($"{bhom} does not contain a property: {propName}, or: CustomData[{propName}], or fragment of type {propName}."); } return(fragment); } }
/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <MethodBase> UsedMethods(this MethodBase method, bool onlyBHoM = false) { if (method == null) { Compute.RecordWarning("Cannot query the used methods of a null method. An empty list will be returned as the list of used methods."); return(new List <MethodBase>()); } try { if (method.GetMethodBody() == null) { return(new List <MethodBase>()); } IEnumerable <MethodBase> methods = Disassembler.GetInstructions(method) .Select(x => x.Operand) .OfType <MethodBase>() .Distinct() .Where(x => x.DeclaringType.Namespace != null) .SelectMany(x => x.IsAutoGenerated() ? x.UsedMethods(onlyBHoM) : new List <MethodBase> { x }); if (onlyBHoM) { return(methods.Where(x => x.DeclaringType.Namespace.StartsWith("BH.")).ToList()); } else { return(methods.ToList()); } } catch (Exception e) { Compute.RecordError("Method " + method.DeclaringType.Namespace + "." + method.Name + " failed to extract the information about the method.\nError: " + e.ToString()); return(new List <MethodBase>()); } }