From 21f0f9157802f011bb02b96fd79057084039ae2b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 4 Nov 2009 10:48:20 +0100 Subject: introduce delayed resolution of aliases this has two effects: - using-declarations which use forward-declared classes work without collecting the forward declarations, as the resolution happens at a place where the class definition must have been encountered already - it should be a bit faster --- .../lupdate/testdata/good/parsecpp2/main.cpp | 19 ++++++++ .../testdata/good/parsecpp2/project.ts.result | 8 +++ tools/linguist/lupdate/cpp.cpp | 57 ++++++++++++++++------ 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp index d720b8f..7ddb68f 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp @@ -93,3 +93,22 @@ TopLevel2::Nested::foo() { TopLevel2::tr("TopLevel2"); } + + + +namespace NameSpace { +class ToBeUsed; +} + +// using statement before class definition +using NameSpace::ToBeUsed; + +class NameSpace::ToBeUsed { + Q_OBJECT + void caller(); +}; + +void ToBeUsed::caller() +{ + tr("NameSpace::ToBeUsed"); +} diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result index ef5adb2..6f48e27 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result @@ -2,6 +2,14 @@ + NameSpace::ToBeUsed + + + NameSpace::ToBeUsed + + + + TopLevel diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 5ef7099..beaf246 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -261,11 +261,14 @@ private: bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const; bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment, NamespaceList *resolved) const; - bool fullyQualify(const NamespaceList &namespaces, const QList &segments, - bool isDeclaration, + bool fullyQualify(const NamespaceList &namespaces, int nsCnt, + const QList &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const; - bool fullyQualify(const NamespaceList &namespaces, const QString &segments, - bool isDeclaration, + bool fullyQualify(const NamespaceList &namespaces, + const QList &segments, bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const; + bool fullyQualify(const NamespaceList &namespaces, + const QString &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const; bool findNamespaceCallback(const Namespace *ns, void *context) const; const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const; @@ -1057,7 +1060,18 @@ bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const } QHash::ConstIterator nsai = ns->aliases.constFind(data->segment); if (nsai != ns->aliases.constEnd()) { - *data->resolved = *nsai; + const NamespaceList &nsl = *nsai; + if (nsl.last().value().isEmpty()) { // Delayed alias resolution + NamespaceList &nslIn = *const_cast(&nsl); + nslIn.removeLast(); + NamespaceList nslOut; + if (!fullyQualify(data->namespaces, data->nsCount, nslIn, false, &nslOut, 0)) { + const_cast(ns)->aliases.remove(data->segment); + return false; + } + nslIn = nslOut; + } + *data->resolved = nsl; return true; } return false; @@ -1086,8 +1100,8 @@ bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const Has return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data); } -bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList &segments, - bool isDeclaration, +bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt, + const QList &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const { int nsIdx; @@ -1104,7 +1118,7 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList &segments, bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const +{ + return fullyQualify(namespaces, namespaces.count(), + segments, isDeclaration, resolved, unresolved); +} + +bool CppParser::fullyQualify(const NamespaceList &namespaces, + const QString &quali, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const { static QString strColons(QLatin1String("::")); @@ -1638,9 +1660,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } if (fullName.isEmpty()) break; - NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) - modifyNamespace(&namespaces)->aliases[ns] = nsl; + fullName.append(HashString(QString())); // Mark as unresolved + modifyNamespace(&namespaces)->aliases[ns] = fullName; } } else if (yyTok == Tok_LeftBrace) { // Anonymous namespace @@ -1681,9 +1702,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet &inclusions) } if (fullName.isEmpty()) break; - NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) - modifyNamespace(&namespaces)->aliases[nsl.last()] = nsl; + // using-declarations cannot rename classes, so the last element of + // fullName is already the resolved name we actually want. + // As we do no resolution here, we'll collect useless usings of data + // members and methods as well. This is no big deal. + HashString &ns = fullName.last(); + fullName.append(HashString(QString())); // Mark as unresolved + modifyNamespace(&namespaces)->aliases[ns] = fullName; } break; case Tok_tr: -- cgit v0.12