From 20af63f43e583a31dfe93f78807aa868f9b9ff14 Mon Sep 17 00:00:00 2001 From: Joenio Costa Date: Tue, 27 Jun 2017 23:10:08 -0300 Subject: add the number of conditionals path and bugfix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rebased with upstream master * Added build instructions to README * Bug 398942 - fixes the problem with instance variables and arguments with the same name Signed-off-by: Antonio Terceiro Signed-off-by: João M. Miranda Signed-off-by: Paulo Meirelles Signed-off-by: Vinicius Daros Signed-off-by: Jonathan Moraes --- addon/doxyparse/CMakeLists.txt | 11 ++++++++ addon/doxyparse/README | 5 ++++ addon/doxyparse/doxyparse.cpp | 59 ++++++++++++++++++++++-------------------- src/code.l | 54 ++++++++++++++++++++++++++++++++++++-- src/memberdef.cpp | 11 ++++++++ src/memberdef.h | 6 +++++ 6 files changed, 116 insertions(+), 30 deletions(-) diff --git a/addon/doxyparse/CMakeLists.txt b/addon/doxyparse/CMakeLists.txt index 24f98cb..e4f9021 100644 --- a/addon/doxyparse/CMakeLists.txt +++ b/addon/doxyparse/CMakeLists.txt @@ -1,11 +1,21 @@ if (build_parse) +# configvalues.h +add_custom_command( + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/src/configgen.py -maph ${CMAKE_SOURCE_DIR}/src/config.xml > ${GENERATED_SRC}/configvalues.h + DEPENDS ${CMAKE_SOURCE_DIR}/src/config.xml ${CMAKE_SOURCE_DIR}/src/configgen.py + OUTPUT ${GENERATED_SRC}/configvalues.h +) +set_source_files_properties(${GENERATED_SRC}/configvalues.h PROPERTIES GENERATED 1) + find_package(Iconv) include_directories( ${CMAKE_SOURCE_DIR}/src + ${GENERATED_SRC} ${CMAKE_SOURCE_DIR}/qtools ${ICONV_INCLUDE_DIR} + ${CLANG_INCLUDEDIR} ) add_executable(doxyparse @@ -21,6 +31,7 @@ ${ICONV_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${SQLITE3_LIBRARIES} ${EXTRA_LIBS} +${CLANG_LIBS} ) install(TARGETS doxyparse DESTINATION bin) diff --git a/addon/doxyparse/README b/addon/doxyparse/README index 7cbc8ff..9f7429c 100644 --- a/addon/doxyparse/README +++ b/addon/doxyparse/README @@ -5,6 +5,11 @@ This directory contains an "source parsing engine" based on doxyapp code. More info and source code repository: https://github.com/analizo/doxygen +## build + + cmake -G "Unix Makefiles" -Dbuild_parse=ON + make + AUTHORS ======= diff --git a/addon/doxyparse/doxyparse.cpp b/addon/doxyparse/doxyparse.cpp index ec1bdae..ee34e3b 100644 --- a/addon/doxyparse/doxyparse.cpp +++ b/addon/doxyparse/doxyparse.cpp @@ -103,7 +103,7 @@ static void findXRefSymbols(FileDef *fd) static bool ignoreStaticExternalCall(MemberDef *context, MemberDef *md) { if (md->isStatic()) { if(md->getFileDef()) { - if(md->getFileDef()->getFileBase() == context->getFileDef()->getFileBase()) + if(md->getFileDef()->getOutputFileBase() == context->getFileDef()->getOutputFileBase()) // TODO ignore prefix of file return false; else @@ -159,6 +159,9 @@ static void printReferenceTo(std::string type, std::string signature, std::strin printf(" type: %s\n", type.c_str()); printf(" defined_in: %s\n", defined_in.c_str()); } +static void printNumberOfConditionalPaths(MemberDef* md) { + printf(" conditional_paths: %d\n", md->numberOfFlowKeyWords()); +} static int isPartOfCStruct(MemberDef * md) { return is_c_code && md->getClassDef() != NULL; @@ -188,7 +191,7 @@ static void referenceTo(MemberDef* md) { std::string signature = ""; if (isPartOfCStruct(md)) { signature = md->getClassDef()->name().data() + std::string("::") + functionSignature(md); - defined_in = md->getClassDef()->getFileDef()->getFileBase().data(); + defined_in = md->getClassDef()->getFileDef()->getOutputFileBase().data(); } else { signature = functionSignature(md); @@ -196,7 +199,7 @@ static void referenceTo(MemberDef* md) { defined_in = md->getClassDef()->name().data(); } else if (md->getFileDef()) { - defined_in = md->getFileDef()->getFileBase().data(); + defined_in = md->getFileDef()->getOutputFileBase().data(); } } printReferenceTo(type, signature, defined_in); @@ -221,6 +224,7 @@ void functionInformation(MemberDef* md) { printNumberOfLines(size); ArgumentList *argList = md->argumentList(); printNumberOfArguments(argList->count()); + printNumberOfConditionalPaths(md); MemberSDict *defDict = md->getReferencesMembers(); if (defDict) { MemberSDict::Iterator msdi(*defDict); @@ -329,7 +333,7 @@ static void listSymbols() { printFile(fd->absFilePath().data()); MemberList *ml = fd->getMemberList(MemberListType_allMembersList); if (ml && ml->count() > 0) { - printModule(fd->getFileBase().data()); + printModule(fd->getOutputFileBase().data()); listMembers(ml); } @@ -355,37 +359,40 @@ int main(int argc,char **argv) { // initialize data structures initDoxygen(); + // check and finalize the configuration + checkConfiguration(); + adjustConfiguration(); + // setup the non-default configuration options // we need a place to put intermediate files std::ostringstream tmpdir; tmpdir << "/tmp/doxyparse-" << getpid(); - Config_getString("OUTPUT_DIRECTORY")= tmpdir.str().c_str(); - + Config_getString(OUTPUT_DIRECTORY)= tmpdir.str().c_str(); // enable HTML (fake) output to omit warning about missing output format - Config_getBool("GENERATE_HTML")=TRUE; + Config_getBool(GENERATE_HTML)=TRUE; // disable latex output - Config_getBool("GENERATE_LATEX")=FALSE; + Config_getBool(GENERATE_LATEX)=FALSE; // be quiet - Config_getBool("QUIET")=TRUE; + Config_getBool(QUIET)=TRUE; // turn off warnings - Config_getBool("WARNINGS")=FALSE; - Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE; - Config_getBool("WARN_IF_DOC_ERROR")=FALSE; + Config_getBool(WARNINGS)=FALSE; + Config_getBool(WARN_IF_UNDOCUMENTED)=FALSE; + Config_getBool(WARN_IF_DOC_ERROR)=FALSE; // Extract as much as possible - Config_getBool("EXTRACT_ALL")=TRUE; - Config_getBool("EXTRACT_STATIC")=TRUE; - Config_getBool("EXTRACT_PRIVATE")=TRUE; - Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE; + Config_getBool(EXTRACT_ALL)=TRUE; + Config_getBool(EXTRACT_STATIC)=TRUE; + Config_getBool(EXTRACT_PRIVATE)=TRUE; + Config_getBool(EXTRACT_LOCAL_METHODS)=TRUE; // Extract source browse information, needed // to make doxygen gather the cross reference info - Config_getBool("SOURCE_BROWSER")=TRUE; + Config_getBool(SOURCE_BROWSER)=TRUE; // find functions call between modules - Config_getBool("CALL_GRAPH")=TRUE; + Config_getBool(CALL_GRAPH)=TRUE; // loop recursive over input files - Config_getBool("RECURSIVE")=TRUE; + Config_getBool(RECURSIVE)=TRUE; // set the input - Config_getList("INPUT").clear(); + Config_getList(INPUT).clear(); for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-") == 0) { char filename[1024]; @@ -394,20 +401,16 @@ int main(int argc,char **argv) { if (feof(stdin)) { break; } - Config_getList("INPUT").append(filename); + Config_getList(INPUT).append(filename); } } else { - Config_getList("INPUT").append(argv[i]); + Config_getList(INPUT).append(argv[i]); } } - if (Config_getList("INPUT").isEmpty()) { + if (Config_getList(INPUT).isEmpty()) { exit(0); } - // check and finalize the configuration - checkConfiguration(); - adjustConfiguration(); - // parse the files parseInput(); @@ -429,7 +432,7 @@ int main(int argc,char **argv) { if (!Doxygen::objDBFileName.isEmpty()) unlink(Doxygen::objDBFileName); if (!Doxygen::entryDBFileName.isEmpty()) unlink(Doxygen::entryDBFileName); // clean up after us - rmdir(Config_getString("OUTPUT_DIRECTORY")); + rmdir(Config_getString(OUTPUT_DIRECTORY)); listSymbols(); diff --git a/src/code.l b/src/code.l index b2564e9..fc511a0 100644 --- a/src/code.l +++ b/src/code.l @@ -126,6 +126,7 @@ static bool g_lexInit = FALSE; static QStack g_classScopeLengthStack; +static int g_prefixed_with_this_keyword = FALSE; static Definition *g_searchCtx; static bool g_collectXRefs; @@ -963,7 +964,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName bool isLocal=FALSE; //printf("generateClassOrGlobalLink(className=%s)\n",className.data()); - if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable + if (!g_prefixed_with_this_keyword || (lcd=g_theVarContext.findVariable(className))==0) // not a local variable { Definition *d = g_currentDefinition; //printf("d=%s g_sourceFileDef=%s\n",d?d->name().data():"",g_sourceFileDef?g_sourceFileDef->name().data():""); @@ -1019,6 +1020,8 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName isLocal=TRUE; DBG_CTX((stderr,"is a local variable cd=%p!\n",cd)); } + g_prefixed_with_this_keyword = FALSE; // discard the "this" prefix for the next calls + if (cd && cd->isLinkable()) // is it a linkable class { DBG_CTX((stderr,"is linkable class %s\n",clName)); @@ -1821,7 +1824,8 @@ SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID}) SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+ KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol"|"@optional"|"@required"|"@throw"|"@synthesize"|"@property") KEYWORD ("asm"|"__assume"|"auto"|"class"|"const"|"delete"|"enum"|"explicit"|"extern"|"false"|"friend"|"gcnew"|"gcroot"|"set"|"get"|"inline"|"internal"|"mutable"|"namespace"|"new"|"nullptr"|"override"|"operator"|"pin_ptr"|"private"|"protected"|"public"|"raise"|"register"|"remove"|"self"|"sizeof"|"static"|"struct"|"__super"|"function"|"template"|"generic"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|"alignas"|"alignof"|{KEYWORD_OBJC}) -FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"for"|"foreach"|"for each"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while"|"@try"|"@catch"|"@finally") +FLOWKW ("break"|"catch"|"continue"|"default"|"do"|"else"|"finally"|"return"|"switch"|"throw"|"throws"|"@catch"|"@finally") +FLOWCONDITION ("case"|"for"|"foreach"|"for each"|"goto"|"if"|"try"|"while"|"@try") TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"object"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"size_t"|"boolean"|"id"|"SEL"|"string"|"nullptr") CASTKW ("const_cast"|"dynamic_cast"|"reinterpret_cast"|"static_cast") CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) @@ -2408,6 +2412,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" \n { codifyLines(yytext); BEGIN(Body); } . { codifyLines(yytext); BEGIN(Body); } "$"?"this"("->"|".") { g_code->codify(yytext); // this-> for C++, this. for C# + g_prefixed_with_this_keyword = TRUE; } {KEYWORD}/([^a-z_A-Z0-9]) { startFontClass("keyword"); @@ -2449,6 +2454,18 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0); BEGIN(FuncCall); } +{FLOWCONDITION}/{BN}*"(" { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + g_name.resize(0);g_type.resize(0); + g_inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0); + BEGIN(FuncCall); + } {FLOWKW}/([^a-z_A-Z0-9]) { startFontClass("keywordflow"); codifyLines(yytext); @@ -2458,11 +2475,33 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_inFunctionTryBlock=FALSE; } } +{FLOWCONDITION}/([^a-z_A-Z0-9]) { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + if (g_inFunctionTryBlock && (strcmp(yytext,"catch")==0 || strcmp(yytext,"finally")==0)) + { + g_inFunctionTryBlock=FALSE; + } + } {FLOWKW}/{B}* { startFontClass("keywordflow"); codifyLines(yytext); endFontClass(); } +{FLOWCONDITION}/{B}* { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + startFontClass("keywordflow"); + codifyLines(yytext); + endFontClass(); + } "*"{B}*")" { // end of cast? g_code->codify(yytext); g_theCallContext.popScope(); @@ -2963,6 +3002,17 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" g_code->codify(yytext); endFontClass(); } +{FLOWCONDITION}/([^a-z_A-Z0-9]) { + if (g_currentMemberDef && g_currentMemberDef->isFunction()) + { + g_currentMemberDef->addFlowKeyWord(); + } + addParmType(); + g_parmName=yytext; + startFontClass("keywordflow"); + g_code->codify(yytext); + endFontClass(); + } {ID}(({B}*"<"[^\n\[\](){}<>]*">")?({B}*"::"{B}*{ID})?)* { addParmType(); g_parmName=yytext; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 26001a1..8403374 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -750,6 +750,7 @@ MemberDef::MemberDef(const char *df,int dl,int dc, //printf("MemberDef::MemberDef(%s)\n",na); m_impl = new MemberDefImpl; m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al); + number_of_flowkw = 1; m_isLinkableCached = 0; m_isConstructorCached = 0; m_isDestructorCached = 0; @@ -4910,6 +4911,16 @@ void MemberDef::invalidateCachedArgumentTypes() invalidateCachedTypesInArgumentList(m_impl->declArgList); } +void MemberDef::addFlowKeyWord() +{ + number_of_flowkw++; +} + +int MemberDef::numberOfFlowKeyWords() +{ + return number_of_flowkw; +} + //---------------- QCString MemberDef::displayName(bool) const diff --git a/src/memberdef.h b/src/memberdef.h index c0825b2..bf7ea9a 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -178,6 +178,7 @@ class MemberDef : public Definition bool isStrongEnumValue() const; bool livesInsideEnum() const; + int numberOfFlowKeyWords(); // derived getters bool isFriendToHide() const; bool isNotFriend() const; @@ -272,6 +273,8 @@ class MemberDef : public Definition // ---- setters ----- //----------------------------------------------------------------------------------- + void addFlowKeyWord(); + // set functions void setMemberType(MemberType t); void setDefinition(const char *d); @@ -424,6 +427,9 @@ class MemberDef : public Definition void _addToSearchIndex(); static int s_indentLevel; + + int number_of_flowkw; + // disable copying of member defs MemberDef(const MemberDef &); MemberDef &operator=(const MemberDef &); -- cgit v0.12