summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2019-11-08 14:38:30 +0100
committerLucie GĂ©rard <lucie.gerard@qt.io>2020-02-18 15:05:41 +0100
commitf685da95bd841c212142c9ba5ce9cad64640af2f (patch)
treea810899959baff697080859624eca38d03befaae
parent4bfea4e31f4a3deec673f519c83081b284f7c556 (diff)
Add PP calls context and fill the information in translator
This is needed to get the context for translations present in macros without a context in their argument and to apply the argument-context in Q_DECLARE_TR_FUNCTIONS to the right translation calls Change-Id: I109f2bf963211dabcf293b772fa7d1d873f6ff60 Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
-rw-r--r--src/linguist/lupdate/clangtoolastreader.cpp261
-rw-r--r--src/linguist/lupdate/clangtoolastreader.h50
-rw-r--r--src/linguist/lupdate/cpp_clang.cpp174
-rw-r--r--src/linguist/lupdate/cpp_clang.h14
4 files changed, 353 insertions, 146 deletions
diff --git a/src/linguist/lupdate/clangtoolastreader.cpp b/src/linguist/lupdate/clangtoolastreader.cpp
index da0fcd5d8..8d384e89a 100644
--- a/src/linguist/lupdate/clangtoolastreader.cpp
+++ b/src/linguist/lupdate/clangtoolastreader.cpp
@@ -33,6 +33,34 @@ QT_BEGIN_NAMESPACE
namespace LupdatePrivate
{
+ /*
+ Retrieves the context for the NOOP macros using the context of
+ the NamedDeclaration within which the Macro is.
+ The context is stripped of the function or method part as it used not to be retrieved
+ in the previous cpp parser.
+ */
+ QString contextForNoopMacro(clang::NamedDecl *namedDecl)
+ {
+ QStringList context;
+ const clang::DeclContext *decl = namedDecl->getDeclContext();
+ while (decl) {
+ if (clang::isa<clang::NamedDecl>(decl) && !decl->isFunctionOrMethod()) {
+ if (const auto *namespaceDecl = clang::dyn_cast<clang::NamespaceDecl>(decl)) {
+ context.prepend(namespaceDecl->isAnonymousNamespace()
+ ? QStringLiteral("(anonymous namespace)")
+ : QString::fromStdString(namespaceDecl->getDeclName().getAsString()));
+ } else if (const auto *recordDecl = clang::dyn_cast<clang::RecordDecl>(decl)) {
+ static const QString anonymous = QStringLiteral("(anonymous %1)");
+ context.prepend(recordDecl->getIdentifier()
+ ? QString::fromStdString(recordDecl->getDeclName().getAsString())
+ : anonymous.arg(QLatin1String(recordDecl->getKindName().data())));
+ }
+ }
+ decl = decl->getParent();
+ }
+ return context.join(QStringLiteral("::"));
+ }
+
QString contextForFunctionDecl(clang::FunctionDecl *func, const std::string &funcName)
{
std::string context;
@@ -104,6 +132,15 @@ namespace LupdatePrivate
return true;
return false;
}
+
+ bool isPointWithin(const clang::SourceRange &sourceRange, const clang::SourceLocation &point,
+ const clang::SourceManager &sm)
+ {
+ clang::SourceLocation start = sourceRange.getBegin();
+ clang::SourceLocation end = sourceRange.getEnd();
+ return point == start || point == end || (sm.isBeforeInTranslationUnit(start, point)
+ && sm.isBeforeInTranslationUnit(point, end));
+ }
}
/*
@@ -206,7 +243,7 @@ bool LupdateVisitor::VisitCallExpr(clang::CallExpr *callExpression)
qCDebug(lcClang) << "Plural : " << store.lupdatePlural;
break;
}
- m_translationStoresFromAST.push_back(store);
+ m_stores.AST.push_back(store);
return true;
}
@@ -423,138 +460,136 @@ void LupdateVisitor::setInfoFromRawComment(const QString &commentString,
}
}
-/*
- Fill the Translator with the retrieved information after traversing the AST.
-*/
-void LupdateVisitor::fillTranslator()
+void LupdateVisitor::processPreprocessorCalls()
{
- for (const auto &store : qAsConst(m_translationStoresFromAST))
- fillTranslator(store);
- // Here also need to fill the translator with the information retrieved from the PreProcessor
+ m_macro = (m_stores.Preprocessor.size() > 0);
+ for (const auto &store : qAsConst(m_stores.Preprocessor))
+ processPreprocessorCall(store);
}
-void LupdateVisitor::fillTranslator(TranslationRelatedStore store)
+void LupdateVisitor::processPreprocessorCall(TranslationRelatedStore store)
{
- bool forcePlural = false;
- switch (trFunctionAliasManager.trFunctionByName(store.funcName)) {
- case TrFunctionAliasManager::Function_Q_DECLARE_TR_FUNCTIONS:
- // If there is a Q_DECLARE_TR_FUNCTION the context given takes priority
- // over the retrieved context.
- // The retrieved context for Q_DECLARE_TR_FUNCTION (where the macro was)
- // has to fit the start of the retrieved context of the tr function or
- // NOOP macro if there is already a argument giving the context, it has
- // priority.
- //handleDeclareTrFunctions(); // TODO: Implement.
- break;
- case TrFunctionAliasManager::Function_QT_TR_N_NOOP:
- forcePlural = true;
- Q_FALLTHROUGH();
- case TrFunctionAliasManager::Function_tr:
- case TrFunctionAliasManager::Function_trUtf8:
- case TrFunctionAliasManager::Function_QT_TR_NOOP:
- case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
- handleTr(store, forcePlural);
- break;
- case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP:
- case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP3:
- forcePlural = true;
- Q_FALLTHROUGH();
- case TrFunctionAliasManager::Function_translate:
- case TrFunctionAliasManager::Function_findMessage:
- case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
- case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
- case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
- case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
- handleTranslate(store, forcePlural);
- break;
- case TrFunctionAliasManager::Function_QT_TRID_N_NOOP:
- forcePlural = true;
- Q_FALLTHROUGH();
- case TrFunctionAliasManager::Function_qtTrId:
- case TrFunctionAliasManager::Function_QT_TRID_NOOP:
- handleTrId(store, forcePlural);
- break;
- }
-}
+ const std::vector<QString> rawComments = rawCommentsFromSourceLocation(store.callLocation);
+ for (const auto &rawComment : rawComments)
+ setInfoFromRawComment(rawComment, &store);
-TranslatorMessage LupdateVisitor::fillTranslatorMessage(const TranslationRelatedStore &store,
- bool forcePlural, bool isId)
-{
- QString context;
- if (!isId) {
- context = ParserTool::transcode(store.contextArg.isEmpty() ? store.contextRetrieved
- : store.contextArg);
+ if (store.isValid()) {
+ if (store.funcName.contains(QStringLiteral("Q_DECLARE_TR_FUNCTIONS")))
+ m_qDeclareTrMacroAll.push_back(store);
+ else
+ m_noopTranslationMacroAll.push_back(store);
+ store.printStore();
}
-
- TranslatorMessage msg(context,
- ParserTool::transcode(isId ? store.lupdateSourceWhenId
- : store.lupdateSource),
- ParserTool::transcode(store.lupdateComment),
- QString(),
- store.lupdateLocationFile,
- store.lupdateLocationLine,
- QStringList(),
- TranslatorMessage::Type::Unfinished,
- (forcePlural ? forcePlural : !store.lupdatePlural.isEmpty()));
-
- if (!store.lupdateAllMagicMetaData.empty())
- msg.setExtras(store.lupdateAllMagicMetaData);
- msg.setExtraComment(ParserTool::transcode(store.lupdateExtraComment));
- return msg;
}
-void LupdateVisitor::handleTranslate(const TranslationRelatedStore &store, bool forcePlural)
+bool LupdateVisitor::VisitNamedDecl(clang::NamedDecl *namedDeclaration)
{
- if (!store.lupdateSourceWhenId.isEmpty())
- qCDebug(lcClang) << "//% is ignored when using translate function\n";
+ if (!m_macro)
+ return true;
+ auto fullLocation = m_context->getFullLoc(namedDeclaration->getBeginLoc());
+ if (!fullLocation.isValid() || !fullLocation.getFileEntry())
+ return true;
+
+ if (fullLocation.getFileEntry()->getName() != m_inputFile)
+ return true;
- TranslatorMessage msg = fillTranslatorMessage(store, forcePlural);
- msg.setId(ParserTool::transcode(store.lupdateIdMetaData)); // //= NOT to be used with qTrId
- m_tor->append(msg);
+ qCDebug(lcClang) << "NamedDecl Name: " << namedDeclaration->getQualifiedNameAsString();
+ qCDebug(lcClang) << "NamedDecl source: " << namedDeclaration->getSourceRange().printToString(
+ m_context->getSourceManager());
+ // Checks if there is a macro located within the range of this NamedDeclaration
+ // in order to find a context for the macro
+ findContextForTranslationStoresFromPP(namedDeclaration);
+ return true;
}
-void LupdateVisitor::handleTr(const TranslationRelatedStore &store, bool forcePlural)
+void LupdateVisitor::findContextForTranslationStoresFromPP(clang::NamedDecl *namedDeclaration)
{
- if (!store.lupdateSourceWhenId.isEmpty())
- qCDebug(lcClang) << "//% is ignored when using tr function\n";
- if (store.contextRetrieved.isEmpty() && store.contextArg.isEmpty()) {
- qCDebug(lcClang) << "tr() cannot be called without context \n";
- return;
+ qCDebug(lcClang) << "=================findContextForTranslationStoresFromPP===================";
+ qCDebug(lcClang) << "m_noopTranslationMacroAll " << m_noopTranslationMacroAll.size();
+ qCDebug(lcClang) << "m_qDeclareTrMacroAll " << m_qDeclareTrMacroAll.size();
+ clang::SourceManager &sm = m_context->getSourceManager();
+
+ // Looking for NOOP context only in the input file
+ // because we are not interested in the NOOP from all related file
+ // Once QT_TR_NOOP are gone this step can be removes because the only
+ // QT_...NOOP left will have an context as argument
+ for (TranslationRelatedStore &store : m_noopTranslationMacroAll) {
+ if (!store.contextArg.isEmpty())
+ continue;
+ clang::SourceLocation sourceLoc = store.callLocation;
+ if (!sourceLoc.isValid())
+ continue;
+ if (LupdatePrivate::isPointWithin(namedDeclaration->getSourceRange(), sourceLoc, sm)) {
+ /*
+ void N3::C1::C12::C121::f2()
+ {
+ const char test_NOOP[] = QT_TR_NOOP("A QT_TR_NOOP N3::C1::C13");
+ }
+ In such case namedDeclaration->getQualifiedNameAsString() will give only
+ test_NOOP as context.
+ This is why the following function is needed
+ */
+ store.contextRetrievedTempNOOP = LupdatePrivate::contextForNoopMacro(namedDeclaration);
+ qCDebug(lcClang) << "------------------------------------------NOOP Macro in range ---";
+ qCDebug(lcClang) << "Range " << namedDeclaration->getSourceRange().printToString(sm);
+ qCDebug(lcClang) << "Point " << sourceLoc.printToString(sm);
+ qCDebug(lcClang) << "=========== Visit Named Declaration =============================";
+ qCDebug(lcClang) << " Declaration Location " <<
+ namedDeclaration->getSourceRange().printToString(sm);
+ qCDebug(lcClang) << " Macro Location "
+ << store.callLocation.printToString(sm);
+ qCDebug(lcClang) << " Context namedDeclaration->getQualifiedNameAsString() "
+ << namedDeclaration->getQualifiedNameAsString();
+ qCDebug(lcClang) << " Context LupdatePrivate::contextForNoopMacro "
+ << store.contextRetrievedTempNOOP;
+ qCDebug(lcClang) << " Context Retrieved " << store.contextRetrievedTempNOOP;
+ qCDebug(lcClang) << "=================================================================";
+ store.printStore();
+ }
}
- TranslatorMessage msg = fillTranslatorMessage(store, forcePlural);
- msg.setId(ParserTool::transcode(store.lupdateIdMetaData)); // //= NOT to be used with qTrId
- m_tor->append(msg);
+ for (TranslationRelatedStore &store : m_qDeclareTrMacroAll) {
+ clang::SourceLocation sourceLoc = store.callLocation;
+ if (!sourceLoc.isValid())
+ continue;
+ if (LupdatePrivate::isPointWithin(namedDeclaration->getSourceRange(), sourceLoc, sm)) {
+ store.contextRetrieved = QString::fromStdString(
+ namedDeclaration->getQualifiedNameAsString());
+ qCDebug(lcClang) << "------------------------------------------DECL Macro in range ---";
+ qCDebug(lcClang) << "Range " << namedDeclaration->getSourceRange().printToString(sm);
+ qCDebug(lcClang) << "Point " << sourceLoc.printToString(sm);
+ qCDebug(lcClang) << "=========== Visit Named Declaration =============================";
+ qCDebug(lcClang) << " Declaration Location " <<
+ namedDeclaration->getSourceRange().printToString(sm);
+ qCDebug(lcClang) << " Macro Location "
+ << store.callLocation.printToString(sm);
+ qCDebug(lcClang) << " Context namedDeclaration->getQualifiedNameAsString() "
+ << store.contextRetrieved;
+ qCDebug(lcClang) << " Context LupdatePrivate::contextForNoopMacro "
+ << LupdatePrivate::contextForNoopMacro(namedDeclaration);
+ qCDebug(lcClang) << " Context Retrieved " << store.contextRetrieved;
+ qCDebug(lcClang) << "=================================================================";
+ store.printStore();
+ }
+ }
}
-void LupdateVisitor::handleTrId(const TranslationRelatedStore &store, bool forcePlural)
+void LupdateVisitor::generateOuput()
{
- if (!store.lupdateIdMetaData.isEmpty())
- qCDebug(lcClang) << "//= is ignored when using qtTrId function \n";
+ qCDebug(lcClang) << "===================generateOuput============================";
- TranslatorMessage msg = fillTranslatorMessage(store, forcePlural, true);
- msg.setId(ParserTool::transcode(store.lupdateId));
- m_tor->append(msg);
-}
-
-void LupdateVisitor::processPreprocessorCalls()
-{
- for (const auto &store : qAsConst(m_translationStoresFromPP))
- processPreprocessorCall(store);
-}
-
-void LupdateVisitor::processPreprocessorCall(TranslationRelatedStore store)
-{
- const std::vector<QString> rawComments = rawCommentsFromSourceLocation(store.callLocation);
- for (const auto &rawComment : rawComments)
- setInfoFromRawComment(rawComment, &store);
+ for (TranslationRelatedStore &store : m_noopTranslationMacroAll) {
+ if (store.contextRetrievedTempNOOP.isEmpty() && store.contextArg.isEmpty())
+ continue;
+ // only fill if a context has been retrieved in the file we're currently visiting
+ m_stores.QNoopTranlsationWithContext.push_back(store);
+ }
- if (store.isValid()) {
- if (store.funcName.contains(QStringLiteral("Q_DECLARE_TR_FUNCTIONS")))
- m_qDeclateTrFunctionContext.push_back(store);
- else
- m_noopTranslationStores.push_back(store);
- store.printStore();
+ for (TranslationRelatedStore &store : m_qDeclareTrMacroAll) {
+ if (store.contextRetrieved.isEmpty())
+ continue;
+ // only fill if a context has been retrieved in the file we're currently visiting
+ m_stores.QDeclareTrWithContext.push_back(store);
}
}
diff --git a/src/linguist/lupdate/clangtoolastreader.h b/src/linguist/lupdate/clangtoolastreader.h
index ea544bdad..8f9a54565 100644
--- a/src/linguist/lupdate/clangtoolastreader.h
+++ b/src/linguist/lupdate/clangtoolastreader.h
@@ -57,17 +57,19 @@ class Translator;
class LupdateVisitor : public clang::RecursiveASTVisitor<LupdateVisitor>
{
public:
- explicit LupdateVisitor(clang::ASTContext *context, Translator *tor)
- : m_context(context),
- m_tor(tor)
+ explicit LupdateVisitor(clang::ASTContext *context, Stores &stores)
+ : m_context(context)
+ , m_stores(stores)
{
m_inputFile = m_context->getSourceManager().getFileEntryForID(
m_context->getSourceManager().getMainFileID())->getName();
}
bool VisitCallExpr(clang::CallExpr *callExpression);
- void fillTranslator();
void processPreprocessorCalls();
+ bool VisitNamedDecl(clang::NamedDecl *namedDeclaration);
+ void findContextForTranslationStoresFromPP(clang::NamedDecl *namedDeclaration);
+ void generateOuput();
private:
std::vector<QString> rawCommentsForCallExpr(const clang::CallExpr *callExpr) const;
@@ -75,30 +77,24 @@ private:
void setInfoFromRawComment(const QString &commentString, TranslationRelatedStore *store);
- void fillTranslator(TranslationRelatedStore store);
- TranslatorMessage fillTranslatorMessage(const TranslationRelatedStore &store,
- bool forcePlural, bool isID = false);
- void handleTr(const TranslationRelatedStore &store, bool forcePlural);
- void handleTrId(const TranslationRelatedStore &store, bool forcePlural);
- void handleTranslate(const TranslationRelatedStore &store, bool forcePlural);
-
void processPreprocessorCall(TranslationRelatedStore store);
clang::ASTContext *m_context { nullptr };
Translator *m_tor { nullptr };
std::string m_inputFile;
- TranslationStores m_translationStoresFromAST;
- TranslationStores m_qDeclateTrFunctionContext;
- TranslationStores m_noopTranslationStores;
- TranslationStores m_translationStoresFromPP;
+ Stores &m_stores;
+
+ TranslationStores m_qDeclareTrMacroAll;
+ TranslationStores m_noopTranslationMacroAll;
+ bool m_macro = false;
};
class LupdateASTConsumer : public clang::ASTConsumer
{
public:
- explicit LupdateASTConsumer(clang::ASTContext *context, Translator *tor)
- : m_visitor(context, tor)
+ explicit LupdateASTConsumer(clang::ASTContext *context, Stores &stores)
+ : m_visitor(context, stores)
{}
// This method is called when the ASTs for entire translation unit have been
@@ -108,7 +104,7 @@ public:
m_visitor.processPreprocessorCalls();
bool traverse = m_visitor.TraverseAST(context);
qCDebug(lcClang) << "TraverseAST: " << traverse;
- m_visitor.fillTranslator();
+ m_visitor.generateOuput();
}
private:
@@ -118,42 +114,42 @@ private:
class LupdateFrontendAction : public clang::ASTFrontendAction
{
public:
- LupdateFrontendAction(Translator *tor)
- : m_tor(tor)
+ LupdateFrontendAction(Stores &outputStoresWithContext)
+ : m_stores(outputStoresWithContext)
{}
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
clang::CompilerInstance &compiler, llvm::StringRef /* inFile */) override
{
- LupdateASTConsumer *consumer = new LupdateASTConsumer(&compiler.getASTContext(), m_tor);
+ auto consumer = new LupdateASTConsumer(&compiler.getASTContext(), m_stores);
return std::unique_ptr<clang::ASTConsumer>(consumer);
}
private:
- Translator *m_tor { nullptr };
+ Stores &m_stores;
};
class LupdateToolActionFactory : public clang::tooling::FrontendActionFactory
{
public:
- LupdateToolActionFactory(Translator *tor)
- : m_tor(tor)
+ LupdateToolActionFactory(Stores &stores)
+ : m_stores(stores)
{}
#if (LUPDATE_CLANG_VERSION >= LUPDATE_CLANG_VERSION_CHECK(10,0,0))
std::unique_ptr<clang::FrontendAction> create() override
{
- return std::make_unique<LupdateFrontendAction>(m_tor);
+ return std::make_unique<LupdateFrontendAction>(m_stores);
}
#else
clang::FrontendAction *create() override
{
- return new LupdateFrontendAction(m_tor);
+ return new LupdateFrontendAction(m_stores);
}
#endif
private:
- Translator *m_tor { nullptr };
+ Stores &m_stores;
};
QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/cpp_clang.cpp b/src/linguist/lupdate/cpp_clang.cpp
index 6b8162c59..fc11253bd 100644
--- a/src/linguist/lupdate/cpp_clang.cpp
+++ b/src/linguist/lupdate/cpp_clang.cpp
@@ -68,8 +68,6 @@ void ClangCppParser::loadCPP(Translator &translator, const QStringList &filename
for (const QString &filename : filenames)
sources.push_back(filename.toStdString());
- // The ClangTool is to be created and run from this function.
-
int argc = 4;
// NEED 2 empty one to start!!! otherwise: LLVM::ERROR
const QByteArray jsonPath = cd.m_compileCommandsPath.toLocal8Bit();
@@ -81,12 +79,10 @@ void ClangCppParser::loadCPP(Translator &translator, const QStringList &filename
Stores stores;
tool.run(new LupdatePreprocessorActionFactory(stores.Preprocessor));
+ tool.run(new LupdateToolActionFactory(stores));
Translator *tor = new Translator();
-
- // A ClangTool needs a new FrontendAction for each translation unit it runs on
- // A Customized FrontendActionFactory is building a customized FrondendAction
- tool.run(new LupdateToolActionFactory(tor));
+ ClangCppParser::fillTranslator(tor, stores);
if (QLoggingCategory("qt.lupdate.clang").isDebugEnabled())
tor->dump();
@@ -95,4 +91,170 @@ void ClangCppParser::loadCPP(Translator &translator, const QStringList &filename
translator.extend(msg, cd);
}
+/*
+ Fill the Translator with the retrieved information after traversing the AST.
+*/
+void ClangCppParser::fillTranslator(Translator *tor, Stores &stores)
+{
+ correctAstTranslationContext(stores);
+ for (auto &store : stores.AST)
+ fillTranslator(tor, store);
+
+ correctNoopTanslationContext(stores);
+ for (auto &store : stores.QNoopTranlsationWithContext)
+ fillTranslator(tor, store);
+}
+
+void ClangCppParser::fillTranslator(Translator *tor, TranslationRelatedStore store)
+{
+ bool plural = false;
+ switch (trFunctionAliasManager.trFunctionByName(store.funcName)) {
+ case TrFunctionAliasManager::Function_Q_DECLARE_TR_FUNCTIONS:
+ break;
+ case TrFunctionAliasManager::Function_QT_TR_N_NOOP:
+ plural = true;
+ Q_FALLTHROUGH();
+ case TrFunctionAliasManager::Function_tr:
+ case TrFunctionAliasManager::Function_trUtf8:
+ case TrFunctionAliasManager::Function_QT_TR_NOOP:
+ case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
+ handleTr(tor, store, plural);
+ break;
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_N_NOOP3:
+ plural = true;
+ Q_FALLTHROUGH();
+ case TrFunctionAliasManager::Function_translate:
+ case TrFunctionAliasManager::Function_findMessage:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
+ handleTranslate(tor, store, plural);
+ break;
+ case TrFunctionAliasManager::Function_QT_TRID_N_NOOP:
+ plural = true;
+ Q_FALLTHROUGH();
+ case TrFunctionAliasManager::Function_qtTrId:
+ case TrFunctionAliasManager::Function_QT_TRID_NOOP:
+ handleTrId(tor, store, plural);
+ break;
+ }
+}
+
+TranslatorMessage ClangCppParser::fillTranslatorMessage(const TranslationRelatedStore &store,
+ const QString &id, bool plural, bool isId)
+{
+ QString context;
+ if (!isId) {
+ context = ParserTool::transcode(store.contextArg.isEmpty() ? store.contextRetrieved
+ : store.contextArg);
+ }
+
+ TranslatorMessage msg(context,
+ ParserTool::transcode(isId ? store.lupdateSourceWhenId
+ : store.lupdateSource),
+ ParserTool::transcode(store.lupdateComment),
+ QString(),
+ store.lupdateLocationFile,
+ store.lupdateLocationLine,
+ QStringList(),
+ TranslatorMessage::Type::Unfinished,
+ (plural ? plural : !store.lupdatePlural.isEmpty()));
+
+ if (!store.lupdateAllMagicMetaData.empty())
+ msg.setExtras(store.lupdateAllMagicMetaData);
+ msg.setExtraComment(ParserTool::transcode(store.lupdateExtraComment));
+ msg.setId(ParserTool::transcode(id));
+ return msg;
+}
+
+void ClangCppParser::handleTranslate(Translator *tor, const TranslationRelatedStore &store,
+ bool plural)
+{
+ if (!store.lupdateSourceWhenId.isEmpty())
+ qCDebug(lcClang) << "//% is ignored when using translate function\n";
+ tor->append(fillTranslatorMessage(store, store.lupdateIdMetaData, plural, false));
+}
+
+void ClangCppParser::handleTr(Translator *tor, const TranslationRelatedStore &store, bool plural)
+{
+ if (!store.lupdateSourceWhenId.isEmpty())
+ qCDebug(lcClang) << "//% is ignored when using tr function\n";
+ if (store.contextRetrieved.isEmpty() && store.contextArg.isEmpty()) {
+ qCDebug(lcClang) << "tr() cannot be called without context \n";
+ return;
+ }
+ tor->append(fillTranslatorMessage(store, store.lupdateIdMetaData, plural, false));
+}
+
+void ClangCppParser::handleTrId(Translator *tor, const TranslationRelatedStore &store, bool plural)
+{
+ if (!store.lupdateIdMetaData.isEmpty())
+ qCDebug(lcClang) << "//= is ignored when using qtTrId function \n";
+ tor->append(fillTranslatorMessage(store, store.lupdateId, plural, true));
+}
+
+void ClangCppParser::correctAstTranslationContext(Stores &stores)
+{
+ for (auto &store : stores.AST) {
+ if (!store.contextArg.isEmpty())
+ continue;
+
+ // If there is a Q_DECLARE_TR_FUNCTION the context given there takes
+ // priority over the retrieved context. The retrieved context for
+ // Q_DECLARE_TR_FUNCTION (where the macro was) has to fit the retrieved
+ // context of the tr function if there is already a argument giving the
+ // context, it has priority
+ for (auto &declareStore : stores.QDeclareTrWithContext) {
+ qCDebug(lcClang) << "----------------------------";
+ qCDebug(lcClang) << "Tr call context retrieved " << store.contextRetrieved;
+ qCDebug(lcClang) << "Tr call source " << store.lupdateSource;
+ qCDebug(lcClang) << "- DECLARE context retrieved " << declareStore.contextRetrieved;
+ qCDebug(lcClang) << "- DECLARE context Arg " << declareStore.contextArg;
+ if (declareStore.contextRetrieved.isEmpty())
+ continue;
+ if (!declareStore.contextRetrieved.startsWith(store.contextRetrieved))
+ continue;
+ if (store.contextRetrieved.size() == declareStore.contextRetrieved.size()) {
+ qCDebug(lcClang) << "* Tr call context retrieved " << store.contextRetrieved;
+ qCDebug(lcClang) << "* DECLARE context retrieved " << declareStore.contextRetrieved;
+ qCDebug(lcClang) << "* DECLARE context Arg " << declareStore.contextArg;
+ store.contextArg = declareStore.contextArg;
+ }
+ }
+ }
+}
+
+void ClangCppParser::correctNoopTanslationContext(Stores &stores)
+{
+ for (auto &store : stores.QNoopTranlsationWithContext) {
+ if (!store.contextArg.isEmpty())
+ continue;
+ qCDebug(lcClang) << "----------------------------";
+ qCDebug(lcClang) << "NOOP call context retrieved Temp" << store.contextRetrievedTempNOOP;
+ qCDebug(lcClang) << "NOOP call source " << store.lupdateSource;
+
+ for (const auto &qDeclare : stores.QDeclareTrWithContext) {
+ bool firstCheck = false;
+ bool secondCheck = false;
+ qCDebug(lcClang) << "- DECLARE context retrieved " << qDeclare.contextRetrieved;
+ qCDebug(lcClang) << "- DECLARE context Arg " << qDeclare.contextArg;
+ if (store.contextRetrievedTempNOOP.startsWith(qDeclare.contextRetrieved)) {
+ firstCheck = (store.contextRetrievedTempNOOP.size() == qDeclare.contextRetrieved.size()
+ || (store.contextRetrievedTempNOOP.at(qDeclare.contextRetrieved.size() + 1)
+ == QLatin1Char(':')));
+ secondCheck = qDeclare.contextRetrieved.size() > store.contextRetrieved.size();
+ if (firstCheck && secondCheck) {
+ store.contextRetrieved = qDeclare.contextRetrieved;
+ store.contextArg = qDeclare.contextArg;
+ qCDebug(lcClang) << "* NOOP call context retrieved " << store.contextRetrieved;
+ qCDebug(lcClang) << "* DECLARE context retrieved " << qDeclare.contextRetrieved;
+ qCDebug(lcClang) << "* DECLARE context Arg " << qDeclare.contextArg;
+ }
+ }
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/cpp_clang.h b/src/linguist/lupdate/cpp_clang.h
index c9d512c5e..acc0157da 100644
--- a/src/linguist/lupdate/cpp_clang.h
+++ b/src/linguist/lupdate/cpp_clang.h
@@ -72,6 +72,7 @@ struct TranslationRelatedStore
qint64 locationCol = -1;
QString contextArg;
QString contextRetrieved;
+ QString contextRetrievedTempNOOP;
QString lupdateSource;
QString lupdateLocationFile;
qint64 lupdateLocationLine = -1;
@@ -189,6 +190,19 @@ namespace LupdatePrivate
namespace ClangCppParser
{
void loadCPP(Translator &translator, const QStringList &filenames, ConversionData &cd);
+
+ void fillTranslator(Translator *tor, Stores &stores);
+ void fillTranslator(Translator *tor, TranslationRelatedStore store);
+
+ TranslatorMessage fillTranslatorMessage(const TranslationRelatedStore &store,
+ const QString &id, bool plural, bool isID);
+
+ void handleTr(Translator *tor, const TranslationRelatedStore &store, bool plural);
+ void handleTrId(Translator *tor, const TranslationRelatedStore &store, bool plural);
+ void handleTranslate(Translator *tor, const TranslationRelatedStore &store, bool plural);
+
+ void correctAstTranslationContext(Stores &stores);
+ void correctNoopTanslationContext(Stores &stores);
}
QT_END_NAMESPACE