summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/MRefBuilder
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/MRefBuilder')
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs328
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs81
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config102
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs339
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj113
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs23
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs19
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs1316
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs273
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs40
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs28
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/TextStrings.txt4
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs243
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/reflection.xsd686
14 files changed, 3595 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs
new file mode 100644
index 0000000..f935921
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs
@@ -0,0 +1,328 @@
+// 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.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ // Extension method add in
+
+ public class ExtensionMethodAddIn : MRefBuilderAddIn {
+
+ private Dictionary < TypeNode, List < Method > > index = new Dictionary < TypeNode, List < Method > >();
+
+ private bool isExtensionMethod = false;
+
+ private ManagedReflectionWriter reflector;
+
+ public ExtensionMethodAddIn(ManagedReflectionWriter reflector, XPathNavigator configuration) : base(reflector, configuration) {
+ this.reflector = reflector;
+ reflector.RegisterStartTagCallback("apis", new MRefBuilderCallback(RecordExtensionMethods));
+ reflector.RegisterEndTagCallback("elements", new MRefBuilderCallback(AddExtensionMethods));
+ reflector.RegisterStartTagCallback("apidata", new MRefBuilderCallback(AddExtensionSubsubgroup));
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="writer"></param>
+ /// <param name="type">the current type being extended</param>
+ /// <param name="extensionMethodTemplate">A reference to the extension method. For generic methods, this is a reference to the
+ /// non-specialized method, e.g. System.Linq.Enumerable.Select``2.
+ /// </param>
+ /// <param name="specialization">When the current type implements or inherits from a specialization of a generic type,
+ /// this parameter has a TypeNode for the type used as apecialization of the generic type's first template param.
+ /// </param>
+ private void AddExtensionMethod(XmlWriter writer, TypeNode type, Method extensionMethodTemplate, TypeNode specialization)
+ {
+ // If this is a specialization of a generic method, construct a Method object that describes the specialization
+ Method extensionMethodTemplate2 = extensionMethodTemplate;
+ if (extensionMethodTemplate2.IsGeneric && (specialization != null))
+ {
+ // the specialization type is the first of the method's template arguments
+ TypeNodeList templateArgs = new TypeNodeList();
+ templateArgs.Add(specialization);
+ // add any additional template arguments
+ for (int i = 1; i < extensionMethodTemplate.TemplateParameters.Count; i++)
+ templateArgs.Add(extensionMethodTemplate.TemplateParameters[i]);
+ extensionMethodTemplate2 = extensionMethodTemplate.GetTemplateInstance(type, templateArgs);
+ }
+ TypeNode extensionMethodTemplateReturnType = extensionMethodTemplate2.ReturnType;
+ ParameterList extensionMethodTemplateParameters = extensionMethodTemplate2.Parameters;
+
+ ParameterList extensionMethodParameters = new ParameterList();
+ for (int i = 1; i < extensionMethodTemplateParameters.Count; i++)
+ {
+ Parameter extensionMethodParameter = extensionMethodTemplateParameters[i];
+ extensionMethodParameters.Add(extensionMethodParameter);
+ }
+ Method extensionMethod = new Method(extensionMethodTemplate.DeclaringType, new AttributeList(), extensionMethodTemplate.Name, extensionMethodParameters, extensionMethodTemplate.ReturnType, null);
+ extensionMethod.Flags = extensionMethodTemplate.Flags & ~MethodFlags.Static;
+
+ // for generic methods, set the template args and params so the template data is included in the id and the method data
+ if (extensionMethodTemplate2.IsGeneric)
+ {
+ extensionMethod.IsGeneric = true;
+ if (specialization != null)
+ {
+ // set the template args for the specialized generic method
+ extensionMethod.TemplateArguments = extensionMethodTemplate2.TemplateArguments;
+ }
+ else
+ {
+ // set the generic template params for the non-specialized generic method
+ extensionMethod.TemplateParameters = extensionMethodTemplate2.TemplateParameters;
+ }
+ }
+
+ // Get the id
+ string extensionMethodTemplateId = reflector.ApiNamer.GetMemberName(extensionMethodTemplate);
+
+ // write the element node
+ writer.WriteStartElement("element");
+ writer.WriteAttributeString("api", extensionMethodTemplateId);
+ writer.WriteAttributeString("source", "extension");
+ isExtensionMethod = true;
+ reflector.WriteMember(extensionMethod);
+ isExtensionMethod = false;
+ writer.WriteEndElement();
+ }
+
+ private void AddExtensionMethods(XmlWriter writer, Object info)
+ {
+
+ MemberDictionary members = info as MemberDictionary;
+ if (members == null) return;
+
+ TypeNode type = members.Type;
+
+ InterfaceList contracts = type.Interfaces;
+ foreach (Interface contract in contracts)
+ {
+ List<Method> extensionMethods = null;
+ if (index.TryGetValue(contract, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, null);
+ }
+ if (contract.IsGeneric && (contract.TemplateArguments != null) && (contract.TemplateArguments.Count > 0))
+ {
+ Interface templateContract = (Interface)ReflectionUtilities.GetTemplateType(contract);
+ TypeNode specialization = contract.TemplateArguments[0];
+ if (index.TryGetValue(templateContract, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ {
+ if (IsValidTemplateArgument(specialization, extensionMethod.TemplateParameters[0]))
+ {
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, specialization);
+ }
+ }
+ }
+ }
+ }
+
+ TypeNode comparisonType = type;
+ while (comparisonType != null)
+ {
+ List<Method> extensionMethods = null;
+ if (index.TryGetValue(comparisonType, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, null);
+ }
+ if (comparisonType.IsGeneric && (comparisonType.TemplateArguments != null) && (comparisonType.TemplateArguments.Count > 0))
+ {
+ TypeNode templateType = ReflectionUtilities.GetTemplateType(comparisonType);
+ TypeNode specialization = comparisonType.TemplateArguments[0];
+ if (index.TryGetValue(templateType, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ {
+ if (IsValidTemplateArgument(specialization, extensionMethod.TemplateParameters[0]))
+ {
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, specialization);
+ }
+ }
+ }
+ }
+ comparisonType = comparisonType.BaseType;
+ }
+ }
+
+ private void AddExtensionSubsubgroup(XmlWriter writer, Object data) {
+ if (isExtensionMethod) writer.WriteAttributeString("subsubgroup", "extension");
+ }
+
+ private bool HasExtensionAttribute(Method method) {
+ AttributeList attributes = method.Attributes;
+ foreach (AttributeNode attribute in attributes) {
+ if (attribute.Type.FullName == "System.Runtime.CompilerServices.ExtensionAttribute") return (true);
+ }
+ return (false);
+ }
+
+ private bool IsValidTemplateArgument(TypeNode type, TypeNode parameter) {
+ if (type == null) throw new ArgumentNullException("type");
+ if (parameter == null) throw new ArgumentNullException("parameter");
+
+ // check that the parameter really is a type parameter
+
+ ITypeParameter itp = parameter as ITypeParameter;
+ if (itp == null) throw new ArgumentException("The 'parameter' argument is null or not an 'ITypeParameter'.");
+
+ // test constraints
+
+ bool reference = ((itp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) > 0);
+ if (reference && type.IsValueType) return (false);
+
+ bool value = ((itp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) > 0);
+ if (value && !type.IsValueType) return (false);
+
+ bool constructor = ((itp.TypeParameterFlags & TypeParameterFlags.DefaultConstructorConstraint) > 0);
+
+
+ InterfaceList contracts = parameter.Interfaces;
+ if (contracts != null) {
+ foreach (Interface contract in contracts) {
+ if (!type.IsAssignableTo(contract)) return (false);
+ }
+ }
+
+ TypeNode parent = parameter.BaseType;
+ if ((parent != null) && !type.IsAssignableTo(parent)) return (false);
+
+ // okay, passed all tests
+
+ return (true);
+
+ }
+
+ private void RecordExtensionMethods(XmlWriter writer, Object info)
+ {
+ NamespaceList spaces = (NamespaceList)info;
+ foreach (Namespace space in spaces)
+ {
+ TypeNodeList types = space.Types;
+ foreach (TypeNode type in types)
+ {
+
+ MemberList members = type.Members;
+
+ // go through the members, looking for fields signaling extension methods
+ foreach (Member member in members)
+ {
+
+ Method method = member as Method;
+ if (method == null) continue;
+
+ if (!reflector.ApiFilter.IsExposedMember(method)) continue;
+
+ if (!HasExtensionAttribute(method)) continue;
+
+ ParameterList parameters = method.Parameters;
+ TypeNode extendedType = parameters[0].Type;
+
+ // recognize generic extension methods where the extended type is a specialization of a generic type,
+ // and the extended type's specialized template arg is a type parameter declared by the generic extension method
+ // In this case, we need to save a TypeNode for the non-specialized type in the index,
+ // because a TypeNode for the specialized type won't match correctly in AddExtensionMethods
+ // Note: we are not interested in extended types that are specialized by a specific type rather than by the extension method's template param.
+ if (method.IsGeneric && (method.TemplateParameters.Count > 0))
+ {
+ if (extendedType.IsGeneric && (extendedType.TemplateArguments != null) && (extendedType.TemplateArguments.Count == 1))
+ {
+ // is the extended type's template arg a template parameter, rather than a specialized type?
+ TypeNode arg = extendedType.TemplateArguments[0];
+ if (arg.IsTemplateParameter)
+ {
+ // is the template parameter declared on the extension method
+ ITypeParameter gtp = (ITypeParameter)arg;
+ if ((gtp.DeclaringMember == method) && (gtp.ParameterListIndex == 0))
+ {
+ // get a TypeNode for the non-specialized type
+ extendedType = ReflectionUtilities.GetTemplateType(extendedType);
+ }
+ }
+ }
+ }
+
+ List<Method> methods = null;
+ if (!index.TryGetValue(extendedType, out methods))
+ {
+ methods = new List<Method>();
+ index.Add(extendedType, methods);
+ }
+ methods.Add(method);
+
+ }
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Determines whether an extension method is hidden by a member that's already defined on the type being extended.
+ /// The extension method is hidden if it has the same name, template params, and parameters as a defined method.
+ /// </summary>
+ /// <param name="extensionMethod">The extension method to compare.</param>
+ /// <param name="members">A dictionary of the members defined on the type being extended.</param>
+ /// <returns></returns>
+ private bool IsExtensionMethodHidden(Method extensionMethod, MemberDictionary members)
+ {
+ if (!members.MemberNames.Contains(extensionMethod.Name.Name))
+ return false;
+
+ // get a list of members with the same name as the extension method
+ List<Member> membersList = members[extensionMethod.Name.Name];
+ foreach (Member member in membersList)
+ {
+ // the hiding member must be a method
+ if (member.NodeType != NodeType.Method)
+ continue;
+ Method method = (Method)member;
+
+ // do the generic template parameters of both methods match?
+ if (!method.TemplateParametersMatch(extensionMethod.TemplateParameters))
+ continue;
+
+ // do both methods have the same number of parameters?
+ // (not counting the extension method's first param, which identifies the extended type)
+ if (method.Parameters.Count != (extensionMethod.Parameters.Count - 1))
+ continue;
+
+ // do the parameter types of both methods match?
+ if (DoParameterTypesMatch(extensionMethod.Parameters, method.Parameters))
+ return true;
+ }
+ return false;
+ }
+
+ private bool DoParameterTypesMatch(ParameterList extensionParams, ParameterList methodParams)
+ {
+ for (int i = 0; i < methodParams.Count; i++)
+ {
+ if (methodParams[i].Type.FullName != extensionParams[i + 1].Type.FullName)
+ return false;
+ }
+ return true;
+ }
+
+
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs b/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs
new file mode 100644
index 0000000..dcd54ad
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs
@@ -0,0 +1,81 @@
+// 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.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mref")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#ApiNamer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#.ctor(System.IO.TextWriter,Microsoft.Ddue.Tools.Reflection.ApiFilter,Microsoft.Ddue.Tools.Reflection.ApiNamer)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#.ctor(System.IO.TextWriter,Microsoft.Ddue.Tools.Reflection.ApiNamer)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.MemberDictionary")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.MemberDictionary")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Type")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Contains(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#CopyTo(System.Compiler.Member[],System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Remove(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt64(System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetAppliedFields(System.Compiler.EnumNode,System.Int64)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt64(System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteLiteral(System.Compiler.Literal,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteStartTypeReference(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetVisibility(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteEventData(System.Compiler.Event)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WritePropertyData(System.Compiler.Property)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#AssemblyNotFound(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#UnresolvedAssemblyReferenceHandler(System.Object,Microsoft.Ddue.Tools.Reflection.AssemblyReferenceEventArgs)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.LastIndexOf(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.EndsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#AddAttachedMembers(System.Xml.XmlWriter,System.Object)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "index", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#CopyTo(System.Compiler.Member[],System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#AddAttachedMembers(System.Xml.XmlWriter,System.Object)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#AllMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Item[System.String]")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "extensionMethodTemplateReturnType", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#AddExtensionMethod(System.Xml.XmlWriter,System.Compiler.TypeNode,System.Compiler.Method,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "constructor", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#IsValidTemplateArgument(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#HasExtensionAttribute(System.Compiler.Method)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#IsValidTemplateArgument(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isSealed", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#.ctor(System.Compiler.TypeNode,Microsoft.Ddue.Tools.Reflection.ApiFilter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.ICollection`1<System.Compiler.Member>.Add(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.ICollection`1<System.Compiler.Member>.IsReadOnly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.IEnumerable.GetEnumerator()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.IEnumerable`1<System.Compiler.Member>.GetEnumerator()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.MRefBuilder")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#AssemblyNotFound(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "addin", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "configuration", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilderAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "writer", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilderAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetParamArrayAttribute(System.Compiler.Parameter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Members")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Types")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Namespaces")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteAssignment(System.Compiler.NamedArgument)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "type", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteAttributes(System.Compiler.AttributeList,System.Compiler.SecurityAttributeList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteMember(System.Compiler.Member,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "member", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteMemberContainers(System.Compiler.Member,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteNamespaces(System.Compiler.NamespaceList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "spaces", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteNamespaces(System.Compiler.NamespaceList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteStartTypeReference(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.DxCoach.ResourceHelper.#GetStream(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.DxCoach.ResourceHelper.#GetString(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "type", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#DoParameterTypesMatch(System.Compiler.ParameterList,System.Compiler.ParameterList)")]
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config
new file mode 100644
index 0000000..2f6c5cd
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config
@@ -0,0 +1,102 @@
+<configuration>
+ <dduetools>
+ <platform version="2.0" path="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\" />
+ <resolver type="Microsoft.Ddue.Tools.Reflection.AssemblyResolver" assembly="Reflection.dll" use-gac="false" />
+ <!--
+ <namer type="Microsoft.Ddue.Tools.Reflection.OrcasNamer" assembly="Microsoft.Ddue.Tools.Reflection.dll" />
+ -->
+ <addins>
+ <addin type="Microsoft.Ddue.Tools.XamlAttachedMembersAddIn" assembly="MRefBuilder.exe" />
+ <addin type="Microsoft.Ddue.Tools.ExtensionMethodAddIn" assembly="MRefBuilder.exe" />
+ </addins>
+ <!--
+ <apiFilter expose="true">
+ <namespace name="System" expose="true">
+ <type name="Object" expose="false">
+ <member name="ToString" expose="true" />
+ </type>
+ </namespace>
+ </apiFilter>
+ -->
+ <attributeFilter expose="true">
+ <!-- Most attributes in System.ComponentModel control designer behavior. Don't show them. -->
+ <!-- The expections are attributes relating to data binding. Do show them. -->
+ <namespace name="System.ComponentModel" expose="false">
+ <type name="BindableAttribute" expose="true"/>
+ <type name="BrowsableAttribute" expose="true" />
+ <type name="ComplexBindingPropertiesAttribute" expose="true"/>
+ <type name="DataObjectAttribute" expose="true"/>
+ <type name="DefaultBindingPropertyAttribute" expose="true"/>
+ <type name="ListBindableAttribute" expose="true"/>
+ <type name="LookupBindingPropertiesAttribute" expose="true"/>
+ <type name="SettingsBindableAttribute" expose="true"/>
+ <type name="TypeConverterAttribute" expose="true"/>
+ </namespace>
+ <namespace name="System.ComponentModel.Design" expose="false" />
+ <namespace name="System.ComponentModel.Design.Serialization" expose="false" />
+ <!-- Most attributes in System.Diagnostics control debugger behavior. Don't show them. -->
+ <namespace name="System.Diagnostics" expose="false">
+ <type name="ConditionalAttribute" expose="true"/>
+ <type name="EventLogPermissionAttribute" expose="true"/>
+ <type name="PerformanceCounterPermissionAttribute" expose="true"/>
+ </namespace>
+ <!-- Attributes in System.Diagnostics.CodeAnalysis control interaction with FxCop. Don't show them. -->
+ <namespace name="System.Diagnostics.CodeAnalysis" expose="false" />
+ <!-- Attributes in System.EnterpriseServices control obscure details of COM+ interop. Don't show them. -->
+ <namespace name="System.EnterpriseServices" expose="false" />
+ <!-- The DefaultMember attribute is usually compiler-generated. Users will see it from the member syntax. -->
+ <namespace name="System.Reflection" expose="true">
+ <type name="DefaultMemberAttribute" expose="false" />
+ </namespace>
+ <!-- Attributes in System.Runtime.CompilerServices control obscure details of compilation. Don't show them. -->
+ <namespace name="System.Runtime.CompilerServices" expose="false">
+ <type name="ExtensionAttribute" expose="true" />
+ </namespace>
+ <!-- Attributes in System.Runtime.ConstrinedExecution control obscure details of compilation. Don't show them. -->
+ <namespace name="System.Runtime.ConstrainedExecution" expose="false" />
+ <!-- Most atributes in System.Runtime.InteropServices control obscure details of COM interop. Don't show them. -->
+ <namespace name="System.Runtime.InteropServices" expose="false">
+ <type name="ComVisibleAttribute" expose="true"/>
+ <type name="GuidAttribute" expose="true"/>
+ <type name="ClassInterfaceAttribute" expose="true"/>
+ <type name="InterfaceTypeAttribute" expose="true"/>
+ </namespace>
+ <!-- Attributes in System.Runtime.Versioning control details of resource loading. Don't show them. -->
+ <namespace name="System.Runtime.Versioning" expose="false" />
+ <!-- Attributes in System.Security might hint as security implementation details. Don't show them. -->
+ <namespace name="System.Security" expose="false">
+ <type name="SecurityCriticalAttribute" expose="true" />
+ <type name="SecurityTreatAsSafeAttribute" expose="true" />
+ <type name="AllowPartiallyTrustedCallersAttribute" expose="true" />
+ </namespace>
+ <!-- Attributes in System.Web.Compilation control interaction with the Expression designer. Don't show them. -->
+ <namespace name="System.Web.Compilation" expose="false" />
+ <!-- The ASP.NET team only wants these attributes exposed from their namespace. Their logic ecscapes me, but here it is. -->
+ <namespace name="System.Web.UI" expose="false">
+ <type name="ControlValuePropertyAttribute" expose="true"/>
+ <type name="PersistenceModeAttribute" expose="true" />
+ <type name="ValidationPropertyAttribute" expose="true"/>
+ <type name="WebResourceAttribute" expose="true"/>
+ <type name="TemplateContainerAttribute" expose="true"/>
+ <type name="ThemeableAttribute" expose="true"/>
+ <type name="TemplateInstanceAttribute" expose="true"/>
+ </namespace>
+ <!-- Don't show attributes related to XAML serialization details. -->
+ <namespace name="System.Windows.Markup" expose="true">
+ <type name="ConstructorArgumentAttribute" expose="false" />
+ <type name="DependsOnAttribute" expose="false" />
+ <type name="DesignerSerializationOptionsAttribute" expose="false" />
+ <type name="ValueSerializerAttribute" expose="false" />
+ <type name="XmlnsCompatibleWithAttribute" expose="false" />
+ <type name="XmlnsDefinitionAttribute" expose="false" />
+ <type name="XmlnsPrefixAttribute" expose="false" />
+ </namespace>
+ <!-- Attributes in System.Xml.Serialization control obscure details of XML serialization. Don't show them.-->
+ <namespace name="System.Xml.Serialization" expose="false" />
+ <!-- The GeneratedCodeAttribute is useful only to tools, and should be hidden from end users.-->
+ <namespace name="System.CodeDom.Compiler" expose="true">
+ <type name="GeneratedCodeAttribute" expose="false" />
+ </namespace>
+ </attributeFilter>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs
new file mode 100644
index 0000000..895d799
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs
@@ -0,0 +1,339 @@
+// 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.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+using System.Compiler;
+using Microsoft.Ddue.Tools.CommandLine;
+using Microsoft.Ddue.Tools.Reflection;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MRefBuilder {
+
+ public static int Main(string[] args) {
+
+ // write banner
+ ConsoleApplication.WriteBanner();
+
+ // specify options
+ OptionCollection options = new OptionCollection();
+ options.Add(new SwitchOption("?", "Show this help page."));
+ options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath"));
+ options.Add(new StringOption("config", "Specify a configuration file. If unspecified, MRefBuilder.config is used", "configFilePath"));
+ options.Add(new ListOption("dep", "Speficy assemblies to load for dependencies.", "dependencyAssembly"));
+ // options.Add( new BooleanOption("namespaces", "Control whether information on namespaces in provided.") );
+ options.Add(new BooleanOption("internal", "Specify whether to document internal as well as externally exposed APIs."));
+
+ // process options
+ ParseArgumentsResult results = options.ParseArguments(args);
+ if (results.Options["?"].IsPresent) {
+ Console.WriteLine("MRefBuilder [options] assemblies");
+ options.WriteOptionSummary(Console.Out);
+ return (0);
+ }
+
+ // check for invalid options
+ if (!results.Success) {
+ results.WriteParseErrors(Console.Out);
+ return (1);
+ }
+
+ // check for missing or extra assembly directories
+ if (results.UnusedArguments.Count < 1) {
+ Console.WriteLine("Specify at least one assembly to reflect.");
+ return (1);
+ }
+
+ // load the configuration file
+ XPathDocument config;
+ string configDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ string configFile = Path.Combine(configDirectory, "MRefBuilder.config");
+ if (results.Options["config"].IsPresent) {
+ configFile = (string)results.Options["config"].Value;
+ configDirectory = Path.GetDirectoryName(configFile);
+ }
+ try {
+ config = new XPathDocument(configFile);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message));
+ return (1);
+ } catch (XmlException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The configuration file '{0}' is not well-formed. The error message is: {1}", configFile, e.Message));
+ return (1);
+ }
+
+ // adjust the target platform
+ XPathNodeIterator platformNodes = config.CreateNavigator().Select("/configuration/dduetools/platform");
+ if (platformNodes.MoveNext()) {
+ XPathNavigator platformNode = platformNodes.Current;
+ string version = platformNode.GetAttribute("version", String.Empty);
+ string path = platformNode.GetAttribute("path", String.Empty);
+ path = Environment.ExpandEnvironmentVariables(path);
+ if (!Directory.Exists(path)) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specifed target platform directory '{0}' does not exist.", path));
+ return (1);
+ }
+ if (version == "2.0") {
+ TargetPlatform.SetToV2(path);
+ } else if (version == "1.1") {
+ TargetPlatform.SetToV1_1(path);
+ } else if (version == "1.0") {
+ TargetPlatform.SetToV1(path);
+ } else {
+ Console.WriteLine("Unknown target platform version '{0}'.", version);
+ return (1);
+ }
+ }
+
+ // create a namer
+ ApiNamer namer = new OrcasNamer();
+ XPathNavigator namerNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/namer");
+ if (namerNode != null) {
+ string assemblyPath = namerNode.GetAttribute("assembly", String.Empty);
+ string typeName = namerNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ namer = (ApiNamer)assembly.CreateInstance(typeName);
+
+ if (namer == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+
+ // create a resolver
+ AssemblyResolver resolver = new AssemblyResolver();
+ XPathNavigator resolverNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/resolver");
+ if (resolverNode != null) {
+ string assemblyPath = resolverNode.GetAttribute("assembly", String.Empty);
+ string typeName = resolverNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ resolver = (AssemblyResolver)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[1] { resolverNode }, null, null);
+
+ if (resolver == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+ resolver.UnresolvedAssemblyReference += new EventHandler < AssemblyReferenceEventArgs >(UnresolvedAssemblyReferenceHandler);
+
+ // get a textwriter for output
+ TextWriter output = Console.Out;
+ if (results.Options["out"].IsPresent) {
+ string file = (string)results.Options["out"].Value;
+ try {
+ output = new StreamWriter(file, false, Encoding.UTF8);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+
+ // dependency directory
+ string[] dependencies = new string[0];
+ if (results.Options["dep"].IsPresent) dependencies = (string[])results.Options["dep"].Value;
+
+
+ try {
+ // create a builder
+ ManagedReflectionWriter builder = new ManagedReflectionWriter(output, namer);
+
+ // specify the resolver for the builder
+ builder.Resolver = resolver;
+
+ // builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+
+ // specify the filter for the builder
+
+ if (results.Options["internal"].IsPresent && (bool)results.Options["internal"].Value) {
+ builder.ApiFilter = new AllDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+ } else {
+ builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+ }
+
+ // register add-ins to the builder
+
+ XPathNodeIterator addinNodes = config.CreateNavigator().Select("/configuration/dduetools/addins/addin");
+ foreach (XPathNavigator addinNode in addinNodes) {
+ string assemblyPath = addinNode.GetAttribute("assembly", String.Empty);
+ string typeName = addinNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ MRefBuilderAddIn addin = (MRefBuilderAddIn)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { builder, addinNode }, null, null);
+
+ if (namer == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the addin assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The addin assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type '{0}' in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the addin assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the addin assembly '{1}' is not an MRefBuilderAddIn type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+
+ try {
+
+
+ // add a handler for unresolved assembly references
+ //builder.UnresolvedModuleHandler = new System.Compiler.Module.AssemblyReferenceResolver(AssemblyNotFound);
+
+ // load dependent bits
+ foreach (string dependency in dependencies) {
+ try {
+ builder.LoadAccessoryAssemblies(dependency);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading dependency assemblies. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+ // parse the bits
+ foreach (string dllPath in results.UnusedArguments) {
+ try {
+ builder.LoadAssemblies(dllPath);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading assemblies for reflection. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Loaded {0} assemblies for reflection and {1} dependency assemblies.", builder.Assemblies.Length, builder.AccessoryAssemblies.Length));
+
+ // register callbacks
+
+ //builder.RegisterStartTagCallback("apis", new MRefBuilderCallback(startTestCallback));
+
+ //MRefBuilderAddIn addin = new XamlAttachedMembersAddIn(builder, null);
+
+ builder.VisitApis();
+
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Wrote information on {0} namespaces, {1} types, and {2} members", builder.Namespaces.Length, builder.Types.Length, builder.Members.Length));
+
+ } finally {
+
+ builder.Dispose();
+ }
+
+ } finally {
+
+ // output.Close();
+
+ }
+
+ return (0);
+
+ }
+
+ private static AssemblyNode AssemblyNotFound(AssemblyReference reference, System.Compiler.Module module) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Unresolved assembly reference: {0} ({1}) required by {2}", reference.Name, reference.StrongName, module.Name));
+ Environment.Exit(1);
+ return (null);
+ }
+
+ private static void UnresolvedAssemblyReferenceHandler(Object o, AssemblyReferenceEventArgs e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Unresolved assembly reference: {0} ({1}) required by {2}", e.Reference.Name, e.Reference.StrongName, e.Referrer.Name));
+ Environment.Exit(1);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj
new file mode 100644
index 0000000..b62e525
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj
@@ -0,0 +1,113 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A8DCAD75-879F-4C97-803B-C9A17F227B04}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MrefBuilder</RootNamespace>
+ <AssemblyName>MrefBuilder</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ExtensionMethodAddIn.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="MemberDictionary.cs" />
+ <Compile Include="MRefBuilder.cs" />
+ <Compile Include="MRefBuilderAddIn.cs" />
+ <Compile Include="MRefBuilderCallback.cs" />
+ <Compile Include="MRefWriter.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ResourceHelper.cs" />
+ <Compile Include="XamlAttachedMembersAddIn.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CCI\CCI.csproj">
+ <Project>{4CB332D6-976E-44F6-A320-A515A9D1D1D3}</Project>
+ <Name>CCI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Reflection\Reflection.csproj">
+ <Project>{74F5EB3F-DC99-4FBE-9495-EE378FC60F65}</Project>
+ <Name>Reflection</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="MRefBuilder.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs
new file mode 100644
index 0000000..975f900
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs
@@ -0,0 +1,23 @@
+// 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.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MRefBuilderAddIn {
+
+ protected MRefBuilderAddIn(ManagedReflectionWriter writer, XPathNavigator configuration) { }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs
new file mode 100644
index 0000000..0331822
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs
@@ -0,0 +1,19 @@
+// 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.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public delegate void MRefBuilderCallback(XmlWriter writer, object information);
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs b/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs
new file mode 100644
index 0000000..33ff1dd
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs
@@ -0,0 +1,1316 @@
+// 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.Generic;
+using System.Security.Cryptography;
+using System.Text;
+using System.IO;
+using System.Xml;
+
+using System.Compiler;
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ // Write out information gained from managed reflection
+
+ public class ManagedReflectionWriter : ApiVisitor {
+ private const string implement = "implement";
+
+ // Implementations
+
+ private const string implements = "implements";
+
+ private Dictionary < string, Object > assemblyNames = new Dictionary < string, Object >();
+
+ // Inheritence
+
+ // Keep track of descendents
+
+ private Dictionary < TypeNode, List < TypeNode > > descendentIndex = new Dictionary < TypeNode, List < TypeNode > >();
+
+ private Dictionary < string, List < MRefBuilderCallback > > endTagCallbacks = new Dictionary < string, List < MRefBuilderCallback > >();
+
+ // Keep track of interface implementors
+
+ private Dictionary < Interface, List < TypeNode > > implementorIndex = new Dictionary < Interface, List < TypeNode > >();
+
+ // private ApiFilter memberFilter = new ExternalDocumentedFilter();
+
+ private bool includeNamespaces = true;
+
+ private ApiNamer namer;
+
+ private List < Member > parsedMembers = new List < Member >();
+
+ private List < Namespace > parsedNamespaces = new List < Namespace >();
+
+ private List < TypeNode > parsedTypes = new List < TypeNode >();
+
+ // add-in callbacks
+
+ private Dictionary < string, List < MRefBuilderCallback > > startTagCallbacks = new Dictionary < string, List < MRefBuilderCallback > >();
+
+ // Stored data
+
+ private XmlWriter writer;
+
+ // Constructor
+
+ public ManagedReflectionWriter(TextWriter output) : this(output, new ExternalTopicFilter()) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiFilter filter) : this(output, filter, new OrcasNamer()) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiNamer namer) : this(output, new ExternalTopicFilter(), namer) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiFilter filter, ApiNamer namer) : base(filter) {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ writer = XmlWriter.Create(output, settings);
+
+ this.namer = namer;
+ }
+
+ // Exposed data
+
+ public ApiNamer ApiNamer {
+ get {
+ return (namer);
+ }
+ set {
+ namer = value;
+ }
+ }
+
+ public bool IncludeNamespaces {
+ get {
+ return (includeNamespaces);
+ }
+ set {
+ includeNamespaces = value;
+ }
+ }
+
+ public Member[] Members {
+ get {
+ return (parsedMembers.ToArray());
+ }
+ }
+
+ public Namespace[] Namespaces {
+ get {
+ return (parsedNamespaces.ToArray());
+ }
+ }
+
+
+ public TypeNode[] Types {
+ get {
+ return (parsedTypes.ToArray());
+ }
+ }
+
+ // disposal
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ writer.Close();
+ }
+ base.Dispose(disposing);
+ }
+
+ public void RegisterEndTagCallback(string name, MRefBuilderCallback callback) {
+ List < MRefBuilderCallback > current;
+ if (!endTagCallbacks.TryGetValue(name, out current)) {
+ current = new List < MRefBuilderCallback >();
+ endTagCallbacks.Add(name, current);
+ }
+ current.Add(callback);
+ }
+
+ public void RegisterStartTagCallback(string name, MRefBuilderCallback callback) {
+ List < MRefBuilderCallback > current;
+ if (!startTagCallbacks.TryGetValue(name, out current)) {
+ current = new List < MRefBuilderCallback >();
+ startTagCallbacks.Add(name, current);
+ }
+ current.Add(callback);
+ }
+
+ public void WriteMember(Member member) {
+ //Console.WriteLine("Write Member {0} [{1}]", member.FullName, member.DeclaringType.DeclaringModule.Name);
+ WriteMember(member, member.DeclaringType);
+ }
+
+ public void WriteMemberReference(Member member) {
+ if (member == null) throw new ArgumentNullException("member");
+ writer.WriteStartElement("member");
+ Member template = ReflectionUtilities.GetTemplateMember(member);
+ writer.WriteAttributeString("api", namer.GetMemberName(template));
+ if (!member.DeclaringType.IsStructurallyEquivalentTo(template.DeclaringType)) {
+ writer.WriteAttributeString("display-api", namer.GetMemberName(member));
+ }
+ WriteTypeReference(member.DeclaringType);
+ writer.WriteEndElement();
+ }
+
+ public void WriteTypeReference(TypeNode type) {
+ if (type == null) throw new ArgumentNullException("type");
+ WriteStartTypeReference(type);
+ writer.WriteEndElement();
+ }
+
+ protected override void VisitMember(Member member) {
+ //Console.WriteLine("Member: {0}", member.Name);
+ parsedMembers.Add(member);
+
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetMemberName(member));
+ StartElementCallbacks("api", member);
+ WriteMember(member);
+ EndElementCallbacks("api", member);
+ writer.WriteEndElement();
+ }
+
+ protected override void VisitNamespace(Namespace space) {
+ parsedNamespaces.Add(space);
+ WriteNamespace(space);
+ base.VisitNamespace(space);
+ }
+
+ // visitation logic
+
+ protected override void VisitNamespaces(NamespaceList spaces) {
+
+ // construct a sorted assembly catalog
+ foreach (AssemblyNode assembly in this.Assemblies) {
+ assemblyNames.Add(assembly.StrongName, null);
+ }
+
+ // catalog type hierarchy and interface implementors
+ for (int i = 0; i < spaces.Count; i++) {
+ TypeNodeList types = spaces[i].Types;
+ for (int j = 0; j < types.Count; j++) {
+ TypeNode type = types[j];
+ if (ApiFilter.IsExposedType(type)) {
+ if (type.NodeType == NodeType.Class) PopulateDescendentIndex(type);
+ PopulateImplementorIndex(type);
+ }
+ }
+ }
+
+ // start the document
+ writer.WriteStartDocument();
+ writer.WriteStartElement("reflection");
+
+ // write assembly info
+ writer.WriteStartElement("assemblies");
+ foreach (AssemblyNode assembly in this.Assemblies) {
+ WriteAssembly(assembly);
+ }
+ writer.WriteEndElement();
+
+ // start api info
+ writer.WriteStartElement("apis");
+ StartElementCallbacks("apis", spaces);
+
+ // write it
+ WriteNamespaces(spaces);
+ base.VisitNamespaces(spaces);
+
+ // finish api info
+ EndElementCallbacks("apis", spaces);
+ writer.WriteEndElement();
+
+ // finish document
+ writer.WriteEndElement();
+ writer.WriteEndDocument();
+
+ }
+
+ protected override void VisitType(TypeNode type) {
+ //Console.WriteLine("Type: {0}", type.FullName);
+ parsedTypes.Add(type);
+ WriteType(type);
+ base.VisitType(type);
+ }
+
+ // Attributes
+
+ protected void WriteAttributes(AttributeList attributes, SecurityAttributeList securityAttributes) {
+ AttributeNode[] exposed = GetExposedAttributes(attributes, securityAttributes);
+ if (exposed.Length == 0) return;
+ writer.WriteStartElement("attributes");
+ for (int i = 0; i < exposed.Length; i++) {
+ AttributeNode attribute = exposed[i];
+ writer.WriteStartElement("attribute");
+
+ TypeNode type = attribute.Type;
+ WriteTypeReference(attribute.Type);
+ // WriteStringAttribute("type", namer.GetApiName(attribute.Type));
+
+ ExpressionList expressions = attribute.Expressions;
+ for (int j = 0; j < expressions.Count; j++) {
+ WriteExpression(expressions[j]);
+ }
+
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ }
+
+ protected void WriteExpression(Expression expression) {
+ if (expression.NodeType == NodeType.Literal) {
+ Literal argument = (Literal)expression;
+ writer.WriteStartElement("argument");
+ WriteLiteral(argument);
+ writer.WriteEndElement();
+ } else if (expression.NodeType == NodeType.NamedArgument) {
+ NamedArgument assignment = (NamedArgument)expression;
+ Literal value = (Literal)assignment.Value;
+ writer.WriteStartElement("assignment");
+ WriteStringAttribute("name", assignment.Name.Name);
+ WriteLiteral(value);
+ writer.WriteEndElement();
+ }
+ }
+
+ private static FieldList GetAppliedFields(EnumNode enumeration, long value) {
+ // if a single field matches, return it;
+ // otherwise return all fields that are in value
+ FieldList list = new FieldList();
+ MemberList members = enumeration.Members;
+ for (int i = 0; i < members.Count; i++) {
+ if (members[i].NodeType != NodeType.Field) continue;
+ Field field = (Field)members[i];
+ if (field.DefaultValue == null) continue;
+ long fieldValue = Convert.ToInt64(field.DefaultValue.Value);
+ if (fieldValue == value) {
+ return (new FieldList(new Field[1] { field }));
+ } else if ((fieldValue & value) == fieldValue) {
+ list.Add(field);
+ }
+ }
+ return (list);
+ }
+
+ // Static utility functions
+
+ private static Namespace GetNamespace(TypeNode type) {
+ if (type.DeclaringType != null) {
+ return (GetNamespace(type.DeclaringType));
+ } else {
+ return (new Namespace(type.Namespace));
+ }
+ }
+
+ private static string GetVisibility(Member api) {
+ if (api == null) throw new ArgumentNullException("api");
+ if (api.IsPublic) {
+ return ("public");
+ } else if (api.IsAssembly) {
+ return ("assembly");
+ } else if (api.IsFamilyOrAssembly) {
+ return ("family or assembly");
+ } else if (api.IsFamily) {
+ return ("family");
+ } else if (api.IsFamilyAndAssembly) {
+ return ("family and assembly");
+ } else if (api.IsPrivate) {
+ return ("private");
+ } else {
+ throw new InvalidOperationException(String.Format("Unknown access level for {0}", api.FullName));
+ }
+ }
+
+ private static bool IsValidXmlChar(char c) {
+ if (c < 0x20) {
+ return ((c == 0x9) || (c == 0xa));
+ } else {
+ return ((c <= 0xd7ff) || ((0xe000 <= c) && (c <= 0xfffd)));
+ }
+ }
+
+ private static bool IsValidXmlText(string text) {
+ foreach (char c in text) {
+ if (!IsValidXmlChar(c)) return (false);
+ }
+ return (true);
+ }
+
+ private void EndElementCallbacks(string name, Object info) {
+ List < MRefBuilderCallback > callbacks;
+ if (endTagCallbacks.TryGetValue(name, out callbacks)) {
+ foreach (MRefBuilderCallback callback in callbacks) callback.Invoke(writer, info);
+ }
+ }
+
+ private AttributeNode[] GetExposedAttributes(AttributeList attributes, SecurityAttributeList securityAttributes) {
+ if (attributes == null) Console.WriteLine("null attribute list");
+ if (securityAttributes == null) Console.WriteLine("null security attribute list");
+ List < AttributeNode > exposedAttributes = new List < AttributeNode >();
+ for (int i = 0; i < attributes.Count; i++) {
+ AttributeNode attribute = attributes[i];
+ if (attribute == null) Console.WriteLine("null attribute");
+ if (this.ApiFilter.IsExposedAttribute(attribute)) exposedAttributes.Add(attribute);
+ }
+ for (int i = 0; i < securityAttributes.Count; i++) {
+ SecurityAttribute securityAttribute = securityAttributes[i];
+ if (securityAttribute == null) Console.WriteLine("null security attribute");
+ AttributeList permissionAttributes = securityAttribute.PermissionAttributes;
+ //if (permissionAttributes == null) Console.WriteLine("null permission attribute list");
+ if (permissionAttributes == null) continue;
+ for (int j = 0; j < permissionAttributes.Count; j++) {
+ AttributeNode permissionAttribute = permissionAttributes[j];
+ //if (permissionAttribute == null) Console.WriteLine("null permission attribute");
+ // saw an example where this was null; ildasm shows no permission attribute, so skip it
+ if (permissionAttribute == null) continue;
+ if (this.ApiFilter.IsExposedAttribute(permissionAttribute)) exposedAttributes.Add(permissionAttribute);
+ }
+ }
+ return (exposedAttributes.ToArray());
+ }
+
+ private Member[] GetExposedImplementedMembers(IEnumerable < Member > members) {
+ List < Member > exposedImplementedMembers = new List < Member >();
+ foreach (Member member in members) {
+ if (this.ApiFilter.IsExposedMember(member)) {
+ exposedImplementedMembers.Add(member);
+ }
+ }
+ return (exposedImplementedMembers.ToArray());
+ }
+
+ private Interface[] GetExposedInterfaces(InterfaceList contracts) {
+ List < Interface > exposedContracts = new List < Interface >();
+ for (int i = 0; i < contracts.Count; i++) {
+ Interface contract = contracts[i];
+ if (this.ApiFilter.IsExposedType(contract)) {
+ // if generic, check whether specialization types are exposed
+ exposedContracts.Add(contract);
+ }
+ }
+ return (exposedContracts.ToArray());
+ }
+
+ private AttributeNode GetParamArrayAttribute(Parameter param)
+ {
+ AttributeList attributes = param.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ if (attr.Type.FullName == "System.ParamArrayAttribute")
+ return attr;
+ }
+ return null;
+ }
+
+ private void PopulateDescendentIndex(TypeNode child) {
+
+ // get the parent of the type in question
+ TypeNode parent = child.BaseType;
+ if (parent == null) return;
+
+ // un-specialize the parent so we see specialized types as children
+ parent = ReflectionUtilities.GetTemplateType(parent);
+
+ // get the list of children for that parent (i.e. the sibling list)
+ List < TypeNode > siblings;
+ if (!descendentIndex.TryGetValue(parent, out siblings)) {
+ siblings = new List < TypeNode >();
+ descendentIndex[parent] = siblings;
+ }
+
+ // add the type in question to the sibling list
+ siblings.Add(child);
+
+ }
+
+ private void PopulateImplementorIndex(TypeNode type) {
+
+ // get the list of interfaces exposed by the type
+ Interface[] contracts = GetExposedInterfaces(type.Interfaces);
+
+ // for each implemented interface...
+ for (int i = 0; i < contracts.Length; i++) {
+
+ // get the unspecialized form of the interface
+ Interface contract = contracts[i];
+ if (contract.IsGeneric) contract = (Interface)ReflectionUtilities.GetTemplateType(contract);
+
+ // get the list of implementors
+ List < TypeNode > implementors;
+ if (!implementorIndex.TryGetValue(contract, out implementors)) {
+ implementors = new List < TypeNode >();
+ implementorIndex[contract] = implementors;
+ }
+
+ // and add the type to it
+ implementors.Add(type);
+ }
+ }
+
+ private void StartElementCallbacks(string name, Object info) {
+ List < MRefBuilderCallback > callbacks;
+ if (startTagCallbacks.TryGetValue(name, out callbacks)) {
+ foreach (MRefBuilderCallback callback in callbacks) callback.Invoke(writer, info);
+ }
+ }
+
+
+ // API data for all entities
+
+ private void WriteApiData(Member api) {
+ writer.WriteStartElement("apidata");
+
+ string name = api.Name.Name;
+
+ string group = null;
+ string subgroup = null;
+ string subsubgroup = null;
+
+ if (api.NodeType == NodeType.Namespace) {
+ group = "namespace";
+ } else if (api is TypeNode) {
+ group = "type";
+
+ TypeNode type = (TypeNode)api;
+ name = type.GetUnmangledNameWithoutTypeParameters();
+
+ switch (api.NodeType) {
+ case NodeType.Class:
+ subgroup = "class";
+ break;
+ case NodeType.Struct:
+ subgroup = "structure";
+ break;
+ case NodeType.Interface:
+ subgroup = "interface";
+ break;
+ case NodeType.EnumNode:
+ subgroup = "enumeration";
+ break;
+ case NodeType.DelegateNode:
+ subgroup = "delegate";
+ break;
+ }
+ } else {
+ group = "member";
+
+ switch (api.NodeType) {
+ case NodeType.Field:
+ subgroup = "field";
+ break;
+ case NodeType.Property:
+ subgroup = "property";
+ break;
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ subgroup = "constructor";
+ // name = api.DeclaringType.GetUnmangledNameWithoutTypeParameters();
+ break;
+ case NodeType.Method:
+ subgroup = "method";
+ if ((api.IsSpecialName) && (name.StartsWith("op_"))) {
+ subsubgroup = "operator";
+ name = name.Substring(3);
+ }
+ break;
+ case NodeType.Event:
+ subgroup = "event";
+ break;
+ }
+
+ // Name of EIIs is just interface member name
+ int dotIndex = name.LastIndexOf(".");
+ if (dotIndex > 0) name = name.Substring(dotIndex + 1);
+
+ }
+
+
+ WriteStringAttribute("name", name);
+ WriteStringAttribute("group", group);
+ if (subgroup != null) WriteStringAttribute("subgroup", subgroup);
+ if (subsubgroup != null) WriteStringAttribute("subsubgroup", subsubgroup);
+
+ StartElementCallbacks("apidata", api);
+
+ // WriteStringAttribute("file", GetGuid(namer.GetApiName(api)).ToString());
+
+ EndElementCallbacks("apidata", api);
+ writer.WriteEndElement();
+ }
+
+ // writing logic
+
+ private void WriteAssembly(AssemblyNode assembly) {
+ // if (assembly == null) Console.WriteLine("null assembly");
+ // Console.WriteLine("assembly: {0}", assembly.Name);
+ writer.WriteStartElement("assembly");
+ // if (assembly.Name == null) Console.WriteLine("null assembly name");
+ WriteStringAttribute("name", assembly.Name);
+ // if (assembly.Version == null) Console.WriteLine("null assembly version");
+
+ // basic assembly data
+ writer.WriteStartElement("assemblydata");
+ WriteStringAttribute("version", assembly.Version.ToString());
+ WriteStringAttribute("culture", assembly.Culture.ToString());
+ byte[] key = assembly.PublicKeyOrToken;
+ writer.WriteStartAttribute("key");
+ writer.WriteBinHex(key, 0, key.Length);
+ writer.WriteEndAttribute();
+ WriteStringAttribute("hash", assembly.HashAlgorithm.ToString());
+ writer.WriteEndElement();
+
+ // assembly attribute data
+ WriteAttributes(assembly.Attributes, assembly.SecurityAttributes);
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteAssignment(NamedArgument assignment) {
+ string name = assignment.Name.Name;
+ Literal value = (Literal)assignment.Value;
+ writer.WriteStartElement("assignment");
+ WriteStringAttribute("name", name);
+ WriteLiteral(value);
+ writer.WriteEndElement();
+ }
+
+ // utilities used to write attributes
+
+ private void WriteBooleanAttribute(string attribute, bool value) {
+ if (value) {
+ writer.WriteAttributeString(attribute, "true");
+ } else {
+ writer.WriteAttributeString(attribute, "false");
+ }
+ }
+
+ private void WriteBooleanAttribute(string attribute, bool value, bool defaultValue) {
+ if (value != defaultValue) {
+ WriteBooleanAttribute(attribute, value);
+ }
+ }
+
+ private void WriteEnumerationData(EnumNode enumeration) {
+ TypeNode underlying = enumeration.UnderlyingType;
+ if (underlying.FullName != "System.Int32") {
+ writer.WriteStartElement("enumerationbase");
+ WriteTypeReference(enumeration.UnderlyingType);
+ writer.WriteEndElement();
+ }
+ }
+
+ private void WriteEventData(Event trigger) {
+
+ Method adder = trigger.HandlerAdder;
+ Method remover = trigger.HandlerRemover;
+ Method caller = trigger.HandlerCaller;
+
+ WriteProcedureData(adder, trigger.OverriddenMember);
+
+ writer.WriteStartElement("eventdata");
+ if (adder != null) WriteBooleanAttribute("add", true);
+ if (remover != null) WriteBooleanAttribute("remove", true);
+ if (caller != null) WriteBooleanAttribute("call", true);
+ writer.WriteEndElement();
+
+ if (adder != null)
+ {
+ writer.WriteStartElement("adder");
+ WriteStringAttribute("name", string.Format("add_{0}", trigger.Name.Name));
+
+ WriteAttributes(adder.Attributes, adder.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ if (remover != null)
+ {
+ writer.WriteStartElement("remover");
+ WriteStringAttribute("name", string.Format("remove_{0}", trigger.Name.Name));
+
+ WriteAttributes(remover.Attributes, remover.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteStartElement("eventhandler");
+ WriteTypeReference(trigger.HandlerType);
+ writer.WriteEndElement();
+
+ // handlers should always be elegates, but I have seen a case where one is not, so check for this
+ DelegateNode handler = trigger.HandlerType as DelegateNode;
+ if (handler != null) {
+ ParameterList parameters = handler.Parameters;
+
+ if ((parameters != null) && (parameters.Count == 2) && (parameters[0].Type.FullName == "System.Object")) {
+ writer.WriteStartElement("eventargs");
+ WriteTypeReference(parameters[1].Type);
+ writer.WriteEndElement();
+ }
+ }
+
+ }
+
+
+ private void WriteFieldData(Field field) {
+ writer.WriteStartElement("fielddata");
+ WriteBooleanAttribute("literal", field.IsLiteral);
+ WriteBooleanAttribute("initonly", field.IsInitOnly);
+ WriteBooleanAttribute("volatile", field.IsVolatile, false);
+ WriteBooleanAttribute("serialized", (field.Flags & FieldFlags.NotSerialized) == 0);
+ writer.WriteEndElement();
+ }
+
+ private void WriteGenericParameter(TypeNode templateParameter)
+ {
+
+ ITypeParameter itp = (ITypeParameter)templateParameter;
+
+ writer.WriteStartElement("template");
+ writer.WriteAttributeString("name", templateParameter.Name.Name);
+
+ // evaluate constraints
+ bool reference = ((itp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) > 0);
+ bool value = ((itp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) > 0);
+ bool constructor = ((itp.TypeParameterFlags & TypeParameterFlags.DefaultConstructorConstraint) > 0);
+ bool contravariant = ((itp.TypeParameterFlags & TypeParameterFlags.Contravariant) > 0);
+ bool covariant = ((itp.TypeParameterFlags & TypeParameterFlags.Covariant) > 0);
+ InterfaceList interfaces = templateParameter.Interfaces;
+ TypeNode parent = templateParameter.BaseType;
+
+ // no need to show inheritance from ValueType if value flag is set
+ if (value && (parent != null) && (parent.FullName == "System.ValueType")) parent = null;
+
+ if ((parent != null) || (interfaces.Count > 0) || reference || value || constructor)
+ {
+ writer.WriteStartElement("constrained");
+ if (reference) WriteBooleanAttribute("ref", true);
+ if (value) WriteBooleanAttribute("value", true);
+ if (constructor) WriteBooleanAttribute("ctor", true);
+ if (parent != null) WriteTypeReference(parent);
+ WriteInterfaces(interfaces);
+ writer.WriteEndElement();
+ }
+ if (covariant || contravariant)
+ {
+ writer.WriteStartElement("variance");
+ if (contravariant) WriteBooleanAttribute("contravariant", true);
+ if (covariant) WriteBooleanAttribute("covariant", true);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteSpecializedTemplateArguments(TypeNodeList templateArguments)
+ {
+ if (templateArguments == null) return;
+ if (templateArguments.Count == 0) return;
+ writer.WriteStartElement("templates");
+ for (int i = 0; i < templateArguments.Count; i++)
+ {
+ WriteTypeReference(templateArguments[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ // Generic Parameters
+
+ private void WriteGenericParameters(TypeNodeList templateParameters)
+ {
+ if (templateParameters == null) return;
+ if (templateParameters.Count == 0) return;
+ writer.WriteStartElement("templates");
+ for (int i = 0; i < templateParameters.Count; i++)
+ {
+ WriteGenericParameter(templateParameters[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteHierarchy(TypeNode type) {
+
+ writer.WriteStartElement("family");
+
+ // write ancestors
+ writer.WriteStartElement("ancestors");
+ for (TypeNode ancestor = type.BaseType; ancestor != null; ancestor = ancestor.BaseType) {
+ WriteTypeReference(ancestor);
+ }
+ writer.WriteEndElement();
+
+ // write descendents
+ if (descendentIndex.ContainsKey(type)) {
+ List < TypeNode > descendents = descendentIndex[type];
+ writer.WriteStartElement("descendents");
+ foreach (TypeNode descendent in descendents) WriteTypeReference(descendent);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+
+ }
+
+ private void WriteImplementedMembers(Member[] members) {
+ if ((members == null) || (members.Length == 0)) return;
+ Member[] exposedMembers = GetExposedImplementedMembers(members);
+ if ((exposedMembers == null) || (exposedMembers.Length == 0)) return;
+ writer.WriteStartElement(implements);
+ for (int i = 0; i < exposedMembers.Length; i++) {
+ Member member = exposedMembers[i];
+ //TypeNode type = member.DeclaringType;
+
+ WriteMemberReference(member);
+
+ }
+ writer.WriteEndElement();
+ }
+
+ // Interfaces
+
+ private void WriteImplementors(Interface contract) {
+ List < TypeNode > implementors;
+ if (!implementorIndex.TryGetValue(contract, out implementors)) return;
+ if ((implementors == null) || (implementors.Count == 0)) return;
+ writer.WriteStartElement("implementors");
+ StartElementCallbacks("implementors", implementors);
+ foreach (TypeNode implementor in implementors) {
+ WriteTypeReference(implementor);
+ }
+ writer.WriteEndElement();
+ EndElementCallbacks("implementors", implementors);
+ }
+
+ private void WriteInterface(Interface contract) {
+ // writer.WriteStartElement("implement");
+ WriteTypeReference(contract);
+ // writer.WriteAttributeString("interface", namer.GetTypeName(contract));
+ // writer.WriteEndElement();
+ }
+
+ private void WriteInterfaces(InterfaceList contracts) {
+ Interface[] implementedContracts = GetExposedInterfaces(contracts);
+ if (implementedContracts.Length == 0) return;
+ writer.WriteStartElement("implements");
+ StartElementCallbacks("implements", implementedContracts);
+ for (int i = 0; i < implementedContracts.Length; i++) {
+ WriteInterface(implementedContracts[i]);
+ }
+ writer.WriteEndElement();
+ EndElementCallbacks("implements", implementedContracts);
+ }
+
+ private void WriteLibraryReference(Module module) {
+ AssemblyNode assembly = module.ContainingAssembly;
+ writer.WriteStartElement("library");
+ WriteStringAttribute("assembly", assembly.Name);
+ WriteStringAttribute("module", module.Name);
+ WriteStringAttribute("kind", module.Kind.ToString());
+ writer.WriteEndElement();
+ }
+
+ private void WriteLiteral(Literal literal) {
+ WriteLiteral(literal, true);
+ }
+
+ private void WriteLiteral(Literal literal, bool showType) {
+ TypeNode type = literal.Type;
+ Object value = literal.Value;
+ if (showType) WriteTypeReference(type);
+ if (value == null) {
+ writer.WriteElementString("nullValue", String.Empty);
+ } else {
+ if (type.NodeType == NodeType.EnumNode) {
+ EnumNode enumeration = (EnumNode)type;
+ FieldList fields = GetAppliedFields(enumeration, Convert.ToInt64(value));
+ writer.WriteStartElement("enumValue");
+ for (int i = 0; i < fields.Count; i++) {
+ writer.WriteStartElement("field");
+ writer.WriteAttributeString("name", fields[i].Name.Name);
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ } else if (type.FullName == "System.Type") {
+ writer.WriteStartElement("typeValue");
+ WriteTypeReference((TypeNode)value);
+ writer.WriteEndElement();
+ } else {
+ string text = value.ToString();
+ if (!IsValidXmlText(text)) text = String.Empty;
+ writer.WriteElementString("value", text);
+ }
+ }
+ }
+
+
+ private void WriteMember(Member member, TypeNode type) {
+ //writer.WriteStartElement("api");
+ //writer.WriteAttributeString("id", namer.GetMemberName(member));
+ //Console.WriteLine("member: {0}", namer.GetMemberName(member));
+
+ WriteApiData(member);
+ WriteMemberData(member);
+
+ SecurityAttributeList securityAttributes = new SecurityAttributeList();
+ switch (member.NodeType) {
+ case NodeType.Field:
+ Field field = (Field)member;
+ WriteFieldData(field);
+ WriteValue(field.Type);
+ // write enumeration field values; expand later to all literal field values?
+ if (field.DeclaringType.NodeType == NodeType.EnumNode) {
+ WriteLiteral(new Literal(field.DefaultValue.Value, ((EnumNode)field.DeclaringType).UnderlyingType), false);
+ }
+ break;
+ case NodeType.Method:
+ Method method = (Method)member;
+ WriteMethodData(method);
+
+ // write the templates node with either the generic template params or the specialized template arguments
+ if (method.TemplateArguments != null)
+ WriteSpecializedTemplateArguments(method.TemplateArguments);
+ else
+ WriteGenericParameters(method.TemplateParameters);
+
+ WriteParameters(method.Parameters);
+ WriteValue(method.ReturnType);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedMethods(method));
+
+ if (method.SecurityAttributes != null) securityAttributes = method.SecurityAttributes;
+ break;
+ case NodeType.Property:
+ Property property = (Property)member;
+ WritePropertyData(property);
+ WriteParameters(property.Parameters);
+ WriteValue(property.Type);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedProperties(property));
+ break;
+ case NodeType.Event:
+ Event trigger = (Event)member;
+ WriteEventData(trigger);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedEvents(trigger));
+ break;
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ Method constructor = (Method)member;
+ WriteParameters(constructor.Parameters);
+ break;
+
+ }
+
+ WriteMemberContainers(member, type);
+
+ WriteAttributes(member.Attributes, securityAttributes);
+
+ //writer.WriteEndElement();
+ }
+
+ private void WriteMemberContainers(Member member, TypeNode type) {
+ writer.WriteStartElement("containers");
+ WriteLibraryReference(type.DeclaringModule);
+ WriteNamespaceReference(GetNamespace(type));
+ WriteTypeReference(type);
+ writer.WriteEndElement();
+ }
+
+ // Member data
+
+ private void WriteMemberData(Member member) {
+
+ writer.WriteStartElement("memberdata");
+
+ WriteStringAttribute("visibility", GetVisibility(member));
+ WriteBooleanAttribute("static", member.IsStatic, false);
+ WriteBooleanAttribute("special", member.IsSpecialName, false);
+
+ // check overload status
+ // don't do this anymore: overload is a doc model concept and may be need to be tweaked afer versioning
+
+ WriteBooleanAttribute("default", ReflectionUtilities.IsDefaultMember(member), false);
+
+ StartElementCallbacks("memberdata", member);
+
+ EndElementCallbacks("memberdata", member);
+ writer.WriteEndElement();
+ }
+
+ private void WriteMethodData(Method method) {
+
+ WriteProcedureData(method, method.OverriddenMember);
+
+ // writer.WriteStartElement("methoddata");
+ // writer.WriteEndElement();
+ }
+
+ private void WriteNamespace(Namespace space) {
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetNamespaceName(space));
+ StartElementCallbacks("api", space);
+
+ WriteApiData(space);
+ WriteNamespaceElements(space);
+
+ EndElementCallbacks("api", space);
+ writer.WriteEndElement();
+ }
+
+ // Members
+
+ private void WriteNamespaceElements(Namespace space) {
+ TypeNodeList types = space.Types;
+ if (types.Count == 0) return;
+ writer.WriteStartElement("elements");
+ for (int i = 0; i < types.Count; i++) {
+ TypeNode type = types[i];
+ //skip hidden types, but if a type is not exposed and has exposed members we must add it
+ if (!ApiFilter.IsExposedType(type) && !ApiFilter.HasExposedMembers(type)) continue;
+ writer.WriteStartElement("element");
+ writer.WriteAttributeString("api", namer.GetTypeName(type));
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteNamespaceReference(Namespace space) {
+ writer.WriteStartElement("namespace");
+ writer.WriteAttributeString("api", namer.GetNamespaceName(space));
+ writer.WriteEndElement();
+ }
+
+ private void WriteNamespaces(NamespaceList spaces) {
+ // This is a part of the doc model; don't do this anymore
+ }
+
+ private void WriteParameter(Parameter parameter) {
+ writer.WriteStartElement("parameter");
+ writer.WriteAttributeString("name", parameter.Name.Name);
+ // writer.WriteAttributeString("type", namer.GetTypeName(parameter.Type));
+ if (parameter.IsIn) WriteBooleanAttribute("in", true);
+ if (parameter.IsOut) WriteBooleanAttribute("out", true);
+ if (GetParamArrayAttribute(parameter) != null) WriteBooleanAttribute("params", true);
+ WriteTypeReference(parameter.Type);
+ if (parameter.IsOptional && parameter.DefaultValue != null) WriteExpression(parameter.DefaultValue);
+ writer.WriteEndElement();
+ }
+
+ // Parameters
+
+ private void WriteParameters(ParameterList parameters) {
+ if (parameters.Count == 0) return;
+ writer.WriteStartElement("parameters");
+ for (int i = 0; i < parameters.Count; i++) {
+ WriteParameter(parameters[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteProcedureData(Method method, Member overrides) {
+ writer.WriteStartElement("proceduredata");
+
+ WriteBooleanAttribute("abstract", method.IsAbstract, false);
+ WriteBooleanAttribute("virtual", method.IsVirtual);
+ WriteBooleanAttribute("final", method.IsFinal, false);
+
+ if (method.IsPrivate && method.IsVirtual) WriteBooleanAttribute("eii", true);
+
+ writer.WriteEndElement();
+
+ if (overrides != null) {
+ writer.WriteStartElement("overrides");
+ WriteMemberReference(overrides);
+ // WriteStringAttribute("overrides", namer.GetMemberName(overrides));
+ writer.WriteEndElement();
+ }
+
+ }
+
+ private void WritePropertyData(Property property) {
+
+ string property_visibility = GetVisibility(property);
+
+ Method getter = property.Getter;
+ Method setter = property.Setter;
+
+ Method accessor = getter;
+ if (accessor == null) accessor = setter;
+
+ // procedure data
+ WriteProcedureData(accessor, property.OverriddenMember);
+
+ // property data
+ writer.WriteStartElement("propertydata");
+ if (getter != null) {
+ WriteBooleanAttribute("get", true);
+ string getter_visibility = GetVisibility(getter);
+
+ if (getter_visibility != property_visibility) WriteStringAttribute("get-visibility", getter_visibility);
+ }
+ if (setter != null) {
+ WriteBooleanAttribute("set", true);
+ string setter_visibility = GetVisibility(setter);
+ if (setter_visibility != property_visibility) WriteStringAttribute("set-visibility", setter_visibility);
+ }
+ writer.WriteEndElement();
+
+ if (getter != null)
+ {
+ writer.WriteStartElement("getter");
+ WriteStringAttribute("name", string.Format("get_{0}", property.Name.Name));
+
+ WriteAttributes(getter.Attributes, getter.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ if (setter != null)
+ {
+ writer.WriteStartElement("setter");
+ WriteStringAttribute("name", string.Format("set_{0}", property.Name.Name.ToString()));
+
+ WriteAttributes(setter.Attributes, setter.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ }
+
+ private void WriteStartTypeReference(TypeNode type) {
+ switch (type.NodeType) {
+ case NodeType.ArrayType:
+ ArrayType array = type as ArrayType;
+ writer.WriteStartElement("arrayOf");
+ writer.WriteAttributeString("rank", array.Rank.ToString());
+ WriteTypeReference(array.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.Reference:
+ Reference reference = type as Reference;
+ writer.WriteStartElement("referenceTo");
+ WriteTypeReference(reference.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.Pointer:
+ Pointer pointer = type as Pointer;
+ writer.WriteStartElement("pointerTo");
+ WriteTypeReference(pointer.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.OptionalModifier:
+ TypeModifier optionalModifierClause = type as TypeModifier;
+ WriteStartTypeReference(optionalModifierClause.ModifiedType);
+ writer.WriteStartElement("optionalModifier");
+ WriteTypeReference(optionalModifierClause.Modifier);
+ writer.WriteEndElement();
+ break;
+ case NodeType.RequiredModifier:
+ TypeModifier requiredModifierClause = type as TypeModifier;
+ WriteStartTypeReference(requiredModifierClause.ModifiedType);
+ writer.WriteStartElement("requiredModifier");
+ WriteTypeReference(requiredModifierClause.Modifier);
+ writer.WriteEndElement();
+ break;
+ default:
+ if (type.IsTemplateParameter) {
+ ITypeParameter gtp = (ITypeParameter)type;
+ writer.WriteStartElement("template");
+ writer.WriteAttributeString("name", type.Name.Name);
+ writer.WriteAttributeString("index", gtp.ParameterListIndex.ToString());
+ writer.WriteAttributeString("api", namer.GetApiName(gtp.DeclaringMember));
+ // writer.WriteEndElement();
+ } else {
+ writer.WriteStartElement("type");
+
+ if (type.IsGeneric) {
+ TypeNode template = ReflectionUtilities.GetTemplateType(type);
+ writer.WriteAttributeString("api", namer.GetTypeName(template));
+ WriteBooleanAttribute("ref", !template.IsValueType);
+
+ // record specialization
+ TypeNodeList arguments = type.TemplateArguments;
+ if ((arguments != null) && (arguments.Count > 0)) {
+ writer.WriteStartElement("specialization");
+ // writer.WriteAttributeString("of", namer.GetTypeName(currentTemplate));
+ for (int i = 0; i < arguments.Count; i++) {
+ WriteTypeReference(arguments[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ } else {
+ writer.WriteAttributeString("api", namer.GetTypeName(type));
+ WriteBooleanAttribute("ref", !type.IsValueType);
+ }
+
+ // record outer types (because they may be specialized, and otherwise that information is lost)
+ if (type.DeclaringType != null) WriteTypeReference(type.DeclaringType);
+
+ }
+ break;
+ }
+ }
+
+ private void WriteStringAttribute(string attribute, string value) {
+ writer.WriteAttributeString(attribute, value);
+ }
+
+ private void WriteType(TypeNode type) {
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetTypeName(type));
+ StartElementCallbacks("api", type);
+
+ WriteApiData(type);
+ WriteTypeData(type);
+
+ switch (type.NodeType) {
+ case NodeType.Class:
+ case NodeType.Struct:
+ WriteGenericParameters(type.TemplateParameters);
+ WriteInterfaces(type.Interfaces);
+ WriteTypeElements(type);
+ break;
+ case NodeType.Interface:
+ WriteGenericParameters(type.TemplateParameters);
+ WriteInterfaces(type.Interfaces);
+ WriteImplementors((Interface)type);
+ WriteTypeElements(type);
+ break;
+ case NodeType.DelegateNode:
+ DelegateNode handler = (DelegateNode)type;
+ WriteGenericParameters(handler.TemplateParameters);
+ WriteParameters(handler.Parameters);
+ WriteValue(handler.ReturnType);
+ break;
+ case NodeType.EnumNode:
+ WriteEnumerationData((EnumNode)type);
+ WriteTypeElements(type);
+ break;
+ }
+
+ WriteTypeContainers(type);
+
+ WriteAttributes(type.Attributes, type.SecurityAttributes);
+
+ EndElementCallbacks("api", type);
+ writer.WriteEndElement();
+
+ }
+
+ private void WriteTypeContainers(TypeNode type) {
+
+ writer.WriteStartElement("containers");
+ WriteLibraryReference(type.DeclaringModule);
+ WriteNamespaceReference(GetNamespace(type));
+
+ // for nested types, record outer types
+ TypeNode outer = type.DeclaringType;
+ if (outer != null) WriteTypeReference(outer);
+
+ writer.WriteEndElement();
+
+ }
+
+ // Type data
+
+ private void WriteTypeData(TypeNode type) {
+ writer.WriteStartElement("typedata");
+
+ // data for all types
+ WriteStringAttribute("visibility", GetVisibility(type));
+ WriteBooleanAttribute("abstract", type.IsAbstract, false);
+ WriteBooleanAttribute("sealed", type.IsSealed, false);
+ WriteBooleanAttribute("serializable", (type.Flags & TypeFlags.Serializable) != 0);
+
+ // interop data
+ TypeFlags layout = type.Flags & TypeFlags.LayoutMask;
+ switch (layout) {
+ case TypeFlags.AutoLayout:
+ WriteStringAttribute("layout", "auto");
+ break;
+ case TypeFlags.SequentialLayout:
+ WriteStringAttribute("layout", "sequential");
+ break;
+ case TypeFlags.ExplicitLayout:
+ WriteStringAttribute("layout", "explicit");
+ break;
+ }
+ TypeFlags format = type.Flags & TypeFlags.StringFormatMask;
+ switch (format) {
+ case TypeFlags.AnsiClass:
+ WriteStringAttribute("format", "ansi");
+ break;
+ case TypeFlags.UnicodeClass:
+ WriteStringAttribute("format", "unicode");
+ break;
+ case TypeFlags.AutoClass:
+ WriteStringAttribute("format", "auto");
+ break;
+ }
+ // also import
+
+ StartElementCallbacks("typedata", type);
+
+
+ EndElementCallbacks("typedata", type);
+ writer.WriteEndElement();
+
+ // for classes, recored base type
+ if (type is Class) {
+ WriteHierarchy(type);
+ // TypeNode parent = type.BaseType;
+ // if (parent != null) WriteStringAttribute("parent", namer.GetTypeName(parent));
+ }
+
+ }
+
+ private void WriteTypeElements(TypeNode type) {
+
+ // collect members
+ MemberDictionary members = new MemberDictionary(type, this.ApiFilter);
+ if (members.Count == 0) return;
+
+ writer.WriteStartElement("elements");
+ StartElementCallbacks("elements", members);
+
+ foreach (Member member in members) {
+ writer.WriteStartElement("element");
+
+ Member template = ReflectionUtilities.GetTemplateMember(member);
+ writer.WriteAttributeString("api", namer.GetMemberName(template));
+
+ bool write = false;
+
+ // inherited, specialized generics get a displayed target different from the target
+ // we also write out their info, since it can't be looked up anywhere
+ if (!member.DeclaringType.IsStructurallyEquivalentTo(template.DeclaringType)) {
+ writer.WriteAttributeString("display-api", namer.GetMemberName(member));
+ write = true;
+ }
+
+ // if a member is from a type in a dependency assembly, write out its info, since it can't be looked up in this file
+ if (!assemblyNames.ContainsKey(member.DeclaringType.DeclaringModule.ContainingAssembly.StrongName)) write = true;
+ // if (Array.BinarySearch(assemblyNames, member.DeclaringType.DeclaringModule.ContainingAssembly.Name) < 0) write = true;
+
+ if (write) WriteMember(member);
+
+ writer.WriteEndElement();
+ }
+
+ EndElementCallbacks("elements", members);
+ writer.WriteEndElement();
+
+ }
+
+ // Return value or property value or field value
+
+ private void WriteValue(TypeNode type) {
+ if (type.FullName == "System.Void") return;
+ writer.WriteStartElement("returns");
+ WriteTypeReference(type);
+ // writer.WriteAttributeString("type", namer.GetTypeName(type));
+ writer.WriteEndElement();
+ }
+
+ }
+
+}
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());
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..91fb255
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MrefBuilder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("MrefBuilder")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(false)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e6670ce1-be5e-4bed-a4af-13d741b7b007")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs b/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs
new file mode 100644
index 0000000..ba2a149
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs
@@ -0,0 +1,28 @@
+// 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.IO;
+using System.Reflection;
+using System.Resources;
+
+namespace Microsoft.Ddue.Tools.DxCoach {
+
+ internal sealed class ResourceHelper {
+
+ private static ResourceManager manager = new ResourceManager("TextStrings", Assembly.GetExecutingAssembly());
+
+ private ResourceHelper() { }
+
+ public static Stream GetStream(string file) {
+ return (Assembly.GetExecutingAssembly().GetManifestResourceStream(file));
+ }
+
+ public static string GetString(string key) {
+ return (manager.GetString(key));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt b/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt
new file mode 100644
index 0000000..b13b4e8
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt
@@ -0,0 +1,4 @@
+HelpOption = Show this help page.
+OutputOption = Specifies an output file.
+ConfigOption = Specifies a configuration file.
+DependencyOption = Specify assemblies on which the reflected assemblies depend.
diff --git a/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs
new file mode 100644
index 0000000..79c7c76
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs
@@ -0,0 +1,243 @@
+// 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.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ // XAML add in
+
+ public class XamlAttachedMembersAddIn : MRefBuilderAddIn {
+
+ private Dictionary < Object, Field > attachedMembers = new Dictionary < Object, Field >();
+
+ private Dictionary < TypeNode, Property > contentProperties = new Dictionary < TypeNode, Property >();
+
+ private ManagedReflectionWriter mrw;
+
+ public XamlAttachedMembersAddIn(ManagedReflectionWriter writer, XPathNavigator configuration) : base(writer, configuration) {
+ // keep track of the writer
+ mrw = writer;
+
+ // register processors as callbacks
+ writer.RegisterStartTagCallback("apis", new MRefBuilderCallback(AddAttachedMembers));
+ writer.RegisterStartTagCallback("apidata", new MRefBuilderCallback(WriteAttachedMember));
+ writer.RegisterStartTagCallback("typedata", new MRefBuilderCallback(WriteContentPropertyData));
+ writer.RegisterEndTagCallback("api", new MRefBuilderCallback(WriteAttachmentData));
+ }
+
+ private void AddAttachedMembers(XmlWriter writer, object info) {
+ NamespaceList spaces = (NamespaceList)info;
+ foreach (Namespace space in spaces) {
+ TypeNodeList types = space.Types;
+ foreach (TypeNode type in types) {
+
+ MemberList members = type.Members;
+
+ // go through the members, looking for fields signaling attached properties
+ foreach (Member member in members) {
+
+ // we need a visible, static, field...
+ if (!member.IsStatic || !member.IsVisibleOutsideAssembly || member.NodeType != NodeType.Field) continue;
+ Field field = (Field)member;
+
+ // of type dependency property....
+ if (field.Type.FullName != "System.Windows.DependencyProperty") continue;
+
+ // with a name ending in "Property"...
+ string name = field.Name.Name;
+ if (!name.EndsWith("Property")) continue;
+ name = name.Substring(0, name.Length - 8);
+
+ // look for a getter and/or a setter
+
+ Method getter = null;
+ MemberList candidateGetters = type.GetMembersNamed(new Identifier("Get" + name));
+ for (int i = 0; i < candidateGetters.Count; i++) {
+ Member candidateGetter = candidateGetters[i];
+ if ((candidateGetter.NodeType == NodeType.Method) && candidateGetter.IsStatic && candidateGetter.IsVisibleOutsideAssembly) getter = (Method)candidateGetter;
+ }
+
+ Method setter = null;
+ MemberList candidateSetters = type.GetMembersNamed(new Identifier("Set" + name));
+ for (int i = 0; i < candidateSetters.Count; i++) {
+ Member candidateSetter = candidateSetters[i];
+ if ((candidateSetter.NodeType == NodeType.Method) && candidateSetter.IsStatic && candidateSetter.IsVisibleOutsideAssembly) setter = (Method)candidateSetter;
+ }
+
+ if ((getter == null) && (setter == null)) continue;
+
+ // make sure there isn't already such a property
+
+ Property existingProperty = type.GetProperty(new Identifier(name), new TypeNode[0]);
+ if (existingProperty != null) continue;
+
+ // okay, this really is an indication of an attached property, so create one
+
+ Property attachedProperty = new Property(type, null, PropertyFlags.None, new Identifier(name), getter, setter);
+ // attached properties have no parameters
+ attachedProperty.Parameters = ParameterList.Empty;
+ // attached properties are instance properties
+ // somehow mark as attached?
+ type.Members.Add(attachedProperty);
+ attachedMembers.Add(attachedProperty, field);
+
+ }
+
+ // go through the members, looking for fields signaling attached events
+ foreach (Member member in members) {
+
+ if (!member.IsStatic || !member.IsVisibleOutsideAssembly) continue;
+
+ if (member.NodeType != NodeType.Field) continue;
+ Field field = (Field)member;
+
+ if (field.Type.FullName != "System.Windows.RoutedEvent") continue;
+
+ string name = field.Name.Name;
+ if (!name.EndsWith("Event")) continue;
+ name = name.Substring(0, name.Length - 5);
+
+ Method adder = null;
+ MemberList candidateAdders = type.GetMembersNamed(new Identifier("Add" + name + "Handler"));
+ for (int i = 0; i < candidateAdders.Count; i++) {
+ Member candidateAdder = candidateAdders[i];
+ if ((candidateAdder.NodeType == NodeType.Method) && candidateAdder.IsStatic) adder = (Method)candidateAdder;
+ }
+
+ Method remover = null;
+ MemberList candidateRemovers = type.GetMembersNamed(new Identifier("Remove" + name + "Handler"));
+ for (int i = 0; i < candidateRemovers.Count; i++) {
+ Member candidateRemover = candidateRemovers[i];
+ if ((candidateRemover.NodeType == NodeType.Method) && candidateRemover.IsStatic) remover = (Method)candidateRemover;
+ }
+
+ if ((adder == null) || (remover == null)) continue;
+
+ // make sure there isn't already such an event
+
+ Event existingEvent = type.GetEvent(new Identifier(name));
+ if (existingEvent != null) continue;
+
+ // okay, this really is an indication of an attached event, so create one
+
+ TypeNode handler = adder.Parameters[1].Type;
+ Event attachedEvent = new Event(type, null, EventFlags.None, new Identifier(name), adder, null, remover, handler);
+ attachedEvent.HandlerFlags = adder.Flags;
+ // attached events are instance events
+ // mark as attached?
+
+ type.Members.Add(attachedEvent);
+ attachedMembers.Add(attachedEvent, field);
+
+ }
+
+ }
+ }
+
+ }
+
+ private Property GetContentProperty(TypeNode type) {
+ return (null);
+ }
+
+ private void WriteAttachedMember(XmlWriter writer, object info) {
+
+ if (attachedMembers.ContainsKey(info)) {
+ if (info is Property) {
+ writer.WriteAttributeString("subsubgroup", "attachedProperty");
+ } else if (info is Event) {
+ writer.WriteAttributeString("subsubgroup", "attachedEvent");
+ }
+ }
+
+ }
+
+ private void WriteAttachmentData(XmlWriter writer, object info) {
+
+ if (attachedMembers.ContainsKey(info)) {
+
+ Member attachedMember = (Member)info;
+ if (attachedMember.NodeType == NodeType.Property) {
+
+ Property attachedProperty = (Property)attachedMember;
+
+ writer.WriteStartElement("attachedpropertydata");
+
+ string fieldName = attachedMember.Name + "Property";
+ Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
+ writer.WriteStartElement("field");
+ mrw.WriteMemberReference(field);
+ writer.WriteEndElement();
+
+ Method getter = attachedProperty.Getter;
+ if (getter != null) {
+ writer.WriteStartElement("getter");
+ mrw.WriteMemberReference(getter);
+ writer.WriteEndElement();
+ }
+
+ Method setter = attachedProperty.Setter;
+ if (setter != null) {
+ writer.WriteStartElement("setter");
+ mrw.WriteMemberReference(setter);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+
+ } else if (attachedMember.NodeType == NodeType.Event) {
+
+ Event attachedEvent = (Event)attachedMember;
+
+ writer.WriteStartElement("attachedeventdata");
+
+ string fieldName = attachedMember.Name + "Event";
+ Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
+ writer.WriteStartElement("field");
+ mrw.WriteMemberReference(field);
+ writer.WriteEndElement();
+
+ Method adder = attachedEvent.HandlerAdder;
+ writer.WriteStartElement("adder");
+ mrw.WriteMemberReference(adder);
+ writer.WriteEndElement();
+
+ Method remover = attachedEvent.HandlerRemover;
+ writer.WriteStartElement("remover");
+ mrw.WriteMemberReference(remover);
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ }
+
+ }
+
+ }
+
+ private void WriteContentPropertyData(XmlWriter writer, object info) {
+ TypeNode type = (TypeNode)info;
+ if (contentProperties.ContainsKey(type)) {
+
+ // get default constructors
+ InstanceInitializer constructor = type.GetConstructor(new TypeNode[0]);
+ if ((constructor != null) && (!constructor.IsPublic)) constructor = null;
+
+ if (constructor != null) writer.WriteAttributeString("defaultConstructor", mrw.ApiNamer.GetMemberName(constructor));
+
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/reflection.xsd b/tools/Sandcastle/Source/MRefBuilder/reflection.xsd
new file mode 100644
index 0000000..f551aed
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/reflection.xsd
@@ -0,0 +1,686 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
+
+ <!-- Api elements -->
+
+ <xsd:element name="reflection">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assemblies" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="apis" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Assembly data -->
+
+ <xsd:element name="assemblies">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assembly" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assemblydata" />
+ <xsd:element ref="attributes" />
+ </xsd:sequence>
+ <xsd:attribute name="name" />
+ <xsd:attribute name="version" />
+ <xsd:attribute name="culture" />
+ <xsd:attribute name="key" />
+ <xsd:attribute name="hash" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assemblydata">
+ <xsd:complexType>
+ <xsd:attribute name="version" />
+ <xsd:attribute name="culture" />
+ <xsd:attribute name="key" />
+ <xsd:attribute name="hash" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Api data -->
+
+ <xsd:element name="apis">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="api" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- uniqueness constraint can only be applied if duplicates are merged -->
+ <!--
+ <xsd:unique name="uniqueId">
+ <xsd:selector xpath="api" />
+ <xsd:field xpath="@id" />
+ </xsd:unique>
+-->
+ </xsd:element>
+
+ <xsd:element name="api">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="apidata" minOccurs="1" maxOccurs="1" />
+ <xsd:choice>
+ <!-- namespace -->
+ <xsd:sequence>
+ <xsd:element ref="elements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- type -->
+ <xsd:sequence>
+ <xsd:element ref="typedata" minOccurs="1" />
+ <xsd:element ref="enumerationbase" minOccurs="0" />
+ <xsd:element ref="family" minOccurs="0" />
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ <xsd:element ref="implements" minOccurs="0" />
+ <xsd:element ref="implementors" minOccurs="0" />
+ <xsd:element ref="elements" minOccurs="0" />
+ <xsd:element ref="containers" minOccurs="1" />
+ </xsd:sequence>
+ <!-- member -->
+ <xsd:sequence>
+ <xsd:element ref="memberdata" minOccurs="1" />
+ <xsd:choice>
+ <!-- field -->
+ <xsd:sequence>
+ <xsd:element name="fielddata" minOccurs="1" />
+ <xsd:element ref="returns" minOccurs="1" />
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <!-- procedure-->
+ <xsd:sequence>
+ <xsd:element name="proceduredata" minOccurs="1" />
+ <xsd:element ref="overrides" minOccurs="0" />
+ <xsd:choice>
+ <!-- method -->
+ <xsd:sequence>
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ </xsd:sequence>
+ <!-- property -->
+ <xsd:sequence>
+ <xsd:element ref="propertydata" minOccurs="1" />
+ <xsd:element ref="getter" minOccurs="0" />
+ <xsd:element ref="setter" minOccurs="0"/>
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="1" />
+ </xsd:sequence>
+ <!-- event -->
+ <xsd:sequence>
+ <xsd:element ref="eventdata" minOccurs="1" />
+ <xsd:element ref="adder" minOccurs="0" />
+ <xsd:element ref="remover" minOccurs="0"/>
+ <xsd:element ref="eventhandler" minOccurs="1" />
+ <xsd:element ref="eventargs" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="implements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- constructor -->
+ <xsd:sequence>
+ <xsd:element ref="parameters" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="containers" minOccurs="1" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="apiId" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:group name="memberContent">
+ <xsd:sequence>
+ <xsd:element name="apidata" minOccurs="1" />
+ <xsd:element ref="memberdata" minOccurs="1" />
+ <xsd:choice>
+ <!-- field -->
+ <xsd:sequence>
+ <xsd:element name="fielddata" minOccurs="1" />
+ <xsd:element ref="returns" minOccurs="1" />
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <!-- procedure-->
+ <xsd:sequence>
+ <xsd:element name="proceduredata" minOccurs="1" />
+ <xsd:element ref="overrides" minOccurs="0" />
+ <xsd:choice>
+ <!-- method -->
+ <xsd:sequence>
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ </xsd:sequence>
+ <!-- property -->
+ <xsd:sequence>
+ <xsd:element ref="propertydata" minOccurs="1" />
+ <xsd:element ref="getter" minOccurs="0" />
+ <xsd:element ref="setter" minOccurs="0"/>
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="1" />
+ </xsd:sequence>
+ <!-- event -->
+ <xsd:sequence>
+ <xsd:element ref="eventdata" minOccurs="1" />
+ <xsd:element ref="adder" minOccurs="0" />
+ <xsd:element ref="remover" minOccurs="0"/>
+ <xsd:element ref="eventhandler" minOccurs="1" />
+ <xsd:element ref="eventargs" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="implements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- constructor -->
+ <xsd:sequence>
+ <xsd:element ref="parameters" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="containers" minOccurs="1" />
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="optionalApiInformation">
+ <xsd:choice minOccurs="0">
+ <xsd:group ref="memberContent" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <!-- Identity and information elements -->
+
+ <xsd:element name="apidata">
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="group" type="apiGroupType" use="required" />
+ <xsd:attribute name="subgroup" type="apiSubgroupType" use="optional" />
+ <xsd:attribute name="subsubgroup" type="apiSubsubgroupType" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="typedata">
+ <xsd:complexType>
+ <xsd:attribute name="visibility" type="visibilityType" use="required" />
+ <xsd:attribute name="abstract" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="sealed" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="serializable" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="layout" type="xsd:string" use="optional" />
+ <xsd:attribute name="format" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="fielddata">
+ <xsd:complexType>
+ <xsd:attribute name="literal" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="initonly" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="volatile" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="serialized" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="memberdata">
+ <xsd:complexType>
+ <xsd:attribute name="visibility" type="visibilityType" />
+ <xsd:attribute name="static" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="special" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="default" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="proceduredata">
+ <xsd:complexType>
+ <xsd:attribute name="abstract" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="virtual" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="final" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="overrides">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="member" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="propertydata">
+ <xsd:complexType>
+ <xsd:attribute name="get" type="xsd:boolean" />
+ <xsd:attribute name="set" type="xsd:boolean" />
+ <xsd:attribute name="get-visibility" type="visibilityType" use="optional" />
+ <xsd:attribute name="set-visibility" type="visibilityType" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="getter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="setter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="eventdata">
+ <xsd:complexType>
+ <xsd:attribute name="add" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="remove" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="call" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="adder">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="remover">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="enumerationbase" type="typeReference" />
+
+ <xsd:element name="eventhandler" type="typeReference" />
+
+ <xsd:element name="eventargs" type="typeReference" />
+
+ <!-- Generic template parameters -->
+
+ <xsd:element name="templates">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="template" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="template">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="constrained" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="api" type="xsd:string" use="optional" />
+ <xsd:attribute name="index" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="constrained">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="implements" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="ref" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="value" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="ctor" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <!-- Parameters and return values -->
+
+ <xsd:element name="parameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="parameter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="in" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="out" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="params" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="returns" type="typeReference" />
+
+ <!-- Interface implementations -->
+
+ <xsd:element name="implements">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:element ref="member" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="implementors" type="typeReferenceList" />
+
+ <!-- Inheritance -->
+
+ <xsd:element name="family">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="ancestors" minOccurs="0" />
+ <xsd:element ref="descendents" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ancestors">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="descendents">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Attributes -->
+
+ <xsd:element name="attributes">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="attribute">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:sequence>
+ <xsd:element ref="argument" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="assignment" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="argument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assignment">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Containers -->
+
+ <xsd:element name="containers">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="typeContainers">
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="memberContainers">
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="library">
+ <xsd:complexType>
+ <xsd:attribute name="assembly" type="xsd:string" />
+ <xsd:attribute name="module" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="outer" type="typeReferenceList" />
+
+ <!-- Elements -->
+
+ <xsd:element name="elements">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="element" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="element">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="optionalApiInformation">
+ <xsd:attribute name="api" type="apiId" use="optional" />
+ <xsd:attribute name="target-api" type="apiId" use="optional" />
+ <xsd:attribute name="display-api" type="apiId" use="optional" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- references -->
+
+ <xsd:element name="namespace">
+ <xsd:complexType>
+ <xsd:attribute name="api" type="namespaceId" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:group name="typeReferenceElements">
+ <xsd:choice>
+ <xsd:element ref="arrayOf" />
+ <xsd:element name="pointerTo" type="typeReference" />
+ <xsd:element name="referenceTo" type="typeReference" />
+ <xsd:element ref="type" />
+ <xsd:element ref="template" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="typeReference">
+ <xsd:group ref="typeReferenceElements" />
+ </xsd:complexType>
+
+ <xsd:complexType name="typeReferenceList">
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <xsd:group ref="typeReferenceElements" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="arrayOf">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:attribute name="rank" type="xsd:positiveInteger" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="type">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="optionalModifier" type="typeReference" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="requiredModifier" type="typeReference" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="specialization" type="typeReferenceList" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="api" type="typeId" use="required" />
+ <xsd:attribute name="ref" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- <xsd:element name="specialization" type="typeReferenceList" /> -->
+
+ <xsd:element name="member">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="optional" />
+ <xsd:attribute name="api" type="xsd:string" use="optional" />
+ <xsd:attribute name="target-api" type="xsd:string" use="optional" />
+ <xsd:attribute name="display-api" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="valueReference">
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:choice>
+ <xsd:element name="value" type="xsd:string" />
+ <xsd:element name="typeValue" type="typeReference" />
+ <xsd:element name="enumValue" />
+ <xsd:element name="nullValue" />
+ </xsd:choice>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:group name="valueReferenceElements">
+ <xsd:choice>
+ <xsd:element name="value" type="xsd:string" />
+ <xsd:element name="typeValue" type="typeReference" />
+ <xsd:element name="enumValue" />
+ <xsd:element name="nullValue" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:simpleType name="rootId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="R:[_\w\.]+" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="namespaceId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="N:([_\w]+\.)*[_\w]*" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="typeId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="T:.+" />
+ <!-- <xsd:pattern value="T:([_\w]+\.)*[_\w]+(\{.+\})?(@|\*|(\[\]))*" /> -->
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="fieldReference">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="F:(\w+\.)*[_\w]+(\{.+\})?\.\w+" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="memberId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="[FMPE]:.+" />
+ <!-- <xsd:pattern value="[FMPE]:(\w+\.)*[_\w]+(\{.+\})?\.([_\.\w&lt;&gt;,]+|#ctor)(\(.+\))?(~(\w+\.)*[_\w]+(\{.+\})?(@|\*|(\[\]))*)?" /> -->
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiId">
+ <xsd:union memberTypes="rootId namespaceId typeId memberId" />
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiGroupType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="namespace" />
+ <xsd:enumeration value="type" />
+ <xsd:enumeration value="member" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiSubgroupType">
+ <xsd:restriction base="xsd:string">
+ <!-- type subgroups -->
+ <xsd:enumeration value="class" />
+ <xsd:enumeration value="structure" />
+ <xsd:enumeration value="interface" />
+ <xsd:enumeration value="enumeration" />
+ <xsd:enumeration value="delegate" />
+ <!-- member subgroups -->
+ <xsd:enumeration value="constructor" />
+ <xsd:enumeration value="method" />
+ <xsd:enumeration value="property" />
+ <xsd:enumeration value="field" />
+ <xsd:enumeration value="event" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiSubsubgroupType">
+ <xsd:restriction base="xsd:string">
+ <!-- method subsubgroups -->
+ <xsd:enumeration value="operator" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="visibilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="public" />
+ <xsd:enumeration value="family" />
+ <xsd:enumeration value="assembly" />
+ <xsd:enumeration value="family or assembly" />
+ <xsd:enumeration value="family and assembly" />
+ <xsd:enumeration value="private" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- format, layout -->
+
+</xsd:schema>