diff options
author | Marko Klopcic <marko.klopcic@isystem.si> | 2012-08-26 20:07:57 +0000 |
---|---|---|
committer | Marko Klopcic <marko.klopcic@isystem.si> | 2012-08-26 20:07:57 +0000 |
commit | 46f2a16608576a11a94f552ef80bf2a712e4d361 (patch) | |
tree | 974f71df3dad9e124c43ae8afae31982c22b64d8 | |
parent | c9eda79264ecb1b82c69ec7bf611918aa5feb9bf (diff) | |
download | swig-46f2a16608576a11a94f552ef80bf2a712e4d361.tar.gz |
more refactoring, typedefs were introduced, DoxyCommandEnum moved to DoxygenParser
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2012-doxygen@13725 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | Source/DoxygenTranslator/src/DoxygenEntity.h | 18 | ||||
-rw-r--r-- | Source/DoxygenTranslator/src/DoxygenParser.cpp | 89 | ||||
-rw-r--r-- | Source/DoxygenTranslator/src/DoxygenParser.h | 110 | ||||
-rw-r--r-- | Source/DoxygenTranslator/src/JavaDocConverter.cpp | 146 | ||||
-rw-r--r-- | Source/DoxygenTranslator/src/JavaDocConverter.h | 2 |
5 files changed, 230 insertions, 135 deletions
diff --git a/Source/DoxygenTranslator/src/DoxygenEntity.h b/Source/DoxygenTranslator/src/DoxygenEntity.h index cf03240d2..d7df95e91 100644 --- a/Source/DoxygenTranslator/src/DoxygenEntity.h +++ b/Source/DoxygenTranslator/src/DoxygenEntity.h @@ -18,24 +18,6 @@ #include <list> -typedef enum { - SIMPLECOMMAND, - COMMANDWORD, - COMMANDLINE, - COMMANDPARAGRAPH, - COMMANDENDCOMMAND, - COMMANDWORDPARAGRAPH, - COMMANDWORDLINE, - COMMANDWORDOWORDWORD, - COMMANDOWORD, - COMMANDERRORTHROW, - COMMANDUNIQUE, - END_LINE, - PARAGRAPH_END, - PLAINSTRING, - COMMAND -} DoxyCommandEnum; - class DoxygenEntity; typedef std::list <DoxygenEntity> DoxygenEntityList; diff --git a/Source/DoxygenTranslator/src/DoxygenParser.cpp b/Source/DoxygenTranslator/src/DoxygenParser.cpp index a66d66c28..fd1acdc78 100644 --- a/Source/DoxygenTranslator/src/DoxygenParser.cpp +++ b/Source/DoxygenTranslator/src/DoxygenParser.cpp @@ -22,7 +22,7 @@ using std::cout; using std::endl; // Define static class members -std::map<std::string, DoxyCommandEnum> DoxygenParser::doxygenCommands; +DoxygenParser::DoxyCommandsMap DoxygenParser::doxygenCommands; std::set<std::string> DoxygenParser::doxygenSectionIndicators; const int TOKENSPERLINE = 8; //change this to change the printing behaviour of the token list @@ -110,16 +110,19 @@ void DoxygenParser::printTree(const DoxygenEntityList &rootList) { } } + int DoxygenParser::commandBelongs(const std::string &theCommand) { std::string smallString = stringToLower(theCommand); //cout << " Looking for command " << theCommand << endl; - std::map<std::string, DoxyCommandEnum>::iterator it; - it = doxygenCommands.find(smallString); - if (it!=doxygenCommands.end()) + std::map<std::string, DoxyCommandEnum>::iterator it = + doxygenCommands.find(smallString); + if (it != doxygenCommands.end()) { return it->second; + } return 0; } + std::string DoxygenParser::getNextWord(const TokenList &tokList) { // MK Token nextToken = tokList.peek(); if (m_tokenListIt == m_tokenList.end()) { @@ -703,7 +706,7 @@ int DoxygenParser::addCommandUnique(const std::string &theCommand, TokenListCIt endCommand = tokList.end(); // go through the commands and find closing endif or else or elseif - for (TokenListCIt it = m_tokenListIt; it!=tokList.end(); it++) { + for (TokenListCIt it = m_tokenListIt; it != tokList.end(); it++) { if (it->m_tokenType == COMMAND) { if (it->m_tokenString == "if" || it->m_tokenString == "ifnot") nestedCounter++; @@ -742,9 +745,10 @@ int DoxygenParser::addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList) { - std::string theCommand = stringToLower(commandString); + string theCommand = stringToLower(commandString); + if (theCommand == "plainstd::string") { - std::string nextPhrase = getStringTilCommand(tokList); + string nextPhrase = getStringTilCommand(tokList); if (noisy) cout << "Parsing plain std::string :" << nextPhrase << endl; doxyList.push_back(DoxygenEntity("plainstd::string", nextPhrase)); @@ -778,9 +782,12 @@ int DoxygenParser::addCommand(const std::string &commandString, } +/** + * This method converts TokenList to DoxygenEntryList. + */ DoxygenEntityList DoxygenParser::parse(TokenListCIt endParsingIndex, - const TokenList &tokList, - bool root) { + const TokenList &tokList, + bool root) { // if we are root, than any strings should be added as 'partofdescription', else as 'plainstd::string' std::string currPlainstringCommandType = root ? "partofdescription" : "plainstd::string"; DoxygenEntityList aNewList; @@ -812,22 +819,30 @@ DoxygenEntityList DoxygenParser::parse(TokenListCIt endParsingIndex, } -DoxygenEntityList DoxygenParser::createTree(const std::string &doxygenBlob, const std::string &fileName, int lineNumber) { - TokenList tokList = tokenizeDoxygenComment(doxygenBlob, fileName, lineNumber); - if (noisy) { - cout << "---TOKEN LIST---" << endl; - printList(); - } - DoxygenEntityList rootList; - rootList = parse(tokList.end(), tokList, true); - if (noisy) { - cout << "PARSED LIST" << endl; - printTree(rootList); - } - return rootList; +DoxygenEntityList DoxygenParser::createTree(const std::string &doxygenBlob, + const std::string &fileName, + int lineNumber) { + + TokenList tokList = tokenizeDoxygenComment(doxygenBlob, fileName, lineNumber); + if (noisy) { + cout << "---TOKEN LIST---" << endl; + printList(); + } + + DoxygenEntityList rootList = parse(tokList.end(), tokList, true); + + if (noisy) { + cout << "PARSED LIST" << endl; + printTree(rootList); + } + return rootList; } +/** + * This is one of the most important methods - it breaks the original + * doxygen comment into tokens. + */ DoxygenParser::TokenList DoxygenParser::tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine) { @@ -842,13 +857,17 @@ DoxygenParser::TokenList DoxygenParser::tokenizeDoxygenComment(const std::string while (true) { isPlainString = false; pos = doxygenComment.find_first_of("\\@\t\n ", lastPos); - if (pos == string::npos) + if (pos == string::npos) { pos = doxygenComment.size(); + } currentWord = doxygenComment.substr(lastPos, pos-lastPos); - if (prevChar == '\n') + + if (prevChar == '\n') { + tokList.push_back(Token(END_LINE, "\n")); - else if (prevChar == '\\' || prevChar == '@') { + + } else if (prevChar == '\\' || prevChar == '@') { // it's a doxygen command // hack to get commands like \\ or \@ or @\ or @@ if (doxygenComment[pos] == '@' || doxygenComment[pos] == '\\') { @@ -871,22 +890,24 @@ DoxygenParser::TokenList DoxygenParser::tokenizeDoxygenComment(const std::string // unknown commands are not translated - treated as literal string tokList.push_back(Token(PLAINSTRING, currentWord)); } - } - else if (currentWord.size() && (currentWord[0] == '!' || currentWord[0] == '*' || currentWord[0] == '/')) { + + } else if (currentWord.size() && (currentWord[0] == '!' || currentWord[0] == '*' || currentWord[0] == '/')) { + // check if it's one of the '!!!', '***', '///' of any length char c = currentWord[0]; isPlainString = false; - for (size_t i=0; i<currentWord.size(); i++) + for (size_t i = 0; i < currentWord.size(); i++) if (currentWord[i] != c) { isPlainString = true; break; } - } - else + } else { isPlainString = true; + } - if (isPlainString && currentWord.size()) + if (isPlainString && currentWord.size()) { tokList.push_back(Token(PLAINSTRING, currentWord)); + } prevChar = doxygenComment[pos]; lastPos = pos + 1; @@ -934,8 +955,6 @@ void DoxygenParser::printListError(int warningType, } } - Swig_warning(warningType, m_fileName.c_str(), - curLine, - "Doxygen parser warning: %s. \n", - message.c_str()); + Swig_warning(warningType, m_fileName.c_str(), curLine, + "Doxygen parser warning: %s. \n", message.c_str()); } diff --git a/Source/DoxygenTranslator/src/DoxygenParser.h b/Source/DoxygenTranslator/src/DoxygenParser.h index d015c1896..e5fc5c06d 100644 --- a/Source/DoxygenTranslator/src/DoxygenParser.h +++ b/Source/DoxygenTranslator/src/DoxygenParser.h @@ -20,55 +20,79 @@ class DoxygenParser { private: - /** This class contains parts of Doxygen comment as a token. */ - class Token { - public: - DoxyCommandEnum m_tokenType; - std::string m_tokenString; /* the data , such as param for @param */ - - Token(DoxyCommandEnum tType, std::string tString) : - m_tokenType(tType), - m_tokenString(tString) {} - - std::string toString() const { - - switch (m_tokenType) { - case END_LINE: - return "{END OF LINE}"; - case PARAGRAPH_END: - return "{END OF PARAGRAPH}"; - case PLAINSTRING: - return "{PLAINSTRING :" + m_tokenString + "}"; - case COMMAND: - return "{COMMAND : " + m_tokenString + "}"; - default: - return ""; - } - } - }; - - - typedef std::list<Token> TokenList; - typedef TokenList::const_iterator TokenListCIt; - typedef TokenList::iterator TokenListIt; - - TokenList m_tokenList; - TokenListCIt m_tokenListIt; - std::string m_fileName; - int m_fileLineNo; + typedef enum { + SIMPLECOMMAND, + COMMANDWORD, + COMMANDLINE, + COMMANDPARAGRAPH, + COMMANDENDCOMMAND, + COMMANDWORDPARAGRAPH, + COMMANDWORDLINE, + COMMANDWORDOWORDWORD, + COMMANDOWORD, + COMMANDERRORTHROW, + COMMANDUNIQUE, + END_LINE, + PARAGRAPH_END, + PLAINSTRING, + COMMAND + } DoxyCommandEnum; + + + + /** This class contains parts of Doxygen comment as a token. */ + class Token { + public: + DoxyCommandEnum m_tokenType; + std::string m_tokenString; /* the data , such as param for @param */ + + Token(DoxyCommandEnum tType, std::string tString) : + m_tokenType(tType), + m_tokenString(tString) {} + + std::string toString() const { + + switch (m_tokenType) { + case END_LINE: + return "{END OF LINE}"; + case PARAGRAPH_END: + return "{END OF PARAGRAPH}"; + case PLAINSTRING: + return "{PLAINSTRING :" + m_tokenString + "}"; + case COMMAND: + return "{COMMAND : " + m_tokenString + "}"; + default: + return ""; + } + } + }; + + + typedef std::list<Token> TokenList; + typedef TokenList::const_iterator TokenListCIt; + typedef TokenList::iterator TokenListIt; + + TokenList m_tokenList; + TokenListCIt m_tokenListIt; + + typedef std::map<std::string, DoxyCommandEnum> DoxyCommandsMap; + typedef DoxyCommandsMap::iterator DoxyCommandsMapIt; + + /* + * Map of Doxygen commands to determine if a string is a + * command and how it needs to be parsed + */ + static DoxyCommandsMap doxygenCommands; + static std::set<std::string> doxygenSectionIndicators; + + std::string m_fileName; + int m_fileLineNo; /* * Whether to print lots of debug info during parsing */ bool noisy; - /* - * Map of Doxygen commands to determine if a string is a - * command and how it needs to be parsed - */ - static std::map<std::string, DoxyCommandEnum> doxygenCommands; - static std::set<std::string> doxygenSectionIndicators; - /* *Changes a std::string to all lower case */ diff --git a/Source/DoxygenTranslator/src/JavaDocConverter.cpp b/Source/DoxygenTranslator/src/JavaDocConverter.cpp index 171ef4dc7..2c2aa8aa0 100644 --- a/Source/DoxygenTranslator/src/JavaDocConverter.cpp +++ b/Source/DoxygenTranslator/src/JavaDocConverter.cpp @@ -120,9 +120,19 @@ JavaDocConverter::JavaDocConverter(bool debugTranslator, bool debugParser) fillStaticTables(); } -std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) { + +/** + * Formats comment lines by inserting '\n *' at to long lines and tabs for + * indent. Currently it is disabled, which means original comment format is + * preserved. Experience shows, that this is usually better than breaking + * lines automatically, especially because original line endings are not removed, + * which results in short lines. To be useful, this function should have much + * better algorithm. + */ +std::string JavaDocConverter::formatCommand(std::string unformattedLine, + int indent) { std::string formattedLines; - return unformattedLine; + return unformattedLine; // currently disabled int lastPosition = 0; int i = 0; int isFirstLine = 1; @@ -160,49 +170,70 @@ std::string JavaDocConverter::formatCommand(std::string unformattedLine, int ind return formattedLines; } + +/** + * Returns true, if the given parameter exists in the current node. If feature + * 'doxygen:nostripparams' is set, then this method always returns true. + */ bool JavaDocConverter::paramExists(std::string param) { - if (GetFlag(currentNode, "feature:doxygen:nostripparams")) + + if (GetFlag(currentNode, "feature:doxygen:nostripparams")) { return true; + } + ParmList *plist = CopyParmList(Getattr(currentNode, "parms")); - Parm *p = NULL; - for (p = plist; p;) { - if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) + + for (Parm *p = plist; p;) { + + if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) { return true; - /* - * doesn't seem to work always: in some cases (especially for 'self' parameters) + } + /* 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); + return false; } -std::string JavaDocConverter::translateSubtree(DoxygenEntity & doxygenEntity) { + +std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) { std::string translatedComment; - if (doxygenEntity.isLeaf) + if (doxygenEntity.isLeaf) { return translatedComment; + } - std::list < DoxygenEntity >::iterator p = doxygenEntity.entityList.begin(); - while (p != doxygenEntity.entityList.end()) { + for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); + p != doxygenEntity.entityList.end(); p++) { + translateEntity(*p, translatedComment); translateSubtree(*p); - p++; } return translatedComment; } -void JavaDocConverter::translateEntity(DoxygenEntity& tag, std::string& translatedComment) { - // check if we have needed handler and call it + +/** + * Checks if a handler for the given tag exists, and calls it. + */ +void JavaDocConverter::translateEntity(DoxygenEntity &tag, + std::string &translatedComment) { + std::map<std::string, std::pair<tagHandler, std::string > >::iterator it; it = tagHandlers.find(tag.typeOfEntity); - if (it!=tagHandlers.end()) + + if (it != tagHandlers.end()) { (this->*(it->second.first))(tag, translatedComment, it->second.second); + } } + void JavaDocConverter::handleTagHtml(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { if (tag.entityList.size()) { // do not include empty tags std::string tagData = translateSubtree(tag); @@ -214,9 +245,13 @@ void JavaDocConverter::handleTagHtml(DoxygenEntity& tag, std::string& translated translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> "; } } + + void JavaDocConverter::handleNewLine(DoxygenEntity&, std::string& translatedComment, std::string&) { translatedComment += "\n * "; } + + void JavaDocConverter::handleTagChar(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { // escape it if we need to, else just print if (arg.size()) @@ -225,26 +260,35 @@ void JavaDocConverter::handleTagChar(DoxygenEntity& tag, std::string& translated translatedComment += tag.typeOfEntity; translatedComment += " "; } + +// handles tags which are the same in Doxygen and Javadoc. void JavaDocConverter::handleTagSame(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { if (arg.size()) tag.typeOfEntity = arg; translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2); } + + void JavaDocConverter::handleParagraph(DoxygenEntity& tag, std::string& translatedComment, std::string&) { translatedComment += formatCommand(translateSubtree(tag), 0); } + + void JavaDocConverter::handlePlainString(DoxygenEntity& tag, std::string& translatedComment, std::string&) { translatedComment += tag.data; if (tag.data.size() && tag.data[tag.data.size()-1] != ' ') translatedComment += " "; } + void JavaDocConverter::handleTagExtended(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { std::string dummy; translatedComment += "{@" + arg + " "; handleParagraph(tag, translatedComment, dummy); translatedComment += "}"; } + + void JavaDocConverter::handleTagIf(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { std::string dummy; translatedComment += arg; @@ -254,11 +298,15 @@ void JavaDocConverter::handleTagIf(DoxygenEntity& tag, std::string& translatedCo translatedComment += " {" + translateSubtree(tag) + "}"; } } + + void JavaDocConverter::handleTagMessage(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { std::string dummy; translatedComment += formatCommand(arg, 0); handleParagraph(tag, translatedComment, dummy); } + + void JavaDocConverter::handleTagImage(DoxygenEntity& tag, std::string& translatedComment, std::string&) { if (tag.entityList.size() < 2) return; @@ -282,6 +330,8 @@ void JavaDocConverter::handleTagImage(DoxygenEntity& tag, std::string& translate translatedComment += " alt=\"" + title +"\""; translatedComment += " />"; } + + void JavaDocConverter::handleTagPar(DoxygenEntity& tag, std::string& translatedComment, std::string&) { std::string dummy; translatedComment += "<p"; @@ -294,6 +344,7 @@ void JavaDocConverter::handleTagPar(DoxygenEntity& tag, std::string& translatedC translatedComment += "</p>"; } + void JavaDocConverter::handleTagParam(DoxygenEntity& tag, std::string& translatedComment, std::string&) { std::string dummy; if (!tag.entityList.size()) @@ -307,6 +358,7 @@ void JavaDocConverter::handleTagParam(DoxygenEntity& tag, std::string& translate handleParagraph(tag, translatedComment, dummy); } + string JavaDocConverter::convertLink(string linkObject) { if (GetFlag(currentNode, "feature:doxygen:nolinktranslate")) return linkObject; @@ -394,6 +446,7 @@ string JavaDocConverter::convertLink(string linkObject) { return linkObject; } + void JavaDocConverter::handleTagLink(DoxygenEntity& tag, std::string& translatedComment, std::string&) { std::string dummy; if (!tag.entityList.size()) @@ -410,6 +463,7 @@ void JavaDocConverter::handleTagLink(DoxygenEntity& tag, std::string& translated translatedComment += "}"; } + void JavaDocConverter::handleTagSee(DoxygenEntity& tag, std::string& translatedComment, std::string&) { std::string dummy; if (!tag.entityList.size()) @@ -429,33 +483,41 @@ void JavaDocConverter::handleTagSee(DoxygenEntity& tag, std::string& translatedC } } -int JavaDocConverter::cleanUpTree(DoxygenEntity &root, int level) + +/* This function moves all endlines at the end of child entities + * out of the child entities to the parent. + * For example, entity tree: + + -root + |-param + |-paramText + |-endline + + should be turned to + + -root + |-param + |-paramText + |-endline + * + */ +int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) { - // this function should move all endlines out of the child entities - // for example: - // root - // -param - // --paramText - // --endline - // should be turned to - // root - // -param - // --paramText - // -endline - - std::list < DoxygenEntity >::iterator it = root.entityList.begin(); + DoxygenEntityListIt it = root.entityList.begin(); while (it != root.entityList.end()) { // remove endlines - int ret = cleanUpTree(*it, level + 1); + int ret = shiftEndlinesUpTree(*it, level + 1); // insert them after this element it++; - for (int i=0; i<ret; i++) + for (int i = 0; i < ret; i++) { root.entityList.insert(it, DoxygenEntity("plainstd::endl")); + } } // continue only if we are not root - if (!level) + if (!level) { return 0; + } int removedCount = 0; while (!root.entityList.empty() && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") { @@ -465,6 +527,7 @@ int JavaDocConverter::cleanUpTree(DoxygenEntity &root, int level) return removedCount; } + String *JavaDocConverter::makeDocumentation(Node *node) { String *documentation = getDoxygenComment(node); @@ -483,10 +546,11 @@ String *JavaDocConverter::makeDocumentation(Node *node) { return comment; } - std::list < DoxygenEntity > entityList = parser.createTree(Char(documentation), Char(Getfile(documentation)), Getline(documentation)); + DoxygenEntityList entityList = parser.createTree(Char(documentation), + Char(Getfile(documentation)), + Getline(documentation)); // entityList.sort(CompareDoxygenEntities()); sorting currently not used, - // see CompareDoxygenEntities::operator() in DoxygenEntity.cpp if (debug) { std::cout << "---RESORTED LIST---" << std::endl; @@ -501,13 +565,19 @@ String *JavaDocConverter::makeDocumentation(Node *node) { DoxygenEntity root("root", entityList); - cleanUpTree(root); + shiftEndlinesUpTree(root); + // strip endlines at the beginning - while (root.entityList.begin()->typeOfEntity == "plainstd::endl") + while (!root.entityList.empty() && + root.entityList.begin()->typeOfEntity == "plainstd::endl") { root.entityList.pop_front(); + } + // and at the end - while (root.entityList.rbegin()->typeOfEntity == "plainstd::endl") + while (!root.entityList.empty() && + root.entityList.rbegin()->typeOfEntity == "plainstd::endl") { root.entityList.pop_back(); + } javaDocString += translateSubtree(root); diff --git a/Source/DoxygenTranslator/src/JavaDocConverter.h b/Source/DoxygenTranslator/src/JavaDocConverter.h index cad228038..1fab5e63b 100644 --- a/Source/DoxygenTranslator/src/JavaDocConverter.h +++ b/Source/DoxygenTranslator/src/JavaDocConverter.h @@ -42,7 +42,7 @@ protected: /* * Fix all endlines location, etc */ - int cleanUpTree(DoxygenEntity &root, int level = 0); + int shiftEndlinesUpTree(DoxygenEntity &root, int level = 0); /* * Convert params in link-objects and references |