Skip to content

Commit 550e009

Browse files
committed
issue #11045 copydoc issue with namespace assignment
1 parent c692605 commit 550e009

8 files changed

Lines changed: 132 additions & 37 deletions

File tree

src/doxygen.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ FileNameLinkedMap *Doxygen::imageNameLinkedMap = nullptr; // images
142142
FileNameLinkedMap *Doxygen::dotFileNameLinkedMap = nullptr; // dot files
143143
FileNameLinkedMap *Doxygen::mscFileNameLinkedMap = nullptr; // msc files
144144
FileNameLinkedMap *Doxygen::diaFileNameLinkedMap = nullptr; // dia files
145-
StringUnorderedMap Doxygen::namespaceAliasMap; // all namespace aliases
145+
NamespaceAliasInfoMap Doxygen::namespaceAliasMap; // all namespace aliases
146146
StringMap Doxygen::tagDestinationMap; // all tag locations
147147
StringUnorderedSet Doxygen::tagFileSet; // all tag file names
148148
StringUnorderedSet Doxygen::expandAsDefinedSet; // all macros that should be expanded
@@ -4180,12 +4180,8 @@ static void findUsedClassesForClass(const Entry *root,
41804180

41814181
int sp=usedClassName.find('<');
41824182
if (sp==-1) sp=0;
4183-
int si=usedClassName.findRev("::",sp);
4184-
if (si!=-1)
4185-
{
4186-
// replace any namespace aliases
4187-
replaceNamespaceAliases(usedClassName,si);
4188-
}
4183+
// replace any namespace aliases
4184+
replaceNamespaceAliases(usedClassName);
41894185
// add any template arguments to the class
41904186
QCString usedName = removeRedundantWhiteSpace(usedClassName+templSpec);
41914187
//printf(" usedName=%s usedClassName=%s templSpec=%s\n",qPrint(usedName),qPrint(usedClassName),qPrint(templSpec));
@@ -4636,7 +4632,7 @@ static bool findClassRelation(
46364632
if (!found && si!=-1)
46374633
{
46384634
// replace any namespace aliases
4639-
replaceNamespaceAliases(baseClassName,si);
4635+
replaceNamespaceAliases(baseClassName);
46404636
baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context,
46414637
baseClassName,
46424638
mode==Undocumented,
@@ -4664,7 +4660,7 @@ static bool findClassRelation(
46644660
auto it = Doxygen::namespaceAliasMap.find(baseClassName.str());
46654661
if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class.
46664662
{
4667-
baseClass=getClassMutable(it->second.c_str());
4663+
baseClass=getClassMutable(QCString(it->second.alias));
46684664
found = baseClass!=nullptr && baseClass!=cd;
46694665
}
46704666
}

src/doxygen.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,21 @@ struct InputFileEncoding
7171
QCString encoding;
7272
};
7373

74+
struct NamespaceAliasInfo
75+
{
76+
NamespaceAliasInfo(const std::string &a,const std::string &ctx=std::string()) : alias(a), context(ctx) {}
77+
std::string alias;
78+
std::string context;
79+
};
80+
7481
using InputFileEncodingList = std::vector<InputFileEncoding>;
7582

7683
using ClangUsrMap = std::unordered_map<std::string,const Definition *>;
7784

7885
using StaticInitMap = std::unordered_map<std::string,BodyInfo>;
7986

87+
using NamespaceAliasInfoMap = std::unordered_map<std::string,NamespaceAliasInfo>;
88+
8089
/*! \brief This class serves as a namespace for global variables used by doxygen.
8190
*
8291
* All fields in this class are public and static, so they can be used directly.
@@ -100,7 +109,7 @@ class Doxygen
100109
static FileNameLinkedMap *diaFileNameLinkedMap;
101110
static MemberNameLinkedMap *memberNameLinkedMap;
102111
static MemberNameLinkedMap *functionNameLinkedMap;
103-
static StringUnorderedMap namespaceAliasMap;
112+
static NamespaceAliasInfoMap namespaceAliasMap;
104113
static GroupLinkedMap *groupLinkedMap;
105114
static NamespaceLinkedMap *namespaceLinkedMap;
106115
static StringMap tagDestinationMap;

src/namespacedef.cpp

Lines changed: 97 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,31 +1675,111 @@ NamespaceDefMutable *toNamespaceDefMutable(Definition *d)
16751675

16761676
// --- Helpers
16771677

1678+
static NamespaceDef *getResolvedNamespaceRec(StringSet &namespacesTried,const NamespaceAliasInfo &aliasInfo);
16781679

1679-
NamespaceDef *getResolvedNamespace(const QCString &name)
1680+
static QCString replaceNamespaceAliasesRec(StringSet &namespacesTried,const QCString &name)
16801681
{
1681-
if (name.isEmpty()) return nullptr;
1682-
auto it = Doxygen::namespaceAliasMap.find(name.str());
1683-
if (it!=Doxygen::namespaceAliasMap.end())
1682+
QCString result = name;
1683+
//printf("> replaceNamespaceAliasesRec(%s)\n",qPrint(name));
1684+
if (namespacesTried.find(name.str())==namespacesTried.end())
16841685
{
1685-
int count=0; // recursion detection guard
1686-
StringUnorderedMap::iterator it2;
1687-
while ((it2=Doxygen::namespaceAliasMap.find(it->second))!=Doxygen::namespaceAliasMap.end() &&
1688-
count<10)
1689-
{
1690-
it=it2;
1691-
count++;
1692-
}
1693-
if (count==10)
1686+
namespacesTried.insert(name.str());
1687+
size_t p = 0;
1688+
for (;;)
16941689
{
1695-
warn_uncond("possible recursive namespace alias detected for %s!\n",qPrint(name));
1690+
size_t i = name.str().find("::",p);
1691+
if (i==std::string::npos)
1692+
{
1693+
auto it = Doxygen::namespaceAliasMap.find(name.str());
1694+
if (it != Doxygen::namespaceAliasMap.end())
1695+
{
1696+
//printf("found map %s->%s\n",qPrint(name),qPrint(it->second.alias));
1697+
auto ns = getResolvedNamespaceRec(namespacesTried,it->second);
1698+
if (ns)
1699+
{
1700+
result = replaceNamespaceAliasesRec(namespacesTried,ns->qualifiedName());
1701+
}
1702+
}
1703+
break;
1704+
}
1705+
else
1706+
{
1707+
auto it = Doxygen::namespaceAliasMap.find(name.left(i).str());
1708+
if (it != Doxygen::namespaceAliasMap.end())
1709+
{
1710+
//printf("found map %s|%s->%s\n",qPrint(name.left(i)),qPrint(name.mid(i)),qPrint(it->second.alias));
1711+
auto ns = getResolvedNamespaceRec(namespacesTried,it->second);
1712+
if (ns)
1713+
{
1714+
result = replaceNamespaceAliasesRec(namespacesTried,ns->qualifiedName()+name.mid(i));
1715+
break;
1716+
}
1717+
}
1718+
}
1719+
p = i+2;
16961720
}
1697-
return Doxygen::namespaceLinkedMap->find(it->second);
16981721
}
1699-
else
1722+
//printf("< replaceNamespaceAliasesRec(%s)=%s\n",qPrint(name),qPrint(result));
1723+
return result;
1724+
}
1725+
1726+
static NamespaceDef *getResolvedNamespaceRec(StringSet &namespacesTried,const NamespaceAliasInfo &aliasInfo)
1727+
{
1728+
size_t j = aliasInfo.context.length();
1729+
for (;;)
17001730
{
1701-
return Doxygen::namespaceLinkedMap->find(name);
1731+
if (j>0)
1732+
{
1733+
//printf("candidate %s|::%s\n",qPrint(aliasInfo.context.substr(0,j)),qPrint(aliasInfo.alias));
1734+
auto candidate = replaceNamespaceAliasesRec(namespacesTried,aliasInfo.context.substr(0,j)+"::"+aliasInfo.alias);
1735+
auto nd = Doxygen::namespaceLinkedMap->find(candidate);
1736+
if (nd)
1737+
{
1738+
return nd;
1739+
}
1740+
}
1741+
if (j>0) // strip one level from context, i.e. given N1::N2::N3
1742+
// j==10 -> j==6 (N1::N2::N3->N1::N2), and then
1743+
// j==6 -> j==2 (N1::N2->N1), and then
1744+
// j==2 -> j==std::string::npos (N1->"")
1745+
{
1746+
j = aliasInfo.context.rfind("::",j-1);
1747+
}
1748+
else
1749+
{
1750+
j = std::string::npos;
1751+
}
1752+
if (j==std::string::npos)
1753+
{
1754+
//printf("candidate %s\n",qPrint(aliasInfo.alias));
1755+
auto candidate = replaceNamespaceAliasesRec(namespacesTried,QCString(aliasInfo.alias));
1756+
auto nd = Doxygen::namespaceLinkedMap->find(candidate);
1757+
if (nd)
1758+
{
1759+
return nd;
1760+
}
1761+
break;
1762+
}
17021763
}
1764+
return nullptr;
1765+
}
1766+
1767+
void replaceNamespaceAliases(QCString &name)
1768+
{
1769+
//printf("> replaceNamespaceAliases(%s)\n",qPrint(name));
1770+
StringSet namespacesTried;
1771+
name = replaceNamespaceAliasesRec(namespacesTried,name);
1772+
//printf("< replaceNamespaceAliases: result=%s\n",qPrint(name));
1773+
}
1774+
1775+
NamespaceDef *getResolvedNamespace(const QCString &name)
1776+
{
1777+
//printf("> getResolvedNamespace(%s)\n",qPrint(name));
1778+
if (name.isEmpty()) return nullptr;
1779+
StringSet namespacesTried;
1780+
auto ns = getResolvedNamespaceRec(namespacesTried,NamespaceAliasInfo(name.str()));
1781+
//printf("< getResolvedNamespace(%s)=%s\n",qPrint(name),ns?qPrint(ns->qualifiedName()):"nullptr");
1782+
return ns;
17031783
}
17041784

17051785
//--------------------------------------------------------------------------------------

src/namespacedef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ NamespaceDefMutable *toNamespaceDefMutable(Definition *d);
145145

146146
// --- Helpers
147147

148+
void replaceNamespaceAliases(QCString &name);
148149
NamespaceDef *getResolvedNamespace(const QCString &key);
149150
inline NamespaceDefMutable *getResolvedNamespaceMutable(const QCString &key)
150151
{

src/scanner.l

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,9 +1879,15 @@ NONLopt [^\n]*
18791879
}
18801880
<NSAliasArg>({ID}"::")*{ID} {
18811881
//printf("Inserting namespace alias %s::%s->%s\n",qPrint(yyextra->current_root->name),qPrint(yyextra->aliasName),yytext);
1882-
// TODO: namespace aliases are now treated as global entities
1883-
// while they should be aware of the scope they are in
1884-
Doxygen::namespaceAliasMap.insert({yyextra->aliasName.str(),std::string(yytext)});
1882+
std::string ctx = yyextra->current_root->name.str();
1883+
if (ctx.empty())
1884+
{
1885+
Doxygen::namespaceAliasMap.insert({yyextra->aliasName.str(),NamespaceAliasInfo(std::string(yytext),std::string())});
1886+
}
1887+
else
1888+
{
1889+
Doxygen::namespaceAliasMap.insert({ctx+"::"+yyextra->aliasName.str(),NamespaceAliasInfo(std::string(yytext),ctx)});
1890+
}
18851891
}
18861892
<NSAliasArg>";" {
18871893
BEGIN( FindMembers );
@@ -1914,9 +1920,8 @@ NONLopt [^\n]*
19141920
//printf("PHP: adding use as relation: %s->%s\n",yytext,qPrint(yyextra->aliasName));
19151921
if (!yyextra->aliasName.isEmpty())
19161922
{
1917-
Doxygen::namespaceAliasMap.insert({yytext,
1918-
std::string(removeRedundantWhiteSpace(
1919-
substitute(yyextra->aliasName,"\\","::")).str())});
1923+
std::string aliasValue = removeRedundantWhiteSpace(substitute(yyextra->aliasName,"\\","::")).str();
1924+
Doxygen::namespaceAliasMap.insert({yytext,NamespaceAliasInfo(aliasValue)});
19201925
}
19211926
yyextra->aliasName.clear();
19221927
}

src/symbolresolver.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ const ClassDef *SymbolResolver::Private::getResolvedTypeRec(
239239
// split off the explicit scope part
240240
explicitScopePart=name.left(qualifierIndex);
241241
// todo: improve namespace alias substitution
242-
replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
242+
replaceNamespaceAliases(explicitScopePart);
243243
name=name.mid(qualifierIndex+2);
244244
}
245245

@@ -400,7 +400,7 @@ const Definition *SymbolResolver::Private::getResolvedSymbolRec(
400400
// split off the explicit scope part
401401
explicitScopePart=name.left(qualifierIndex);
402402
// todo: improve namespace alias substitution
403-
replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
403+
replaceNamespaceAliases(explicitScopePart);
404404
name=name.mid(qualifierIndex+2);
405405
}
406406
AUTO_TRACE_ADD("qualifierIndex={} name={} explicitScopePart={}",qualifierIndex,name,explicitScopePart);

src/util.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5214,8 +5214,10 @@ QCString stripExtension(const QCString &fName)
52145214
return stripExtensionGeneral(fName, Doxygen::htmlFileExtension);
52155215
}
52165216

5217+
#if 0
52175218
void replaceNamespaceAliases(QCString &scope,size_t i)
52185219
{
5220+
printf("replaceNamespaceAliases(%s,%zu)\n",qPrint(scope),i);
52195221
while (i>0)
52205222
{
52215223
QCString ns = scope.left(i);
@@ -5230,7 +5232,9 @@ void replaceNamespaceAliases(QCString &scope,size_t i)
52305232
}
52315233
if (i>0 && ns==scope.left(i)) break;
52325234
}
5235+
printf("result=%s\n",qPrint(scope));
52335236
}
5237+
#endif
52345238

52355239
QCString stripPath(const QCString &s)
52365240
{
@@ -5566,7 +5570,7 @@ static MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fil
55665570
if (qualifierIndex!=-1)
55675571
{
55685572
explicitScopePart = name.left(qualifierIndex);
5569-
replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
5573+
replaceNamespaceAliases(explicitScopePart);
55705574
name = name.mid(qualifierIndex+2);
55715575
}
55725576
//printf("explicitScopePart=%s\n",qPrint(explicitScopePart));

src/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ QCString stripExtensionGeneral(const QCString &fName, const QCString &ext);
340340

341341
QCString stripExtension(const QCString &fName);
342342

343-
void replaceNamespaceAliases(QCString &scope,size_t i);
343+
//void replaceNamespaceAliases(QCString &scope,size_t i);
344344

345345
int computeQualifiedIndex(const QCString &name);
346346

0 commit comments

Comments
 (0)