From 1364c1363406eda9b462f4e48ed09248ae0cdaf8 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 17 Jun 2022 18:22:55 +0200 Subject: 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 (cherry picked from commit e4ebb97fe3bb154897394b94473848992f83cf99) --- src/linguist/lupdate/cpp.cpp | 63 ++++++++++++++++++++------------------------ 1 file 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 namespaceDepths; + QStack 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: -- cgit v1.2.1