diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2022-06-17 18:22:55 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2022-06-23 10:40:43 +0200 |
commit | 1364c1363406eda9b462f4e48ed09248ae0cdaf8 (patch) | |
tree | db09d01a6542022ca81186af6c09fc913a968880 | |
parent | b4c51ba393b19996726b122a4cd5fe6b1fe128d3 (diff) | |
download | qttools-1364c1363406eda9b462f4e48ed09248ae0cdaf8.tar.gz |
lupdate: Apply a simpler fix for static initializers
...in the old C++ parser.
The fix for QTBUG-91521 was overly complicated and slow. Also it
introduced the (minor) issue QTBUG-104426.
Old fix: on encountering an identifier that is not a tr function,
we checked
- Are we on namespace level?
- Is the pending context empty?
- Are we not in a class declaration?
If all are true, we walk up the namespace stack and check whether we're
in a class declaration. Promote the prospecting to the pending context.
New fix: On encountering a first level left parenthesis we promote the
prospective context to pending context. On encountering the matching
right parenthesis we demote the pending context to prospective context.
This has the effect that the prospective context is pending between
matching first-level parentheses like here:
QString MyClass::member(QT_TR_NOOP("some text"));
^^^^^^^^^^^^^^^^^^^^^^^^ ^
pendingContext empty
^^^^^^^^^^^^^^^^^^^^^^^
pendingContext: "MyClass"
The pending context is then picked up by handleTr.
This approach fits better into the overall architecture of the parser.
Task-number: QTBUG-91521
Task-number: QTBUG-104426
Change-Id: Ibc9dfe955f2a56fc13a7bede11344532537e2f5d
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
(cherry picked from commit e4ebb97fe3bb154897394b94473848992f83cf99)
-rw-r--r-- | src/linguist/lupdate/cpp.cpp | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp index b0cfde5a8..adaed23de 100644 --- a/src/linguist/lupdate/cpp.cpp +++ b/src/linguist/lupdate/cpp.cpp @@ -84,16 +84,10 @@ private: QBitArray m_ba; }; -struct NamespaceStackItem -{ - qsizetype depth = 0; // the depth of CppParser::namespaces - int token = 0; // the token that opened the namespace or class -}; - struct CppParserState { NamespaceList namespaces; - QStack<NamespaceStackItem> namespaceDepths; + QStack<qsizetype> namespaceDepths; NamespaceList functionContext; QString functionContextUnresolved; QString pendingContext; @@ -199,7 +193,6 @@ private: void enterNamespace(NamespaceList *namespaces, const HashString &name); void truncateNamespaces(NamespaceList *namespaces, int lenght); Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true); - bool isInClassDeclaration() const; // Tokenizer state QString yyFileName; @@ -1159,14 +1152,6 @@ void CppParser::truncateNamespaces(NamespaceList *namespaces, int length) namespaces->erase(namespaces->begin() + length, namespaces->end()); } -bool CppParser::isInClassDeclaration() const -{ - for (const NamespaceStackItem &item : namespaceDepths) - if (item.token == Tok_class) - return true; - return false; -} - /* Functions for processing include files. @@ -1798,10 +1783,10 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac yyMsg() << "Ignoring definition of undeclared qualified class\n"; break; } - namespaceDepths.push({ namespaces.count(), Tok_class }); + namespaceDepths.push(namespaces.count()); namespaces = nsl; } else { - namespaceDepths.push({ namespaces.count(), Tok_class }); + namespaceDepths.push(namespaces.count()); } enterNamespace(&namespaces, fct); @@ -1834,7 +1819,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac ns = HashString(text); } if (yyTok == Tok_LeftBrace) { - namespaceDepths.push({ namespaces.count(), Tok_namespace }); + namespaceDepths.push(namespaces.count()); for (const auto &nns : nestedNamespaces) enterNamespace(&namespaces, nns); enterNamespace(&namespaces, ns); @@ -1867,7 +1852,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac } } else if (yyTok == Tok_LeftBrace) { // Anonymous namespace - namespaceDepths.push({ namespaces.count(), Tok_namespace }); + namespaceDepths.push(namespaces.count()); metaExpected = true; yyTok = getToken(); } @@ -1974,15 +1959,8 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac } else { notrfunc: prefix.clear(); - if (yyBraceDepth == namespaceDepths.count() && pendingContext.isEmpty() && !isInClassDeclaration()) { - if (!prospectiveContext.isEmpty()) { - pendingContext = prospectiveContext; - prospectiveContext.clear(); - } - } else { - if (yyTok == Tok_Ident && !yyParenDepth) - prospectiveContext.clear(); - } + if (yyTok == Tok_Ident && !yyParenDepth) + prospectiveContext.clear(); } metaExpected = false; break; @@ -2018,7 +1996,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac if (!yyTokColonSeen) { if (yyBraceDepth + 1 == namespaceDepths.count()) { // class or namespace - truncateNamespaces(&namespaces, namespaceDepths.pop().depth); + truncateNamespaces(&namespaces, namespaceDepths.pop()); } if (yyBraceDepth == namespaceDepths.count()) { // function, class or namespace @@ -2080,20 +2058,37 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac yyTokColonSeen = false; } } - Q_FALLTHROUGH(); + yyTokIdentSeen = false; + metaExpected = true; + yyTok = getToken(); + break; case Tok_LeftParen: + if (!yyTokColonSeen && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 1 + && !prospectiveContext.isEmpty()) { + pendingContext = prospectiveContext; + prospectiveContext.clear(); + } yyTokIdentSeen = false; - Q_FALLTHROUGH(); + metaExpected = true; + yyTok = getToken(); + break; case Tok_Comma: case Tok_QuestionMark: metaExpected = true; yyTok = getToken(); break; case Tok_RightParen: - if (yyParenDepth == 0) + if (yyParenDepth == 0) { + if (!yyTokColonSeen && !pendingContext.isEmpty() + && yyBraceDepth == namespaceDepths.count()) { + // Demote the pendingContext to prospectiveContext. + prospectiveContext = pendingContext; + pendingContext.clear(); + } metaExpected = true; - else + } else { metaExpected = false; + } yyTok = getToken(); break; default: |