Fixed lots of PyDoc converter problems, see doxygen_tricky_constructs test

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2012-doxygen@13633 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dmitry Kabak 2012-08-16 14:18:47 +00:00
commit 316be573f8
5 changed files with 169 additions and 154 deletions

View file

@ -0,0 +1,106 @@
# This file contains tests for situations, which do not normally
# appear in the code, but must neverthless be handled correctly.
%module doxygen_tricky_constructs
%inline %{
# Bug 1: Tag '@endink' is not recognized becuse it is not
# followed by whitespace.
/**
* Tag endlink must be recognized also when followed by nonspace charater.
*
* @link Connection::getId() @endlink<br>
*/
char g_counter;
/**
* Tag endlink must be recognized also when it is the last token
* in the commment.
*
* @link Connection::getId() @endlink<br>
* @link debugIdeTraceProfilerCoverageSample.py Python example. @endlink
*/
int g_zipCode;
# Bug 2: Paramter 'isReportSize' is missing in comment of the overload, which
# has it. This bug disappears if @endlink is follwed by a space.
#
# Bug 3: Empty line before the link is missing,
# making the link text part of parameter description. This bug appears also
# when there is ordinary text in place of the link in case of overload
# with only 2 parameters.
/**
* Returns address of file line.
*
* @param fileName name of the file, where the source line is located
* @param line line number
* @param isGetSize if set, for every object location both address and size are returned
*
* @link Connection::getId() @endlink <br>
*/
std::vector<DWORD> getAddress(const std::string &fileName,
int line,
bool isGetSize = false);
# Bug 4: The first comment is attached to the second in Python (wrong),
# but not in Java (correct).
/**
* \defgroup icFacade isystem.connect Facade
*
* This page shows the core classes, which can be used to control
* all aspects of winIDEA, for example: debugging, analyzers, IO module, ...
*/
/**
* This class contains information for connection to winIDEA. Its methods
* return reference to self, so we can use it like this:
* <pre>
* CConnectionConfig config = new CConnectionConfig();
* config.discoveryPort(5534).dllPath("C:\\myWinIDEA\\connect.dll").id("main");
* </pre>
*
* All parameters are optional. Set only what is required, default values are
* used for unspecified parameters.
* <p>
*
* @link advancedWinIDEALaunching.py Python example. @endlink <br>
*/
class CConnectionConfig
{
};
# Bug 5: Text after '\c' has no space following in Python.
# There are also to many empty lines in multiline comments in Python.
# Whitespaces are really a problem in Python (space and newlines),
# I like a parameter type added to each parameter description!
# """
# Determines how long the isystem.connectshould wait for running
#
# instances to respond. Only one of lfWaitXXXflags from IConnect::ELaunchFlags
#
# may be specified.
#
# """
/**
* Determines how long the \c isystem.connect should wait for running
* instances to respond. Only one of \c lfWaitXXX flags from IConnect::ELaunchFlags
* may be specified.
*/
int waitTime(long waitTime);
# Bug 6: Text after tag \ingroup appears in Python comment (empty line in
# Java, which is acceptable):
/** \ingroup icFacade
*
* This class manages connection.
*/
int getConnection();
%}

View file

@ -19,12 +19,6 @@ def check(got, expected):
check(doxygen_translate_all_tags.function.__doc__, '' check(doxygen_translate_all_tags.function.__doc__, ''
' _Hello_' ' _Hello_'
'' ''
' SomeLatexIndex '
''
' someGroup"Some title" '
''
' theAnchor'
''
' -some list item ' ' -some list item '
'' ''
' This is attention! ' ' This is attention! '
@ -44,60 +38,29 @@ check(doxygen_translate_all_tags.function.__doc__, ''
'' ''
' codeword' ' codeword'
'' ''
' someCategoryheaderFile.hheaderName'
''
' \'citationword\'' ' \'citationword\''
'' ''
' someClassheaderFile.hheaderName'
''
' some test code ' ' some test code '
'' ''
' Conditional comment: SOMECONDITION' ' Conditional comment: SOMECONDITION'
' Some conditional comment ' ' Some conditional comment '
' End of conditional comment.' ' End of conditional comment.'
'' ''
' someClass::someMethod'
''
' someClass::someMethod2'
''
' someClass::someMethod3'
''
' Copyright:' ' Copyright:'
' some copyright ' ' some copyright '
'' ''
' 1970 - 2012 ' ' 1970 - 2012 '
'' ''
' someDefine'
''
' someGroupSome titles '
''
' Deprecated:' ' Deprecated:'
' Now use another function ' ' Now use another function '
'' ''
' This is very large ' ' This is very large '
' and detailed description of some thing ' ' and detailed description of some thing '
'' ''
' /somePath/someFolder'
''
' someFile.h'
''
' digraph example { '
' node [shape=record, fontname=Helvetica, fontsize=10]; '
''
' b [ label="class B" URL=" B"]; '
' c [ label="class C" URL=" C"]; '
' b -> c [ arrowhead="open", style="dashed" ]; '
' } '
''
''
' dotFile.dotThe caption'
''
' _italicword_' ' _italicword_'
'' ''
' emphazedWord' ' emphazedWord'
'' ''
' someEnum'
''
' Example:' ' Example:'
' someFile.txt' ' someFile.txt'
' Some details on using the example ' ' Some details on using the example '
@ -105,16 +68,6 @@ check(doxygen_translate_all_tags.function.__doc__, ''
' Throws:' ' Throws:'
' SuperError' ' SuperError'
'' ''
' someOtherFunction'
''
' file.h'
''
' someFn '
''
' someHeader.hHeader name'
''
' htmlFile.htm'
''
' This will only appear in hmtl ' ' This will only appear in hmtl '
'' ''
' If: ANOTHERCONDITION {' ' If: ANOTHERCONDITION {'
@ -135,21 +88,11 @@ check(doxygen_translate_all_tags.function.__doc__, ''
' This is printed if not ' ' This is printed if not '
' }' ' }'
'' ''
' Image: htmltestImage.bmpHello, world!asd=10qwe' ' Image: testImage.bmp(Hello, world!)'
''
' someFunction'
''
' header.h'
''
' header2.h'
''
' someGroupanotherGroup'
'' ''
' Some text ' ' Some text '
' describing invariant. ' ' describing invariant. '
'' ''
' someInterfacesomeHeader.hHeader name'
''
' This will only appear in LATeX ' ' This will only appear in LATeX '
'' ''
' <ul> ' ' <ul> '
@ -160,28 +103,10 @@ check(doxygen_translate_all_tags.function.__doc__, ''
'' ''
' </ul> ' ' </ul> '
'' ''
' example '
''
' someMember Some description follows ' ' someMember Some description follows '
'' ''
' Sometitle '
''
' This will only appear in man ' ' This will only appear in man '
'' ''
' someThing'
''
' Sender,Receiver; '
' Sender->Receiver [label="Command()", URL=" '
' Receiver::Command()"]; '
' Sender<-Receiver [label="Ack()", URL=" '
' Ack()", ID="1"]; '
''
' mscFile.mscThe caption'
''
' someHeader.h '
''
' someNamespace'
''
' Notes:' ' Notes:'
' Here ' ' Here '
' is the note! ' ' is the note! '
@ -191,37 +116,13 @@ check(doxygen_translate_all_tags.function.__doc__, ''
'' ''
' someword' ' someword'
'' ''
' superPackage'
''
' somePageThe title '
''
' Title: The paragraph title ' ' Title: The paragraph title '
' The paragraph text. ' ' The paragraph text. '
' Maybe even multiline ' ' Maybe even multiline '
'' ''
' someParagraphParagraph title '
''
' Arguments:' ' Arguments:'
' a (int) -- the first param ' ' a (int) -- the first param '
'' ''
' Some description '
''
' Some description '
''
' someVar '
''
' someProtocolheader.hHeader name'
''
' someAnchor'
''
' toSomething'
''
' toSomethingElse'
''
' someName'
''
' someName'
''
' Remarks:' ' Remarks:'
' Some remark text ' ' Some remark text '
'' ''
@ -234,47 +135,20 @@ check(doxygen_translate_all_tags.function.__doc__, ''
'' ''
' may return ' ' may return '
'' ''
' someValueSome description '
''
''
' This will only appear in RTF ' ' This will only appear in RTF '
'' ''
'' ''
' See also:' ' See also:'
' someOtherMethod ' ' someOtherMethod '
'' ''
' someSectionSome title '
''
' function ' ' function '
'' ''
' Same as ' ' Same as '
' brief description ' ' brief description '
'' ''
''
''
' Since:' ' Since:'
' version 0.0.0.1 ' ' version 0.0.0.1 '
'' ''
' somePattern '
''
' someLine '
''
' example.hSome snippet '
''
' someStruct'
''
' someSubpageSome description'
''
' someSubsectionSome title '
''
' someSubsectionSome title '
''
''
''
' Some '
' description of the '
' test case '
''
' Throws:' ' Throws:'
' superException' ' superException'
'' ''
@ -286,34 +160,17 @@ check(doxygen_translate_all_tags.function.__doc__, ''
' Arguments:' ' Arguments:'
' b (float) -- B is mentioned again... ' ' b (float) -- B is mentioned again... '
'' ''
' someTypedef '
''
' someUnion'
''
' somePattern '
''
' someVar '
''
''
' very long ' ' very long '
' text with tags <sometag> ' ' text with tags <sometag> '
'' ''
''
' someFile.h'
''
' Version:' ' Version:'
' 0.0.0.2 ' ' 0.0.0.2 '
'' ''
' Warning:' ' Warning:'
' This is senseless! ' ' This is senseless! '
'' ''
' someGroupSome title '
''
''
' This will only appear in XML ' ' This will only appear in XML '
'' ''
' todo"Todo"Todo List'
''
' Here goes test of symbols: ' ' Here goes test of symbols: '
' $@\&~<>#%".::' ' $@\&~<>#%".::'
'' ''

View file

@ -71,7 +71,7 @@ check(doxygen_translate.function.__doc__, ''
' This is printed if not ' ' This is printed if not '
' }' ' }'
'' ''
' Image: htmltestImage.bmpHello, world!asd=10qwe' ' Image: testImage.bmp(Hello, world!)'
'' ''
' <ul> ' ' <ul> '
'' ''
@ -92,7 +92,7 @@ check(doxygen_translate.function.__doc__, ''
'' ''
' someword' ' someword'
'' ''
' superPackage' ''
'' ''
' Title: The paragraph title ' ' Title: The paragraph title '
' The paragraph text. ' ' The paragraph text. '

View file

@ -68,6 +68,46 @@ void PyDocConverter::fillStaticTables() {
tagHandlers["\""] = make_pair(&PyDocConverter::handleTagChar, ""); tagHandlers["\""] = make_pair(&PyDocConverter::handleTagChar, "");
tagHandlers["."] = make_pair(&PyDocConverter::handleTagChar, ""); tagHandlers["."] = make_pair(&PyDocConverter::handleTagChar, "");
tagHandlers["::"] = make_pair(&PyDocConverter::handleTagChar, ""); tagHandlers["::"] = make_pair(&PyDocConverter::handleTagChar, "");
// these commands are stripped out, and only their content is printed
tagHandlers["attention"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["author"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["authors"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["brief"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["bug"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["c"] = make_pair(&PyDocConverter::handleParagraph, " ");
tagHandlers["code"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["copyright"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["date"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["deprecated"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["details"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["em"] = make_pair(&PyDocConverter::handleParagraph, " ");
tagHandlers["example"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["exception"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["htmlonly"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["invariant"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["latexonly"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["link"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["manonly"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["note"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["p"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["partofdescription"] = make_pair(&PyDocConverter::handleParagraph, " ");
tagHandlers["rtfonly"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["return"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["returns"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["result"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["remark"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["remarks"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["sa"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["see"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["since"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["short"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["throw"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["throws"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["todo"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["version"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["verbatim"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["warning"] = make_pair(&PyDocConverter::handleParagraph, "");
tagHandlers["xmlonly"] = make_pair(&PyDocConverter::handleParagraph, "");
// these commands have special handlers // these commands have special handlers
tagHandlers["arg"] = make_pair(&PyDocConverter::handleTagMessage, " -"); tagHandlers["arg"] = make_pair(&PyDocConverter::handleTagMessage, " -");
tagHandlers["cond"] = make_pair(&PyDocConverter::handleTagMessage, "Conditional comment: "); tagHandlers["cond"] = make_pair(&PyDocConverter::handleTagMessage, "Conditional comment: ");
@ -76,7 +116,7 @@ void PyDocConverter::fillStaticTables() {
tagHandlers["endcond"] = make_pair(&PyDocConverter::handleTagMessage, "End of conditional comment."); tagHandlers["endcond"] = make_pair(&PyDocConverter::handleTagMessage, "End of conditional comment.");
tagHandlers["if"] = make_pair(&PyDocConverter::handleTagIf, "If: "); tagHandlers["if"] = make_pair(&PyDocConverter::handleTagIf, "If: ");
tagHandlers["ifnot"] = make_pair(&PyDocConverter::handleTagIf, "If not: "); tagHandlers["ifnot"] = make_pair(&PyDocConverter::handleTagIf, "If not: ");
tagHandlers["image"] = make_pair(&PyDocConverter::handleTagMessage, "Image: "); tagHandlers["image"] = make_pair(&PyDocConverter::handleTagImage, "");
tagHandlers["li"] = make_pair(&PyDocConverter::handleTagMessage, " -"); tagHandlers["li"] = make_pair(&PyDocConverter::handleTagMessage, " -");
tagHandlers["overload"] = make_pair(&PyDocConverter::handleTagMessage, "This is an overloaded member function, provided for" tagHandlers["overload"] = make_pair(&PyDocConverter::handleTagMessage, "This is an overloaded member function, provided for"
" convenience.\nIt differs from the above function only in what" " convenience.\nIt differs from the above function only in what"
@ -165,17 +205,14 @@ std::string PyDocConverter::translateSubtree(DoxygenEntity & doxygenEntity) {
void PyDocConverter::translateEntity(DoxygenEntity & doxyEntity, std::string &translatedComment) { void PyDocConverter::translateEntity(DoxygenEntity & doxyEntity, std::string &translatedComment) {
// check if we have needed handler and call it // check if we have needed handler and call it
std::string dummy;
std::map<std::string, std::pair<tagHandler, std::string > >::iterator it; std::map<std::string, std::pair<tagHandler, std::string > >::iterator it;
it = tagHandlers.find(doxyEntity.typeOfEntity); it = tagHandlers.find(doxyEntity.typeOfEntity);
if (it!=tagHandlers.end()) if (it!=tagHandlers.end())
(this->*(it->second.first))(doxyEntity, translatedComment, it->second.second); (this->*(it->second.first))(doxyEntity, translatedComment, it->second.second);
else
handleParagraph(doxyEntity, translatedComment, dummy);
} }
void PyDocConverter::handleParagraph(DoxygenEntity& tag, std::string& translatedComment, std::string&) { void PyDocConverter::handleParagraph(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) {
translatedComment += justifyString(translateSubtree(tag), 0); translatedComment += translateSubtree(tag) + arg;
} }
void PyDocConverter::handlePlainString(DoxygenEntity& tag, std::string& translatedComment, std::string&) { void PyDocConverter::handlePlainString(DoxygenEntity& tag, std::string& translatedComment, std::string&) {
translatedComment += tag.data; translatedComment += tag.data;
@ -207,6 +244,17 @@ void PyDocConverter::handleTagPar(DoxygenEntity& tag, std::string& translatedCom
tag.entityList.pop_front(); tag.entityList.pop_front();
handleParagraph(tag, translatedComment, dummy); handleParagraph(tag, translatedComment, dummy);
} }
void PyDocConverter::handleTagImage(DoxygenEntity& tag, std::string& translatedComment, std::string&) {
std::string dummy = " ";
if (tag.entityList.size() < 2)
return;
tag.entityList.pop_front();
translatedComment += "Image: ";
translatedComment += tag.entityList.begin()->data;
tag.entityList.pop_front();
if (tag.entityList.size())
translatedComment += "(" + tag.entityList.begin()->data + ")";
}
void PyDocConverter::handleTagParam(DoxygenEntity& tag, std::string& translatedComment, std::string&) { void PyDocConverter::handleTagParam(DoxygenEntity& tag, std::string& translatedComment, std::string&) {
std::string dummy; std::string dummy;
if (tag.entityList.size() < 2) { if (tag.entityList.size() < 2) {
@ -231,7 +279,7 @@ void PyDocConverter::handleTagWrap(DoxygenEntity& tag, std::string& translatedCo
std::string tagData = translateSubtree(tag); std::string tagData = translateSubtree(tag);
// wrap the thing, ignoring whitespaces // wrap the thing, ignoring whitespaces
size_t wsPos = tagData.find_last_not_of("\n\t "); size_t wsPos = tagData.find_last_not_of("\n\t ");
if (wsPos != std::string::npos) if (wsPos != std::string::npos && wsPos != tagData.size() - 1)
translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1); translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1);
else else
translatedComment += arg + tagData + arg + " "; translatedComment += arg + tagData + arg + " ";

View file

@ -90,6 +90,10 @@ protected:
* Insert 'Title: ...' * Insert 'Title: ...'
*/ */
void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
/*
* Insert 'Image: ...'
*/
void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg);
/* /*
* Format nice param description with type information * Format nice param description with type information
*/ */