/// <summary>
        /// Makes a table of documentation pulled from the XML C# comments in the assembly for the given type.
        /// </summary>
        /// <param name="t">The type to make the documentation table for.</param>
        /// <param name="summaryDescriptions">The list of all the XML comments for the members of the type.</param>
        /// <param name="reflectedMembers">The list of all the reflected properties and fields of the type.</param>
        /// <returns></returns>
        protected StringBuilder MakeDocumentationTableForType(Type t, List <MemberSummary> summaryDescriptions, List <MemberInfo> reflectedMembers)
        {
            if (t == null || summaryDescriptions == null || reflectedMembers == null)
            {
                return(null);
            }

            StringBuilder tableBuilder = new StringBuilder();

            foreach (MemberInfo reflectedMember in reflectedMembers)
            {
                MemberSummary match = summaryDescriptions.FirstOrDefault(item => item.Name == reflectedMember.Name);
                if (ShouldIncludeInDocTable(match, reflectedMember) == false)
                {
                    continue;
                }

                Type   itemType = (reflectedMember is PropertyInfo) ? (reflectedMember as PropertyInfo).PropertyType : (reflectedMember as FieldInfo).FieldType;
                string summary  = (match == null) ? "??" : match.Description;
                string jsType   = GetJavaScriptTypeEquivalent(itemType);
                if (jsType == null)
                {
                    jsType = "??";
                }

                string tableLine = GetTableLine(reflectedMember, summary, jsType);
                tableBuilder.AppendLine(tableLine);
            }

            return(tableBuilder);
        }
        /// <summary>
        /// Writes all the lines of documentation needed for the JSON example and properties table for an object of the given type to the internal string builder, _builder.
        /// </summary>
        /// <param name="t">The type to produce documentation for.</param>
        protected void MakeDocumentationForType(Type t)
        {
            if (t == null)
            {
                return;
            }

            List <MemberSummary> matches          = GetMemberSummariesForType(t);  //find all the summary descriptions from the XML file for the given type and its members
            List <MemberInfo>    reflectedMembers = GetReflectedMembersForType(t); //get all the public fields and properties belonging to the type

            if (matches == null || reflectedMembers == null || (matches.Count == 0 && reflectedMembers.Count == 0))
            {
                return;
            }

            string        typeStringToMatch = (t.IsNested == true) ?  t.FullName.Replace("+", ".") : t.FullName;
            MemberSummary typeSummary       = matches.Where(item => item.NamespacePath + "." + item.Name == typeStringToMatch && item.MemberType == MemberType.Type).FirstOrDefault(); //get the doc summary entry for the type definition itself
            string        header            = t.Name + " - " + ((typeSummary == null) ? "??" : typeSummary.Description);

            _builder.Append(header);
            _builder.AppendLine();
            _builder.Append(MakeJSONSampleForType(t, reflectedMembers));
            _builder.AppendLine("\n");
            _builder.Append(MakeDocumentationTableForType(t, matches, reflectedMembers));
            _builder.AppendLine("---------------------------------------------------------------------------------------");
        }
 /// <summary>
 /// Whether or not to include a member in the table of summary descriptions.
 /// </summary>
 /// <param name="summary">The summary description from the XML doc file.</param>
 /// <param name="reflectionMemberInfo">The reflected member info of the member to include or not.</param>
 /// <returns></returns>
 protected virtual bool ShouldIncludeInDocTable(MemberSummary summary, MemberInfo reflectionMemberInfo)
 {
     if (reflectionMemberInfo.DeclaringType.IsEnum == true && reflectionMemberInfo.Name == "value__")
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Reads the assembly's XML documentation and parses out the names and summary descriptions of each member.
        /// </summary>
        /// <param name="xmlDocFilePath"></param>
        protected void ReadXMLDoc(string xmlDocFilePath)
        {
            if (xmlDocFilePath == null || File.Exists(xmlDocFilePath) == false)
            {
                return;
            }

            using (XmlReader reader = XmlTextReader.Create(xmlDocFilePath))
            {
                while (reader.Read() == true)
                {
                    if (reader.Name != "member" || reader.NodeType == XmlNodeType.EndElement)
                    {
                        continue;
                    }

                    string name    = reader.GetAttribute("name");
                    string summary = null;

                    while (reader.Read() == true)
                    {
                        if (reader.Name == "summary")
                        {
                            reader.Read();
                            summary = reader.Value.Trim();
                            break;
                        }
                    }

                    MemberSummary info = ProcessXMLData(name, summary, reader);
                    if (info != null)
                    {
                        _members.Add(info);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Walks through the parameters for a method in the xml documentation file, parses them, and adds them as MethodDefinition.MethodParameter to the methodInfo's parameter list.
        /// </summary>
        /// <param name="methodInfo">The data from the XML file that pertains to the method and its signature.</param>
        /// <param name="reader">The XML reader that is reading the </param>
        /// <returns></returns>
        protected MemberSummary ReadMethodParameters(MemberSummary methodInfo, XmlReader reader)
        {
            if (methodInfo == null || reader == null)
            {
                return(null);
            }

            string originalName = methodInfo.Name;

            string[] parameterTypes = null;

            if (methodInfo.Name != null)
            {
                int signatureStart = methodInfo.Name.IndexOf("(");
                if (signatureStart != -1)
                {
                    methodInfo.Name = methodInfo.Name.Substring(0, signatureStart);

                    string paramTypesString = originalName.Substring(signatureStart + 1, originalName.Length - signatureStart - 2); //skip over first parenthsis, last parenthsis
                    parameterTypes = paramTypesString.Split(',');

                    if (parameterTypes.Length == 0)
                    {
                        parameterTypes = null;
                    }
                }

                if (methodInfo.Name.Contains("#ctor") == true) //its a constructor - we dont want the #ctor in the name because it is ugly and will confuse some developers/consumers of documentation
                {
                    int finalSegmentStart = methodInfo.NamespacePath.LastIndexOf(".");
                    if (finalSegmentStart != -1)
                    {
                        methodInfo.Name = methodInfo.NamespacePath.Substring(finalSegmentStart + 1, methodInfo.NamespacePath.Length - finalSegmentStart - 1);
                    }
                }
            }

            int paramNumber = 0;

            while (reader.Read() == true)
            {
                if (reader.Name == "member" && reader.NodeType == XmlNodeType.EndElement)
                {
                    break;                                                                       //reached the end of the method defintion
                }
                if (reader.Name != "param" || reader.NodeType == XmlNodeType.EndElement)
                {
                    continue;
                }

                string name    = reader.GetAttribute("name");
                string summary = null;

                reader.Read();
                summary = reader.Value.Trim();

                MethodDefinition.MethodParameter curParam = new MethodDefinition.MethodParameter();
                curParam.ParamName        = name;
                curParam.ParamDescription = summary;

                if (parameterTypes != null && paramNumber <= parameterTypes.Length)
                {
                    curParam.ParamType = parameterTypes[paramNumber]; //we got the types from the method signature and the params are in the same order as the types, so we can match them up.
                }

                (methodInfo as MethodDefinition).Parameters.Add(curParam);
                paramNumber++;
            }

            return(methodInfo);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Turns an entry from a XML documentation file into a MemberSummary object.
        /// </summary>
        /// <param name="name">The value of the "Name" attribute from the XML documentation.</param>
        /// <param name="summary">The summary string from the XML documentation.</param>
        /// <param name="reader">The XML reader that is reading the XML file.</param>
        /// <returns></returns>
        protected MemberSummary ProcessXMLData(string name, string summary, XmlReader reader)
        {
            if (name == null || summary == null || name.Length == 0)
            {
                return(null);
            }

            MemberSummary info      = null;
            string        firstChar = name.Substring(0, 1).ToLower();

            if (firstChar == "p" || firstChar == "t" || firstChar == "f") //property, field, or type
            {
                int    lastDot       = name.LastIndexOf(".");
                string description   = summary;
                string namespacePath = name.Substring(2, lastDot - 2); //the name of the member always starts with a type prefix and a colon, get the rest of the string after the prefix
                string memberName    = name.Substring(lastDot + 1);

                info               = new MemberSummary();
                info.Name          = memberName;
                info.Description   = description;
                info.NamespacePath = namespacePath;

                if (firstChar == "p")
                {
                    info.MemberType = MemberType.Property;
                }
                else if (firstChar == "t")
                {
                    info.MemberType = MemberType.Type;
                }
                else if (firstChar == "f")
                {
                    info.MemberType = MemberType.Field;
                }
            }
            else if (firstChar == "m") //method
            {
                int lastDot          = name.LastIndexOf(".");
                int firstParenthesis = name.IndexOf("(");

                string description   = summary;
                string namespacePath = null;
                string memberName    = null;

                if (firstParenthesis == -1)                         //no parenthsis on the method signature in the xml documentation if it has no parameters
                {
                    namespacePath = name.Substring(2, lastDot - 2); //the name of the member always starts with a type prefix and a colon, get the rest of the string after the prefix
                    memberName    = name.Substring(lastDot + 1);
                }
                else
                {
                    string withoutParams = name.Substring(0, firstParenthesis); //cut off the parameter string
                    lastDot = withoutParams.LastIndexOf(".");                   //get the last dot in the parameterless name (otherwise the namespaces of the parameters get used as the last dot)

                    namespacePath = withoutParams.Substring(2, lastDot - 2);    //the name of the member always starts with a type prefix and a colon, get the rest of the string after the prefix
                    memberName    = name.Substring(namespacePath.Length + 3);   //2 for the prefix, 1 for the last dot
                }

                info               = new MethodDefinition();
                info.Name          = memberName;
                info.Description   = description;
                info.NamespacePath = namespacePath;
                info.MemberType    = MemberType.Method;

                return(ReadMethodParameters(info, reader));
            }

            return(info);
        }