From 1c25efff32ab9b8032b032f5e2374f77b09354eb Mon Sep 17 00:00:00 2001 From: albert-github Date: Fri, 15 Feb 2019 15:27:14 +0100 Subject: issue #6831 Failure to recognize class array with PHP in @var There are 2 different situations here: - @var, here a special change is necessary to check and handle whether or not we are in PHP (declinfo.*, doxygen.cpp) - @param - the type recognition for the PHP type has to be extended with the `[]` possibility and subsequently the `[]` part has to be handled separately from the 'datatype' (doctokinizer.l, docparser.*). - In the output we now can have multiple text strings resulting in a small change in handling of the separator between the data type (*docvisitor.*) --- src/declinfo.h | 3 ++- src/declinfo.l | 15 +++++++++++++-- src/docbookvisitor.cpp | 7 +++++-- src/docparser.cpp | 22 +++++++++++++++++++--- src/docparser.h | 16 +++++++++++++++- src/doctokenizer.l | 2 +- src/doxygen.cpp | 2 +- src/htmldocvisitor.cpp | 6 ++++-- src/latexdocvisitor.cpp | 6 ++++-- src/printdocvisitor.h | 22 +++++++++++++++------- src/rtfdocvisitor.cpp | 6 ++++-- src/xmldocvisitor.cpp | 9 +++++++-- 12 files changed, 90 insertions(+), 26 deletions(-) diff --git a/src/declinfo.h b/src/declinfo.h index d226c7d..2039dca 100644 --- a/src/declinfo.h +++ b/src/declinfo.h @@ -20,9 +20,10 @@ #include #include +#include "types.h" extern void parseFuncDecl(const QCString &decl, - bool objC, + const SrcLangExt lang, QCString &clName, QCString &type, QCString &name, diff --git a/src/declinfo.l b/src/declinfo.l index a91f832..6c28099 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -30,6 +30,7 @@ #include "declinfo.h" #include "util.h" #include "message.h" +#include "types.h" #define YY_NO_INPUT 1 #define YY_NO_UNISTD_H 1 @@ -53,6 +54,7 @@ static bool classTempListFound; static bool funcTempListFound; static QCString exceptionString; static bool insideObjC; +static bool insidePHP; static void addType() { @@ -132,6 +134,14 @@ ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+) name += yytext; } } +([~!]{B}*)?{ID}{B}*"["{B}*"]" { // PHP + if (!insidePHP) + { + REJECT; + } + addTypeName(); + name += yytext; + } ([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java, // the / was add to deal with multi- // dimensional C++ arrays like A[][15] @@ -230,7 +240,7 @@ ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+) /*@ ---------------------------------------------------------------------------- */ -void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, +void parseFuncDecl(const QCString &decl,const SrcLangExt lang,QCString &cl,QCString &t, QCString &n,QCString &a,QCString &ftl,QCString &exc) { printlex(yy_flex_debug, TRUE, __FILE__, NULL); @@ -240,7 +250,8 @@ void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t, inputPosition = 0; classTempListFound = FALSE; funcTempListFound = FALSE; - insideObjC = objC; + insideObjC = lang==SrcLangExt_ObjC; + insidePHP = lang==SrcLangExt_PHP; scope.resize(0); className.resize(0); classTempList.resize(0); diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index c36bb00..ca31e07 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -1413,11 +1413,9 @@ DB_VIS_C { QListIterator li(pl->paramTypes()); DocNode *type; - bool first=TRUE; m_t << " "; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1426,6 +1424,11 @@ DB_VIS_C { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } + } m_t << " "; } diff --git a/src/docparser.cpp b/src/docparser.cpp index bcf4bac..4db4dd7 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1229,16 +1229,32 @@ static void handleLinkedWord(DocNode *parent,QList &children,bool ignor static void handleParameterType(DocNode *parent,QList &children,const QCString ¶mTypes) { + static QRegExp re("[ \t\r\n\\[\\]]"); QCString name = g_token->name; - int p=0,i; + QCString name1; + int p=0,i,l,ii; while ((i=paramTypes.find('|',p))!=-1) { - g_token->name = paramTypes.mid(p,i-p); + name1 = paramTypes.mid(p,i-p); + ii=re.match(name1,0,&l); + if (ii != -1) + g_token->name=name1.mid(0,ii); + else + g_token->name=name1; handleLinkedWord(parent,children); + if (ii != -1) children.append(new DocWord(parent,name1.mid(ii).data())); p=i+1; + children.append(new DocSeparator(parent,"|")); } - g_token->name = paramTypes.mid(p); + name1 = paramTypes.mid(p); + ii=re.match(name1,0,&l); + if (ii != -1) + g_token->name=name1.mid(0,ii); + else + g_token->name=name1; handleLinkedWord(parent,children); + if (ii != -1) children.append(new DocWord(parent,name1.mid(ii).data())); + g_token->name = name; } diff --git a/src/docparser.h b/src/docparser.h index 5d2cc89..af1a21d 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -141,7 +141,8 @@ class DocNode Kind_VhdlFlow = 50, Kind_ParBlock = 51, Kind_DiaFile = 52, - Kind_Emoji = 53 + Kind_Emoji = 53, + Kind_Sep = 54 }; /*! Creates a new node */ DocNode() : m_parent(0), m_insidePre(FALSE) {} @@ -504,6 +505,19 @@ class DocWhiteSpace : public DocNode QCString m_chars; }; +/** Node representing a separator */ +class DocSeparator : public DocNode +{ + public: + DocSeparator(DocNode *parent,const QCString &chars) : + m_chars(chars) { m_parent = parent; } + Kind kind() const { return Kind_Sep; } + QCString chars() const { return m_chars; } + void accept(DocVisitor *v) { } + private: + QCString m_chars; +}; + /** Node representing a verbatim, unparsed text fragment */ class DocVerbatim : public DocNode { diff --git a/src/doctokenizer.l b/src/doctokenizer.l index 5cf5f02..3498bc4 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -1150,7 +1150,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV} g_token->name = g_token->name.left((int)yyleng-2); return TK_WORD; } -({PHPTYPE}{BLANK}*"|"{BLANK}*)*{PHPTYPE}{WS}+("&")?"$"{LABELID} { +({PHPTYPE}{BLANK}*("["{BLANK}*"]")*{BLANK}*"|"{BLANK}*)*{PHPTYPE}{BLANK}*("["{BLANK}*"]")*{WS}+("&")?"$"{LABELID} { QCString params = yytext; int j = params.find('&'); int i = params.find('$'); diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 9cdad02..ce38489 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -5982,7 +5982,7 @@ static void findMember(EntryNav *rootNav, else { // extract information from the declarations - parseFuncDecl(funcDecl,root->lang==SrcLangExt_ObjC,scopeName,funcType,funcName, + parseFuncDecl(funcDecl,root->lang,scopeName,funcType,funcName, funcArgs,funcTempList,exceptions ); } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 25166bc..7a7bcbe 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -1977,10 +1977,8 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) m_t << ""; QListIterator li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1989,6 +1987,10 @@ void HtmlDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } m_t << ""; } diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 463eedf..250d9d1 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -1567,10 +1567,8 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { QListIterator li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1579,6 +1577,10 @@ void LatexDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } if (useTable) m_t << " & "; } diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h index 8d375fc..5e5f40d 100644 --- a/src/printdocvisitor.h +++ b/src/printdocvisitor.h @@ -615,16 +615,24 @@ class PrintDocVisitor : public DocVisitor //const char *s; DocNode *param; printf(""); - for (sli.toFirst();(param=sli.current());++sli) + if (sli.count() > 0) { printf(""); - if (param->kind()==DocNode::Kind_Word) + for (sli.toFirst();(param=sli.current());++sli) { - visit((DocWord*)param); - } - else if (param->kind()==DocNode::Kind_LinkedWord) - { - visit((DocLinkedWord*)param); + if (param->kind()==DocNode::Kind_Word) + { + visit((DocWord*)param); + } + else if (param->kind()==DocNode::Kind_LinkedWord) + { + visit((DocLinkedWord*)param); + } + else if (param->kind()==DocNode::Kind_Sep) + { + printf(""); + printf(""); + } } printf(""); } diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index f44da77..d53ca23 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -1477,10 +1477,8 @@ void RTFDocVisitor::visitPre(DocParamList *pl) } QListIterator li(pl->paramTypes()); DocNode *type; - bool first=TRUE; for (li.toFirst();(type=li.current());++li) { - if (!first) m_t << " | "; else first=FALSE; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -1489,6 +1487,10 @@ void RTFDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << " " << ((DocSeparator *)type)->chars() << " "; + } } if (useTable) { diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index 01e0a6d..39d1fc9 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -972,9 +972,9 @@ void XmlDocVisitor::visitPre(DocParamList *pl) { QListIterator li(pl->paramTypes()); DocNode *type; + m_t << ""; for (li.toFirst();(type=li.current());++li) { - m_t << ""; if (type->kind()==DocNode::Kind_Word) { visit((DocWord*)type); @@ -983,8 +983,13 @@ void XmlDocVisitor::visitPre(DocParamList *pl) { visit((DocLinkedWord*)type); } - m_t << "" << endl; + else if (type->kind()==DocNode::Kind_Sep) + { + m_t << "" << endl; + m_t << ""; + } } + m_t << "" << endl; } m_t << "direction()!=DocParamSect::Unspecified) -- cgit v0.12