public ITypeDescription GetPropertyType(string assemblyName, string typeName, string propertyStr)
        {
            const char delim = '.';

            string[] propertyElems = propertyStr.Split(delim);
            Exception = null;
            ErrorCode = 0;
            if (!_assemblies.ContainsKey(assemblyName))
            {
                this.ErrorCode = ModuleErrorCode.AssemblyNotLoad;
                return(null);
            }
            try
            {
                Type dataType = _assemblies[assemblyName].GetType(typeName);
                if (null == dataType)
                {
                    ErrorCode = ModuleErrorCode.TypeCannotLoad;
                    return(null);
                }
                foreach (string propertyElem in propertyElems)
                {
                    if (string.IsNullOrWhiteSpace(propertyElem))
                    {
                        continue;
                    }
                    PropertyInfo propertyInfo = dataType.GetProperty(propertyElem,
                                                                     BindingFlags.Instance | BindingFlags.Public);
                    if (null == propertyInfo)
                    {
                        ErrorCode = ModuleErrorCode.PropertyNotFound;
                        return(null);
                    }
                    dataType = propertyInfo.PropertyType;
                    AddToAssemblyMapping(dataType);
                }

                TestflowCategoryAttribute categoryAttribute = dataType.GetCustomAttribute <TestflowCategoryAttribute>();
                string category = null == categoryAttribute ? string.Empty : categoryAttribute.CategoryString;

                DescriptionAttribute descriptionAttribute = dataType.GetCustomAttribute <DescriptionAttribute>();
                string description = null == descriptionAttribute ? string.Empty : descriptionAttribute.Description;

                TypeDescription typeDescription = new TypeDescription()
                {
                    AssemblyName = dataType.Assembly.GetName().Name,
                    Category     = category,
                    Description  = description,
                    Name         = GetTypeName(dataType),
                    Namespace    = GetNamespace(dataType)
                };
                return(typeDescription);
            }
            catch (Exception ex)
            {
                this.ErrorCode = ModuleErrorCode.LibraryLoadError;
                this.Exception = ex;
                return(null);
            }
        }
        private void AddDataTypeDescription(ComInterfaceDescription descriptionData, Type classType, string assemblyName, VariableType classKind)
        {
            TestflowCategoryAttribute category        = classType.GetCustomAttribute <TestflowCategoryAttribute>();
            DescriptionAttribute      descriptionAttr = classType.GetCustomAttribute <DescriptionAttribute>();

            string typeCategory        = null != category ? category.CategoryString : string.Empty;
            string classDescriptionStr = (null != descriptionAttr) ? descriptionAttr.Description : string.Empty;

            TypeDescription typeDescription = new TypeDescription()
            {
                AssemblyName = assemblyName,
                Category     = typeCategory,
                Description  = classDescriptionStr,
                Name         = GetTypeName(classType),
                Namespace    = GetNamespace(classType),
                Kind         = classKind
            };

            // 枚举类型需要添加枚举值到类型信息中
            if (classType.IsEnum)
            {
                typeDescription.Enumerations = Enum.GetNames(classType);
            }

            descriptionData.TypeDescriptions.Add(typeDescription);
        }
        private void AddMethodDescription(Type classType, ClassInterfaceDescription classDescription)
        {
            MethodInfo[] methods  = classType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
            bool         isStatic = methods.All(item => item.IsStatic || _ignoreMethod.Contains(item.Name));

            foreach (MethodInfo methodInfo in methods)
            {
                // 忽略object对象继承方法和实例类的getset方法
                if (_ignoreMethod.Contains(methodInfo.Name))
                {
                    continue;
                }
                if (!isStatic && (methodInfo.Name.StartsWith(Constants.GetPrefix) ||
                                  methodInfo.Name.StartsWith(Constants.SetPrefix)))
                {
                    continue;
                }
                DescriptionAttribute descriptionAttribute = methodInfo.GetCustomAttribute <DescriptionAttribute>();
                string descriptionStr = (null == descriptionAttribute)
                    ? string.Empty
                    : descriptionAttribute.Description;

                TestflowCategoryAttribute categoryAttribute = methodInfo.GetCustomAttribute <TestflowCategoryAttribute>();
                string categoryStr = null == categoryAttribute
                    ? classDescription.ClassTypeDescription.Category
                    : categoryAttribute.CategoryString;

                FunctionType       funcType          = FunctionType.InstanceFunction;
                CallBackAttribute  callBackAttribute = methodInfo.GetCustomAttribute <CallBackAttribute>();
                AssertionAttribute assertAttribute   = methodInfo.GetCustomAttribute <AssertionAttribute>();
                if (null != callBackAttribute)
                {
                    funcType = FunctionType.CallBack;
                }
                else if (null != assertAttribute)
                {
                    funcType = FunctionType.Assertion;
                }
                else if (methodInfo.IsStatic)
                {
                    funcType = FunctionType.StaticFunction;
                }

                FunctionInterfaceDescription funcDescription = new FunctionInterfaceDescription()
                {
                    Category    = categoryStr,
                    Description = descriptionStr,
                    FuncType    = funcType,
                    IsGeneric   = methodInfo.IsGenericMethod,
                    Name        = methodInfo.Name,
                };
                InitMethodParamDescription(methodInfo, funcDescription);
                funcDescription.Signature = ModuleUtils.GetSignature(classDescription.Name, funcDescription);

                classDescription.Functions.Add(funcDescription);
            }
        }
        private void AddClassDescription(ComInterfaceDescription comDescription, Type classType, string assemblyName, VariableType classKind)
        {
            TestflowTypeAttribute     testflowType    = classType.GetCustomAttribute <TestflowTypeAttribute>();
            TestflowCategoryAttribute category        = classType.GetCustomAttribute <TestflowCategoryAttribute>();
            DescriptionAttribute      descriptionAttr = classType.GetCustomAttribute <DescriptionAttribute>();
            string typeCategory = null != category ? category.CategoryString : string.Empty;

            string classDescriptionStr = (null != descriptionAttr) ? descriptionAttr.Description : string.Empty;

            TypeDescription typeDescription = new TypeDescription()
            {
                AssemblyName = assemblyName,
                Category     = typeCategory,
                Name         = GetTypeName(classType),
                Namespace    = GetNamespace(classType),
                Description  = classDescriptionStr,
                Kind         = classKind
            };
            ClassInterfaceDescription classDescription = new ClassInterfaceDescription()
            {
                ClassTypeDescription = typeDescription,
                Description          = typeDescription.Description,
                Name = GetTypeName(classType),
                Kind = classKind
            };

            AddConstructorDescription(classType, classDescription, classKind);
            AddPropertySetterDescription(classType, classDescription);
            AddFieldSetterDescription(classType, classDescription);
            AddMethodDescription(classType, classDescription);

            classDescription.IsStatic = classKind == VariableType.Class && classDescription.Functions.All(
                item => item.FuncType != FunctionType.Constructor && item.FuncType != FunctionType.InstanceFunction);

            comDescription.Classes.Add(classDescription);

            // 如果是Testflow数据类型,则添加到数据类型列表中。默认所有的实例类都是Testflow数据类型(包含实例方法,并且有公开的实例属性)
            if (!classDescription.IsStatic && (null == testflowType || testflowType.IsTestflowDataType))
            {
                comDescription.TypeDescriptions.Add(typeDescription);
            }
        }
 public ClassInterfaceDescription GetClassDescription(string assemblyName, string typeFullName, out string path,
                                                      out string version)
 {
     Exception = null;
     ErrorCode = 0;
     path      = string.Empty;
     version   = Constants.DefaultVersion;
     if (!_assemblies.ContainsKey(assemblyName))
     {
         ErrorCode = ModuleErrorCode.AssemblyNotLoad;
         return(null);
     }
     try
     {
         Assembly assembly = _assemblies[assemblyName];
         path    = assembly.Location;
         version = assembly.GetName().Version.ToString();
         Type classType = assembly.GetType(typeFullName);
         if (null == classType)
         {
             ErrorCode = ModuleErrorCode.TypeCannotLoad;
             return(null);
         }
         VariableType classKind = GetKindOfType(classType);
         TestflowCategoryAttribute categoryAttr    = classType.GetCustomAttribute <TestflowCategoryAttribute>();
         DescriptionAttribute      descriptionAttr = classType.GetCustomAttribute <DescriptionAttribute>();
         string          typeCategory        = null != categoryAttr ? categoryAttr.CategoryString : string.Empty;
         string          classDescriptionStr = null != descriptionAttr ? descriptionAttr.Description : string.Empty;
         TypeDescription typeDescription     = new TypeDescription
         {
             AssemblyName = assemblyName,
             Category     = typeCategory,
             Name         = GetTypeName(classType),
             Namespace    = GetNamespace(classType),
             Description  = classDescriptionStr,
             Kind         = classKind
         };
         ClassInterfaceDescription classDescription = new ClassInterfaceDescription
         {
             ClassTypeDescription = typeDescription,
             Description          = typeDescription.Description,
             Name = GetTypeName(classType),
             Kind = classKind
         };
         classDescription.IsStatic = classKind == VariableType.Class && classDescription.Functions.All(
             item => item.FuncType != FunctionType.Constructor && item.FuncType != FunctionType.InstanceFunction);
         if (classKind == VariableType.Class || classKind == VariableType.Struct)
         {
             AddConstructorDescription(classType, classDescription, classKind);
             AddPropertySetterDescription(classType, classDescription);
             AddFieldSetterDescription(classType, classDescription);
             AddMethodDescription(classType, classDescription);
         }
         return(classDescription);
     }
     catch (Exception ex)
     {
         ErrorCode = ModuleErrorCode.LibraryLoadError;
         Exception = ex;
         return(null);
     }
 }