summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs')
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs273
1 files changed, 273 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs b/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs
new file mode 100644
index 0000000..4c40c54
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs
@@ -0,0 +1,273 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MemberDictionary : ICollection < Member > {
+
+ private Dictionary < string, List < Member > > index = new Dictionary < string, List < Member > >();
+
+ private TypeNode type;
+
+ // 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);
+
+ }
+
+ }
+
+ }
+
+ public List < Member > AllMembers {
+ get {
+ List < Member > list = new List < Member >();
+ foreach (List < Member > entries in index.Values) {
+ list.AddRange(entries);
+ }
+ return (list);
+ }
+ }
+
+ public int Count {
+ get {
+ int count = 0;
+ foreach (List < Member > entries in index.Values) {
+ count += entries.Count;
+ }
+ return (count);
+ }
+ }
+
+ public IList < string > MemberNames {
+ get {
+ return (new List < string >(index.Keys));
+ }
+ }
+
+ // access the data
+
+ public TypeNode Type {
+ get {
+ return (type);
+ }
+ }
+
+ bool ICollection < Member >.IsReadOnly {
+ get {
+ return (true);
+ }
+ }
+
+ public List < Member > this[string name] {
+ get {
+ List < Member > members;
+ index.TryGetValue(name, out members);
+ return (members);
+ }
+ }
+
+ public void Clear() {
+ throw new InvalidOperationException();
+ }
+
+ public bool Contains(Member member) {
+
+ // get candidate members with the same name
+ List < Member > candidates;
+ bool found = index.TryGetValue(member.Name.Name, out candidates);
+
+ // if no candidates were found, we don't have the member
+ if (!found) return (false);
+
+ // iterate over the candidates, looking for one of the same type with the same parameters
+ ParameterList parameters = GetParameters(member);
+ foreach (Member candidate in candidates) {
+
+ // candidates must be of the same type
+ if (candidate.NodeType != member.NodeType) continue;
+
+ // get candidate parameters
+ ParameterList candidateParameters = GetParameters(candidate);
+
+ // number of parameters must match
+ if (parameters.Count != candidateParameters.Count) continue;
+
+ // each parameter type must match
+ bool parameterMismatch = false;
+ for (int i = 0; i < parameters.Count; i++) {
+ if (parameters[i].Type != candidateParameters[i].Type) parameterMismatch = true;
+ }
+ // if the parameters match, we have the member
+ if (!parameterMismatch) return (true);
+
+ }
+
+ // no candidates matched
+ return (false);
+
+ }
+
+ // methods to complete ICollection<Member>
+
+ public void CopyTo(Member[] array, int index) {
+ throw new NotImplementedException();
+ }
+
+ void ICollection < Member >.Add(Member member) {
+ throw new InvalidOperationException();
+ }
+
+ IEnumerator < Member > IEnumerable < Member >.GetEnumerator() {
+ return (GetEnumerator());
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() {
+ return (GetEnumerator());
+ }
+
+ public bool Remove(Member member) {
+ throw new InvalidOperationException();
+ }
+
+ private static ParameterList GetParameters(Member member) {
+
+ // if the member is a method, get it's parameter list
+ Method method = member as Method;
+ if (method != null) {
+ return (method.Parameters);
+ }
+
+ // if the member is a property, get it's parameter list
+ Property property = member as Property;
+ if (property != null) {
+ return (property.Parameters);
+ }
+
+ // member is neither a method nor a property
+ return (new ParameterList());
+ //return(null);
+
+ }
+
+ private void AddMember(Member member) {
+
+ // get the member name
+ string name = member.Name.Name;
+
+ // look up the member list for that name
+ List < Member > members;
+ if (!index.TryGetValue(name, out members)) {
+ // if there isn't one already, make one
+ members = new List < Member >();
+ index.Add(name, members);
+ }
+ // add the member to the list
+ members.Add(member);
+
+ }
+
+ // enumerator stuff
+
+ private IEnumerator < Member > GetEnumerator() {
+ return (AllMembers.GetEnumerator());
+ }
+
+ }
+
+}