Example #1
0
        public static string ListMembers(object obj, MemberTypes memberTypes = MemberTypes.All)
        {
            //if obj is a already a type, cast it and use it; otherwise, grab its type
            Type objType = obj is Type type ? type : obj.GetType();

            return(objType.GetMembers().Where(member => memberTypes.HasFlag(member.MemberType)).Aggregate($"[{objType}] {memberTypes}:", (current, member) => current + $"\n\t{FormatMember(member, obj)}"));
        }
Example #2
0
 public static IEnumerable <MemberInfo> GetMembers(this Type type, MemberTypes types)
 {
     return(from MemberInfo member in type.GetMembers()
            where types.HasFlag(member.MemberType)
            select member);
 }
 /// <summary>
 /// 获取当前 <see cref="System.Type"/> 定义的指定名称和类型的所有成员,包括其所有内部成员和继承的成员。
 /// </summary>
 /// <param name="_this">表示待查找成员的 System.Type 对象。</param>
 /// <param name="name">指定的 MemberInfo 名称。</param>
 /// <param name="memberType">指定的 MemberTypes 成员类型;如果该参数值为 MemberTypes.All,则不按成员类型过滤返回列表。</param>
 /// <returns>一个表示具有指定名称的公共成员的 <see cref="System.Reflection.MemberInfo"/> 对象数组(如果找到的话);否则为空数组。</returns>
 public static MemberInfo[] GetAllMembers(this Type _this, string name, MemberTypes memberType)
 {
     Check.NotEmpty(name, "name");
     return GetAllMembers(_this).Where(m => m.Name == name && memberType.HasFlag(m.MemberType)).ToArray();
 }
 /// <summary>
 /// 获取当前 <see cref="System.Type"/> 定义的指定类型的所有成员,包括其所有内部成员和继承的成员。
 /// </summary>
 /// <param name="_this">表示待查找成员的 System.Type 对象。</param>
 /// <param name="memberType">指定的 MemberTypes 成员类型;如果该参数值为 MemberTypes.All,则不按成员类型过滤返回列表。</param>
 /// <returns>返回 System.Type 对象中符合过滤条件的所有 MemberInfo 成员对象。</returns>
 public static MemberInfo[] GetAllMembers(this Type _this, MemberTypes memberType)
 {
     return GetAllMembers(_this).Where(m => memberType.HasFlag(m.MemberType)).ToArray();
 }
#pragma warning restore CA1825 // Avoid zero-length array allocations.

        /// <summary>
        /// Gets information about members.
        /// </summary>
        /// <param name="instance">A root object.</param>
        /// <param name="type">A type of a root object.
        /// If <paramref name="instance"/> is not <c>null</c>, then its type is used instead.
        /// </param>
        /// <param name="memberPath">A path to a member.</param>
        /// <param name="parameterTypes">Types of parameters to find methods or constructors.
        /// If <c>null</c> is passed, then types of parameters are ignored.</param>
        /// <param name="bindingFlags">Binding flags to find members.</param>
        /// <exception cref="TargetException">
        /// An intermediate member on a path thrown an exception. See inner exception for details.
        /// </exception>
        /// <returns>
        /// Information about found members or an empty array if no members are found
        /// or
        /// they are not reachable
        /// or
        /// they are not accessible.
        /// </returns>
        /// <example>
        /// var dt = DateTime.Now;
        ///
        /// var info = Reflector.GetInfo(instance: dt, type: null, memberPath: "TimeOfDay.Negate");
        ///
        /// // info[0].Name == "Negate";
        /// // info[0].MemberType == MemberTypes.Property;
        /// </example>
        public static MemberInfo[] GetInfo(
            object instance,
            Type type,
            string memberPath,
            Type[] parameterTypes     = null,
            BindingFlags bindingFlags = DefaultBindingFlags)
        {
            if ((instance == null && type == null) || string.IsNullOrEmpty(memberPath))
            {
                return(EmptyMemberInfo);
            }

            var container     = instance;
            var containerType = container?.GetType() ?? type;

            MemberInfo[] memberInfos = null;

            while (true)
            {
                var dot  = memberPath.IndexOf('.');
                var size = (dot == -1) ? memberPath.Length : dot;
                var prop = memberPath.Substring(0, size);

                if (dot == -1 && prop.Equals("ctor", StringComparison.OrdinalIgnoreCase))
                {
                    prop = ".ctor";
                }

                memberInfos = containerType
                              .GetTypeInfo()
                              .GetMember(
                    prop,
                    MemberTypes.Field | MemberTypes.Property | MemberTypes.Method | MemberTypes.Constructor,
                    bindingFlags);

                if (dot == -1)
                {
                    break;
                }

                var found = GetNextContainer(memberInfos, ref container, ref containerType);

                if (!found)
                {
                    return(EmptyMemberInfo);
                }

                memberPath = memberPath.Substring(prop.Length + 1);
            }

            var matchedMemberInfo = new List <MemberInfo>();

            for (int i = memberInfos.Length - 1; i >= 0; i--)
            {
                var mi = memberInfos[i];

                if (PropertyOrFieldMemberTypes.HasFlag(mi.MemberType) ||
                    ParameterTypesMatch(((MethodBase)mi).GetParameters(), parameterTypes))
                {
                    matchedMemberInfo.Add(mi);
                }
            }

            return(matchedMemberInfo.ToArray());
        }
Example #6
0
 public static IEnumerable <MemberInfo> GetMembers(this Type input, BindingFlags flags, MemberTypes types, bool?hidden = null, bool?mutable = null, bool?serializable = null)
 {
     return(input.GetMembers(flags).Where(i => types.HasFlag(i.MemberType) && CheckHidden(hidden, i) && CheckMutable(mutable, i) && CheckSerializable(serializable, i)));
 }
Example #7
0
        /// <summary>
        /// Returns a list of all items that can be accessed in the current scope.
        /// </summary>
        /// <param name="ScopedBlock"></param>
        /// <param name="ImportCache"></param>
        /// <returns></returns>
        public static IEnumerable<INode> EnumAllAvailableMembers(
			IBlockNode ScopedBlock
			, IStatement ScopedStatement,
			CodeLocation Caret,
			IEnumerable<IAbstractSyntaxTree> CodeCache,
			MemberTypes VisibleMembers)
        {
            /*
             * Shown items:
             * 1) First walk through the current scope.
             * 2) Walk up the node hierarchy and add all their items (private as well as public members).
             * 3) Resolve base classes and add their non-private|static members.
             *
             * 4) Then add public members of the imported modules
             */
            var ret = new List<INode>();
            var ImportCache = ResolveImports(ScopedBlock.NodeRoot as DModule, CodeCache);

            #region Current module/scope related members

            // 1)
            if (ScopedStatement != null)
            {
                ret.AddRange(BlockStatement.GetItemHierarchy(ScopedStatement, Caret));
            }

            var curScope = ScopedBlock;

            // 2)
            while (curScope != null)
            {
                // Walk up inheritance hierarchy
                if (curScope is DClassLike)
                {
                    var curWatchedClass = curScope as DClassLike;
                    // MyClass > BaseA > BaseB > Object
                    while (curWatchedClass != null)
                    {
                        if (curWatchedClass.TemplateParameters != null)
                            ret.AddRange(curWatchedClass.TemplateParameterNodes as IEnumerable<INode>);

                        foreach (var m in curWatchedClass)
                        {
                            var dm2 = m as DNode;
                            var dm3 = m as DMethod; // Only show normal & delegate methods
                            if (!CanAddMemberOfType(VisibleMembers, m) || dm2 == null ||
                                (dm3 != null && !(dm3.SpecialType == DMethod.MethodType.Normal || dm3.SpecialType == DMethod.MethodType.Delegate))
                                )
                                continue;

                            // Add static and non-private members of all base classes;
                            // Add everything if we're still handling the currently scoped class
                            if (curWatchedClass == curScope || dm2.IsStatic || !dm2.ContainsAttribute(DTokens.Private))
                                ret.Add(m);
                        }

                        // Stop adding if Object class level got reached
                        if (!string.IsNullOrEmpty(curWatchedClass.Name) && curWatchedClass.Name.ToLower() == "object")
                            break;

                        // 3)
                        var baseclassDefs = DResolver.ResolveBaseClass(curWatchedClass, new ResolverContext {
                            ParseCache = CodeCache,
                            ScopedBlock=ScopedBlock,
                            ImportCache = ImportCache });

                        if (baseclassDefs == null || baseclassDefs.Length<0)
                            break;
                        if (curWatchedClass == baseclassDefs[0].ResolvedTypeDefinition)
                            break;
                        curWatchedClass = baseclassDefs[0].ResolvedTypeDefinition as DClassLike;
                    }
                }
                else if (curScope is DMethod)
                {
                    var dm = curScope as DMethod;

                    if (VisibleMembers.HasFlag(MemberTypes.Variables))
                        ret.AddRange(dm.Parameters);

                    if (dm.TemplateParameters != null)
                        ret.AddRange(dm.TemplateParameterNodes as IEnumerable<INode>);

                    // The method's declaration children are handled above already via BlockStatement.GetItemHierarchy().
                    // except AdditionalChildren:
                    foreach (var ch in dm.AdditionalChildren)
                        if (CanAddMemberOfType(VisibleMembers, ch))
                            ret.Add(ch);

                    // If the method is a nested method,
                    // this method won't be 'linked' to the parent statement tree directly -
                    // so, we've to gather the parent method and add its locals to the return list
                    if (dm.Parent is DMethod)
                    {
                        var parDM = dm.Parent as DMethod;
                        var nestedBlock = parDM.GetSubBlockAt(Caret);

                        // Search for the deepest statement scope and add all declarations done in the entire hierarchy
                        ret.AddRange(BlockStatement.GetItemHierarchy(nestedBlock.SearchStatementDeeply(Caret), Caret));
                    }
                }
                else foreach (var n in curScope)
                    {
                        // Add anonymous enums' items
                        if (n is DEnum && string.IsNullOrEmpty(n.Name) && CanAddMemberOfType(VisibleMembers, n))
                        {
                            ret.AddRange((n as DEnum).Children);
                            continue;
                        }

                        var dm3 = n as DMethod; // Only show normal & delegate methods
                        if (
                            !CanAddMemberOfType(VisibleMembers, n) ||
                            (dm3 != null && !(dm3.SpecialType == DMethod.MethodType.Normal || dm3.SpecialType == DMethod.MethodType.Delegate)))
                            continue;

                        ret.Add(n);
                    }

                curScope = curScope.Parent as IBlockNode;
            }
            #endregion

            #region Global members
            // Add all non-private and non-package-only nodes
            foreach (var mod in ImportCache)
            {
                if (mod.FileName == (ScopedBlock.NodeRoot as IAbstractSyntaxTree).FileName)
                    continue;

                foreach (var i in mod)
                {
                    var dn = i as DNode;
                    if (dn != null)
                    {
                        // Add anonymous enums' items
                        if (dn is DEnum &&
                            string.IsNullOrEmpty(i.Name) &&
                            dn.IsPublic &&
                            !dn.ContainsAttribute(DTokens.Package) &&
                            CanAddMemberOfType(VisibleMembers, i))
                        {
                            ret.AddRange((i as DEnum).Children);
                            continue;
                        }

                        if (dn.IsPublic && !dn.ContainsAttribute(DTokens.Package) &&
                            CanAddMemberOfType(VisibleMembers, dn))
                            ret.Add(dn);
                    }
                    else
                        ret.Add(i);
                }
            }
            #endregion

            if (ret.Count < 1)
                return null;
            return ret;
        }
Example #8
0
        public static bool CanAddMemberOfType(MemberTypes VisibleMembers, INode n)
        {
            if(n is DMethod)
                return (n as DMethod).Name!="" && VisibleMembers.HasFlag(MemberTypes.Methods);

            if(n is DVariable)
            {
                var d=n as DVariable;

                // Only add aliases if at least types,methods or variables shall be shown.
                if(d.IsAlias)
                    return
                        VisibleMembers.HasFlag(MemberTypes.Methods) ||
                        VisibleMembers.HasFlag(MemberTypes.Types) ||
                        VisibleMembers.HasFlag(MemberTypes.Variables);

                return VisibleMembers.HasFlag(MemberTypes.Variables);
            }

            if (n is DClassLike)
                return VisibleMembers.HasFlag(MemberTypes.Types);

            if(n is DEnum)
            {
                var d=n as DEnum;

                // Only show enums if a) they're named and types are allowed or b) variables are allowed
                return (d.IsAnonymous ? false : VisibleMembers.HasFlag(MemberTypes.Types)) ||
                    VisibleMembers.HasFlag(MemberTypes.Variables);
            }

            return false;
        }
Example #9
0
 /// <summary>
 /// 获取当前 <see cref="System.Type"/> 定义的指定名称和类型的所有成员,包括其所有内部成员和继承的成员。
 /// </summary>
 /// <param name="_this">表示待查找成员的 System.Type 对象。</param>
 /// <param name="name">指定的 MemberInfo 名称。</param>
 /// <param name="memberType">指定的 MemberTypes 成员类型;如果该参数值为 MemberTypes.All,则不按成员类型过滤返回列表。</param>
 /// <returns>一个表示具有指定名称的公共成员的 <see cref="System.Reflection.MemberInfo"/> 对象数组(如果找到的话);否则为空数组。</returns>
 public static MemberInfo[] GetAllMembers(this Type _this, string name, MemberTypes memberType)
 {
     Check.NotEmpty(name, "name");
     return(GetAllMembers(_this).Where(m => m.Name == name && memberType.HasFlag(m.MemberType)).ToArray());
 }
Example #10
0
 /// <summary>
 /// 获取当前 <see cref="System.Type"/> 定义的指定类型的所有成员,包括其所有内部成员和继承的成员。
 /// </summary>
 /// <param name="_this">表示待查找成员的 System.Type 对象。</param>
 /// <param name="memberType">指定的 MemberTypes 成员类型;如果该参数值为 MemberTypes.All,则不按成员类型过滤返回列表。</param>
 /// <returns>返回 System.Type 对象中符合过滤条件的所有 MemberInfo 成员对象。</returns>
 public static MemberInfo[] GetAllMembers(this Type _this, MemberTypes memberType)
 {
     return(GetAllMembers(_this).Where(m => memberType.HasFlag(m.MemberType)).ToArray());
 }