From 316be573f8bc8f75a9a7d80b015a72d1d43cffe3 Mon Sep 17 00:00:00 2001 From: Dmitry Kabak Date: Thu, 16 Aug 2012 14:18:47 +0000 Subject: [PATCH] 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 --- .../test-suite/doxygen_tricky_constructs.i | 106 +++++++++++++ .../doxygen_translate_all_tags_runme.py | 145 +----------------- .../python/doxygen_translate_runme.py | 6 +- .../DoxygenTranslator/src/PyDocConverter.cpp | 62 +++++++- Source/DoxygenTranslator/src/PyDocConverter.h | 4 + 5 files changed, 169 insertions(+), 154 deletions(-) create mode 100644 Examples/test-suite/doxygen_tricky_constructs.i diff --git a/Examples/test-suite/doxygen_tricky_constructs.i b/Examples/test-suite/doxygen_tricky_constructs.i new file mode 100644 index 000000000..96b1dfae3 --- /dev/null +++ b/Examples/test-suite/doxygen_tricky_constructs.i @@ -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
+ */ + char g_counter; + + + /** + * Tag endlink must be recognized also when it is the last token + * in the commment. + * + * @link Connection::getId() @endlink
+ * @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
+ */ + std::vector 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: + *
+     * CConnectionConfig config = new CConnectionConfig();
+     * config.discoveryPort(5534).dllPath("C:\\myWinIDEA\\connect.dll").id("main");
+     * 
+ * + * All parameters are optional. Set only what is required, default values are + * used for unspecified parameters. + *

+ * + * @link advancedWinIDEALaunching.py Python example. @endlink
+ */ + 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(); + + +%} diff --git a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py index e1d7a33b7..f71cb7e11 100644 --- a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py +++ b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py @@ -19,12 +19,6 @@ def check(got, expected): check(doxygen_translate_all_tags.function.__doc__, '' ' _Hello_' '' -' SomeLatexIndex ' -'' -' someGroup"Some title" ' -'' -' theAnchor' -'' ' -some list item ' '' ' This is attention! ' @@ -44,60 +38,29 @@ check(doxygen_translate_all_tags.function.__doc__, '' '' ' codeword' '' -' someCategoryheaderFile.hheaderName' -'' ' \'citationword\'' '' -' someClassheaderFile.hheaderName' -'' ' some test code ' '' ' Conditional comment: SOMECONDITION' ' Some conditional comment ' ' End of conditional comment.' '' -' someClass::someMethod' -'' -' someClass::someMethod2' -'' -' someClass::someMethod3' -'' ' Copyright:' ' some copyright ' '' ' 1970 - 2012 ' '' -' someDefine' -'' -' someGroupSome titles ' -'' ' Deprecated:' ' Now use another function ' '' ' This is very large ' ' 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_' '' ' emphazedWord' '' -' someEnum' -'' ' Example:' ' someFile.txt' ' Some details on using the example ' @@ -105,16 +68,6 @@ check(doxygen_translate_all_tags.function.__doc__, '' ' Throws:' ' SuperError' '' -' someOtherFunction' -'' -' file.h' -'' -' someFn ' -'' -' someHeader.hHeader name' -'' -' htmlFile.htm' -'' ' This will only appear in hmtl ' '' ' If: ANOTHERCONDITION {' @@ -135,21 +88,11 @@ check(doxygen_translate_all_tags.function.__doc__, '' ' This is printed if not ' ' }' '' -' Image: htmltestImage.bmpHello, world!asd=10qwe' -'' -' someFunction' -'' -' header.h' -'' -' header2.h' -'' -' someGroupanotherGroup' +' Image: testImage.bmp(Hello, world!)' '' ' Some text ' ' describing invariant. ' '' -' someInterfacesomeHeader.hHeader name' -'' ' This will only appear in LATeX ' '' '

' '' -' example ' -'' ' someMember Some description follows ' '' -' Sometitle ' -'' ' 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:' ' Here ' ' is the note! ' @@ -191,37 +116,13 @@ check(doxygen_translate_all_tags.function.__doc__, '' '' ' someword' '' -' superPackage' -'' -' somePageThe title ' -'' ' Title: The paragraph title ' ' The paragraph text. ' ' Maybe even multiline ' '' -' someParagraphParagraph title ' -'' ' Arguments:' ' a (int) -- the first param ' '' -' Some description ' -'' -' Some description ' -'' -' someVar ' -'' -' someProtocolheader.hHeader name' -'' -' someAnchor' -'' -' toSomething' -'' -' toSomethingElse' -'' -' someName' -'' -' someName' -'' ' Remarks:' ' Some remark text ' '' @@ -234,47 +135,20 @@ check(doxygen_translate_all_tags.function.__doc__, '' '' ' may return ' '' -' someValueSome description ' -'' -'' ' This will only appear in RTF ' '' '' ' See also:' ' someOtherMethod ' '' -' someSectionSome title ' -'' ' function ' '' ' Same as ' ' brief description ' '' -'' -'' ' Since:' ' version 0.0.0.1 ' '' -' somePattern ' -'' -' someLine ' -'' -' example.hSome snippet ' -'' -' someStruct' -'' -' someSubpageSome description' -'' -' someSubsectionSome title ' -'' -' someSubsectionSome title ' -'' -'' -'' -' Some ' -' description of the ' -' test case ' -'' ' Throws:' ' superException' '' @@ -286,34 +160,17 @@ check(doxygen_translate_all_tags.function.__doc__, '' ' Arguments:' ' b (float) -- B is mentioned again... ' '' -' someTypedef ' -'' -' someUnion' -'' -' somePattern ' -'' -' someVar ' -'' -'' ' very long ' ' text with tags ' '' -'' -' someFile.h' -'' ' Version:' ' 0.0.0.2 ' '' ' Warning:' ' This is senseless! ' '' -' someGroupSome title ' -'' -'' ' This will only appear in XML ' '' -' todo"Todo"Todo List' -'' ' Here goes test of symbols: ' ' $@\&~<>#%".::' '' diff --git a/Examples/test-suite/python/doxygen_translate_runme.py b/Examples/test-suite/python/doxygen_translate_runme.py index 61e5f5398..e7d819199 100644 --- a/Examples/test-suite/python/doxygen_translate_runme.py +++ b/Examples/test-suite/python/doxygen_translate_runme.py @@ -71,7 +71,7 @@ check(doxygen_translate.function.__doc__, '' ' This is printed if not ' ' }' '' -' Image: htmltestImage.bmpHello, world!asd=10qwe' +' Image: testImage.bmp(Hello, world!)' '' '
    ' '' @@ -92,7 +92,7 @@ check(doxygen_translate.function.__doc__, '' '' ' someword' '' -' superPackage' +'' '' ' Title: The paragraph title ' ' The paragraph text. ' @@ -145,4 +145,4 @@ check(doxygen_translate.function.__doc__, '' ' $@\&~<>#%".::' '' ' And here goes simple text ' -) \ No newline at end of file +) diff --git a/Source/DoxygenTranslator/src/PyDocConverter.cpp b/Source/DoxygenTranslator/src/PyDocConverter.cpp index 1826bcab5..d7b1f937f 100644 --- a/Source/DoxygenTranslator/src/PyDocConverter.cpp +++ b/Source/DoxygenTranslator/src/PyDocConverter.cpp @@ -68,6 +68,46 @@ void PyDocConverter::fillStaticTables() { 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 tagHandlers["arg"] = make_pair(&PyDocConverter::handleTagMessage, " -"); 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["if"] = make_pair(&PyDocConverter::handleTagIf, "If: "); 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["overload"] = make_pair(&PyDocConverter::handleTagMessage, "This is an overloaded member function, provided for" " 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) { // check if we have needed handler and call it - std::string dummy; std::map >::iterator it; it = tagHandlers.find(doxyEntity.typeOfEntity); if (it!=tagHandlers.end()) (this->*(it->second.first))(doxyEntity, translatedComment, it->second.second); - else - handleParagraph(doxyEntity, translatedComment, dummy); } -void PyDocConverter::handleParagraph(DoxygenEntity& tag, std::string& translatedComment, std::string&) { - translatedComment += justifyString(translateSubtree(tag), 0); +void PyDocConverter::handleParagraph(DoxygenEntity& tag, std::string& translatedComment, std::string &arg) { + translatedComment += translateSubtree(tag) + arg; } void PyDocConverter::handlePlainString(DoxygenEntity& tag, std::string& translatedComment, std::string&) { translatedComment += tag.data; @@ -207,6 +244,17 @@ void PyDocConverter::handleTagPar(DoxygenEntity& tag, std::string& translatedCom tag.entityList.pop_front(); 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&) { std::string dummy; if (tag.entityList.size() < 2) { @@ -231,7 +279,7 @@ void PyDocConverter::handleTagWrap(DoxygenEntity& tag, std::string& translatedCo std::string tagData = translateSubtree(tag); // wrap the thing, ignoring whitespaces 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); else translatedComment += arg + tagData + arg + " "; diff --git a/Source/DoxygenTranslator/src/PyDocConverter.h b/Source/DoxygenTranslator/src/PyDocConverter.h index 9787891c8..6094b4100 100644 --- a/Source/DoxygenTranslator/src/PyDocConverter.h +++ b/Source/DoxygenTranslator/src/PyDocConverter.h @@ -90,6 +90,10 @@ protected: * Insert 'Title: ...' */ 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 */