Exemplo n.º 1
0
        private void ParseFunctionArgList(Symbol s, string content)
        {
            s.parameters.Clear();

            int endIdx;
            content = FindStringInBetween(content, 0, "<table class=\"memname\">", "</table>", out endIdx);
            if (endIdx == -1)
                return;

            int startIdx = 0;
            while (startIdx < content.Length)
            {
                string paramType = FindStringInBetween(content, startIdx, "<td class=\"paramtype\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                string paramName = FindStringInBetween(content, startIdx, "<td class=\"paramname\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                string strippedParamName = FindStringInBetween(paramName, 0, "<em>", "</em>", out endIdx);

                Parameter p = new Parameter();
                p.type = paramType.StripHtmlCharacters().StripHtmlLinks();
                p.name = strippedParamName.StripHtmlCharacters().StripHtmlLinks();
                s.parameters.Add(p);
            }
        }
Exemplo n.º 2
0
        /*
        /// <summary>
        /// Each doxygen documentation file on a class contains a single class comment near the top of the page.
        /// </summary>
        /// <param name="dataString"></param>
        private void ParseDocumentationFileForClassComments(string dataString)
        {
            int endIndex;
            string className = FindStringInBetween(dataString, 0, "<!-- doxytag: class=\"", "\" -->", out endIndex);
            if (endIndex == -1)
                return;
            if (!symbols.ContainsKey(className))
                return;
            Symbol classSymbol = symbols[className];

            string classComments = FindStringInBetween(dataString, endIndex,
                "<hr/><a name=\"_details\"></a><h2>Detailed Description</h2>",
                "<hr/><h2>Member",
                out endIndex);
            if (endIndex != -1)
            {
                classSymbol.comments.AddRange(SplitToParagraphs(classComments));
            }
        }
        */
        /*
        /// <summary>
        /// Breaks down the single string form arglist into a member args list structure.
        /// </summary>
        /// <param name="s"></param>
        static private void GenerateArgList(Symbol s)
        {
            s.parameters.Clear();
            string argList = s.argList;
            if (argList.StartsWith("("))
                argList = argList.Substring(1);
            if (argList.EndsWith(")"))
                argList = argList.Substring(0, argList.Length - 1);
            if (argList.EndsWith(")=0"))
                argList = argList.Substring(0, argList.Length - 3);
            argList = argList.Trim();
            if (argList.Length == 0)
                return;
            string[] args = argList.Split(',');
            foreach (string arg in args)
            {
                string a = arg.Trim();
//                int lastSpace = a.LastIndexOf(' ');
                Parameter p = new Parameter();
                p.type = a.StripHtmlCharacters().StripHtmlLinks();// a.Substring(0, lastSpace).Trim();
//                p.name = a.Substring(lastSpace + 1, a.Length - (lastSpace + 1)).Trim();
                s.parameters.Add(p);
            }
        }

        private void ParseFunctionArgList(Symbol s, string content)
        {
            s.parameters.Clear();

            int endIdx;
            content = FindStringInBetween(content, 0, "<table class=\"memname\">", "</table>", out endIdx);
            if (endIdx == -1)
                return;

            int startIdx = 0;
            while (startIdx < content.Length)
            {
                string paramType = FindStringInBetween(content, startIdx, "<td class=\"paramtype\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                string paramName = FindStringInBetween(content, startIdx, "<td class=\"paramname\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                string strippedParamName = FindStringInBetween(paramName, 0, "<em>", "</em>", out endIdx);

                Parameter p = new Parameter();
                p.type = paramType.StripHtmlCharacters().StripHtmlLinks();
                p.name = strippedParamName.StripHtmlCharacters().StripHtmlLinks();
                s.parameters.Add(p);
            }
        }

        private void ParseFunctionParameterComments(Symbol s, string memdocContent)
        {
            int endIdx;
            string memberData = FindStringInBetween(memdocContent, 0, "<dl><dt><b>Parameters:</b></dt><dd>",
                "</table>", out endIdx);
            if (endIdx == -1)
                return;
            int startIdx = 0;
            while(startIdx < memberData.Length)
            {
                string row = FindStringInBetween(memberData, startIdx, "<tr>", "</tr>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                int paramNameEnd;
                string paramName = FindStringInBetween(row, 0, "<em>", "</em>", out paramNameEnd);
                paramName = paramName.Trim();
                if (paramNameEnd == -1)
                    continue;
                int cmEnd;
                string comment = FindStringInBetween(row, paramNameEnd, "<td>", "</td>", out cmEnd);
                if (cmEnd == -1)
                    continue;
                Parameter param = s.FindParamByName(paramName);
                if (param == null)
                    continue;

                param.comment = comment.Trim();
            }
        }

        private void ParseFunctionReturnValueComments(Symbol s, string memdocContent)
        {
            int endIdx;
            string memberData = FindStringInBetween(memdocContent, 0, "<dl class=\"return\"><dt><b>Returns:</b></dt><dd>",
                "</dd></dl>", out endIdx);
            if (endIdx == -1)
                return;
            s.returnComment = memberData;
        }

        private void ParseDocumentationFileForBriefMemberComments(string dataString)
        {
            int startIdx = 0;
            while(startIdx < dataString.Length)
            {
                int endIdx;
                string elemRefStr = "<tr><td class=\"memItemLeft\" align=\"right\" valign=\"top\">";
                string memberLine1 = FindStringInBetween(dataString, startIdx,
                    elemRefStr,
                    "</tr>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                int endIdx2;
                int nextElemRefEnd;
                string nextElemRef = FindStringInBetween(dataString, endIdx+1,
                    elemRefStr, "</tr>", out nextElemRefEnd);
                string memberLine2 = FindStringInBetween(dataString, endIdx + 1,
                    "<tr><td class=\"mdescLeft\">", "</tr>",
                    out endIdx2);
                if (endIdx2 == -1)
                    continue;
                if (endIdx2 >= nextElemRefEnd)
                    continue; // Parsed too far with the comment line.
                startIdx = endIdx2 + 1;

                // Find the ref this brief comment is for.
                string refString = FindStringInBetween(memberLine1, 0, " ref=\"", "\"", out endIdx);
                if (endIdx == -1)
                    continue;
                if (!symbolsByAnchor.ContainsKey(refString))
                    continue;
                Symbol s = symbolsByAnchor[refString];
                string briefComment = FindStringInBetween(memberLine2, 0, "<td class=\"mdescRight\">",
                    "</td>", out endIdx);
                if (endIdx == -1)
                    continue;
                s.comments.Add(briefComment);
            }
        }

        private void ParseDocumentationFile(string filename)
        {
//            Console.WriteLine("Parsing documentation from file \"" + filename + "\"");
            TextReader t;
            try
            {
                t = new StreamReader(filename);
            } catch(System.IO.FileNotFoundException)
            {
                return;
            }

            string dataString = t.ReadToEnd();

            ParseDocumentationFileForClassComments(dataString);
            ParseDocumentationFileForBriefMemberComments(dataString);
            int startIndex = 0;
            int strLen = dataString.Length;
            while (startIndex < strLen)
            {
                int index = dataString.IndexOf("doxytag:", startIndex);
                if (index == -1)
                    break;
                startIndex = index + 1;
                int refStartIndex = dataString.IndexOf(" ref=\"", startIndex);
                if (refStartIndex == -1)
                    break;
                int refIndex = refStartIndex + 6;
                int refEndIndex = dataString.IndexOf("\"", refIndex);
                if (refEndIndex == -1)
                    break;
                startIndex = refEndIndex + 1;
                string anchorRef = dataString.Substring(refIndex, refEndIndex - refIndex);
                if (!symbolsByAnchor.ContainsKey(anchorRef))
                    continue;
                Symbol s = symbolsByAnchor[anchorRef];

                // Try to find memdoc content (detailed comment block).
                int memdocEnd;
                string memdocContent;
                bool success = FindMemdocContent(dataString, startIndex, out memdocContent, out memdocEnd);
                if (success)
                {
                    s.comments.AddRange(SplitToParagraphs(memdocContent));

                    if (s.kind == "function")
                    {
                        int protoEndIdx;
                        string memProto = FindStringInBetween(dataString, startIndex, "<div class=\"memproto\">",
                            "</div>", out protoEndIdx);
                        if (protoEndIdx != -1)
                            ParseFunctionArgList(s, memProto);
                        ParseFunctionParameterComments(s, memdocContent);
                        ParseFunctionReturnValueComments(s, memdocContent);
                    }

                    startIndex = memdocEnd + 1;
                }
                else
                {
                    success = FindBriefdocContent(dataString, startIndex, out memdocContent, out memdocEnd);
                    if (success)
                    {
                        s.comments.AddRange(SplitToParagraphs(memdocContent));
                        startIndex = memdocEnd + 1;
                    }
                }
            }

            foreach (Symbol s in symbolsByAnchor.Values)
                ProcessDocGeneratorCommentDirectives(s);

//            XmlDocument doc = new XmlDocument();
 //           doc.XmlResolver = null;
  //          doc.LoadXml(dataString);
/*
            HTMLDocument doc = new HTMLDocument();
            IHTMLDocument2 doc2 = (IHTMLDocument2)doc;
            doc2.write(dataString);
            doc.get
*/
   //         WebBrowser wb = new WebBrowser();
  //          wb.DocumentText = dataString;
 //           HtmlDocument doc = wb.Document;// new HtmlDocument();
//            doc.
//            doc.
/*
            List<XmlElement> anchorElements = new List<XmlElement>();
            FindAnchorElements(doc.DocumentElement, anchorElements);
            foreach (XmlElement n in anchorElements)
            {
                XmlElement memDocSibling = FindMemDocSibling(n);
                Symbol s = symbolsByAnchor[memDocSibling.GetAttribute("id")];

                List<XmlElement> paragraphs = GetChildElementsByName(memDocSibling, "p");
                foreach (XmlElement p in paragraphs)
                {
                    s.comments.Add(p.InnerXml);
                }
            }
 */ 
   //     }

        public void ParseSectionDefElement(Symbol parent, XmlElement e)
        {
            foreach(XmlElement child in e.ChildNodes)
            {
                if (child.Name == "memberdef")
                {
                    Symbol member = new Symbol();
                    member.parent = parent;
                    member.id = child.GetAttribute("id");
                    member.kind = child.GetAttribute("kind");
                    member.visibilityLevel = ParseVisibilityLevel(child.GetAttribute("prot"));
                    member.isStatic = (child.GetAttribute("static") == "yes");
                    member.isConst = (child.GetAttribute("const") == "yes");
                    member.isMutable = (child.GetAttribute("mutable") == "yes");
                    member.isExplicit = (child.GetAttribute("explicit") == "yes");
                    member.virtualness = ParseVirtualness(child.GetAttribute("virt"));
                    member.type = GetXmlElementChildNodeValue(child, "type", true);
                    member.fullDefinition = GetXmlElementChildNodeValue(child, "definition");
                    member.argList = GetXmlElementChildNodeValue(child, "argsstring");

                    member.classMemberIndexTitle = member.name = GetXmlElementChildNodeValue(child, "name");
                    if (member.name.StartsWith("@"))
                        continue; // Doxygen creates items with names starting with '@' at least for unnamed unions, ignore those altogether.
                    symbols[member.id] = member;
//                    symbolsByName[member.name] = member;
                    parent.children.Add(member);
                    
                    // Function parameters.
                    foreach(XmlElement param in child.ChildNodes.OfType<XmlElement>())
                        if (param.Name == "param")
                        {
                            Parameter p = new Parameter();
                            if (member.kind == "define") // This is a #define macro.
                            {
                                p.type = "";
                                p.name = GetXmlElementChildNodeValue(param, "defname");
                            }
                            else // This is a real function
                            {
                                p.type = GetXmlElementChildNodeValue(param, "type", true);
                                p.name = GetXmlElementChildNodeValue(param, "declname");
                            }
                            member.parameters.Add(p);
                        }

                    // If this is a #define macro, get the macro body code.
                    if (member.kind == "define")
                    {                    
                        member.macroBody = GetXmlElementChildNodeValue(child, "initializer");
                        // Create the argList from scratch, because it is not present in the xml in same form than for functions.
                        member.argList = member.ArgStringWithoutTypes();
                    }

                    // Function parameter comments.
                    List<XmlElement> parameters = child.AllGrandChildElementsOfTypeAndAttribute("parameterlist", "kind", "param");
                    if (parameters != null && parameters.Count > 0)
                    {
                        foreach (XmlElement paramNode in parameters.OfType<XmlElement>())
                        {
                            foreach (XmlElement param in paramNode.ChildNodes.OfType<XmlElement>())
                            {
                                if (param.Name == "parameteritem")
                                {
                                    string paramName = param.FirstChildElementOfType("parameternamelist").FirstChildElementOfType("parametername").InnerText.Trim();
                                    Parameter p = member.FindParamByName(paramName);
                                    if (p != null)
                                        p.comment = param.FirstChildElementOfType("parameterdescription").InnerText;
                                }
                            }
                            // Remove the parameterlist from the detailed description node so that it won't appear in the 'detailedDescription' documentation string.
                            // The detailed description is created manually.
                            paramNode.ParentNode.RemoveChild(paramNode);
                        }
                    }

                    // TODOs ^ BUGs 
                    List<XmlElement> xrefsects = child.AllGrandChildElementsOfType("xrefsect");
                    if (xrefsects != null)
                    {
                        foreach (XmlElement elem in xrefsects)
                        {
                            if (GetXmlElementChildNodeValue(elem, "xreftitle") == "Todo")
                                member.todos.Add(GetXmlElementChildNodeValue(elem, "xrefdescription"));
                            if (GetXmlElementChildNodeValue(elem, "xreftitle") == "Bug")
                                member.bugs.Add(GetXmlElementChildNodeValue(elem, "xrefdescription"));
                            elem.ParentNode.RemoveChild(elem);
                        }
                    }

                    // @notes.
                    List<XmlElement> notesects = child.AllGrandChildElementsOfTypeAndAttribute("simplesect", "kind", "note");
                    if (notesects != null)
                    {
                        foreach (XmlElement elem in notesects)
                        {
                            member.notes.Add(elem.InnerText);
                            elem.ParentNode.RemoveChild(elem);
                        }
                    }

                    // Function return value.
                    XmlElement retVal = child.FirstGrandChildElementOfTypeAndAttribute("simplesect", "kind", "return");
                    if (retVal != null)
                    {
                        member.returnComment = retVal.InnerText;
                        retVal.ParentNode.RemoveChild(retVal);
                    }

                    // The "see also" section.
                    XmlElement see = child.FirstGrandChildElementOfTypeAndAttribute("simplesect", "kind", "see");
                    if (see != null)
                    {
                        member.seeAlsoDocumentation = see.InnerXml;
                        see.ParentNode.RemoveChild(see);
                    }

                    member.briefDescription = GetXmlElementChildNodeValue(child, "briefdescription").Trim();
                    member.inbodyDescription = GetXmlElementChildNodeValue(child, "inbodydescription").Trim();
                    member.detailedDescription = GetXmlElementChildNodeValue(child, "detaileddescription").Trim();
                    XmlElement loc = child.FirstChildElementOfType("location");
                    if (loc != null)
                    {
                        member.sourceFilename = loc.GetAttribute("bodyfile");
                        int.TryParse(loc.GetAttribute("bodystart"), out member.sourceFileStartLine);
                        int.TryParse(loc.GetAttribute("bodyend"), out member.sourceFileEndLine);
                        if (member.sourceFileEndLine == -1)
                            member.sourceFileEndLine = member.sourceFileStartLine;
                    }
                    ProcessDocGeneratorCommentDirectives(member);

                    ///\todo Add location.
                }
            }            
        }
Exemplo n.º 3
0
 /// <summary>
 /// Breaks down the single string form arglist into a member args list structure.
 /// </summary>
 /// <param name="s"></param>
 private static void GenerateArgList(Symbol s)
 {
     s.parameters.Clear();
     string argList = s.argList;
     if (argList.StartsWith("("))
         argList = argList.Substring(1);
     if (argList.EndsWith(")"))
         argList = argList.Substring(0, argList.Length - 1);
     if (argList.EndsWith(")=0"))
         argList = argList.Substring(0, argList.Length - 3);
     argList = argList.Trim();
     if (argList.Length == 0)
         return;
     string[] args = argList.Split(',');
     foreach (string arg in args)
     {
         string a = arg.Trim();
     //                int lastSpace = a.LastIndexOf(' ');
         Parameter p = new Parameter();
         p.type = a.StripHtmlCharacters().StripHtmlLinks();// a.Substring(0, lastSpace).Trim();
     //                p.name = a.Substring(lastSpace + 1, a.Length - (lastSpace + 1)).Trim();
         s.parameters.Add(p);
     }
 }