diff --git a/Source/DoxygenTranslator/src/JavaDocConverter.cpp b/Source/DoxygenTranslator/src/JavaDocConverter.cpp index 5081156bd..0ba97fc60 100644 --- a/Source/DoxygenTranslator/src/JavaDocConverter.cpp +++ b/Source/DoxygenTranslator/src/JavaDocConverter.cpp @@ -128,8 +128,6 @@ bool JavaDocConverter::getDocumentation(Node *n, String *&documentation){ return false; std::list entityList = DoxygenParser().createTree(Char(documentation)); - Delete(documentation); - entityList.sort(CompareDoxygenEntities()); if(debug){ diff --git a/Source/DoxygenTranslator/src/PyDocConverter.cpp b/Source/DoxygenTranslator/src/PyDocConverter.cpp index 2065b090e..dbee97233 100644 --- a/Source/DoxygenTranslator/src/PyDocConverter.cpp +++ b/Source/DoxygenTranslator/src/PyDocConverter.cpp @@ -9,8 +9,9 @@ #include "PyDocConverter.h" #include "DoxygenParser.h" -#include #include +#include +#include //TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a pydoc tag PyDocConverter::PyDocConverter() @@ -121,39 +122,91 @@ std::string PyDocConverter::translateEntity(Node *n, DoxygenEntity &doxyEntity){ return justifyString(doxyEntity.data); } -bool PyDocConverter::getDocumentation(Node *n, String *&documentation){ - documentation = Getattr(n,"DoxygenComment"); - if(documentation == NULL) - return false; - - std::list entityList = DoxygenParser().createTree(Char(documentation)); - Delete(documentation); - - std::string pyDocString = "\"\"\"\n"; - +std::string PyDocConverter::processEntityList(Node *n, std::list& entityList){ + std::string result; bool inParamsSection = false; for(std::list::iterator entityIterator = entityList.begin(); entityIterator != entityList.end();){ - if(entityIterator->typeOfEntity.compare("param") == 0 && !inParamsSection) - { + if(entityIterator->typeOfEntity.compare("param") == 0 && !inParamsSection){ inParamsSection = true; - pyDocString += "\nArguments:\n"; + result += "\nArguments:\n"; } else if(entityIterator->typeOfEntity.compare("param") != 0 && inParamsSection) inParamsSection = false; - pyDocString += translateEntity(n, *entityIterator); + result += translateEntity(n, *entityIterator); entityIterator++; - } + } + + return result; +} - pyDocString += "\n\"\"\"\n"; +bool PyDocConverter::getDocumentation(Node *n, String *&documentation){ + std::string pyDocString, result; - if(debug){ - std::cout << "\n---RESULT IN PYDOC---" << std::endl; - std::cout << pyDocString; - std::cout << std::endl; + // for overloaded functions we must concat documentation for underlying overloads + if(Checkattr(n, "kind", "function") && Getattr(n, "sym:overloaded")){ + // rewind to the first overload + while (Getattr(n, "sym:previousSibling")) + n = Getattr(n, "sym:previousSibling"); + + std::vector allDocumentation; + + // for each real method (not a generated overload) append the documentation + while(n){ + documentation = Getattr(n,"DoxygenComment"); + if(!Swig_is_generated_overload(n) && documentation){ + std::list entityList = DoxygenParser().createTree(Char(documentation)); + allDocumentation.push_back(processEntityList(n, entityList)); + } + n = Getattr(n, "sym:nextSibling"); + } + + // construct final documentation string + if(allDocumentation.size() > 1){ + std::ostringstream concatDocString; + for(int realOverloadCount = 0; realOverloadCount < (int)allDocumentation.size(); realOverloadCount++){ + concatDocString << generateDivider(); + concatDocString << "Overload " << (realOverloadCount + 1) << ":" << std::endl; + concatDocString << generateDivider(); + concatDocString << allDocumentation[realOverloadCount] << std::endl; + } + pyDocString = concatDocString.str(); + } + else if (allDocumentation.size() == 1) { + pyDocString = *(allDocumentation.begin()); + } + } + // for other nodes just process as normal + else { + documentation = Getattr(n,"DoxygenComment"); + if(documentation != NULL){ + std::list entityList = DoxygenParser().createTree(Char(documentation)); + pyDocString = processEntityList(n, entityList); + } } - documentation = NewString(pyDocString.c_str()); - return true; -} \ No newline at end of file + // if we got something log the result and construct DOH string to return + if(pyDocString.length()) { + result = "\"\"\"\n" + pyDocString + "\"\"\"\n"; + + if(debug){ + std::cout << "\n---RESULT IN PYDOC---" << std::endl; + std::cout << result; + std::cout << std::endl; + } + + documentation = NewString(result.c_str()); + return true; + } + + return false; +} + +std::string PyDocConverter::generateDivider(){ + std::ostringstream dividerString; + for(int i = 0; i < DOC_STRING_LENGTH; i++) + dividerString << '-'; + dividerString << std::endl; + return dividerString.str(); +} diff --git a/Source/DoxygenTranslator/src/PyDocConverter.h b/Source/DoxygenTranslator/src/PyDocConverter.h index 5da58e4ec..500e39fe8 100644 --- a/Source/DoxygenTranslator/src/PyDocConverter.h +++ b/Source/DoxygenTranslator/src/PyDocConverter.h @@ -26,6 +26,14 @@ public: bool getDocumentation(Node *node, String *&documentation); protected: + + /* + * Process the contents of the entity list producing a documentation string. + * @param node The parse tree node that the entity list relates to. + * @param entityList The entity list to process + */ + std::string processEntityList(Node *node, std::list& entityList); + /* * Format the doxygen comment relating to a function or method parameter * @param node The parse tree node that the parameter relates to. @@ -51,6 +59,11 @@ protected: std::string translateSubtree( DoxygenEntity &doxygenEntity); std::string translateEntity(Node *n, DoxygenEntity &doxyEntity); + + /* + * Utility method to generate a diving line for a documentation string. + */ + std::string generateDivider(); private: bool debug; diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 94b3c1377..8a3160ef3 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -3129,30 +3129,11 @@ public: Printv(f_shadow, tab4, "def ", symname, "(",parms , ")", returnTypeAnnotation(n), ":", NIL); Printv(f_shadow, "\n", NIL); if (doxygen) { - /*Node *documented_node = n; - if(Getattr(n, "sym:overloaded")){ - // If the function is overloaded then this funciton is called - // for the last one. Rewind to the first so the docstrings are - // in order. - while (Getattr(documented_node, "sym:previousSibling")) - documented_node = Getattr(documented_node, "sym:previousSibling"); - - int real_overload_count = 0; - std::ostringstream all_documentation; - - // for each real method (not a generated overload) append the documentation - while(documented_node){ - if(!is_generated_overload(documented_node) && Getattr(documented_node,"DoxygenComment")){ - all_documentation << "Overload " << ++real_overload_count << ":" << std::endl; - all_documentation << Char(Getattr(documented_node,"DoxygenComment")) << std::endl; - } - documented_node = Getattr(documented_node, "sym:nextSibling"); - } - - char *convertedString = doxyTranslator.convert(n,const_cast< char *>(all_documentation.str().c_str()), "PYDOC"); - Printf(f_shadow, Char(pythoncode(convertedString, tab8))); - free(convertedString); - }*/ + String *doxygen_comments; + if(DoxygenTranslator::getDocumentation(n, PyDoc, doxygen_comments)){ + Printf(f_shadow, Char(pythoncode(doxygen_comments, tab8))); + Delete(doxygen_comments); + } } else if (have_docstring(n)) Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL);