/// <summary> /// This is used to visit a list of members /// </summary> /// <param name="members">The list of members to visit</param> protected virtual void VisitMembers(MemberList members) { // Visit the members in sorted order foreach (Member member in members.OrderBy(m => m.FullName)) { // Don't visit nested types either as they are already visited if (!(member is TypeNode) && filter.IsExposedMember(member)) { this.VisitMember(member); } } }
//===================================================================== /// <summary> /// Constructor /// </summary> /// <param name="type">The type for which the dictionary is created</param> /// <param name="filter">The API filter used to exclude unwanted members</param> public MemberDictionary(TypeNode type, ApiFilter filter) { this.type = type; index = new Dictionary <string, List <Member> >(); // !EFW - Track excluded overridden members. These need to be filtered out below or the inherited // base member shows up in the member list. var excludedOverriddenMembers = new List <Member>(); // Add all member of the type except nested types and members that the filter rejects foreach (var member in type.Members) { if (!(member is TypeNode) && filter.IsExposedMember(member)) { this.AddMember(member); } else if (member.OverridesBaseClassMember) { excludedOverriddenMembers.Add(member.OverriddenMember); } } // For enumerations, don't list inherited members if (type is EnumNode) { return; } // For interfaces, list members of inherited interfaces if (type is Interface && filter.IncludeInheritedMembers) { var derivedMembers = new HashSet <string>(); string nameAndParams; int pos; // !EFW - This is a hack to filter out duplicate members by name and parameters for cases where // an interface member in the derived type uses the "new" keyword to re-implement a member using // the same name as in the base type. In such cases, the member is not truly hidden as it is in // a class since it still needs to be explicitly implemented when derived from but we don't want // to see it duplicated below as part of the inherited members. foreach (var m in this) { pos = m.FullName.LastIndexOf('('); if (pos != -1) { pos = m.FullName.LastIndexOf('.', pos, pos); } else { pos = m.FullName.LastIndexOf('.'); } if (pos != -1) { derivedMembers.Add(m.FullName.Substring(pos)); } else { derivedMembers.Add(m.FullName); } } foreach (var contract in type.Interfaces) { // Members of hidden interfaces don't count if (filter.IsExposedType(contract)) { // Otherwise, add inherited interface members except those rejected by the filters. This // is necessary to remove accessor methods. foreach (var contractMember in contract.Members) { pos = contractMember.FullName.LastIndexOf('('); if (pos != -1) { pos = contractMember.FullName.LastIndexOf('.', pos, pos); } else { pos = contractMember.FullName.LastIndexOf('.'); } if (pos != -1) { nameAndParams = contractMember.FullName.Substring(pos); } else { nameAndParams = contractMember.FullName; } if (!filter.IsExcludedFrameworkMember(type, contractMember) && filter.IsExposedMember(contractMember) && !derivedMembers.Contains(nameAndParams)) { this.AddMember(contractMember); derivedMembers.Add(nameAndParams); } } } } return; } // Don't list inherited members for static classes if (type.IsAbstract && type.IsSealed) { return; } // If not including inherited members, don't go any further if (!filter.IncludeInheritedMembers) { return; } // Now iterate up through the type hierarchy for (TypeNode parentType = type.BaseType; parentType != null; parentType = parentType.BaseType) { foreach (var parentMember in parentType.Members) { // Don't add constructors if (parentMember.NodeType == NodeType.InstanceInitializer || parentMember.NodeType == NodeType.StaticInitializer) { continue; } // Don't add inherited static members if (parentMember.IsStatic) { continue; } // Don't add nested types if (parentMember is TypeNode) { continue; } // Don't add protected members if the derived type is sealed and they are not wanted if (!filter.IncludeSealedProtected && type.IsSealed && (parentMember.IsFamily || parentMember.IsFamilyOrAssembly)) { continue; } // Don't add members that the filter rejects if (filter.IsExcludedFrameworkMember(type, parentMember) || !filter.IsExposedMember(parentMember)) { if (parentMember.OverridesBaseClassMember) { excludedOverriddenMembers.Add(parentMember.OverriddenMember); } continue; } // Don't add members we have overridden if (this.Contains(parentMember)) { continue; } // Don't add virtual members that have had their overridden counterparts excluded if (excludedOverriddenMembers.Contains(parentMember)) { if (parentMember.OverridesBaseClassMember) { excludedOverriddenMembers.Add(parentMember.OverriddenMember); } continue; } // Otherwise, add the member this.AddMember(parentMember); } } }
// construct the dictionary public MemberDictionary(TypeNode type, ApiFilter filter) { this.type = type; bool isSealed = type.IsSealed; // add all member of the type that the filter allows MemberList members = type.Members; for (int i = 0; i < members.Count; i++) { Member member = members[i]; // don't add nested types if (member is TypeNode) { continue; } // if our type is sealed, don't add protected members (is this check even necessary?) // if (isSealed && (member.IsFamily || member.IsFamilyAndAssembly)) continue; // don't add members that the filter rejects if (!filter.IsExposedMember(member)) { continue; } // okay, add the member AddMember(member); } // for enumerations, don't list inherited members if (type is EnumNode) { return; } // for interfaces, list members of inherited interfaces if (type is Interface) { InterfaceList contracts = type.Interfaces; for (int i = 0; i < contracts.Count; i++) { Interface contract = contracts[i]; // members of hidden interfaces don't count if (!filter.IsExposedType(contract)) { continue; } // otherwise, add inherited interface members MemberList contractMembers = contract.Members; for (int j = 0; j < contractMembers.Count; j++) { Member contractMember = contractMembers[j]; // check for exposure; this is necessary to remove accessor methods if (!filter.IsExposedMember(contractMember)) { continue; } AddMember(contractMember); } } return; } // don't list inherited memers for static classes if (type.IsAbstract && type.IsSealed) { return; } // now interate up through the type hierarchy for (TypeNode parentType = type.BaseType; parentType != null; parentType = parentType.BaseType) { // iterate through the members of each type MemberList parentMembers = parentType.Members; for (int i = 0; i < parentMembers.Count; i++) { Member parentMember = parentMembers[i]; // don't add constructors if ((parentMember.NodeType == NodeType.InstanceInitializer) || (parentMember.NodeType == NodeType.StaticInitializer)) { continue; } // don't add inherited static members if (parentMember.IsStatic) { continue; } // don't add nested types if (parentMember is TypeNode) { continue; } // if our type is sealed, don't add protected members // if (isSealed && (parentMember.IsFamily || parentMember.IsFamilyAndAssembly)) continue; // don't add members that the filter rejects if (!filter.IsExposedMember(parentMember)) { continue; } // don't add members we have overridden if (this.Contains(parentMember)) { continue; } // otherwise, add the member AddMember(parentMember); } } }