示例#1
0
文件: Path.cs 项目: BHoM/BHoM_Engine
        /***************************************************/

        public static string Path(this MethodBase method, bool userReturnTypeForCreate = true, bool useExtentionType = false)
        {
            if (method == null)
            {
                Compute.RecordError("Cannot query the path of a null method base.");
                return(null);
            }

            Type type = method.DeclaringType;

            if (userReturnTypeForCreate && type.Name == "Create" && method is MethodInfo)
            {
                Type returnType = ((MethodInfo)method).ReturnType.UnderlyingType().Type;
                if (returnType.Namespace.StartsWith("BH."))
                {
                    type = returnType;
                }
            }
            else if (useExtentionType && method.IsDefined(typeof(ExtensionAttribute), false))
            {
                ParameterInfo[] parameters = method.GetParameters();
                if (parameters.Length > 0)
                {
                    type = parameters[0].ParameterType;
                }
            }

            return(type.ToText(true, true));
        }
示例#2
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static string UnqualifiedName(string qualifiedName)
        {
            if (qualifiedName == null)
            {
                Compute.RecordError("Cannot extract the unqualified name from a null string.");
                return("");
            }

            int openIndex  = qualifiedName.IndexOf('[');
            int closeIndex = qualifiedName.LastIndexOf(']');

            if (openIndex < 0 || closeIndex < 0)
            {
                return(qualifiedName.Split(',').First());
            }

            string        inside = qualifiedName.Substring(openIndex + 1, closeIndex - openIndex - 1);
            List <int>    cuts   = FindLevelZero(inside, ',', '[', ']');
            List <string> parts  = SplitByIndices(inside, cuts);

            for (int i = 0; i < parts.Count; i++)
            {
                parts[i] = UnqualifiedName(parts[i].Trim('[', ']', ' '));
            }

            return(qualifiedName.Substring(0, openIndex + 1) + parts.Aggregate((a, b) => a + ',' + b) + "]");
        }
示例#3
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static List <Type> UsedTypes(this MethodBase method, bool onlyBHoM = false)
        {
            try
            {
                IEnumerable <Type> varTypes = new List <Type>();
                MethodBody         body     = method.GetMethodBody();
                if (body != null)
                {
                    varTypes = method.GetMethodBody().LocalVariables.Select(x => x.LocalType);
                }

                IEnumerable <Type> methodTypes = method.UsedMethods(onlyBHoM).Select(x => x.DeclaringType);
                IEnumerable <Type> paramTypes  = method.GetParameters().Select(x => x.ParameterType);
                IEnumerable <Type> types       = methodTypes.Union(paramTypes).Union(varTypes).Distinct();

                if (onlyBHoM)
                {
                    return(types.Where(x => x.Namespace.StartsWith("BH.")).ToList());
                }
                else
                {
                    return(types.ToList());
                }
            }
            catch (Exception e)
            {
                Compute.RecordError(method.ToString() + " failed t oextract its types.\nError: " + e.ToString());
                return(new List <Type>());
            }
        }
示例#4
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static Type Type(string name)
        {
            Dictionary <string, List <Type> > typeDictionary = Query.BHoMTypeDictionary();

            List <Type> types = null;

            if (!typeDictionary.TryGetValue(name, out types))
            {
                Compute.RecordError($"A type corresponding to {name} cannot be found.");
                return(null);
            }
            else if (types.Count == 1)
            {
                return(types[0]);
            }
            else
            {
                string message = "Ambiguous match: Multiple types correspond the the name provided: \n";
                foreach (Type type in types)
                {
                    message += "- " + type.FullName + "\n";
                }

                Compute.RecordError(message);
                return(null);
            }
        }
示例#5
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static List <MethodBase> UsedMethods(this MethodBase method, bool onlyBHoM = false)
        {
            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>());
            }
        }
示例#6
0
        public static string PropertyAbbreviation(this object obj, string propName)
        {
            if (obj == null)
            {
                Compute.RecordError("Cannot query the property abbreviation of a null object.");
                return("");
            }

            if (propName == null)
            {
                Compute.RecordError("Cannot query the property abbreviation where the property name is null.");
                return("");
            }

            System.Reflection.PropertyInfo prop = obj.GetType().GetProperty(propName);

            if (prop != null)
            {
                object[] attributes = prop.GetCustomAttributes(typeof(AbbreviationAttribute), false);
                if (attributes.Length == 1)
                {
                    AbbreviationAttribute attribute = (AbbreviationAttribute)attributes[0];
                    if (attribute != null)
                    {
                        return(attribute.Name);
                    }
                }
            }

            return("");
        }
示例#7
0
        public static Type MakeFromGeneric(this Type genericType)
        {
            if (genericType == null)
            {
                Compute.RecordError("Cannot make generic from null type.");
                return(null);
            }

            if (genericType.IsGenericParameter)
            {
                Type[] constrains = genericType.GetGenericParameterConstraints();
                if (constrains.Length == 0)
                {
                    return(typeof(object));
                }
                else
                {
                    return(MakeFromGeneric(constrains[0]));
                }
            }
            else if (genericType.ContainsGenericParameters)
            {
                if (genericType.GetGenericArguments().Any(x => x.IsGenericParameter && x.GetGenericParameterConstraints().Any(c => c == genericType)))
                {
                    return(genericType.GetGenericTypeDefinition().MakeGenericType(new Type[] { typeof(object) }));
                }

                Type[] constrains = genericType.GetGenericArguments().Select(x => MakeFromGeneric(x)).ToArray();
                return(genericType.GetGenericTypeDefinition().MakeGenericType(constrains));
            }
            else
            {
                return(genericType);
            }
        }
示例#8
0
文件: Type.cs 项目: BHoM/BHoM_Engine
        /***************************************************/

        public static Type GenericType(string name, bool silent = false)
        {
            if (name == null)
            {
                Compute.RecordError("Cannot create a type from a null string.");
                return(null);
            }

            string[] parts     = name.Split('<', '>', ',').Select(x => x.Trim()).ToArray();
            string[] arguments = parts.Skip(1).Where(x => x.Length > 0).ToArray();

            Type typeDefinition = Type(parts[0] + "`" + arguments.Length);

            if (typeDefinition == null)
            {
                return(null);
            }

            try
            {
                return(typeDefinition.MakeGenericType(arguments.Select(x => Type(x)).ToArray()));
            }
            catch
            {
                return(null);
            }
        }
示例#9
0
        /***************************************************/
        /**** 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);
        }
示例#10
0
文件: Path.cs 项目: BHoM/BHoM_Engine
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static string Path(this Type type)
        {
            if (type == null)
            {
                Compute.RecordError("Cannot query the path of a null type.");
                return(null);
            }

            return(type.Namespace);
        }
示例#11
0
        /*************************************/
        /**** 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);
        }
示例#12
0
文件: Type.cs 项目: BHoM/BHoM_Engine
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static Type Type(string name, bool silent = false)
        {
            if (name == null)
            {
                Compute.RecordError("Cannot create a type from a null string.");
                return(null);
            }

            Dictionary <string, List <Type> > typeDictionary = Query.BHoMTypeDictionary();

            if (name.Contains('<'))
            {
                return(GenericType(name, silent));
            }

            List <Type> types = null;

            if (!typeDictionary.TryGetValue(name, out types))
            {
                Type type = System.Type.GetType(name);
                if (type == null && name.EndsWith("&"))
                {
                    type = Type(name.TrimEnd(new char[] { '&' }), true);
                    if (type != null)
                    {
                        type = type.MakeByRefType();
                    }
                }


                if (type == null && !silent)
                {
                    Compute.RecordError($"A type corresponding to {name} cannot be found.");
                }

                return(type);
            }
            else if (types.Count == 1)
            {
                return(types[0]);
            }
            else if (!silent)
            {
                string message = "Ambiguous match: Multiple types correspond the the name provided: \n";
                foreach (Type type in types)
                {
                    message += "- " + type.FullName + "\n";
                }

                Compute.RecordError(message);
            }

            return(null);
        }
示例#13
0
文件: Type.cs 项目: BHoM/BHoM_Engine
        /***************************************************/

        public static List <Type> AllTypes(string name, bool silent = false)
        {
            if (name == null)
            {
                Compute.RecordError("Cannot create types from a null string.");
                return(new List <Type>());
            }

            List <Type> typeList = new List <Type>();

            if (name.StartsWith("BH.Engine"))
            {
                typeList = Query.EngineTypeList();
            }
            else if (name.StartsWith("BH.Adapter"))
            {
                typeList = Query.AdapterTypeList();
            }
            else if (name.StartsWith("BH.oM"))
            {
                typeList = Query.BHoMTypeList();
            }
            else
            {
                typeList = Query.AllTypeList();
            }

            List <Type> types = typeList.Where(x => x.AssemblyQualifiedName.Contains(name)).ToList();

            if (types.Count != 0)
            {
                return(types);
            }
            else
            {
                //No method found in dictionary, try System.Type
                Type type = System.Type.GetType(name);
                if (type == null)
                {
                    if (!silent)
                    {
                        Compute.RecordError($"A type corresponding to {name} cannot be found.");
                    }
                    return(new List <Type>());
                }
                return(new List <Type> {
                    type
                });
            }
        }
示例#14
0
        public static MethodInfo MakeFromGeneric(this MethodInfo genericMethod)
        {
            if (genericMethod == null)
            {
                Compute.RecordError("Cannot make generic from a null method.");
                return(null);
            }

            if (genericMethod.ContainsGenericParameters)
            {
                Type[] types = genericMethod.GetGenericArguments().Select(x => x.MakeFromGeneric()).ToArray();
                genericMethod = genericMethod.MakeGenericMethod(types);
            }
            return(genericMethod);
        }
示例#15
0
        /***************************************************/

        public static Func <object[], object> ToFunc(this ConstructorInfo ctor)
        {
            if (ctor == null)
            {
                Compute.RecordError("Cannot convert constructor info to func if the constructor is null.");
                return(null);
            }

            ParameterExpression lambdaInput = Expression.Parameter(typeof(object[]), "x");

            Expression[]  inputs = ctor.GetParameters().Select((x, i) => Expression.Convert(Expression.ArrayIndex(lambdaInput, Expression.Constant(i)), x.ParameterType)).ToArray();
            NewExpression constructorExpression = Expression.New(ctor as ConstructorInfo, inputs);

            return(Expression.Lambda <Func <object[], object> >(Expression.Convert(constructorExpression, typeof(object)), lambdaInput).Compile());
        }
示例#16
0
        /***************************************************/

        public static Func <object[], object> ToFunc(this MethodInfo method)
        {
            if (method == null)
            {
                Compute.RecordError("Cannot convert method info to func if method is null.");
                return(null);
            }

            ParameterExpression lambdaInput = Expression.Parameter(typeof(object[]), "x");

            Expression[] inputs = method.GetParameters().Select((x, i) => Expression.Convert(Expression.ArrayIndex(lambdaInput, Expression.Constant(i)), x.ParameterType.GetTypeIfRef())).ToArray();

            MethodCallExpression methodExpression;

            if (method.IsStatic)
            {
                methodExpression = Expression.Call(method, inputs);
                if (method.ReturnType == typeof(void))
                {
                    return(Expression.Lambda <Action <object[]> >(Expression.Convert(methodExpression, typeof(void)), lambdaInput).Compile().ToFunc());
                }
                else
                {
                    return(Expression.Lambda <Func <object[], object> >(Expression.Convert(methodExpression, typeof(object)), lambdaInput).Compile());
                }
            }
            else
            {
                ParameterExpression instanceParameter = Expression.Parameter(typeof(object), "instance");
                Expression          instanceInput     = Expression.Convert(instanceParameter, method.DeclaringType);
                methodExpression = Expression.Call(instanceInput, method, inputs);

                if (method.ReturnType == typeof(void))
                {
                    return(Expression.Lambda <Action <object, object[]> >(
                               Expression.Convert(methodExpression, typeof(void)),
                               new ParameterExpression[] { instanceParameter, lambdaInput }
                               ).Compile().ToFunc());
                }
                else
                {
                    return(Expression.Lambda <Func <object, object[], object> >(
                               Expression.Convert(methodExpression, typeof(object)),
                               new ParameterExpression[] { instanceParameter, lambdaInput }
                               ).Compile().ToFunc());
                }
            }
        }
示例#17
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static Type Type(string name, bool silent = false)
        {
            Dictionary <string, List <Type> > typeDictionary = Query.BHoMTypeDictionary();

            if (name.Contains('<'))
            {
                return(GenericType(name, silent));
            }

            List <Type> types = null;

            if (!typeDictionary.TryGetValue(name, out types))
            {
                Type type = System.Type.GetType(name);
                if (type != null)
                {
                    return(type);
                }
                else
                {
                    if (!silent)
                    {
                        Compute.RecordError($"A type corresponding to {name} cannot be found.");
                    }
                    return(null);
                }
            }
            else if (types.Count == 1)
            {
                return(types[0]);
            }
            else if (!silent)
            {
                string message = "Ambiguous match: Multiple types correspond the the name provided: \n";
                foreach (Type type in types)
                {
                    message += "- " + type.FullName + "\n";
                }

                Compute.RecordError(message);
            }

            return(null);
        }
        public static bool IsAssignableFromIncludeGenerics(this Type assignableTo, Type assignableFrom)
        {
            if (assignableTo == null || assignableFrom == null)
            {
                Compute.RecordError("Cannot assign to or from null types.");
                return(false);
            }

            //Check if standard IsAssignableFrom works.
            if (assignableTo.IsAssignableFrom(assignableFrom))
            {
                return(true);
            }
            //If not, check if the argument is generic, and if so, use the IsAssignableToGenericType method to check if it can be assigned.
            else
            {
                return(assignableTo.IsGenericType && assignableFrom.IsAssignableToGenericType(assignableTo.GetGenericTypeDefinition()));
            }
        }
示例#19
0
        /***************************************************/

        public static bool RecordEvent(Event newEvent)
        {
            if (newEvent == null)
            {
                Compute.RecordError("Cannot record a null event.");
                return(false);
            }

            string trace = System.Environment.StackTrace;

            newEvent.StackTrace = string.Join("\n", trace.Split('\n').Skip(4).ToArray());

            Log log = Query.DebugLog();

            log.AllEvents.Add(newEvent);
            log.CurrentEvents.Add(newEvent);

            return(true);
        }
示例#20
0
文件: Type.cs 项目: BHoM/BHoM_Engine
        /***************************************************/

        public static Type EngineType(string name, bool silent = false)
        {
            if (name == null)
            {
                Compute.RecordError("Cannot create a type from a null string.");
                return(null);
            }

            List <Type> methodTypeList = Query.EngineTypeList();

            List <Type> types = methodTypeList.Where(x => x.AssemblyQualifiedName.StartsWith(name)).ToList();

            if (types.Count == 1)
            {
                return(types[0]);
            }
            else
            {
                //Unique method not found in list, check if it can be extracted using the system Type
                Type type = System.Type.GetType(name, silent);
                if (type == null && !silent)
                {
                    if (types.Count == 0)
                    {
                        Compute.RecordError($"A type corresponding to {name} cannot be found.");
                    }
                    else
                    {
                        string message = "Ambiguous match: Multiple types correspond the the name provided: \n";
                        foreach (Type t in types)
                        {
                            message += "- " + t.FullName + "\n";
                        }

                        message += "To get a Engine type from a specific Assembly, try adding ', NameOfTheAssmebly' at the end of the name string, or use the AllEngineTypes method to retreive all the types.";

                        Compute.RecordError(message);
                    }
                }

                return(type);
            }
        }
示例#21
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static MethodInfo MakeGenericFromInputs(this MethodInfo method, List <Type> inputTypes)
        {
            if (method == null)
            {
                Compute.RecordError("Cannot make generic from inputs of a null method.");
                return(null);
            }

            if (inputTypes == null)
            {
                Compute.RecordWarning("The 'inputTypes' input is null and was replaced by an empty list");
                return(null);
            }

            if (!method.IsGenericMethod)
            {
                return(method);
            }

            List <Type> paramTypes = method.GetParameters().Select(x => x.ParameterType).ToList();

            // Get where the generic arguments are actually used
            Dictionary <string, Type> dic = new Dictionary <string, Type>();

            for (int i = 0; i < paramTypes.Count; i++)
            {
                Type paramType = paramTypes[i];
                if (paramType.IsGenericType || paramType.IsGenericParameter)
                {
                    MatchGenericParameters(paramTypes[i], inputTypes[i], ref dic);
                }
            }

            // Actually make the generic method
            List <Type> actualTypes = method.GetGenericArguments().Select(x => dic.ContainsKey(x.Name) ? dic[x.Name] : typeof(object)).ToList();

            return(method.MakeGenericMethod(actualTypes.ToArray()));
        }
示例#22
0
        public static object SetPropertyValue(this object obj, string propName, object value = null)
        {
            if (obj == null)
            {
                Compute.RecordError("Cannot set the property value of a null object.");
                return(obj);
            }

            if (propName == null)
            {
                Compute.RecordError("Cannot set the property value where the property name is null.");
                return(obj);
            }

            object toChange = obj;

            if (propName.Contains("."))
            {
                string[] props = propName.Split('.');
                for (int i = 0; i < props.Length - 1; i++)
                {
                    toChange = toChange.PropertyValue(props[i]);
                    if (toChange == null)
                    {
                        break;
                    }
                }
                propName = props[props.Length - 1];
            }

            System.Reflection.PropertyInfo prop = toChange.GetType().GetProperty(propName);
            if (prop != null)
            {
                if (!prop.CanWrite)
                {
                    Engine.Reflection.Compute.RecordError("This property doesn't have a public setter so it is not possible to modify it.");
                    return(obj);
                }

                Type propType = prop.PropertyType;
                if (value == null)
                {
                    if (propType == typeof(string))
                    {
                        value = "";
                    }
                    else if (propType.IsValueType || typeof(IEnumerable).IsAssignableFrom(propType))
                    {
                        value = Activator.CreateInstance(propType);
                    }
                }

                if (propType.IsEnum && value is string)
                {
                    string enumName = (value as string).Split('.').Last();
                    try
                    {
                        object enumValue = Enum.Parse(propType, enumName);
                        if (enumValue != null)
                        {
                            value = enumValue;
                        }
                    }
                    catch
                    {
                        Engine.Reflection.Compute.RecordError($"An enum of type {propType.ToText(true)} does not have a value of {enumName}");
                    }
                }

                if (propType == typeof(DateTime) && value is string)
                {
                    DateTime date;
                    if (DateTime.TryParse(value as string, out date))
                    {
                        value = date;
                    }
                    else
                    {
                        Engine.Reflection.Compute.RecordError($"The value provided for {propName} is not a valid DateTime.");
                        value = DateTime.MinValue;
                    }
                }

                if (propType == typeof(Type) && value is string)
                {
                    value = Create.Type(value as string);
                }

                if (value != null)
                {
                    if (value.GetType() != propType && value.GetType().GenericTypeArguments.Length > 0 && propType.GenericTypeArguments.Length > 0)
                    {
                        value = Modify.CastGeneric(value as dynamic, propType.GenericTypeArguments[0]);
                    }
                    if (value.GetType() != propType)
                    {
                        ConstructorInfo constructor = propType.GetConstructor(new Type[] { value.GetType() });
                        if (constructor != null)
                        {
                            value = constructor.Invoke(new object[] { value });
                        }
                    }
                }

                prop.SetValue(toChange, value);
                return(obj);
            }
            else
            {
                SetValue(toChange as dynamic, propName, value);
                return(obj);
            }
        }