Refactored comment translator class, implemented result caching

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2012-doxygen@13191 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dmitry Kabak 2012-06-25 15:47:36 +00:00
commit 4289b8e273
10 changed files with 159 additions and 112 deletions

View file

@ -13,18 +13,41 @@
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
#include "DoxygenTranslator.h" #include "DoxygenTranslator.h"
#include "JavaDocConverter.h"
#include "PyDocConverter.h"
bool DoxygenTranslator::getDocumentation(Node *node, DocumentationFormat format, String *&documentation) { DoxygenTranslator::DoxygenTranslator() {
switch (format) { // Init the cache
case JavaDoc: resultsCache = NewHash();
return JavaDocConverter().getDocumentation(node, documentation); }
case PyDoc: DoxygenTranslator::~DoxygenTranslator() {
return PyDocConverter().getDocumentation(node, documentation); // Clean up the cache
default: Delete(resultsCache);
return false; }
}
bool DoxygenTranslator::hasDocumentation(Node *node) {
return getDoxygenComment(node);
}
String *DoxygenTranslator::getDoxygenComment(Node *node) {
return Getattr(node, "DoxygenComment");
}
String *DoxygenTranslator::getDocumentation(Node *node) {
if (!hasDocumentation(node))
return 0;
// get from cache
String *resultedDocs = Getattr(resultsCache, getDoxygenComment(node));
if (resultedDocs)
return resultedDocs;
// not found in cache, produce it
resultedDocs = makeDocumentation(node);
Setattr(resultsCache, getDoxygenComment(node), resultedDocs);
return resultedDocs;
} }
void DoxygenTranslator::printTree(std::list < DoxygenEntity > &entityList) { void DoxygenTranslator::printTree(std::list < DoxygenEntity > &entityList) {

View file

@ -17,16 +17,9 @@
#include "swig.h" #include "swig.h"
#include "DoxygenEntity.h" #include "DoxygenEntity.h"
#include "DoxygenParser.h"
#include <list> #include <list>
/*
* Describes the availible documentation systems
* that can be translated to.
*/
enum DocumentationFormat {
JavaDoc = 1,
PyDoc = 2
};
/* /*
* A class to translate doxygen comments attacted to parser nodes * A class to translate doxygen comments attacted to parser nodes
@ -34,20 +27,31 @@ enum DocumentationFormat {
*/ */
class DoxygenTranslator { class DoxygenTranslator {
public: public:
/*
* Constructor
*/
DoxygenTranslator();
/* /*
* Virtual destructor. * Virtual destructor.
*/ */
virtual ~ DoxygenTranslator() { virtual ~ DoxygenTranslator();
}
/* /*
* Return the documentation for a given node formated for the correct * Return the documentation for a given node formated for the correct
* documentation system. * documentation system. The result is cached and translated only once.
* @param node The node to extract and translate documentation for. * @param node The node to extract and translate documentation for.
* @param format The documentation format to output. * @param format The documentation format to output.
* @param documentation The returned documentation string. * @param documentation The returned documentation string.
* @return A bool to indicate if there was documentation to return for the node. * @return A bool to indicate if there was documentation to return for the node.
*/ */
static bool getDocumentation(Node *node, DocumentationFormat format, String *&documentation); String *getDocumentation(Node *node);
/*
* Whether the specified node has comment or not
*/
bool hasDocumentation(Node *node);
/*
* Get original, Doxygen-format comment string
*/
String *getDoxygenComment(Node *node);
protected: protected:
/* /*
@ -57,12 +61,22 @@ protected:
* @param documentation The returned documentation string. * @param documentation The returned documentation string.
* @return A bool to indicate if there was documentation to return for the node. * @return A bool to indicate if there was documentation to return for the node.
*/ */
virtual bool getDocumentation(Node *node, String *&documentation) = 0; virtual String *makeDocumentation(Node *node) = 0;
/* /*
* Prints the details of a parsed entity list to stdout (for debugging). * Prints the details of a parsed entity list to stdout (for debugging).
*/ */
void printTree(std::list < DoxygenEntity > &entityList); void printTree(std::list < DoxygenEntity > &entityList);
/*
* Doxygen parser object
*/
DoxygenParser parser;
/*
* Cache of translated comments
*/
Hash *resultsCache;
}; };
#endif #endif

View file

@ -150,12 +150,12 @@ std::string JavaDocConverter::translateEntity(DoxygenEntity & doxyEntity) {
} }
bool JavaDocConverter::getDocumentation(Node *node, String *&documentation) { String *JavaDocConverter::makeDocumentation(Node *node) {
documentation = Getattr(node, "DoxygenComment"); String *documentation = getDoxygenComment(node);
if (documentation == NULL) { if (documentation == NULL) {
return false; return NULL;
} }
std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation)); std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation));
@ -181,7 +181,6 @@ bool JavaDocConverter::getDocumentation(Node *node, String *&documentation) {
std::cout << "\n---RESULT IN JAVADOC---" << std::endl; std::cout << "\n---RESULT IN JAVADOC---" << std::endl;
std::cout << javaDocString; std::cout << javaDocString;
} }
documentation = NewString(javaDocString.c_str()); return NewString(javaDocString.c_str());
return true;
} }

View file

@ -23,7 +23,7 @@ class JavaDocConverter : public DoxygenTranslator {
public: public:
JavaDocConverter() : debug(false) { JavaDocConverter() : debug(false) {
} }
virtual bool getDocumentation(Node *node, String *&documentation); String *makeDocumentation(Node *node);
protected: protected:
std::string formatCommand(std::string unformattedLine, int indent); std::string formatCommand(std::string unformattedLine, int indent);

View file

@ -19,7 +19,7 @@
//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a pydoc tag //TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a pydoc tag
PyDocConverter::PyDocConverter() { PyDocConverter::PyDocConverter() {
debug = 1; debug = 0;
} }
std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity) { std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity) {
@ -40,6 +40,8 @@ std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity)
std::string paramDescription = justifyString(paramDescriptionEntity.data, DOC_PARAM_STRING_LENGTH); std::string paramDescription = justifyString(paramDescriptionEntity.data, DOC_PARAM_STRING_LENGTH);
for (p = plist; p;) { for (p = plist; p;) {
//Swig_print(p, 1);
if (Char(Getattr(p, "name")) == paramNameEntity.data) { if (Char(Getattr(p, "name")) == paramNameEntity.data) {
std::string name = Char(Swig_name_make(n, 0, Getattr(p, "name"), 0, 0)); std::string name = Char(Swig_name_make(n, 0, Getattr(p, "name"), 0, 0));
std::string type = Char(Swig_name_make(n, 0, Getattr(p, "type"), 0, 0)); std::string type = Char(Swig_name_make(n, 0, Getattr(p, "type"), 0, 0));
@ -52,7 +54,12 @@ std::string PyDocConverter::formatParam(Node *n, DoxygenEntity & doxygenEntity)
result += "-- " + paramDescription.substr(DOC_PARAM_STRING_LENGTH); result += "-- " + paramDescription.substr(DOC_PARAM_STRING_LENGTH);
break; break;
} }
p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p); /*
* doesn't seem to work always: in some cases (especially for 'self' parameters)
* tmap:in is present, but tmap:in:next is not and so this code skips all the parameters
*/
//p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p);
p = nextSibling(p);
} }
Delete(plist); Delete(plist);
@ -147,7 +154,8 @@ std::string PyDocConverter::processEntityList(Node *n, std::list < DoxygenEntity
return result; return result;
} }
bool PyDocConverter::getDocumentation(Node *n, String *&documentation) { String *PyDocConverter::makeDocumentation(Node *n) {
String *documentation;
std::string pyDocString, result; std::string pyDocString, result;
// for overloaded functions we must concat documentation for underlying overloads // for overloaded functions we must concat documentation for underlying overloads
@ -160,7 +168,7 @@ bool PyDocConverter::getDocumentation(Node *n, String *&documentation) {
// for each real method (not a generated overload) append the documentation // for each real method (not a generated overload) append the documentation
while (n) { while (n) {
documentation = Getattr(n, "DoxygenComment"); documentation = getDoxygenComment(n);
if (!Swig_is_generated_overload(n) && documentation) { if (!Swig_is_generated_overload(n) && documentation) {
std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation)); std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation));
allDocumentation.push_back(processEntityList(n, entityList)); allDocumentation.push_back(processEntityList(n, entityList));
@ -184,7 +192,7 @@ bool PyDocConverter::getDocumentation(Node *n, String *&documentation) {
} }
// for other nodes just process as normal // for other nodes just process as normal
else { else {
documentation = Getattr(n, "DoxygenComment"); documentation = getDoxygenComment(n);
if (documentation != NULL) { if (documentation != NULL) {
std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation)); std::list < DoxygenEntity > entityList = DoxygenParser().createTree(Char(documentation));
pyDocString = processEntityList(n, entityList); pyDocString = processEntityList(n, entityList);
@ -201,11 +209,10 @@ bool PyDocConverter::getDocumentation(Node *n, String *&documentation) {
std::cout << std::endl; std::cout << std::endl;
} }
documentation = NewString(result.c_str()); return NewString(result.c_str());
return true;
} }
return false; return 0;
} }
std::string PyDocConverter::generateDivider() { std::string PyDocConverter::generateDivider() {

View file

@ -26,7 +26,7 @@
class PyDocConverter : public DoxygenTranslator { class PyDocConverter : public DoxygenTranslator {
public: public:
PyDocConverter(); PyDocConverter();
bool getDocumentation(Node *node, String *&documentation); String *makeDocumentation(Node *node);
protected: protected:

View file

@ -17,7 +17,7 @@ char cvsroot_java_cxx[] = "$Id$";
#include <limits.h> // for INT_MAX #include <limits.h> // for INT_MAX
#include "cparse.h" #include "cparse.h"
#include <ctype.h> #include <ctype.h>
#include "../DoxygenTranslator/src/DoxygenTranslator.h" #include "../DoxygenTranslator/src/JavaDocConverter.h"
/* Hash type used for upcalls from C/C++ */ /* Hash type used for upcalls from C/C++ */
typedef DOH UpcallData; typedef DOH UpcallData;
@ -158,11 +158,19 @@ public:
dmethods_seq(NULL), dmethods_seq(NULL),
dmethods_table(NULL), dmethods_table(NULL),
n_dmethods(0), n_dmethods(0),
n_directors(0) { n_directors(0){
/* for now, multiple inheritance in directors is disabled, this /* for now, multiple inheritance in directors is disabled, this
should be easy to implement though */ should be easy to implement though */
director_multiple_inheritance = 0; director_multiple_inheritance = 0;
director_language = 1; director_language = 1;
if (doxygen)
doxygenTranslator = new JavaDocConverter();
}
~JAVA() {
if (doxygen)
delete doxygenTranslator;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -286,6 +294,9 @@ public:
} }
} }
} }
if (doxygen)
doxygenTranslator = new JavaDocConverter();
// Add a symbol to the parser for conditional compilation // Add a symbol to the parser for conditional compilation
Preprocessor_define("SWIGJAVA 1", 0); Preprocessor_define("SWIGJAVA 1", 0);
@ -545,14 +556,12 @@ public:
if (module_imports) if (module_imports)
Printf(f_module, "%s\n", module_imports); Printf(f_module, "%s\n", module_imports);
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc,doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(f_module, "/* This was generated from top() */");
Printf(f_module, "/* This was generated from top() */"); Printf(f_module, Char(doxygen_comments));
Printf(f_module, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
if (Len(module_class_modifiers) > 0) if (Len(module_class_modifiers) > 0)
Printf(f_module, "%s ", module_class_modifiers); Printf(f_module, "%s ", module_class_modifiers);
@ -1417,14 +1426,12 @@ public:
return SWIG_ERROR; return SWIG_ERROR;
//translate and write javadoc comment if flagged //translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(enum_code, "/* This was generated from enumvalueDeclaration() */");
Printf(enum_code, "/* This was generated from enumvalueDeclaration() */"); Printf(enum_code, Char(doxygen_comments));
Printf(enum_code, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) {
@ -1489,14 +1496,12 @@ public:
* file * file
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
virtual int doxygenComment(Node *n){ virtual int doxygenComment(Node *n){
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(structuralComments, "/* This was generated from doxygenComment() */");
Printf(structuralComments, "/* This was generated from doxygenComment() */"); Printf(structuralComments, Char(doxygen_comments));
Printf(structuralComments, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
return SWIG_OK; return SWIG_OK;
} }
@ -1523,14 +1528,12 @@ public:
Swig_save("constantWrapper", n, "value", NIL); Swig_save("constantWrapper", n, "value", NIL);
//translate and write javadoc comment if flagged //translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(constants_code, "/* This was generated from constantWrapper() */");
Printf(constants_code, "/* This was generated from constantWrapper() */"); Printf(constants_code, Char(doxygen_comments));
Printf(constants_code, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
@ -1821,14 +1824,12 @@ public:
const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE); const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE);
//translate and write javadoc comment if flagged //translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */");
Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */"); Printf(proxy_class_def, Char(doxygen_comments));
Printf(proxy_class_def, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
// Start writing the proxy class // Start writing the proxy class
@ -2227,14 +2228,12 @@ public:
} }
//translate and write javadoc comment if flagged //translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */");
Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */"); Printf(function_code, Char(doxygen_comments));
Printf(function_code, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
/* Start generating the proxy function */ /* Start generating the proxy function */
@ -2460,14 +2459,12 @@ public:
Printf(im_return_type, "%s", tm); Printf(im_return_type, "%s", tm);
//translate and write javadoc comment if flagged //translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)){ if(comment_creation_chatter)
if(comment_creation_chatter) Printf(function_code, "/* This was generated from constructionhandler() */");
Printf(function_code, "/* This was generated from constructionhandler() */"); Printf(function_code, Char(doxygen_comments));
Printf(function_code, Char(doxygen_comments)); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
Printf(function_code, " %s %s(", methodmods, proxy_class_name); Printf(function_code, " %s %s(", methodmods, proxy_class_name);
@ -2732,14 +2729,12 @@ public:
String *post_code = NewString(""); String *post_code = NewString("");
// translate and write javadoc comment if flagged // translate and write javadoc comment if flagged
if (doxygen){ if (doxygen && doxygenTranslator->hasDocumentation(n)){
String *doxygen_comments; String *doxygen_comments=doxygenTranslator->getDocumentation(n);
if(DoxygenTranslator::getDocumentation(n, JavaDoc, doxygen_comments)) { if(comment_creation_chatter)
if(comment_creation_chatter) Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */");
Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */"); Printv(function_code, doxygen_comments, NIL);
Printv(function_code, doxygen_comments, NIL); Delete(doxygen_comments);
Delete(doxygen_comments);
}
} }
if (l) { if (l) {
@ -4527,3 +4522,4 @@ Java Options (available with -java)\n\
-oldvarnames - Old intermediary method names for variable wrappers\n\ -oldvarnames - Old intermediary method names for variable wrappers\n\
-package <name> - Set name of the Java package to <name>\n\ -package <name> - Set name of the Java package to <name>\n\
\n"; \n";

View file

@ -2869,9 +2869,10 @@ int Language::usingDeclaration(Node *n) {
* ---------------------------------------------------------------------- */ * ---------------------------------------------------------------------- */
int Language::doxygenComment(Node *n){ int Language::doxygenComment(Node *n){
String *comment = Getattr(n, "comment"); String *comment = Getattr(n, "comment");
Printf(stdout, "doxygenComment : %s\n", comment);
return SWIG_OK; return SWIG_OK;
} }

View file

@ -20,7 +20,7 @@ static int treduce = SWIG_cparse_template_reduce(0);
#include <ctype.h> #include <ctype.h>
#include <sstream> #include <sstream>
#include "../DoxygenTranslator/src/DoxygenTranslator.h" #include "../DoxygenTranslator/src/PyDocConverter.h"
#include "../../../swig/bug.h" #include "../../../swig/bug.h"
#define PYSHADOW_MEMBER 0x2 #define PYSHADOW_MEMBER 0x2
@ -548,6 +548,9 @@ public:
if (cppcast) { if (cppcast) {
Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0); Preprocessor_define((DOH *) "SWIG_CPLUSPLUS_CAST", 0);
} }
if (doxygen)
doxygenTranslator = new PyDocConverter;
if (!global_name) if (!global_name)
global_name = NewString("cvar"); global_name = NewString("cvar");
@ -1203,7 +1206,7 @@ public:
String *str = Getattr(n, "feature:docstring"); String *str = Getattr(n, "feature:docstring");
return ((str && Len(str) > 0) return ((str && Len(str) > 0)
|| (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"))
|| (doxygen && Getattr(n, "DoxygenComment")) || (doxygen && doxygenTranslator->hasDocumentation(n))
); );
} }
@ -1219,7 +1222,7 @@ public:
String *doxygen_comment = 0; String *doxygen_comment = 0;
bool have_ds = (str && Len(str) > 0); bool have_ds = (str && Len(str) > 0);
bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc"));
bool have_doxygen = doxygen && DoxygenTranslator::getDocumentation(n, PyDoc, doxygen_comment); bool have_doxygen = doxygen && doxygenTranslator->hasDocumentation(n);
const char *triple_double = use_triple ? "\"\"\"" : ""; const char *triple_double = use_triple ? "\"\"\"" : "";
String *autodoc = NULL; String *autodoc = NULL;
String *doc = NULL; String *doc = NULL;
@ -1237,6 +1240,7 @@ public:
have_auto = (autodoc && Len(autodoc) > 0); have_auto = (autodoc && Len(autodoc) > 0);
} }
if (have_doxygen) { if (have_doxygen) {
doxygen_comment = doxygenTranslator->getDocumentation(n);
have_doxygen = (doxygen_comment && Len(doxygen_comment) > 0); have_doxygen = (doxygen_comment && Len(doxygen_comment) > 0);
} }
// If there is more than one line then make docstrings like this: // If there is more than one line then make docstrings like this:

View file

@ -17,6 +17,7 @@
#include "swig.h" #include "swig.h"
#include "preprocessor.h" #include "preprocessor.h"
#include "swigwarn.h" #include "swigwarn.h"
#include "../DoxygenTranslator/src/DoxygenTranslator.h"
#if !defined(HAVE_BOOL) #if !defined(HAVE_BOOL)
typedef int bool; typedef int bool;
@ -315,6 +316,8 @@ protected:
/* Director language module */ /* Director language module */
int director_language; int director_language;
// Class instance to translate comments
DoxygenTranslator *doxygenTranslator;
private: private:
Hash *symtabs; /* symbol tables */ Hash *symtabs; /* symbol tables */
Hash *classtypes; Hash *classtypes;