Index: src/entry.h =================================================================== --- src/entry.h (revision 661) +++ src/entry.h (working copy) @@ -61,12 +61,14 @@ struct Argument { /*! Construct a new argument. */ - Argument() {} + Argument() {suffixSpacer = " ";} /*! Copy an argument (does a deep copy of all strings). */ Argument(const Argument &a) { attrib=a.attrib.copy(); type=a.type.copy(); + suffixSpacer=a.suffixSpacer.copy(); + suffixType=a.suffixType.copy(); name=a.name.copy(); defval=a.defval.copy(); docs=a.docs.copy(); @@ -79,6 +81,9 @@ { attrib=a.attrib.copy(); type=a.type.copy(); + suffixSpacer=a.suffixSpacer.copy(); + suffixType = a.suffixType.copy(); + name=a.name.copy(); defval=a.defval.copy(); docs=a.docs.copy(); @@ -96,6 +101,10 @@ QCString attrib; /*!< Argument's attribute (IDL only) */ QCString type; /*!< Argument's type */ + QCString suffixSpacer; /*! To separate the argument name from the suffixType */ + QCString suffixType; /*! The argument's type for languages where the type + appears after the argument name, eg ActionScript */ + QCString canType; /*!< Cached value of canonical type (after type resolution). Empty initially. */ QCString name; /*!< Argument's name (may be empty) */ QCString array; /*!< Argument's array specifier (may be empty) */ @@ -118,6 +127,8 @@ volatileSpecifier(FALSE), pureSpecifier(FALSE) { setAutoDelete(TRUE); } + + ArgumentList(const ArgumentList &toCopy); /*! Destroys the argument list */ ~ArgumentList() {} bool hasDocumentation() const; @@ -337,6 +348,7 @@ QCString args; //!< member argument string QCString bitfields; //!< member's bit fields ArgumentList *argList; //!< member arguments as a list + ArgumentList *declArgList; //!< declaration arguments as a list QList *tArgLists; //!< template argument declarations QGString program; //!< the program text QGString initializer; //!< initial value (for variables) @@ -372,6 +384,11 @@ bool artificial; //!< Artificially introduced item GroupDocType groupDocType; + QCString suffixSpacer; //!< string to place before the suffixType + QCString suffixType; //!< the entry's type for languages where the type is + // is written after the function declaration (eg ActionScript) + + static int num; //!< counts the total number of entries /// return the command name used to define GROUPDOC_SEC Index: src/util.cpp =================================================================== --- src/util.cpp (revision 661) +++ src/util.cpp (working copy) @@ -1916,7 +1916,16 @@ } if (!a->name.isEmpty() || !a->array.isEmpty()) { - result+= type1+" "+a->name+type2+a->array; + + result+= type1; + if (!type1.isEmpty()) + result += a->suffixSpacer; + + result += a->name+type2 + a->array; + + if (!a->suffixType.isEmpty()) + result += a->suffixSpacer + a->suffixType; + } else { @@ -6393,6 +6402,7 @@ { "python", "python", SrcLangExt_Python }, { "fortran", "fortran", SrcLangExt_F90 }, { "vhdl", "vhdl", SrcLangExt_VHDL }, + { "actionscript", "c", SrcLangExt_ActionScript}, { 0, 0, (SrcLangExt)0 } }; @@ -6455,6 +6465,7 @@ updateLanguageMapping(".f90", "fortran"); updateLanguageMapping(".vhd", "vhdl"); updateLanguageMapping(".vhdl", "vhdl"); + updateLanguageMapping(".as", "actionscript"); } SrcLangExt getLanguageFromFileName(const QCString fileName) Index: src/doxygen.cpp =================================================================== --- src/doxygen.cpp (revision 661) +++ src/doxygen.cpp (working copy) @@ -1802,7 +1802,7 @@ md->typeString(),memName,md->argsString(), md->excpString(),root->protection,root->virt, md->isStatic(),Member,md->memberType(), - templAl.pointer(),al.pointer() + templAl.pointer(),al.pointer(), root->declArgList,root->suffixSpacer,root->suffixType ); } newMd->setMemberClass(cd); @@ -1972,7 +1972,7 @@ root->fileName,root->startLine, root->type,name,root->args,0, prot,Normal,root->stat,related, - mtype,0,0); + mtype,0,0,0,root->suffixSpacer, root->suffixType); md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); @@ -2154,7 +2154,7 @@ root->fileName,root->startLine, root->type,name,root->args,0, Public, Normal,root->stat,Member, - mtype,0,0); + mtype,0,0,0,root->suffixSpacer,root->suffixType); md->setTagInfo(rootNav->tagInfo()); md->setDocumentation(root->doc,root->docFile,root->docLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine); @@ -2676,7 +2676,9 @@ root->stat && root->relatesType != MemberOf, root->relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, - mtype,root->tArgLists ? root->tArgLists->last() : 0,root->argList); + mtype,root->tArgLists ? root->tArgLists->last() : 0,root->argList, + root->declArgList, root->suffixSpacer, root->suffixType); + md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -3019,7 +3021,8 @@ root->fileName,root->startLine, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,Member, - MemberDef::Function,tArgList,root->argList); + MemberDef::Function,tArgList,root->argList, root->declArgList, + root->suffixSpacer, root->suffixType); md->setTagInfo(rootNav->tagInfo()); //md->setDefFile(root->fileName); @@ -5654,7 +5657,7 @@ root->fileName,root->startLine, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, - mtype,tArgList,root->argList); + mtype,tArgList,root->argList, root->declArgList,root->suffixSpacer,root->suffixType); //printf("new specialized member %s args=`%s'\n",md->name().data(),funcArgs.data()); md->setTagInfo(rootNav->tagInfo()); md->setMemberClass(cd); @@ -5718,7 +5721,7 @@ root->fileName,root->startLine, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Related, - mtype,tArgList,root->argList); + mtype,tArgList,root->argList,root->declArgList,root->suffixSpacer, root->suffixType); md->setTagInfo(rootNav->tagInfo()); md->setTypeConstraints(root->typeConstr); md->setMemberClass(cd); @@ -5851,7 +5854,7 @@ isMemberOf ? Foreign : isRelated ? Related : Member, mtype, (root->tArgLists ? root->tArgLists->last() : 0), - funcArgs.isEmpty() ? 0 : root->argList); + funcArgs.isEmpty() ? 0 : root->argList, root->declArgList, root->suffixSpacer, root->suffixType); // // we still have the problem that // MemberDef::writeDocumentation() in memberdef.cpp @@ -5975,7 +5978,7 @@ root->fileName,root->startLine, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, - MemberDef::Function,0,root->argList); + MemberDef::Function,0,root->argList, root->declArgList,root->suffixSpacer, root->suffixType); md->setTagInfo(rootNav->tagInfo()); md->makeImplementationDetail(); md->setMemberClass(cd); @@ -6303,7 +6306,7 @@ root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberDef::Enumeration, - 0,0); + 0,0,0,root->suffixSpacer, root->suffixType); md->setTagInfo(rootNav->tagInfo()); if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); md->setBodySegment(root->bodyLine,root->endBodyLine); @@ -7501,7 +7504,8 @@ { MemberDef *md=new MemberDef("",1, "#define",root->name,root->args,0, - Public,Normal,FALSE,Member,MemberDef::Define,0,0); + Public,Normal,FALSE,Member,MemberDef::Define,0,0,0, + root->suffixSpacer,root->suffixType); md->setTagInfo(rootNav->tagInfo()); //printf("Searching for `%s' fd=%p\n",filePathName.data(),fd); md->setFileDef(rootNav->parent()->fileDef()); Index: src/util.h =================================================================== --- src/util.h (revision 661) +++ src/util.h (working copy) @@ -95,7 +95,8 @@ SrcLangExt_JS = 0x0400, SrcLangExt_Python = 0x0800, SrcLangExt_F90 = 0x1000, - SrcLangExt_VHDL = 0x2000 + SrcLangExt_VHDL = 0x2000, + SrcLangExt_ActionScript = 0x4000 }; //-------------------------------------------------------------------- Index: src/pre.l =================================================================== --- src/pre.l (revision 661) +++ src/pre.l (working copy) @@ -1042,7 +1042,7 @@ MemberDef *md=new MemberDef( g_yyFileName,g_yyLineNr, "#define",g_defName,g_defArgsStr,0, - Public,Normal,FALSE,Member,MemberDef::Define,0,0); + Public,Normal,FALSE,Member,MemberDef::Define,0,0,0,0,0); if (!g_defArgsStr.isEmpty()) { ArgumentList *argList = new ArgumentList; Index: src/entry.cpp =================================================================== --- src/entry.cpp (revision 661) +++ src/entry.cpp (working copy) @@ -63,6 +63,7 @@ anchors = new QList; // Doxygen::sectionDict takes ownership of the items! argList = new ArgumentList; argList->setAutoDelete(TRUE); + declArgList = 0; //printf("Entry::Entry() tArgList=0\n"); tArgLists = 0; typeConstr = 0; @@ -75,6 +76,31 @@ reset(); } + +static ArgumentList * copyArgList(const ArgumentList *argList) +{ + + if (NULL == argList) + return NULL; + + ArgumentList *newArgList; + newArgList = new ArgumentList; + newArgList->setAutoDelete(TRUE); + + QListIterator ali(*argList); + Argument *a; + for (;(a=ali.current());++ali) + { + newArgList->append(new Argument(*a)); + } + newArgList->constSpecifier = argList->constSpecifier; + newArgList->volatileSpecifier = argList->volatileSpecifier; + newArgList->pureSpecifier = argList->pureSpecifier; + + return newArgList; +} + + Entry::Entry(const Entry &e) { //printf("Entry::Entry(%p):copy\n",this); @@ -129,12 +155,13 @@ groups = new QList; groups->setAutoDelete(TRUE); anchors = new QList; - argList = new ArgumentList; - argList->setAutoDelete(TRUE); + typeConstr = new ArgumentList; typeConstr->setAutoDelete(TRUE); tArgLists = 0; groupDocType = e.groupDocType; + suffixSpacer = e.suffixSpacer.copy(); + suffixType = e.suffixType.copy(); // deep copy of the child entry list QListIterator eli(*e.m_sublist); @@ -167,18 +194,13 @@ anchors->append(new SectionInfo(*s)); } - // deep copy argument list - QListIterator ali(*e.argList); - Argument *a; - for (;(a=ali.current());++ali) - { - argList->append(new Argument(*a)); - } - argList->constSpecifier = e.argList->constSpecifier; - argList->volatileSpecifier = e.argList->volatileSpecifier; - argList->pureSpecifier = e.argList->pureSpecifier; + // deep copy argument lists + argList = copyArgList(e.argList); + declArgList = copyArgList(e.declArgList); + // deep copy type contraint list + Argument *a; if (e.typeConstr) { QListIterator tcli(*e.typeConstr); @@ -461,3 +483,24 @@ m_noLoad=TRUE; } + + + +ArgumentList::ArgumentList(const ArgumentList &toCopy) +{ + setAutoDelete(TRUE); + ArgumentListIterator ali(toCopy); + Argument *a; + for (;(a=ali.current());++ali) + { + //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data()); + append(new Argument(*a)); + } + constSpecifier = toCopy.constSpecifier; + volatileSpecifier = toCopy.volatileSpecifier; + pureSpecifier = toCopy.pureSpecifier; + +} + + + Index: src/outputlist.h =================================================================== --- src/outputlist.h (revision 661) +++ src/outputlist.h (working copy) @@ -381,6 +381,12 @@ void endParameterList() { forall(&OutputGenerator::endParameterList); } + void startSuffix() + { forall(&OutputGenerator::startSuffix); } + + void endSuffix() + { forall(&OutputGenerator::endSuffix); } + void startConstraintList(const char *header) { forall(&OutputGenerator::startConstraintList,header); } void startConstraintParam() Index: src/htmlgen.cpp =================================================================== --- src/htmlgen.cpp (revision 661) +++ src/htmlgen.cpp (working copy) @@ -1464,7 +1464,7 @@ t << " "; if (closeBracket) t << ")"; t << "" << endl; - t << " "; + t << ""; } } else @@ -1472,8 +1472,23 @@ t << "" << endl; t << " " << endl; } + } + +void HtmlGenerator::startSuffix() +{ + DBG_HTML(t << "" << endl;) + t << ""; +} + + +void HtmlGenerator::endSuffix() +{ + DBG_HTML(t << "" << endl;) + t << ""; +} + void HtmlGenerator::endParameterList() { DBG_HTML(t << "" << endl;) Index: src/outputgen.h =================================================================== --- src/outputgen.h (revision 661) +++ src/outputgen.h (working copy) @@ -384,6 +384,9 @@ virtual void startParameterList(bool) = 0; virtual void endParameterList() = 0; + virtual void startSuffix(){}; + virtual void endSuffix(){}; + virtual void startConstraintList(const char *) = 0; virtual void startConstraintParam() = 0; virtual void endConstraintParam() = 0; Index: src/scanner.l =================================================================== --- src/scanner.l (revision 661) +++ src/scanner.l (working copy) @@ -115,7 +115,9 @@ static bool insideObjC = FALSE; //!< processing Objective C code? static bool insideCli = FALSE; //!< processing C++/CLI code? static bool insideJS = FALSE; //!< processing JavaScript code? +static bool insideActionScript = FALSE; + static bool insideCppQuote = FALSE; static bool insideProtocolList = FALSE; @@ -333,6 +335,8 @@ insidePHP = langExt==SrcLangExt_PHP; insideObjC = langExt==SrcLangExt_ObjC; insideJS = langExt==SrcLangExt_JS; + insideActionScript = langExt == (SrcLangExt_ActionScript); + if ( insidePHP ) { useOverrideCommands = TRUE; @@ -695,6 +699,12 @@ %x IDLProp %x IDLPropName +%x ASMethod +%x ASMethodParam +%x ASMethodParamType +%x ASMethodReturnType +%x ASVar + /** Prototype scanner states */ %x Prototype @@ -766,6 +776,210 @@ unput(*yytext); BEGIN( FindMembers ); } +{BN}*"var "{B}* { + + if (!insideActionScript) + { + REJECT; + } + else + { + lineCount(); + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->section = Entry::VARIABLE_SEC; + current->proto = true; + //current->protection = protection = Public ; + if (QCString(yytext).stripWhiteSpace()[0] != 'f') + { + if (QCString(yytext).contains("private",false) > 0) + { + current->protection = protection = Private ; } + if (QCString(yytext).contains("protected",false) > 0) + { + current->protection = protection = Protected ; + } + } + current->mtype = mtype = Method; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + BEGIN( ASVar ); + } +} +{B}*{ID}{B}* { + current->name = QCString(yytext).stripWhiteSpace(); + current->type = "var"; +} +{BN}*":"{BN}*({ID}".")*{ID} { + + current->suffixType = QCString(yytext).right(QCString(yytext).size() - 2).stripWhiteSpace(); + current->suffixSpacer = QCString(":"); + BEGIN(FindMembers); +} + +";" { +//an untyped variable + unput(';'); + BEGIN(FindMembers); +} + + +{B}*"function"{B}* { + if (!insideActionScript) + { + REJECT; + } + else + { + //printf("*** insideActionScript\n"); + lineCount(); + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + current->section = Entry::FUNCTION_SEC; + current->proto = true; + + + + current->mtype = mtype = Method; + current->type.resize(0); + current->type = QCString("Void"); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + + + BEGIN( ASMethod ); + + } + } + +{B}*"get"{B}+{ID}{B}* { //A getter function + + //remove the "get" from the start of the name + current->name = QCString(yytext).right(QCString(yytext).size() - 4).stripWhiteSpace(); + current->type = QCString("function get"); + +} + + +{B}*"set"{B}+{ID}{B}* { //A setter function + + //remove the "set" from the start of the name + current->name = QCString(yytext).right(QCString(yytext).size() - 4).stripWhiteSpace(); + current->type = QCString("function set"); +} + + +{B}*{ID}{B}* { //Method Name + current->name = QCString(yytext).stripWhiteSpace(); + current->type = QCString("function"); + + //printf("*** ASMethod %s\n", current->name.data()); + } +"("{B}* { //Start of parameter + BEGIN(ASMethodParam); + } + +{ID} { // parameter name + Argument *a = new Argument; + a->name = QCString(yytext); + //printf("*** ASMethodParam %s\n", a->name.data()); + current->argList->append(a); + BEGIN(ASMethodParamType); + } + + +{BN}*", "{BN}* { // no type, there's another param + //QCString text = QCString(yytext); + // Argument *a = current->argList->getLast(); + BEGIN(ASMethodParam); + } + +{B}*")"{B}* { //no more parameters + BEGIN(ASMethodReturnType); + } + +{B}*")"{B}* { // no type, end of parameter list + BEGIN(ASMethodReturnType); + } + + +{BN}*":"{BN}*({ID}".")*{ID} { //param type + + Argument *a = current->argList->getLast(); + a->type = ""; + a->suffixType = QCString(yytext).stripWhiteSpace(); + + if (QCString(a->suffixType)[0] == ':') + { + a->suffixType = QCString(a->suffixType).right(QCString(a->suffixType).size() - 2); + } + + a->suffixSpacer = QCString(":"); + BEGIN(ASMethodParam); + } + +{BN}*", "{BN}* { //other param + QCString text = QCString(yytext); + // Argument *a = current->argList->getLast(); + BEGIN(ASMethodParam); + } + +{BN}*":"{B}*({ID}".")*{ID} { + current->suffixType = QCString(yytext).right(QCString(yytext).size() - 2).stripWhiteSpace(); + current->suffixSpacer = QCString(":"); + if (QCString(current->suffixType)[0] == ':') + { + current->suffixType = QCString(current->suffixType).right(QCString(current->suffixType).size() - 2); + } + } + +{BN}*"{" { + + current->args = argListToString(current->argList); + + current->declArgList = new ArgumentList(*(current->argList)); + current->declArgList->setAutoDelete(FALSE); + + unput('{'); + + BEGIN( Function ); + } + + +{BN}*";" { + + current->args = argListToString(current->argList); + + current->declArgList = new ArgumentList(*(current->argList)); + current->declArgList->setAutoDelete(FALSE); + + unput(';'); + + BEGIN( Function ); + } + + +{B}*"intrinsic class"{BN}+ { + lineCount(); + isTypedef=FALSE; + current->section = Entry::CLASS_SEC; + current->protection = protection = Public ; + addType( current ) ; + current->type += " intrinsic " ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current->bodyLine = yyLineNr; + BEGIN( CompoundName ); + } + + + + "{B}*((("disp")?"interface")|"valuetype"){BN}+ { // M$/Corba IDL/Java interface lineCount(); - if (insideIDL || insideJava || insideCS || insideD || insidePHP) + if (insideIDL || insideJava || insideActionScript || insideCS || insideD || insidePHP) { isTypedef=FALSE; current->section = Entry::CLASS_SEC; @@ -1849,7 +2063,7 @@ { BEGIN(CppQuote); } - else if ((insideIDL || insideJava || insideD) && yyleng==6 && strcmp(yytext,"import")==0) + else if ((insideIDL || insideJava || insideActionScript || insideD) && yyleng==6 && strcmp(yytext,"import")==0) { if (insideIDL) BEGIN(NextSemi); @@ -1870,11 +2084,11 @@ insideTryBlock=FALSE; BEGIN(TryFunctionBlock); } - else if (insideJS && strcmp(yytext,"var")==0) + else if ((insideJS || insideActionScript) && strcmp(yytext,"var")==0) { // javascript variable current->type="var"; } - else if (insideJS && strcmp(yytext,"function")==0) + else if ((insideJS || insideActionScript )&& strcmp(yytext,"function")==0) { // javascript function current->type="function"; } @@ -1884,7 +2098,7 @@ { addType( current ) ; } - bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS; + bool javaLike = insideJava || insideActionScript || insideCS || insideD || insidePHP || insideJS; if (javaLike && strcmp(yytext,"public")==0) { current->protection = Public; @@ -1955,7 +2169,7 @@ [0-9]{ID} { // some number where we did not expect one } "." { - if (insideJava || insideCS || insideD) + if (insideJava || insideActionScript || insideCS || insideD) { current->name+="."; } @@ -3019,7 +3233,7 @@ current = new Entry(*current); if (current->section==Entry::NAMESPACE_SEC || (current->spec==Entry::Interface) || - insideJava || insidePHP || insideCS || insideD || insideJS + insideJava || insidePHP || insideCS || insideD || insideJS || insideActionScript ) { // namespaces and interfaces and java classes ends with a closing bracket without semicolon current->reset(); @@ -3492,7 +3706,8 @@ *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); - if (insideJS) + + if (insideJS || insideActionScript) { fixArgumentListForJavaScript(current->argList); } @@ -3810,7 +4025,8 @@ lineCount() ; current->args += ' ' ; } -"#" { if (insidePHP) +"#" { + if (insidePHP) REJECT; lastCPPContext = YY_START; BEGIN(SkipCPP); @@ -4075,7 +4291,7 @@ } if ( *yytext == '{' ) { - if ( !insidePHP && (current_root->section & Entry::COMPOUND_MASK) ) + if ( !insideActionScript && !insidePHP && (current_root->section & Entry::COMPOUND_MASK) ) { previous->spec |= Entry::Inline; } @@ -4445,7 +4661,7 @@ roundCount=0; BEGIN(SkipUnionSwitch); } - else if ((insideJava || insidePHP || insideJS) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) + else if ((insideJava || insidePHP || insideJS || insideActionScript) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) { current->type.resize(0); baseProt=Public; @@ -5507,7 +5723,7 @@ if( ce->section==Entry::CLASS_SEC ) // class { - if (insidePHP || insideD || insideJS) + if (insidePHP || insideD || insideJS || insideActionScript) { current->protection = protection = Public ; } Index: src/memberdef.cpp =================================================================== --- src/memberdef.cpp (revision 661) +++ src/memberdef.cpp (working copy) @@ -84,65 +84,20 @@ return result; } -static bool writeDefArgumentList(OutputList &ol,ClassDef *cd, - const QCString & /*scopeName*/,MemberDef *md) -{ - LockingPtr defArgList=(md->isDocsForDefinition()) ? - md->argumentList() : md->declArgumentList(); - //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition()); - if (defArgList==0 || md->isProperty()) - { - return FALSE; // member has no function like argument list - } - if (!md->isDefine()) ol.docify(" "); - //printf("writeDefArgList(%d)\n",defArgList->count()); - ol.pushGeneratorState(); - ol.disableAllBut(OutputGenerator::Html); - { - // html - ol.endMemberDocName(); - ol.startParameterList(!md->isObjCMethod()); - } - ol.enableAll(); - ol.disable(OutputGenerator::Html); - { - // other formats - if (!md->isObjCMethod()) ol.docify("("); // start argument list - ol.endMemberDocName(); - } - ol.popGeneratorState(); - //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine()); - Argument *a=defArgList->first(); - QCString cName; - if (cd) +static void writeArgType(OutputList &ol, + ClassDef *cd, + MemberDef *md, + LockingPtr &defArgList, + QCString &cName, + const Argument *a, + const bool first) { - cName=cd->name(); - int il=cName.find('<'); - int ir=cName.findRev('>'); - if (il!=-1 && ir!=-1 && ir>il) - { - cName=cName.mid(il,ir-il+1); - //printf("1. cName=%s\n",cName.data()); - } - else if (cd->templateArguments()) - { - cName=tempArgListToString(cd->templateArguments()); - //printf("2. cName=%s\n",cName.data()); - } - else // no template specifier - { - cName.resize(0); - } - } - //printf("~~~ %s cName=%s\n",md->name().data(),cName.data()); - //if (!md->isDefine()) ol.startParameter(TRUE); else ol.docify(" "); - bool first=TRUE; - while (a) - { - if (md->isDefine() || first) ol.startParameterType(first,md->isObjCMethod()?"dummy":0); + ol.startParameterType(first,md->isObjCMethod()?"dummy":0); + + QRegExp re(")("),res("(.*\\*"); int vp=a->type.find(re); int wp=a->type.find(res); @@ -177,14 +132,33 @@ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n); } } + if (!md->isDefine()) { ol.endParameterType(); + } +} + +static void writeArgName(OutputList &ol, + ClassDef *cd, + MemberDef *md, + LockingPtr &defArgList, + QCString &cName, + const Argument *a, + const bool first, + const bool last, + const bool hasFuncPtrType) +{ + if (!md->isDefine()) + { ol.startParameterName(defArgList->count()<2); } + QRegExp re(")("),res("(.*\\*"); + int vp=a->type.find(re); + int wp=a->type.find(res); + if (hasFuncPtrType) - { - ol.docify(a->type.mid(wp,vp-wp)); + { ol.docify(a->type.mid(wp,vp-wp)); } if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name { @@ -210,6 +184,8 @@ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(), md->name(),a->type.right(a->type.length()-vp)); } + + if (!a->defval.isEmpty()) // write the default value { QCString n=a->defval; @@ -221,10 +197,93 @@ ol.endTypewriter(); } - a=defArgList->next(); + + + if (!a->suffixType.isEmpty()) + { + + linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(), a->suffixType, + a->suffixSpacer + a->suffixType); + } + + if (!last &&!md->isObjCMethod()) + ol.docify(", "); + + ol.endParameterName(last,(first && last),!md->isObjCMethod()); +} + + +static bool writeDefArgumentList(OutputList &ol,ClassDef *cd, + const QCString & /*scopeName*/,MemberDef *md) +{ + LockingPtr defArgList=(md->isDocsForDefinition()) ? + md->argumentList() : md->declArgumentList(); + //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition()); + if (defArgList==0 || md->isProperty()) + { + return FALSE; // member has no function like argument list + } + if (!md->isDefine()) ol.docify(" "); + + //printf("writeDefArgList(%d)\n",defArgList->count()); + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + { + // html + ol.endMemberDocName(); + ol.startParameterList(!md->isObjCMethod()); + } + ol.enableAll(); + ol.disable(OutputGenerator::Html); + { + // other formats + if (!md->isObjCMethod()) ol.docify("("); // start argument list + ol.endMemberDocName(); + } + ol.popGeneratorState(); + //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine()); + + Argument *a=defArgList->first(); + QCString cName; + if (cd) + { + cName=cd->name(); + int il=cName.find('<'); + int ir=cName.findRev('>'); + if (il!=-1 && ir!=-1 && ir>il) + { + cName=cName.mid(il,ir-il+1); + //printf("1. cName=%s\n",cName.data()); + } + else if (cd->templateArguments()) + { + cName=tempArgListToString(cd->templateArguments()); + //printf("2. cName=%s\n",cName.data()); + } + else // no template specifier + { + cName.resize(0); + } + } + //printf("~~~ %s cName=%s\n",md->name().data(),cName.data()); + + //if (!md->isDefine()) ol.startParameter(TRUE); else ol.docify(" "); + bool first=TRUE; + Argument *next = NULL; + while (a) + { + // ol.startParameter(first, md->isObjCMethod()?"dummy":0 ); + + next = defArgList->next(); + bool last = (next==0); + + writeArgType(ol,cd,md,defArgList,cName,a,first); + writeArgName(ol,cd,md,defArgList,cName,a, first, last, FALSE); + + a = next; if (a) { - if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments + if (!md->isDefine()) { QCString key; @@ -235,8 +294,6 @@ key=a->attrib.mid(1,a->attrib.length()-2); if (key!=",") key+=":"; // for normal keywords add colon } - ol.endParameterName(FALSE,FALSE,!md->isObjCMethod()); - ol.startParameterType(FALSE,key); } } first=FALSE; @@ -244,22 +301,29 @@ ol.pushGeneratorState(); bool htmlOn = ol.isEnabled(OutputGenerator::Html); ol.disable(OutputGenerator::Html); + //if (!first) ol.writeString(" "); if (!md->isObjCMethod()) ol.docify(")"); // end argument list ol.enableAll(); ol.disableAllBut(OutputGenerator::Html); if (!htmlOn) ol.disable(OutputGenerator::Html); + if (!md->isDefine()) { - if (first) ol.startParameterName(defArgList->count()<2); - ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod()); + if (first) + { + //ie, there were no parameters + ol.startParameterType(first,0); + ol.endParameterName(TRUE,TRUE,!md->isObjCMethod()); } + } else { ol.endParameterType(); ol.startParameterName(TRUE); ol.endParameterName(TRUE,TRUE,!md->isObjCMethod()); } + ol.popGeneratorState(); if (md->extraTypeChars()) { @@ -308,7 +372,8 @@ void init(Definition *def,const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberDef::MemberType mt,const ArgumentList *tal, - const ArgumentList *al + const ArgumentList *al, const ArgumentList *declAl, + const char *suffixSpacer, const char *suffixType ); ClassDef *classDef; // member of or related to @@ -410,6 +475,9 @@ bool docsForDefinition; // TRUE => documentation block is put before // definition. // FALSE => block is put before declaration. + + QCString suffixType; + QCString suffixSpacer; }; MemberDefImpl::MemberDefImpl() : @@ -442,7 +510,10 @@ const char *t,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r, MemberDef::MemberType mt,const ArgumentList *tal, - const ArgumentList *al + const ArgumentList *al, + const ArgumentList *declAl, + const char *sfxSpacer, + const char *sfxType ) { classDef=0; @@ -463,6 +534,7 @@ hasCallerGraph = FALSE; initLines=0; type=t; + if (mt==MemberDef::Typedef) type.stripPrefix("typedef "); // type.stripPrefix("struct "); // type.stripPrefix("class " ); @@ -470,8 +542,16 @@ type=removeRedundantWhiteSpace(type); args=a; args=removeRedundantWhiteSpace(args); - if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args; + suffixSpacer = sfxSpacer; + suffixType = sfxType; + + + if (type.isEmpty()) + decl = def->name()+args; + else + decl = type + " " + def->name()+args; + memberGroup=0; virt=v; prot=p; @@ -533,8 +613,16 @@ // convert function declaration arguments (if any) if (!args.isEmpty()) { - declArgList = new ArgumentList; + if (declAl) + { + declArgList = new ArgumentList(*declAl); + declArgList->setAutoDelete(FALSE); + } + else + { + declArgList = new ArgumentList(); stringToArgumentList(args,declArgList,&extraTypeChars); + } //printf("setDeclArgList %s to %s const=%d\n",args.data(), // argListToString(declArgList).data(),declArgList->constSpecifier); } @@ -578,20 +666,24 @@ * \param mt The kind of member. See #MemberDef::MemberType for a list of * all types. * \param tal The template arguments of this member. - * \param al The arguments of this member. This is a structured form of - * the string past as argument \a a. + * \param al The arguments of this member. + * \param declAl The arguments of the declaration of this member. This is a + * structured form of the string passed as argument \a a. + * \param suffixType The string representing the type of the member, where the type + * should appear as a suffix to the member's name. */ MemberDef::MemberDef(const char *df,int dl, const char *t,const char *na,const char *a,const char *e, Protection p,Specifier v,bool s,Relationship r,MemberType mt, - const ArgumentList *tal,const ArgumentList *al + const ArgumentList *tal,const ArgumentList *al, const ArgumentList *declAl, + const char *suffixSpacer,const char *suffixType ) : Definition(df,dl,removeRedundantWhiteSpace(na)) { m_storagePos=-1; m_cacheHandle=-1; m_impl = new MemberDefImpl; - m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al); + m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al, declAl,suffixSpacer, suffixType); m_flushPending = FALSE; } @@ -1067,6 +1159,102 @@ } + + +void MemberDef::writeSuffixType(OutputList &ol, Definition *d) +{ + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(), m_impl->suffixType, m_impl->suffixSpacer + m_impl->suffixType); + +} + + + +void MemberDef::writeType(OutputList &ol, + ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + ClassDef *annoClassDef, + Definition *d, + bool inGroup, + bool &endAnonScopeNeeded) + +{ + + QCString ltype(m_impl->type); + if (m_impl->mtype==Typedef) ltype.prepend("typedef "); + // strip `friend' keyword from ltype + ltype.stripPrefix("friend "); + static QRegExp r("@[0-9]+"); + + endAnonScopeNeeded=FALSE; + int l,i=r.match(ltype,0,&l); + if (i!=-1) // member has an anonymous type + { + //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n", + // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data()); + + if (annoClassDef) // type is an anonymous compound + { + int ir=i+l; + //printf("<<<<<<<<<<<<<<\n"); + ol.startAnonTypeScope(s_indentLevel++); + annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup); + //printf(">>>>>>>>>>>>>> startMemberItem(2)\n"); + ol.startMemberItem(2); + int j; + for (j=0;j< s_indentLevel-1;j++) + { + ol.writeNonBreakableSpace(3); + } + QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace(); + //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data()); + ol.docify("}"); + if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) + { + ol.docify(";"); + } + endAnonScopeNeeded=TRUE; + } + else + { + if (getAnonymousEnumType()) // type is an anonymous enum + { + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype.left(i),TRUE); + getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd); + //ol+=*getAnonymousEnumType()->enumDecl(); + linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); + } + else + { + ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l)); + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); + } + } + } + else if (ltype=="@") // rename type from enum values + { + ltype=""; + } + else + { + if (isObjCMethod()) + { + ltype.prepend("("); + ltype.append(")"); + } + linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); + } + bool htmlOn = ol.isEnabled(OutputGenerator::Html); + if (htmlOn && Config_getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty()) + { + ol.disable(OutputGenerator::Html); + } + if (!ltype.isEmpty()) ol.docify(" "); + if (htmlOn) + { + ol.enable(OutputGenerator::Html); + } +} + + void MemberDef::writeDeclaration(OutputList &ol, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, bool inGroup @@ -1195,81 +1383,11 @@ } // *** write type - QCString ltype(m_impl->type); - if (m_impl->mtype==Typedef) ltype.prepend("typedef "); - // strip `friend' keyword from ltype - ltype.stripPrefix("friend "); - static QRegExp r("@[0-9]+"); - bool endAnonScopeNeeded=FALSE; - int l,i=r.match(ltype,0,&l); - if (i!=-1) // member has an anonymous type - { - //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n", - // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data()); + writeType(ol, cd,nd,fd,gd,annoClassDef,d,inGroup,endAnonScopeNeeded); - if (annoClassDef) // type is an anonymous compound - { - int ir=i+l; - //printf("<<<<<<<<<<<<<<\n"); - ol.startAnonTypeScope(s_indentLevel++); - annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup); - //printf(">>>>>>>>>>>>>> startMemberItem(2)\n"); - ol.startMemberItem(2); - int j; - for (j=0;j< s_indentLevel-1;j++) - { - ol.writeNonBreakableSpace(3); - } - QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace(); - //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data()); - ol.docify("}"); - if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) - { - ol.docify(";"); - } - endAnonScopeNeeded=TRUE; - } - else - { - if (getAnonymousEnumType()) // type is an anonymous enum - { - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype.left(i),TRUE); - getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd); - //ol+=*getAnonymousEnumType()->enumDecl(); - linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); - } - else - { - ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l)); - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); - } - } - } - else if (ltype=="@") // rename type from enum values - { - ltype=""; - } - else - { - if (isObjCMethod()) - { - ltype.prepend("("); - ltype.append(")"); - } - linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); - } - bool htmlOn = ol.isEnabled(OutputGenerator::Html); - if (htmlOn && Config_getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty()) - { - ol.disable(OutputGenerator::Html); - } - if (!ltype.isEmpty()) ol.docify(" "); - if (htmlOn) - { - ol.enable(OutputGenerator::Html); - } + if (m_impl->annMemb) { ol.pushGeneratorState(); @@ -1367,6 +1485,11 @@ ol.docify(excpString()); } + if (!m_impl->suffixType.isEmpty()) + { + writeSuffixType(ol, d); + } + // *** write bitfields if (!m_impl->bitfields.isEmpty()) // add bitfields { @@ -1788,6 +1911,12 @@ hasParameterList=writeDefArgumentList(ol,cd,scopeName,this); } + if (!m_impl->suffixType.isEmpty()) + { + ol.startSuffix(); + writeSuffixType(ol,container); + ol.endSuffix(); + } if (hasOneLineInitializer()) // add initializer { if (!isDefine()) @@ -2547,7 +2676,8 @@ methodName, substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs), m_impl->exception, m_impl->prot, - m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0 + m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0, + 0,0,0 ); imd->setArgumentList(actualArgList); imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs)); @@ -3863,6 +3993,8 @@ marshalBool (Doxygen::symbolStorage,m_impl->tspec); marshalBool (Doxygen::symbolStorage,m_impl->groupHasDocs); marshalBool (Doxygen::symbolStorage,m_impl->docsForDefinition); + marshalQCString (Doxygen::symbolStorage,m_impl->suffixSpacer); + marshalQCString (Doxygen::symbolStorage,m_impl->suffixType); marshalUInt(Doxygen::symbolStorage,END_MARKER); // function doesn't modify the object conceptually but compiler doesn't know this. @@ -3963,6 +4095,9 @@ m_impl->tspec = unmarshalBool (Doxygen::symbolStorage); m_impl->groupHasDocs = unmarshalBool (Doxygen::symbolStorage); m_impl->docsForDefinition = unmarshalBool (Doxygen::symbolStorage); + m_impl->suffixSpacer = unmarshalQCString (Doxygen::symbolStorage); + m_impl->suffixType = unmarshalQCString (Doxygen::symbolStorage); + marker = unmarshalUInt(Doxygen::symbolStorage); assert(marker==END_MARKER); } Index: src/htmlgen.h =================================================================== --- src/htmlgen.h (revision 661) +++ src/htmlgen.h (working copy) @@ -224,6 +224,9 @@ void startParameterList(bool); void endParameterList(); + + void startSuffix(); + void endSuffix(); void startConstraintList(const char *); void startConstraintParam(); void endConstraintParam(); Index: src/marshal.cpp =================================================================== --- src/marshal.cpp (revision 661) +++ src/marshal.cpp (working copy) @@ -52,6 +52,24 @@ if (l>0) s->write(str.data(),l); } + + +void marshalArgument(StorageIntf *s, const Argument *a) +{ + marshalQCString(s,a->attrib); + marshalQCString(s,a->type); + marshalQCString(s,a->canType); + marshalQCString(s,a->name); + marshalQCString(s,a->array); + marshalQCString(s,a->defval); + marshalQCString(s,a->docs); + marshalQCString(s,a->suffixSpacer); + marshalQCString(s,a->suffixType); + +} + + + void marshalArgumentList(StorageIntf *s,ArgumentList *argList) { if (argList==0) @@ -67,13 +85,7 @@ Argument *a; for (ali.toFirst();(a=ali.current());++ali) { - marshalQCString(s,a->attrib); - marshalQCString(s,a->type); - marshalQCString(s,a->canType); - marshalQCString(s,a->name); - marshalQCString(s,a->array); - marshalQCString(s,a->defval); - marshalQCString(s,a->docs); + marshalArgument(s, a); } } marshalBool(s,argList->constSpecifier); @@ -82,6 +94,10 @@ } } + + + + void marshalArgumentLists(StorageIntf *s,QList *argLists) { if (argLists==0) @@ -381,6 +397,7 @@ marshalQCString(s,e->bitfields); marshalArgumentList(s,e->argList); marshalArgumentLists(s,e->tArgLists); + marshalArgumentList(s,e->declArgList); marshalQGString(s,e->program); marshalQGString(s,e->initializer); marshalQCString(s,e->includeFile); @@ -414,6 +431,9 @@ marshalBool(s,e->hidden); marshalBool(s,e->artificial); marshalInt(s,(int)e->groupDocType); + marshalQCString(s, e->suffixSpacer); + marshalQCString(s,e->suffixType); + } void marshalEntryTree(StorageIntf *s,Entry *e) @@ -484,6 +504,24 @@ return result; } + +Argument *unmarshalArgument(StorageIntf *s) +{ + Argument *a = new Argument; + a->attrib = unmarshalQCString(s); + a->type = unmarshalQCString(s); + a->canType = unmarshalQCString(s); + a->name = unmarshalQCString(s); + a->array = unmarshalQCString(s); + a->defval = unmarshalQCString(s); + a->docs = unmarshalQCString(s); + a->suffixSpacer = unmarshalQCString(s); + a->suffixType = unmarshalQCString(s); + return a; +} + + + ArgumentList *unmarshalArgumentList(StorageIntf *s) { uint i; @@ -494,14 +532,7 @@ //printf("unmarshalArgumentList: %d\n",count); for (i=0;iattrib = unmarshalQCString(s); - a->type = unmarshalQCString(s); - a->canType = unmarshalQCString(s); - a->name = unmarshalQCString(s); - a->array = unmarshalQCString(s); - a->defval = unmarshalQCString(s); - a->docs = unmarshalQCString(s); + Argument *a = unmarshalArgument(s); result->append(a); } result->constSpecifier = unmarshalBool(s); @@ -774,6 +805,8 @@ delete e->argList; e->argList = unmarshalArgumentList(s); e->tArgLists = unmarshalArgumentLists(s); + delete e->declArgList; + e->declArgList = unmarshalArgumentList(s); e->program = unmarshalQGString(s); e->initializer = unmarshalQGString(s); e->includeFile = unmarshalQCString(s); @@ -810,6 +843,8 @@ e->hidden = unmarshalBool(s); e->artificial = unmarshalBool(s); e->groupDocType = (Entry::GroupDocType)unmarshalInt(s); + e->suffixSpacer = unmarshalQCString(s); + e->suffixType = unmarshalQCString(s); return e; } Index: src/memberdef.h =================================================================== --- src/memberdef.h (revision 661) +++ src/memberdef.h (working copy) @@ -69,7 +69,8 @@ const char *type,const char *name,const char *args, const char *excp,Protection prot,Specifier virt,bool stat, Relationship related,MemberType t,const ArgumentList *tal, - const ArgumentList *al); + const ArgumentList *al, const ArgumentList *declAl, + const char *suffixSpacer, const char *suffixType); ~MemberDef(); DefType definitionType() const { return TypeMember; } @@ -363,6 +364,16 @@ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, bool onlyText=FALSE); + void writeType(OutputList &ol, + ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, + ClassDef *annoClassDef, + Definition *d, + bool inGroup, + bool &endAnonScopeNeeded); + + void writeSuffixType(OutputList &ol, Definition *d); + + MemberDefImpl *m_impl; int m_cacheHandle; off_t m_storagePos; // location where the item is stored in file (if impl==0)