diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2004-03-07 21:00:29 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2004-03-07 21:00:29 (GMT) |
commit | f12fe31aed103718f5d4c368473302cc6ac82a47 (patch) | |
tree | ecc570be1c038ecdb55dda6d9ffe794945151261 /src | |
parent | 5edb3c85109d09e5fa43529bf8b584382f7501a5 (diff) | |
download | Doxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.zip Doxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.tar.gz Doxygen-f12fe31aed103718f5d4c368473302cc6ac82a47.tar.bz2 |
Release-1.3.6-20040307
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 9 | ||||
-rw-r--r-- | src/code.l | 176 | ||||
-rw-r--r-- | src/commentcnv.l | 7 | ||||
-rw-r--r-- | src/config.l | 8 | ||||
-rw-r--r-- | src/definition.cpp | 10 | ||||
-rw-r--r-- | src/docparser.cpp | 5 | ||||
-rw-r--r-- | src/dot.cpp | 2 | ||||
-rw-r--r-- | src/doxygen.cpp | 101 | ||||
-rw-r--r-- | src/entry.h | 4 | ||||
-rw-r--r-- | src/htmlgen.cpp | 14 | ||||
-rw-r--r-- | src/htmlgen.h | 2 | ||||
-rw-r--r-- | src/index.cpp | 3 | ||||
-rw-r--r-- | src/latexgen.h | 2 | ||||
-rw-r--r-- | src/mangen.h | 2 | ||||
-rw-r--r-- | src/memberdef.cpp | 26 | ||||
-rw-r--r-- | src/memberdef.h | 8 | ||||
-rw-r--r-- | src/outputgen.h | 2 | ||||
-rw-r--r-- | src/outputlist.cpp | 1 | ||||
-rw-r--r-- | src/outputlist.h | 5 | ||||
-rw-r--r-- | src/pre.l | 38 | ||||
-rw-r--r-- | src/rtfgen.h | 2 | ||||
-rw-r--r-- | src/scanner.l | 39 | ||||
-rw-r--r-- | src/translator_nl.h | 5 | ||||
-rw-r--r-- | src/util.cpp | 14 | ||||
-rw-r--r-- | src/util.h | 1 |
25 files changed, 391 insertions, 95 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index ffc6779..7721925 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -1371,10 +1371,10 @@ void ClassDef::writeDocumentation(OutputList &ol) // write the list of used files (not for man pages) ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); if (Config_getBool("SHOW_USED_FILES")) { - ol.disable(OutputGenerator::Man); ol.writeRuler(); ol.parseText(theTranslator->trGeneratedFromFiles( m_isObjC && m_compType==Interface ? Class : m_compType, @@ -1633,7 +1633,7 @@ void ClassDef::writeMemberList(OutputList &ol) ol.writeString("<td>"); } if ( - (prot!=Public || virt!=Normal || + (prot!=Public || (virt!=Normal && !m_isObjC) || md->isFriend() || md->isRelated() || md->isExplicit() || md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) || md->isSignal() || md->isSlot() || @@ -1655,7 +1655,8 @@ void ClassDef::writeMemberList(OutputList &ol) if (prot==Protected) sl.append("protected"); else if (prot==Private) sl.append("private"); else if (prot==Package) sl.append("package"); - if (virt==Virtual) sl.append("virtual"); + if (virt==Virtual && + !m_isObjC) sl.append("virtual"); else if (virt==Pure) sl.append("pure virtual"); if (md->isStatic()) sl.append("static"); if (md->isSignal()) sl.append("signal"); @@ -2572,7 +2573,7 @@ ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName, ClassDef *templateClass=m_templateInstances->find(templSpec); if (templateClass==0) { - Debug::print(Debug::Classes,0," New template instance class %s%s\n",name().data(),templSpec.data()); + Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data()); templateClass = new ClassDef( fileName,startLine,name()+templSpec,ClassDef::Class); templateClass->setTemplateMaster(this); @@ -103,6 +103,8 @@ static int g_lastVerbStringContext; static int g_memCallContext; static int g_lastCContext; +static bool g_insideObjC; + //------------------------------------------------------------------- /*! Represents a stack of variable to class mappings as found in the @@ -860,6 +862,8 @@ static bool generateClassMemberLink(BaseCodeDocInterface &ol,ClassDef *mcd,const if (xd) { + //printf("g_currentDefiniton=%p g_currentMemberDef=%p xmd=%p g_insideBody=%d\n",g_currentDefinition,g_currentMemberDef,xmd,g_insideBody); + // add usage reference if (g_currentDefinition && g_currentMemberDef && xmd!=g_currentMemberDef && g_insideBody) @@ -1080,7 +1084,7 @@ TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" SCOPETNAME ((({ID}{TEMPLIST}?){BN}*"::"{BN}*)*)((~{BN}*)?{ID}) SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*"::"{BN}*)+ KEYWORD_OBJC ("@public"|"@private"|"@protected"|"@class"|"@implementation"|"@interface"|"@end"|"@selector"|"@protocol") -KEYWORD ("asm"|"auto"|"class"|"const"|"const_cast"|"delete"|"dynamic_cast"|"enum"|"explicit"|"extern"|"false"|"friend"|"inline"|"mutable"|"namespace"|"new"|"operator"|"private"|"protected"|"public"|"register"|"reinterpret_cast"|"sizeof"|"static"|"static_cast"|"struct"|"template"|"this"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|KEYWORD_OBJC) +KEYWORD ("asm"|"auto"|"class"|"const"|"const_cast"|"delete"|"dynamic_cast"|"enum"|"explicit"|"extern"|"false"|"friend"|"inline"|"mutable"|"namespace"|"new"|"operator"|"private"|"protected"|"public"|"register"|"reinterpret_cast"|"sizeof"|"static"|"static_cast"|"struct"|"template"|"this"|"self"|"true"|"typedef"|"typeid"|"typename"|"union"|"using"|"virtual"|"volatile"|"abstract"|"final"|"import"|"synchronized"|"transient"|KEYWORD_OBJC) FLOWKW ("break"|"case"|"catch"|"continue"|"default"|"do"|"else"|"for"|"goto"|"if"|"return"|"switch"|"throw"|"throws"|"try"|"while") TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned"|"void"|"wchar_t"|"boolean"|"id"|"SEL") @@ -1106,6 +1110,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" %x ReadInclude %x TemplDecl %x CallEnd +%x ObjCMethod +%x ObjCParams +%x ObjCParamType +%x ObjCMemberCall +%x ObjCMemberCall2 +%x ObjCMemberCall3 %% @@ -1115,7 +1125,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_code->codify(yytext); BEGIN( ReadInclude ); } -<Body>("class"|"struct"|"union"|"namespace"|"@interface"|"@implementation"|"@interface")[ \t\n]+ { +<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ { + g_insideObjC=TRUE; + startFontClass("keyword"); + codifyLines(yytext); + endFontClass(); + if (!g_insideTemplate) + BEGIN( ClassName ); + } +<Body>("class"|"struct"|"union"|"namespace")[ \t\n]+ { startFontClass("keyword"); codifyLines(yytext); endFontClass(); @@ -1128,6 +1146,63 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" endFontClass(); BEGIN( PackageName ); } +<Body,ClassVar>"-"|"+" { + if (!g_insideObjC) + { + g_code->codify(yytext); + } + else // Start of Objective-C method + { + //printf("Method!\n"); + g_code->codify(yytext); + BEGIN(ObjCMethod); + } + } +<ObjCMethod>":" { + g_code->codify(yytext); + BEGIN(ObjCParams); + } +<ObjCParams>"(" { + g_code->codify(yytext); + BEGIN(ObjCParamType); + } +<ObjCParams,ObjCMethod>";"|"{" { + g_code->codify(yytext); + if (*yytext=='{') + { + g_insideBody=TRUE; + } + BEGIN(Body); + } +<ObjCParams>{ID}{B}*":" { + g_code->codify(yytext); + } +<ObjCParamType>{TYPEKW} { + startFontClass("keywordtype"); + g_code->codify(yytext); + endFontClass(); + g_parmType=yytext; + } +<ObjCParamType>{ID} { + g_code->codify(yytext); + g_parmType=yytext; + } +<ObjCParamType>")" { + g_code->codify(yytext); + BEGIN(ObjCParams); + } +<ObjCParams>{ID} { + g_code->codify(yytext); + g_parmName=yytext; + g_theVarContext.addVariable(g_parmType,g_parmName); + g_parmType.resize(0);g_parmName.resize(0); + } +<ObjCMethod,ObjCParams,ObjCParamType>. { + g_code->codify(yytext); + } +<ObjCMethod,ObjCParams,ObjCParamType>\n { + codifyLines(yytext); + } <ReadInclude>[^\n\"\>]+/(">"|"\"") { //FileInfo *f; bool ambig; @@ -1239,6 +1314,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" BEGIN(Body); } <Body>"@end" { + //printf("End of objc scope fd=%s\n",g_sourceFileDef->name().data()); + if (g_sourceFileDef) + { + FileDef *fd=g_sourceFileDef; + g_insideObjC = fd->name().lower().right(2)==".m" || + fd->name().lower().right(3)==".mm"; + //printf("insideObjC=%d\n",g_insideObjC); + } + else + { + g_insideObjC = FALSE; + } g_theVarContext.popScope(); int *scope = g_scopeStack.pop(); @@ -1458,7 +1545,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_theCallContext.popScope(); } } -<Body,TemplDecl>{TYPEKW}/{B}* { +<Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* { startFontClass("keywordtype"); g_code->codify(yytext); endFontClass(); @@ -1516,7 +1603,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_name+=yytext; BEGIN( FuncCall ); } -<FuncCall,Body,MemberCall,MemberCall2>\" { +<FuncCall,Body,MemberCall,MemberCall2,ObjCMemberCall2,ObjCMemberCall3>\" { startFontClass("stringliteral"); g_code->codify(yytext); g_lastStringContext=YY_START; @@ -1638,27 +1725,82 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" BEGIN(g_memCallContext); } <Body>[,=;\[] { - g_code->codify(yytext); - g_saveName = g_name.copy(); - g_saveType = g_type.copy(); - if (!g_type.isEmpty()) + if (g_insideObjC && *yytext=='[') + { + //printf("Found start of ObjC call!\n"); + // start of a method call + g_code->codify(yytext); + g_theCallContext.pushScope(); + BEGIN(ObjCMemberCall); + } + else { - if (g_scopeStack.top()!=CLASSBLOCK) + g_code->codify(yytext); + g_saveName = g_name.copy(); + g_saveType = g_type.copy(); + if (!g_type.isEmpty()) + { + if (g_scopeStack.top()!=CLASSBLOCK) + { + g_theVarContext.addVariable(g_type,g_name); + } + g_name.resize(0); + } + if (*yytext==';') { - g_theVarContext.addVariable(g_type,g_name); + g_type.resize(0); + g_name.resize(0); } - g_name.resize(0); + else if (*yytext=='[') + { + g_theCallContext.pushScope(); + } + g_args.resize(0); } - if (*yytext==';') + } +<ObjCMemberCall>{ID} { + if (strcmp(yytext,"self")==0 || strcmp(yytext,"super")==0) { - g_type.resize(0); - g_name.resize(0); + // TODO: get proper base class for "super" + g_theCallContext.setClass(getClass(g_curClassName)); + startFontClass("keyword"); + g_code->codify(yytext); + endFontClass(); } - else if (*yytext=='[') + else { + generateClassOrGlobalLink(*g_code,yytext); + } + g_name.resize(0); + BEGIN(ObjCMemberCall2); + } +<ObjCMemberCall>"[" { + g_code->codify(yytext); g_theCallContext.pushScope(); + } +<ObjCMemberCall2>{ID}":"? { + g_name+=yytext; + if (g_theCallContext.getClass()) + { + //printf("Calling method %s\n",g_name.data()); + if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),g_name)) + { + g_code->codify(yytext); + addToSearchIndex(g_name); + } } - g_args.resize(0); + else + { + g_code->codify(yytext); + addToSearchIndex(g_name); + } + g_name.resize(0); + BEGIN(ObjCMemberCall3); + } +<ObjCMemberCall2,ObjCMemberCall3>"]" { + g_theCallContext.popScope(); + g_code->codify(yytext); + BEGIN(Body); } <Body>"]" { g_theCallContext.popScope(); @@ -2215,6 +2357,8 @@ void parseCode(BaseCodeDocInterface &od,const char *className,const QCString &s, if (fd) { setCurrentDoc(fd->name(),fd->getSourceFileBase()); + g_insideObjC = fd->name().lower().right(2)==".m" || + fd->name().lower().right(3)==".mm"; } g_currentDefinition = 0; g_currentMemberDef = 0; diff --git a/src/commentcnv.l b/src/commentcnv.l index 668e2e9..7e7d6a4 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -112,6 +112,8 @@ void replaceComment(int offset); %} +CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^' \\\n]{1,4}"'")) + %option noyywrap %x Scan @@ -123,13 +125,16 @@ void replaceComment(int offset); %% -<Scan>[^\"\/\n\\]* { /* eat anything that is not " / or \n */ +<Scan>[^"'\/\n\\]* { /* eat anything that is not " / or \n */ copyToOutput(yytext,yyleng); } <Scan>"\"" { /* start of a string */ copyToOutput(yytext,yyleng); BEGIN(SkipString); } +<Scan>{CHARLIT} { + copyToOutput(yytext,yyleng); + } <Scan>\n { /* new line */ copyToOutput(yytext,yyleng); } diff --git a/src/config.l b/src/config.l index 7c1cc28..faee601 100644 --- a/src/config.l +++ b/src/config.l @@ -1608,6 +1608,14 @@ void Config::create() TRUE ); cb = addBool( + "EXTRACT_LOCAL_METHODS", + "This flag is only useful for Objective-C code. When set to YES local \n" + "methods, which are defined in the implementation section but not in \n" + "the interface are included in the documentation. \n" + "If set to NO (the default) only methods in the interface are included. \n", + FALSE + ); + cb = addBool( "HIDE_UNDOC_MEMBERS", "If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n" "undocumented members of documented classes, files or namespaces. \n" diff --git a/src/definition.cpp b/src/definition.cpp index ac18ebe..a99549b 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -39,7 +39,7 @@ static void addToMap(const char *name,Definition *d) { QCString symbolName = name; - int index=symbolName.findRev("::"); + int index=computeQualifiedIndex(symbolName); if (index!=-1) symbolName=symbolName.mid(index+2); if (!symbolName.isEmpty()) { @@ -58,7 +58,7 @@ static void addToMap(const char *name,Definition *d) static void removeFromMap(Definition *d) { QCString symbolName = d->symbolName(); - int index=symbolName.findRev("::"); + int index=computeQualifiedIndex(symbolName); if (index!=-1) symbolName=symbolName.mid(index+2); if (!symbolName.isEmpty()) { @@ -512,8 +512,10 @@ void Definition::writeSourceRefList(OutputList &ol,const char *scopeName, name.prepend(scope+"::"); } } - if (md->isFunction() || md->isSlot() || - md->isPrototype() || md->isSignal() + if (!md->isObjCMethod() && + (md->isFunction() || md->isSlot() || + md->isPrototype() || md->isSignal() + ) ) name+="()"; //Definition *d = md->getOutputFileBase(); //if (d==Doxygen::globalScope) d=md->getBodyDef(); diff --git a/src/docparser.cpp b/src/docparser.cpp index 703ed07..645a8f9 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -252,13 +252,14 @@ static void checkArgumentName(const QString &name,bool isParam) while ((i=re.match(name,p,&l))!=-1) { QString aName=name.mid(i,l); - //printf("aName=%s\n",aName.data()); + //printf("aName=`%s'\n",aName.data()); ArgumentListIterator ali(*al); Argument *a; bool found=FALSE; for (ali.toFirst();(a=ali.current());++ali) { QString argName = g_memberDef->isDefine() ? a->type : a->name; + //printf("argName=`%s'\n",argName.data()); if (argName.right(3)=="...") argName=argName.left(argName.length()-3); if (aName==argName) { @@ -4085,6 +4086,8 @@ int DocPara::handleHtmlStartTag(const QString &tagName,const HtmlAttribList &tag break; case HTML_UNKNOWN: warn_doc_error(g_fileName,doctokenizerYYlineno,"Warning: Unsupported html tag <%s> found", tagName.data()); + m_children.append(new DocWord(this, "<"+tagName+">")); + break; break; default: // we should not get here! diff --git a/src/dot.cpp b/src/dot.cpp index d7de2db..86ef71e 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -486,7 +486,7 @@ static void writeBoxMemberList(QTextStream &t,char prot,MemberList &ml,ClassDef if (mma->getClassDef() == scope) { t << prot << " " << convertLabel(mma->name()); - if (mma->isFunction()) t << "()"; + if (!mma->isObjCMethod() && mma->isFunction()) t << "()"; t << "\\l"; } } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index bf1cbc9..fbfc687 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -187,6 +187,11 @@ void statistics() static void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, ArgumentList *al,bool over_load,NamespaceSDict *nl=0); +static void findMember(Entry *root, + QCString funcDecl, + bool overloaded, + bool isFunc + ); const char idMask[] = "[A-Za-z_][A-Za-z_0-9]*"; QCString spaces; @@ -2914,7 +2919,7 @@ static QDict<int> *getTemplateArgumentsInName(ArgumentList *templateArguments,co { QDict<int> *templateNames = new QDict<int>(17); templateNames->setAutoDelete(TRUE); - static QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); + static QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); if (templateArguments) { ArgumentListIterator ali(*templateArguments); @@ -3108,12 +3113,7 @@ static void findUsedClassesForClass(Entry *root, } // add any template arguments to the class QCString usedName = usedClassName+templSpec; - - //if (!typeName.isEmpty()) - //{ - // usedName=typeName; - //} - //printf("usedName=`%s'\n",usedName.data()); + //printf("usedName=%s\n",usedName.data()); bool delTempNames=FALSE; if (templateNames==0) @@ -3147,7 +3147,7 @@ static void findUsedClassesForClass(Entry *root, if (usedCd) { if (isArtificial) usedCd->setClassIsArtificial(); - Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data()); + Debug::print(Debug::Classes,0," Adding used class `%s' (1)\n", usedCd->name().data()); instanceCd->addUsedClass(usedCd,md->name()); usedCd->addUsedByClass(instanceCd,md->name()); } @@ -3160,10 +3160,10 @@ static void findUsedClassesForClass(Entry *root, ClassDef *usedCd=findClassWithinClassContext(masterCd,usedName); //printf("Looking for used class: result=%p master=%p\n",usedCd,masterCd); - if (usedCd /*&& usedCd!=masterCd*/) + if (usedCd) { found=TRUE; - Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data()); + Debug::print(Debug::Classes,0," Adding used class `%s' (2)\n", usedCd->name().data()); instanceCd->addUsedClass(usedCd,md->name()); // class exists usedCd->addUsedByClass(instanceCd,md->name()); } @@ -3192,7 +3192,7 @@ static void findUsedClassesForClass(Entry *root, if (usedCd) { if (isArtificial) usedCd->setClassIsArtificial(); - Debug::print(Debug::Classes,0," Adding used class `%s'\n", usedCd->name().data()); + Debug::print(Debug::Classes,0," Adding used class `%s' (3)\n", usedCd->name().data()); instanceCd->addUsedClass(usedCd,md->name()); usedCd->addUsedByClass(instanceCd,md->name()); } @@ -3297,6 +3297,7 @@ static bool findTemplateInstanceRelation(Entry *root, if (freshInstance) { + Debug::print(Debug::Classes,0," found fresh instance!\n"); Doxygen::classSDict.append(instanceClass->name(),instanceClass); instanceClass->setTemplateBaseClassNames(templateNames); @@ -3305,6 +3306,7 @@ static bool findTemplateInstanceRelation(Entry *root, Entry *templateRoot = classEntries.find(templateClass->name()); if (templateRoot) { + Debug::print(Debug::Classes,0," template root found %s!\n",templateRoot->name.data()); ArgumentList *templArgs = new ArgumentList; stringToArgumentList(templSpec,templArgs); findBaseClassesForClass(templateRoot,templateClass,instanceClass, @@ -3316,12 +3318,17 @@ static bool findTemplateInstanceRelation(Entry *root, } else { + Debug::print(Debug::Classes,0," no template root entry found!\n"); // TODO: what happened if we get here? } //Debug::print(Debug::Classes,0," Template instance %s : \n",instanceClass->name().data()); //ArgumentList *tl = templateClass->templateArguments(); } + else + { + Debug::print(Debug::Classes,0," instance already exists!\n"); + } return TRUE; } @@ -4199,11 +4206,8 @@ static bool findGlobalMember(Entry *root, } else // got docs for an undefined member! { - if (root->parent && root->parent->section==Entry::OBJCIMPL_SEC) - { - // probably a local member ObjC method not found in the interface - } - else + if (root->type!="friend class" && root->type!="friend struct" && + root->type!="friend union") { warn(root->fileName,root->startLine, "Warning: documented function `%s' was not defined.",decl @@ -4389,8 +4393,8 @@ static void findMember(Entry *root, funcArgs,funcTempList,exceptions ); } - //printf("scopeName=`%s' funcType=`%s' funcName=`%s'\n", - // scopeName.data(),funcType.data(),funcName.data()); + //printf("scopeName=`%s' funcType=`%s' funcName=`%s' funcArgs=`%s'\n", + // scopeName.data(),funcType.data(),funcName.data(),funcArgs.data()); // the class name can also be a namespace name, we decide this later. // if a related class name is specified and the class name could @@ -4751,9 +4755,11 @@ static void findMember(Entry *root, delete nl; } } - if (count==0 && !(isFriend && funcType=="class") && - (root->parent==0 || root->parent->section!=Entry::OBJCIMPL_SEC) - ) + if (count==0 && root->parent && root->parent->section==Entry::OBJCIMPL_SEC) + { + goto localObjCMethod; + } + if (count==0 && !(isFriend && funcType=="class")) { int candidates=0; if (mn->count()>0) @@ -5050,6 +5056,59 @@ static void findMember(Entry *root, ); } } + else if (root->parent && root->parent->section==Entry::OBJCIMPL_SEC) + { +localObjCMethod: + ClassDef *cd; + //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + if (Config_getBool("EXTRACT_LOCAL_METHODS") && (cd=getClass(scopeName))) + { + bool ambig; + //printf("Local objective C method `%s' of class `%s' found\n",root->name.data(),cd->name().data()); + MemberDef *md=new MemberDef( + root->fileName,root->startLine, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,FALSE, + MemberDef::Function,0,root->argList); + if (root->tagInfo) + { + md->setAnchor(root->tagInfo->anchor); + md->setReference(root->tagInfo->tagName); + } + md->makeImplementationDetail(); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->bodyLine,root->endBodyLine); + FileDef *fd=findFileDef(Doxygen::inputNameDict,root->fileName,ambig); + md->setBodyDef(fd); + md->setMemberSpecifiers(root->memSpec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md); + cd->insertUsedFile(root->fileName); + md->setRefItems(root->sli); + if ((mn=Doxygen::memberNameSDict[root->name])) + { + mn->append(md); + } + else + { + mn = new MemberName(root->name); + mn->append(md); + Doxygen::memberNameSDict.append(root->name,mn); + } + } + else + { + // local objective C method found for class without interface + } + } else // unrelated not overloaded member found { bool globMem = findGlobalMember(root,namespaceName,funcName,funcTempList,funcArgs,funcDecl); diff --git a/src/entry.h b/src/entry.h index 44504fc..4670a48 100644 --- a/src/entry.h +++ b/src/entry.h @@ -237,7 +237,9 @@ class Entry Explicit = 0x02, Mutable = 0x04, Settable = 0x08, - Gettable = 0x10 + Gettable = 0x10, + Readable = 0x20, + Writable = 0x40 }; Entry(); diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 30d9a5c..66ecb52 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -37,8 +37,8 @@ // #define GROUP_COLOR "#ff8080" -//#define DBG_HTML(x) x; -#define DBG_HTML(x) +#define DBG_HTML(x) x; +//#define DBG_HTML(x) static const char *defaultStyleSheet = "H1 {\n" @@ -1069,7 +1069,7 @@ void HtmlGenerator::startParameterName(bool oneArgOnly) t << "\" nowrap>"; // "; } -void HtmlGenerator::endParameterName(bool last,bool emptyList) +void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket) { DBG_HTML(t << "<!-- endParameterName -->" << endl;) if (last) @@ -1077,7 +1077,9 @@ void HtmlGenerator::endParameterName(bool last,bool emptyList) if (emptyList) { t << " </td>" << endl; - t << " <td class=\"md\" valign=\"top\"> ) </td>" << endl; + t << " <td class=\"md\" valign=\"top\">"; + if (closeBracket) t << " )"; + t << " </td>" << endl; t << " <td class=\"md\" nowrap>"; } else @@ -1086,7 +1088,9 @@ void HtmlGenerator::endParameterName(bool last,bool emptyList) t << " </tr>" << endl; t << " <tr>" << endl; t << " <td></td>" << endl; - t << " <td class=\"md\">) </td>" << endl; + t << " <td class=\"md\">"; + if (closeBracket) t << ")"; + t << " </td>" << endl; t << " <td class=\"md\" colspan=\"2\">"; } } diff --git a/src/htmlgen.h b/src/htmlgen.h index 4c303d6..b832b35 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -200,7 +200,7 @@ class HtmlGenerator : public OutputGenerator void startParameterType(bool first,const char *key); void endParameterType(); void startParameterName(bool); - void endParameterName(bool last,bool emptyList); + void endParameterName(bool last,bool emptyList,bool closeBracket); void startParameterList(bool); void endParameterList(); diff --git a/src/index.cpp b/src/index.cpp index fa080ac..ecbf8dd 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1650,7 +1650,8 @@ void writeMemberList(OutputList &ol,bool useSections,ClassMemberHighlight filter ) { found=TRUE; - isFunc=md->isFunction() || md->isSlot() || md->isSignal(); + isFunc=!md->isObjCMethod() && + (md->isFunction() || md->isSlot() || md->isSignal()); } md=mn->next(); } diff --git a/src/latexgen.h b/src/latexgen.h index 2ec1563..9272290 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -275,7 +275,7 @@ class LatexGenerator : public OutputGenerator void startParameterType(bool,const char *) {} void endParameterType() {} void startParameterName(bool) {} - void endParameterName(bool,bool) {} + void endParameterName(bool,bool,bool) {} void startParameterList(bool) {} void endParameterList() {} diff --git a/src/mangen.h b/src/mangen.h index a830a32..c9abef4 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -242,7 +242,7 @@ class ManGenerator : public OutputGenerator void startParameterType(bool,const char *) {} void endParameterType() {} void startParameterName(bool) {} - void endParameterName(bool,bool) {} + void endParameterName(bool,bool,bool) {} void startParameterList(bool) {} void endParameterList() {} diff --git a/src/memberdef.cpp b/src/memberdef.cpp index c47ab09..dfc0685 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -33,8 +33,6 @@ #include "docparser.h" #include "dot.h" #include "searchindex.h" -//#include "xml.h" - //----------------------------------------------------------------------------- @@ -197,7 +195,7 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd, key=a->attrib.mid(1,a->attrib.length()-2); if (key!=",") key+=":"; // for normal keywords add colon } - ol.endParameterName(FALSE,FALSE); + ol.endParameterName(FALSE,FALSE,!md->isObjCMethod()); ol.startParameterType(FALSE,key); } } @@ -212,13 +210,13 @@ static void writeDefArgumentList(OutputList &ol,ClassDef *cd, if (!md->isDefine()) { if (first) ol.startParameterName(defArgList->count()<2); - ol.endParameterName(!md->isObjCMethod(),defArgList->count()<2); + ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod()); } else { ol.endParameterType(); ol.startParameterName(TRUE); - ol.endParameterName(TRUE,TRUE); + ol.endParameterName(TRUE,TRUE,!md->isObjCMethod()); } ol.popGeneratorState(); if (defArgList->constSpecifier) @@ -391,6 +389,7 @@ MemberDef::MemberDef(const char *df,int dl, m_isTypedefValCached = FALSE; m_cachedTypedefValue = 0; m_inbodyLine = -1; + m_implOnly=FALSE; } /*! Destroys the member definition. */ @@ -1047,6 +1046,12 @@ void MemberDef::writeDeclaration(OutputList &ol, linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),init); } } + if (isObjCMethod() && isImplementation()) + { + ol.startTypewriter(); + ol.docify(" [implementation]"); + ol.endTypewriter(); + } if (!detailsVisible && !annMemb) { @@ -1385,7 +1390,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, isMutable() || (isInline() && Config_getBool("INLINE_INFO")) || isSignal() || isSlot() || isStatic() || (classDef && classDef!=container) || - isSettable() || isGettable() + isSettable() || isGettable() || isReadable() || isWritable() ) ) { @@ -1405,6 +1410,8 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, if (isStatic()) sl.append("static"); if (isGettable()) sl.append("get"); if (isSettable()) sl.append("set"); + if (isReadable()) sl.append("read"); + if (isWritable()) sl.append("write"); if (protection()==Protected) sl.append("protected"); else if (protection()==Private) sl.append("private"); else if (protection()==Package) sl.append("package"); @@ -1424,6 +1431,13 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ol.docify("]"); ol.endTypewriter(); } + else if (isObjCMethod() && isImplementation()) + { + ol.writeLatexSpacing(); + ol.startTypewriter(); + ol.docify(" [implementation]"); + ol.endTypewriter(); + } if (!isDefine() && defArgList) ol.endParameterList(); ol.endMemberDoc(); ol.endDoxyAnchor(cfname,anchor()); diff --git a/src/memberdef.h b/src/memberdef.h index b3dc90f..e880a12 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -125,6 +125,9 @@ class MemberDef : public Definition bool isMutable() const { return (memSpec&Entry::Mutable)!=0; } bool isGettable() const { return (memSpec&Entry::Gettable)!=0; } bool isSettable() const { return (memSpec&Entry::Settable)!=0; } + bool isReadable() const { return (memSpec&Entry::Readable)!=0; } + bool isWritable() const { return (memSpec&Entry::Writable)!=0; } + bool isImplementation() const { return m_implOnly; } bool isExternal() const { return explExt; } bool isObjCMethod() const; bool isConstructor() const; @@ -229,6 +232,7 @@ class MemberDef : public Definition MemberGroup *getMemberGroup() const { return memberGroup; } void setMemberGroupId(int id) { grpId=id; } int getMemberGroupId() const { return grpId; } + void makeImplementationDetail() { m_implOnly=TRUE; } // anonymous scope members void setFromAnonymousScope(bool b) { annScope=b; } @@ -360,6 +364,10 @@ class MemberDef : public Definition int m_inbodyLine; QCString m_inbodyFile; QCString m_inbodyDocs; + + // objective-c + bool m_implOnly; // function found in implementation but not + // in the interface }; #endif diff --git a/src/outputgen.h b/src/outputgen.h index cb85446..980dfdf 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -351,7 +351,7 @@ class OutputGenerator : public BaseOutputDocInterface virtual void startParameterType(bool,const char *) = 0; virtual void endParameterType() = 0; virtual void startParameterName(bool) = 0; - virtual void endParameterName(bool,bool) = 0; + virtual void endParameterName(bool,bool,bool) = 0; virtual void startParameterList(bool) = 0; virtual void endParameterList() = 0; diff --git a/src/outputlist.cpp b/src/outputlist.cpp index fbacc76..eaa7811 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -269,6 +269,7 @@ FORALL1(SectionTypes a1,a1) FORALL1(bool a1,a1) FORALL2(bool a1,int a2,a1,a2) FORALL2(bool a1,bool a2,a1,a2) +FORALL3(bool a1,bool a2,bool a3,a1,a2,a3) FORALL4(const char *a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4) #endif FORALL2(int a1,bool a2,a1,a2) diff --git a/src/outputlist.h b/src/outputlist.h index 86600df..52fc346 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -339,8 +339,8 @@ class OutputList : public OutputDocInterface { forall(&OutputGenerator::endParameterType); } void startParameterName(bool one) { forall(&OutputGenerator::startParameterName,one); } - void endParameterName(bool last,bool one) - { forall(&OutputGenerator::endParameterName,last,one); } + void endParameterName(bool last,bool one,bool bracket) + { forall(&OutputGenerator::endParameterName,last,one,bracket); } void startParameterList(bool openBracket) { forall(&OutputGenerator::startParameterList,openBracket); } void endParameterList() @@ -388,6 +388,7 @@ class OutputList : public OutputDocInterface FORALLPROTO1(bool); FORALLPROTO2(bool,int); FORALLPROTO2(bool,bool); + FORALLPROTO3(bool,bool,bool); FORALLPROTO4(const char *,const char *,const char *,int); #endif FORALLPROTO2(int,bool); @@ -397,6 +397,18 @@ static void returnCharToStream(char c) unput(c); } +static inline void addTillEndOfString(const QCString &expr,QCString *rest, + uint &pos,char term,QCString &arg) +{ + char cc; + while ((cc=getNextChar(expr,rest,pos))!=EOF) + { + if (cc=='\\') arg+=cc,cc=getNextChar(expr,rest,pos); + else if (cc==term) return; + arg+=cc; + } +} + /*! replaces the function macro \a def whose argument list starts at * \a pos in expression \a expr. * Notice that this routine may scan beyond the \a expr string if needed. @@ -449,28 +461,23 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int { int level=1; arg+=c; - char term='\0'; + //char term='\0'; while ((cc=getNextChar(expr,rest,j))!=EOF) { char c=(char)cc; + //printf("processing %c: term=%c (%d)\n",c,term,term); if (c=='\'' || c=='\"') // skip ('s and )'s inside strings { - if (term!='\0') - { - if (c==term && expr.at(j-2)!='\\') term='\0'; - } - else - { - term=c; - } + arg+=c; + addTillEndOfString(expr,rest,j,c,arg); } - if (term=='\0' && c==')') + if (c==')') { level--; arg+=c; if (level==0) break; } - else if (term=='\0' && c=='(') + else if (c=='(') { level++; arg+=c; @@ -625,7 +632,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int { inString=TRUE; // entering a literal string } - else if (inString && d.at(k)=='\"' && d.at(k-1)!='\\') + else if (inString && d.at(k)=='\"' && (d.at(k-1)!='\\' || d.at(k-2)=='\\')) { inString=FALSE; // leaving a literal string } @@ -665,10 +672,12 @@ static int getNextId(const QCString &expr,int p,int *l) } else if (c=='"') // skip string { - char pc=c; + char ppc=0,pc=c; if (p<(int)expr.length()) c=expr.at(p); - while (p<(int)expr.length() && (c!='"' || pc=='\\')) + while (p<(int)expr.length() && (c!='"' || (pc=='\\' && ppc!='\\'))) + // continue as long as no " is found, but ignoring \", but not \\" { + ppc=pc; pc=c; c=expr.at(p); p++; @@ -1189,6 +1198,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) Define *def=0; if (skipFuncMacros && + name!="Q_PROPERTY" && !( (g_includeStack.isEmpty() || g_curlyCount>0) && g_macroExpansion && diff --git a/src/rtfgen.h b/src/rtfgen.h index 65cd94e..bd611cf 100644 --- a/src/rtfgen.h +++ b/src/rtfgen.h @@ -245,7 +245,7 @@ class RTFGenerator : public OutputGenerator void startParameterType(bool,const char *) {} void endParameterType() {} void startParameterName(bool) {} - void endParameterName(bool,bool) {} + void endParameterName(bool,bool,bool) {} void startParameterList(bool) {} void endParameterList() {} diff --git a/src/scanner.l b/src/scanner.l index 70ae82e..2db9d21 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -807,6 +807,9 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] %x ObjCReturnType %x ObjCParams %x ObjCParamType +%x QtPropType +%x QtPropName +%x QtPropRW %% @@ -1032,6 +1035,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] current->bodyLine = yyLineNr; current->section = Entry::FUNCTION_SEC; current->protection = protection = Public ; + current->virt = Virtual; current->stat=yytext[0]=='+'; current->mtype = mtype = Method; current->type.resize(0); @@ -1110,14 +1114,6 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] lineCount(); } <PackageName>{ID}("."{ID})* { - //current->name = yytext; - //current->fileName = yyFileName; - //current->startLine = yyLineNr; - //current->section=Entry::PACKAGE_SEC; - //current_root->addSubEntry(current); - //current = new Entry ; - //initEntry(); - isTypedef=FALSE; current->name = yytext; current->name = substitute(current->name,".","::"); @@ -1567,6 +1563,31 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] else REJECT; } +<FindMembers>"Q_OBJECT" { // Qt object macro + } +<FindMembers>"Q_PROPERTY" { // Qt property declaration + current->protection = protection = Public ; + current->mtype = mtype = Property; + BEGIN(QtPropType); + } +<QtPropType>{ID} { + current->type=yytext; + BEGIN(QtPropName); + } +<QtPropName>{ID} { + current->name=yytext; + BEGIN(QtPropRW); + } +<QtPropRW>"READ" { + current->memSpec |= Entry::Readable; + } +<QtPropRW>"WRITE" { + current->memSpec |= Entry::Writable; + } +<QtPropRW>")" { + unput(';'); + BEGIN(FindMembers); + } <FindMembers,FindMemberName>{SCOPENAME} { lineCount(); if (insideIDL && yyleng==9 && strcmp(yytext,"cpp_quote")==0) @@ -3869,7 +3890,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } BEGIN( tmpDocType ); } -<Doc,JavaDoc>{B}*{CMD}("fn"|"var"|"typedef"){B}+ { +<Doc,JavaDoc>{B}*{CMD}("fn"|"var"|"typedef"|"property"){B}+ { current->section = Entry::MEMBERDOC_SEC; current->fileName = yyFileName; current->startLine = yyLineNr; diff --git a/src/translator_nl.h b/src/translator_nl.h index 3e80326..91d8c73 100644 --- a/src/translator_nl.h +++ b/src/translator_nl.h @@ -707,9 +707,12 @@ class TranslatorDutch : public Translator "relatie tussen twee klassen.\n" "<li>Een donkergroene pijl wordt gebruikt voor protected inheritance.\n" "<li>Een donkerrode pijl wordt gebruikt voor private inheritance.\n" - "<li>Een paars gestreepte pijl wordt gebruikt indien een klasse bevat is of gebruikt wordt " + "<li>Een paars gestippelde pijl wordt gebruikt indien een klasse bevat is of gebruikt wordt " "door een andere klasse. De pijl is gelabeled met de variable(n) " "die toegang geven tot de aangewezen klasse of structure. \n" + "<li>Een geel gestippelde pijl wordt gebruikt om een relatie tussen een \n" + "template instantie en een template klasse aan te geven. De pijl is gelabeld met \n" + "template parameters van de instantie.\n" "</ul>\n"; } /*! text for the link to the legend page */ diff --git a/src/util.cpp b/src/util.cpp index a72a968..5a1099a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -959,6 +959,12 @@ done: return result; } +int computeQualifiedIndex(const QString &name) +{ + int i = name.find('<'); + return name.findRev("::",i==-1 ? name.length() : i); +} + /* Find the fully qualified class name refered to by the input class * or typedef name against the input scope. * Loops through scope and each of its parent scopes looking for a @@ -976,7 +982,9 @@ ClassDef *getResolvedClassRec(Definition *scope, QCString name=n; QCString explicitScopePart; - int qualifierIndex = name.findRev("::"); // todo: deal with cases like A<B::C> + //int qualifierIndex = name.findRev("::"); // todo: deal with cases like A<B::C> + int qualifierIndex = computeQualifiedIndex(name); + //printf("name=%s qualifierIndex=%d\n",name.data(),qualifierIndex); if (qualifierIndex!=-1) // qualified name { // split off the explicit scope part @@ -1101,7 +1109,7 @@ ClassDef *getResolvedClass(Definition *scope, } //printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"<global>", // n,result?result->name().data():"<none>"); - // + // //printf("-------- end\n"); return result; } @@ -1168,7 +1176,7 @@ QCString removeRedundantWhiteSpace(const QCString &s) result+=' '; result+=s.at(i); } - else if (c=='t' && csp==5 && !(isId(s.at(i+1)) || s.at(i+1)==' ')) // prevent const ::A from being converted to const::A + else if (c=='t' && csp==5 && !(isId(s.at(i+1)) || s.at(i+1)==' ' || s.at(i+1)==')' || s.at(i+1)==',' || s.at(i+1)=='\0')) // prevent const ::A from being converted to const::A { result+="t "; csp=0; @@ -212,6 +212,7 @@ void replaceNamespaceAliases(QCString &scope,int i); int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item); int isAccessibleFrom(Definition *scope,FileDef *fileScope,Definition *item, const QCString &explicitScopePart); +int computeQualifiedIndex(const QString &name); #endif |