diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-07-24 11:10:28 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-08-03 09:52:57 +0000 |
commit | 3b95913c674edcdf94eea673aa81d4f670231555 (patch) | |
tree | 4c8136e08faeedcd351e75301f6ebe0276988df0 | |
parent | de14d18638b6aaf7c52847fec2e534f50c14b95d (diff) |
Add FileTagger.priority
Enable users to override FileTagger items by creating a conflicting
FileTagger that has a higher numerical priority value.
[ChangeLog] Introduced the property FileTagger.priority, and enable
users to override FileTagger items.
Change-Id: Idc6f5d003b7ad468f03a2eae5d19404c1f3eb06b
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | doc/reference/items/language/filetagger.qdoc | 26 | ||||
-rw-r--r-- | src/lib/corelib/language/builtindeclarations.cpp | 1 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluator.cpp | 9 | ||||
-rw-r--r-- | src/lib/corelib/language/evaluator.h | 2 | ||||
-rw-r--r-- | src/lib/corelib/language/language.cpp | 17 | ||||
-rw-r--r-- | src/lib/corelib/language/language.h | 9 | ||||
-rw-r--r-- | src/lib/corelib/language/projectresolver.cpp | 8 | ||||
-rw-r--r-- | tests/auto/language/testdata/filetags.qbs | 20 | ||||
-rw-r--r-- | tests/auto/language/tst_language.cpp | 1 |
9 files changed, 85 insertions, 8 deletions
diff --git a/doc/reference/items/language/filetagger.qdoc b/doc/reference/items/language/filetagger.qdoc index 4a87824f2..55fbb4ac9 100644 --- a/doc/reference/items/language/filetagger.qdoc +++ b/doc/reference/items/language/filetagger.qdoc @@ -34,9 +34,21 @@ \keyword QML.FileTagger \title FileTagger Item - \brief Maps file patterns to tags. + \brief Assigns file tags to files. - This item maps file patterns to tags. It can be attached to a product or a module. + This item assigns file tags to files. + The FileTagger item can appear in \c{Product} items or \c{Module} items. + + For every source artifact that has no file tag, \QBS will search for a + FileTagger with a pattern that matches the file name of the source + artifact. If a matching file tagger is found, then the file tags specified + in the FileTagger item are assigned to the source artifact. + + If there is more than one matching FileTagger, all file taggers with the + same highest priority are taken into account and their file tags are + accumulated. + + The FileTagger item can be attached to a product or a module. In the latter case, its effect is the same as if it had been attached to all products having a dependency on the respective module. For instance, the cpp module of \QBS has, among others, the following file tagger: @@ -71,17 +83,27 @@ \li Property \li Type \li Default + \li Since \li Description \row \li patterns \li stringList \li none + \li 1.0 \li The patterns to match against. Supports the usual wildcards '*', '?' and '[]'. Neither the list itself nor any of its elements may be empty. \row \li fileTags \li list \li empty list + \li 1.0 \li Tags to attach to a product's files. These can then be matched by a rule. + \row + \li priority + \li int + \li 0 + \li 1.10 + \li The priority of the FileTagger. A higher numerical value means + higher priority. \endtable */ diff --git a/src/lib/corelib/language/builtindeclarations.cpp b/src/lib/corelib/language/builtindeclarations.cpp index c8ad3c245..32a85665d 100644 --- a/src/lib/corelib/language/builtindeclarations.cpp +++ b/src/lib/corelib/language/builtindeclarations.cpp @@ -235,6 +235,7 @@ void BuiltinDeclarations::addFileTaggerItem() item << conditionProperty(); item << PropertyDeclaration(QLatin1String("patterns"), PropertyDeclaration::StringList); item << PropertyDeclaration(QLatin1String("fileTags"), PropertyDeclaration::StringList); + item << PropertyDeclaration(QLatin1String("priority"), PropertyDeclaration::Integer); insert(item); } diff --git a/src/lib/corelib/language/evaluator.cpp b/src/lib/corelib/language/evaluator.cpp index c4b5419fb..193e73618 100644 --- a/src/lib/corelib/language/evaluator.cpp +++ b/src/lib/corelib/language/evaluator.cpp @@ -92,6 +92,15 @@ bool Evaluator::boolValue(const Item *item, const QString &name, bool defaultVal return v.toBool(); } +int Evaluator::intValue(const Item *item, const QString &name, int defaultValue, + bool *propertyWasSet) +{ + QScriptValue v; + if (!evaluateProperty(&v, item, name, propertyWasSet)) + return defaultValue; + return v.toInt32(); +} + FileTags Evaluator::fileTagsValue(const Item *item, const QString &name, bool *propertySet) { return FileTags::fromStringList(stringListValue(item, name, propertySet)); diff --git a/src/lib/corelib/language/evaluator.h b/src/lib/corelib/language/evaluator.h index 80ab9a3b4..840c808ed 100644 --- a/src/lib/corelib/language/evaluator.h +++ b/src/lib/corelib/language/evaluator.h @@ -69,6 +69,8 @@ public: QScriptValue value(const Item *item, const QString &name, bool *propertySet = 0); bool boolValue(const Item *item, const QString &name, bool defaultValue = false, bool *propertyWasSet = 0); + int intValue(const Item *item, const QString &name, int defaultValue = 0, + bool *propertyWasSet = 0); FileTags fileTagsValue(const Item *item, const QString &name, bool *propertySet = 0); QString stringValue(const Item *item, const QString &name, const QString &defaultValue = QString(), bool *propertyWasSet = 0); diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp index 4c66b4e16..988e7489e 100644 --- a/src/lib/corelib/language/language.cpp +++ b/src/lib/corelib/language/language.cpp @@ -69,6 +69,7 @@ #include <QtScript/qscriptvalue.h> #include <algorithm> +#include <memory> #include <mutex> namespace qbs { @@ -84,8 +85,8 @@ template<typename T> bool equals(const T *v1, const T *v2) } -FileTagger::FileTagger(const QStringList &patterns, const FileTags &fileTags) - : m_fileTags(fileTags) +FileTagger::FileTagger(const QStringList &patterns, const FileTags &fileTags, int priority) + : m_fileTags(fileTags), m_priority(priority) { setPatterns(patterns); } @@ -107,6 +108,7 @@ void FileTagger::load(PersistentPool &pool) { setPatterns(pool.load<QStringList>()); pool.load(m_fileTags); + pool.load(m_priority); } void FileTagger::store(PersistentPool &pool) const @@ -116,6 +118,7 @@ void FileTagger::store(PersistentPool &pool) const patterns << regExp.pattern(); pool.store(patterns); pool.store(m_fileTags); + pool.store(m_priority); } @@ -501,9 +504,19 @@ QList<SourceArtifactPtr> ResolvedProduct::allEnabledFiles() const FileTags ResolvedProduct::fileTagsForFileName(const QString &fileName) const { FileTags result; + std::unique_ptr<int> priority; for (const FileTaggerConstPtr &tagger : qAsConst(fileTaggers)) { for (const QRegExp &pattern : tagger->patterns()) { if (FileInfo::globMatches(pattern, fileName)) { + if (priority) { + if (*priority != tagger->priority()) { + // The taggers are expected to be sorted by priority. + QBS_ASSERT(*priority > tagger->priority(), return result); + return result; + } + } else { + priority.reset(new int(tagger->priority())); + } result.unite(tagger->fileTags()); break; } diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h index 4df1fd976..64d51a47f 100644 --- a/src/lib/corelib/language/language.h +++ b/src/lib/corelib/language/language.h @@ -78,15 +78,17 @@ class FileTagger : public PersistentObject { public: static FileTaggerPtr create() { return FileTaggerPtr(new FileTagger); } - static FileTaggerPtr create(const QStringList &patterns, const FileTags &fileTags) { - return FileTaggerPtr(new FileTagger(patterns, fileTags)); + static FileTaggerPtr create(const QStringList &patterns, const FileTags &fileTags, + int priority) { + return FileTaggerPtr(new FileTagger(patterns, fileTags, priority)); } const QList<QRegExp> &patterns() const { return m_patterns; } const FileTags &fileTags() const { return m_fileTags; } + int priority() const { return m_priority; } private: - FileTagger(const QStringList &patterns, const FileTags &fileTags); + FileTagger(const QStringList &patterns, const FileTags &fileTags, int priority); FileTagger() {} void setPatterns(const QStringList &patterns); @@ -96,6 +98,7 @@ private: QList<QRegExp> m_patterns; FileTags m_fileTags; + int m_priority = 0; }; class Probe : public PersistentObject diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index 348b0af42..d1d70e445 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -943,7 +943,9 @@ void ProjectResolver::resolveFileTagger(Item *item, ProjectContext *projectConte if (pattern.isEmpty()) throw ErrorInfo(Tr::tr("A FileTagger pattern must not be empty."), item->location()); } - fileTaggers += FileTagger::create(patterns, fileTags); + + const int priority = m_evaluator->intValue(item, QLatin1String("priority")); + fileTaggers += FileTagger::create(patterns, fileTags, priority); } void ProjectResolver::resolveScanner(Item *item, ProjectResolver::ProjectContext *projectContext) @@ -1185,6 +1187,10 @@ void ProjectResolver::postProcess(const ResolvedProductPtr &product, ProjectContext *projectContext) const { product->fileTaggers += projectContext->fileTaggers; + std::sort(std::begin(product->fileTaggers), std::end(product->fileTaggers), + [] (const FileTaggerConstPtr &a, const FileTaggerConstPtr &b) { + return a->priority() > b->priority(); + }); for (const RulePtr &rule : qAsConst(projectContext->rules)) { RulePtr clonedRule = rule->clone(); clonedRule->product = product.get(); diff --git a/tests/auto/language/testdata/filetags.qbs b/tests/auto/language/testdata/filetags.qbs index eb1cf57c6..b2a85f953 100644 --- a/tests/auto/language/testdata/filetags.qbs +++ b/tests/auto/language/testdata/filetags.qbs @@ -58,4 +58,24 @@ Project { fileTags: ["zzz"] } } + + Product { + name: "prioritized_filetagger" + files: ["main.cpp"] + FileTagger { + patterns: ["*.cpp"] + fileTags: ["cpp1"] + priority: 3 + } + FileTagger { + patterns: ["*.cpp"] + fileTags: ["cpp2"] + priority: 3 + } + FileTagger { + patterns: ["*.cpp"] + fileTags: ["ignored"] + priority: 2 + } + } } diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index fc04f9e6a..78a8caf1a 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -2305,6 +2305,7 @@ void TestLanguage::fileTags_data() QTest::newRow("set_file_tag_via_group") << 2 << (QStringList() << "c++"); QTest::newRow("override_file_tag_via_group") << 2 << (QStringList() << "c++"); QTest::newRow("add_file_tag_via_group") << 2 << (QStringList() << "cpp" << "zzz"); + QTest::newRow("prioritized_filetagger") << 1 << (QStringList() << "cpp1" << "cpp2"); QTest::newRow("cleanup") << 0 << QStringList(); } |