diff --git a/doc/commands.doc b/doc/commands.doc index fc968b4feca..436fd865dba 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -2634,7 +2634,7 @@ Commands for displaying examples \ref cfg_example_path "EXAMPLE_PATH" tag of doxygen's configuration file. - You can add option `{lineno}` to enable line numbers for the included code if desired. + You can add option `lineno` to enable line numbers for the included code if desired. The class and member declarations and definitions inside the code fragment are 'remembered' during the parsing of the comment block that contained @@ -2698,9 +2698,11 @@ Commands for displaying examples \note Doxygen's special commands do not work inside blocks of code. It is allowed to nest C-style comments inside a code block though. - The `option` can either be `lineno` or `doc`. - The `option` `lineno` can be used to enable line numbers for the included code if desired. - The `option` `doc` can be used to treat the file as documentation rather than code. + The `option` can either be `lineno`, or `doc`, and additionally `local` can be specified. + - The `option` `lineno` can be used to enable line numbers for the included code if desired. + - The `option` `doc` can be used to treat the file as documentation rather than code. + - The `option` `local` can be used make doxygen interpret the code as if it was in the + class or namespace in which the include command appears, rather than the global namespace. \note When using the `{doc}` option, some commands like \ref cmdcond "\\cond" and \ref cmdif "\\if" don't work with @@ -2830,11 +2832,13 @@ Commands for displaying examples Note also that the [block_id] markers should appear exactly twice in the source file. - - The `option` can either be `lineno`, `trimleft` or `doc`. + The `option` can either be `lineno`, `trimleft` or `doc`, and additionally `local` can be specified. - The `option` `lineno` can be used to enable line numbers for the included code if desired. - The `option` `trimleft` can be used to remove the common spacing in front of all lines (also taking in account the setting of the \ref cfg_tab_size "TAB_SIZE" tag). - The `option` `doc` can be used to treat the file as documentation rather than code. + - The `option` `local` can be used make doxygen interpret the code as if it was in the + class or namespace in which the include command appears, rather than the global namespace. \note When using the `{doc}` option, some commands like \ref cmdcond "\\cond" and \ref cmdif "\\if" don't work with diff --git a/src/classdef.cpp b/src/classdef.cpp index f78a69c0779..e4e56d1b362 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -4223,7 +4223,7 @@ const MemberDef *ClassDefImpl::getMemberByName(const QCString &name) const int m=minClassDistance(this,mcd); //printf("found member in %s linkable=%d m=%d\n", // qPrint(mcd->name()),mcd->isLinkable(),m); - if (misLinkable()) + if (mmemberDef(); diff --git a/src/code.l b/src/code.l index 33adfa8c53e..b386ce82d6f 100644 --- a/src/code.l +++ b/src/code.l @@ -807,7 +807,7 @@ ENDQopt ("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"seale yyextra->scopeStack.push(CLASSBLOCK); pushScope(yyscanner,yyextra->curClassName); DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",qPrint(yyextra->curClassName))); - if (yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->curClassName)==0) + if (yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->curClassName,true)==0) { DBG_CTX((stderr,"Adding new class %s\n",qPrint(yyextra->curClassName))); ScopedTypeVariant var(yyextra->curClassName); @@ -820,7 +820,7 @@ ENDQopt ("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"seale { bcd = toClassDef(it->second.globalDef()); } - if (bcd==0) bcd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,QCString(s)); + if (bcd==0) bcd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,QCString(s),true); if (bcd && bcd->name()!=yyextra->curClassName) { var.localDef()->insertBaseClass(bcd->name()); @@ -1776,7 +1776,7 @@ ENDQopt ("const"|"volatile"|"sealed"|"override")({BN}+("const"|"volatile"|"seale { QCString scope = yyextra->name.left((uint32_t)index); if (!yyextra->classScope.isEmpty()) scope.prepend((yyextra->classScope+"::")); - const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope); + const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope,true); if (cd) { setClassScope(yyscanner,cd->name()); @@ -2288,7 +2288,7 @@ static void addVariable(yyscan_t yyscanner,QCString type,QCString name) { auto findVariableType = [&yyscanner,&yyg,<ype,&lname,&name](const Definition *d) -> const ClassDef * { - const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype); + const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype,true); int i=0; if (varDef) { @@ -2775,11 +2775,11 @@ static const ClassDef *stripClassName(yyscan_t yyscanner,const QCString &s,const const ClassDef *cd=0; if (!yyextra->classScope.isEmpty()) { - cd=yyextra->symbolResolver.resolveClass(d,yyextra->classScope+"::"+clName); + cd=yyextra->symbolResolver.resolveClass(d,yyextra->classScope+"::"+clName,true); } if (cd==0) { - cd=yyextra->symbolResolver.resolveClass(d,clName); + cd=yyextra->symbolResolver.resolveClass(d,clName,true); } DBG_CTX((stderr,"stripClass trying '%s' = %p\n",qPrint(clName),(void*)cd)); if (cd) @@ -3051,7 +3051,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, auto checkForClass = [&yyg,&bareName,&className](const Definition *d, const ClassDef *&cd_,const MemberDef *&md_) { - cd_ = yyextra->symbolResolver.resolveClass(d,className); + cd_ = yyextra->symbolResolver.resolveClass(d,className,true); md_ = yyextra->symbolResolver.getTypedef(); DBG_CTX((stderr,"non-local variable name=%s cd=%s md=%s!\n", qPrint(className),cd_?qPrint(cd_->name()):"", @@ -3061,7 +3061,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"bareName=%s\n",qPrint(bareName))); if (bareName!=className) { - cd_ = yyextra->symbolResolver.resolveClass(d,bareName); // try unspecialized version + cd_ = yyextra->symbolResolver.resolveClass(d,bareName,true); // try unspecialized version md_ = yyextra->symbolResolver.getTypedef(); } } @@ -3368,7 +3368,7 @@ static void generateMemberLink(yyscan_t yyscanner, } else // variable not in current context, maybe it is in a parent context { - const ClassDef *vcd = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->classScope); + const ClassDef *vcd = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->classScope,true); if (vcd && vcd->isLinkable()) { DBG_CTX((stderr,"Found class %s for variable '%s'\n",qPrint(yyextra->classScope),qPrint(varName))); @@ -3616,7 +3616,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) } else { - ctx->objectType = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,ctx->objectTypeOrName); + ctx->objectType = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,ctx->objectTypeOrName,true); ctx->method = yyextra->symbolResolver.getTypedef(); } DBG_CTX((stderr," object is class? %p\n",(void*)ctx->objectType)); diff --git a/src/docnode.cpp b/src/docnode.cpp index a479b74db30..bd23ab2e05a 100644 --- a/src/docnode.cpp +++ b/src/docnode.cpp @@ -3607,6 +3607,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) QCString saveCmdName = cmdName; int tok=parser()->tokenizer.lex(); bool isBlock = false; + bool localScope = false; if (tok==TK_WORD && parser()->context.token->name=="{") { parser()->tokenizer.setStateOptions(); @@ -3617,6 +3618,7 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) { return std::find(optList.begin(),optList.end(),kw)!=optList.end(); }; + localScope = contains("local"); if (t==DocInclude::Include && contains("lineno")) { t = DocInclude::IncWithLines; @@ -3726,8 +3728,11 @@ void DocPara::handleInclude(const QCString &cmdName,DocInclude::Type t) } else { - children().append(parser(),thisVariant(),fileName, - parser()->context.context,t, + children().append(parser(), + thisVariant(), + fileName, + localScope ? parser()->context.context : "", + t, parser()->context.isExample, parser()->context.exampleName, blockId,isBlock); diff --git a/src/pycode.l b/src/pycode.l index a3007218159..342aa0d6c17 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -422,7 +422,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU // Try to find class in global scope if (baseDefToAdd==0) { - baseDefToAdd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,s.c_str()); + baseDefToAdd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,s.c_str(),true); } if (baseDefToAdd && baseDefToAdd->name()!=yyextra->curClassName) @@ -976,11 +976,11 @@ static const ClassDef *stripClassName(yyscan_t yyscanner,const QCString &s,Defin const ClassDef *cd=0; if (!yyextra->classScope.isEmpty()) { - cd=yyextra->symbolResolver.resolveClass(d,yyextra->classScope+"::"+clName); + cd=yyextra->symbolResolver.resolveClass(d,yyextra->classScope+"::"+clName,true); } if (cd==0) { - cd=yyextra->symbolResolver.resolveClass(d,clName); + cd=yyextra->symbolResolver.resolveClass(d,clName,true); } if (cd) { @@ -1341,7 +1341,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, const Definition *d = yyextra->currentDefinition; QCString scope = substitute(className,".","::"); - cd = yyextra->symbolResolver.resolveClass(d,substitute(className,".","::")); + cd = yyextra->symbolResolver.resolveClass(d,substitute(className,".","::"),true); md = yyextra->symbolResolver.getTypedef(); DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",