summaryrefslogtreecommitdiff
path: root/src/lib/language
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2013-11-14 14:31:13 +0100
committerJoerg Bornemann <joerg.bornemann@digia.com>2013-11-14 14:40:22 +0100
commite91f6b50957c504bd05bba20734c56eb8d6f2f23 (patch)
tree9bd7e563e8530b8db4fb7fdc90b83edfb4f252b3 /src/lib/language
parent154b78e01ad4fdec9c68ca84b9ac0afd8d5a22e8 (diff)
parent4d97182f31e19881d8246324bc1a119b7d77e28a (diff)
downloadqbs-e91f6b50957c504bd05bba20734c56eb8d6f2f23.tar.gz
Merge remote-tracking branch 'origin/1.1'
Change-Id: I7475c4a71c15c83c59400c44ef96d73d15caea58
Diffstat (limited to 'src/lib/language')
-rw-r--r--src/lib/language/builtindeclarations.cpp5
-rw-r--r--src/lib/language/builtindeclarations.h1
-rw-r--r--src/lib/language/language.cpp50
-rw-r--r--src/lib/language/language.h10
-rw-r--r--src/lib/language/moduleloader.cpp16
-rw-r--r--src/lib/language/projectresolver.cpp10
-rw-r--r--src/lib/language/testdata/Banana1
-rw-r--r--src/lib/language/testdata/erroneous/unknown_item_type.qbs3
-rw-r--r--src/lib/language/testdata/filetags.qbs9
-rw-r--r--src/lib/language/tst_language.cpp3
10 files changed, 99 insertions, 9 deletions
diff --git a/src/lib/language/builtindeclarations.cpp b/src/lib/language/builtindeclarations.cpp
index 87beda2fd..ebc876b60 100644
--- a/src/lib/language/builtindeclarations.cpp
+++ b/src/lib/language/builtindeclarations.cpp
@@ -124,6 +124,11 @@ QByteArray BuiltinDeclarations::qmlTypeInfo() const
return result;
}
+bool BuiltinDeclarations::containsType(const QString &typeName) const
+{
+ return m_builtins.contains(typeName);
+}
+
QList<PropertyDeclaration> BuiltinDeclarations::declarationsForType(const QString &typeName) const
{
return m_builtins.value(typeName);
diff --git a/src/lib/language/builtindeclarations.h b/src/lib/language/builtindeclarations.h
index 1f0c26e69..4cbd352a7 100644
--- a/src/lib/language/builtindeclarations.h
+++ b/src/lib/language/builtindeclarations.h
@@ -47,6 +47,7 @@ public:
QString languageVersion() const;
QByteArray qmlTypeInfo() const;
+ bool containsType(const QString &typeName) const;
QList<PropertyDeclaration> declarationsForType(const QString &typeName) const;
void setupItemForBuiltinType(qbs::Internal::Item *item) const;
diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp
index 131b5e4b4..9241af3da 100644
--- a/src/lib/language/language.cpp
+++ b/src/lib/language/language.cpp
@@ -1015,6 +1015,7 @@ template<typename T> bool listsAreEqual(const QList<T> &l1, const QList<T> &l2)
QString keyFromElem(const SourceArtifactPtr &sa) { return sa->absoluteFilePath; }
QString keyFromElem(const ResolvedTransformerConstPtr &t) { return t->transform->sourceCode; }
+QString keyFromElem(const RulePtr &r) { return r->toString(); }
bool operator==(const SourceArtifact &sa1, const SourceArtifact &sa2)
{
@@ -1048,5 +1049,54 @@ bool transformerListsAreEqual(const QList<ResolvedTransformerConstPtr> &l1,
return listsAreEqual(l1, l2);
}
+bool operator==(const Rule &r1, const Rule &r2)
+{
+ if (&r1 == &r2)
+ return true;
+ if (!&r1 != !&r2)
+ return false;
+ if (r1.artifacts.count() != r2.artifacts.count())
+ return false;
+ for (int i = 0; i < r1.artifacts.count(); ++i) {
+ if (*r1.artifacts.at(i) != *r2.artifacts.at(i))
+ return false;
+ }
+
+ return r1.module->name == r2.module->name
+ && r1.script->sourceCode == r2.script->sourceCode
+ && r1.inputs == r2.inputs
+ && r1.auxiliaryInputs == r2.auxiliaryInputs
+ && r1.usings == r2.usings
+ && r1.explicitlyDependsOn == r2.explicitlyDependsOn
+ && r1.multiplex == r2.multiplex;
+}
+
+bool ruleListsAreEqual(const QList<RulePtr> &l1, const QList<RulePtr> &l2)
+{
+ return listsAreEqual(l1, l2);
+}
+
+bool operator==(const RuleArtifact &a1, const RuleArtifact &a2)
+{
+ if (&a1 == &a2)
+ return true;
+ if (!&a1 != !&a2)
+ return false;
+ return a1.fileName == a2.fileName
+ && a1.fileTags == a2.fileTags
+ && a1.alwaysUpdated == a2.alwaysUpdated
+ && a1.bindings.toList().toSet() == a2.bindings.toList().toSet();
+}
+
+bool operator==(const RuleArtifact::Binding &b1, const RuleArtifact::Binding &b2)
+{
+ return b1.code == b2.code && b1.name == b2.name;
+}
+
+uint qHash(const RuleArtifact::Binding &b)
+{
+ return qHash(qMakePair(b.code, b.name.join(QLatin1String(","))));
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/language/language.h b/src/lib/language/language.h
index 98bf2f7f1..a41f1f948 100644
--- a/src/lib/language/language.h
+++ b/src/lib/language/language.h
@@ -113,6 +113,13 @@ private:
void load(PersistentPool &pool);
void store(PersistentPool &pool) const;
};
+uint qHash(const RuleArtifact::Binding &b);
+bool operator==(const RuleArtifact::Binding &b1, const RuleArtifact::Binding &b2);
+inline bool operator!=(const RuleArtifact::Binding &b1, const RuleArtifact::Binding &b2) {
+ return !(b1 == b2);
+}
+bool operator==(const RuleArtifact &a1, const RuleArtifact &a2);
+inline bool operator!=(const RuleArtifact &a1, const RuleArtifact &a2) { return !(a1 == a2); }
class SourceArtifact : public PersistentObject
{
@@ -289,6 +296,9 @@ private:
void load(PersistentPool &pool);
void store(PersistentPool &pool) const;
};
+bool operator==(const Rule &r1, const Rule &r2);
+inline bool operator!=(const Rule &r1, const Rule &r2) { return !(r1 == r2); }
+bool ruleListsAreEqual(const QList<RulePtr> &l1, const QList<RulePtr> &l2);
class ResolvedTransformer : public PersistentObject
{
diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp
index c5d722710..c26e55d76 100644
--- a/src/lib/language/moduleloader.cpp
+++ b/src/lib/language/moduleloader.cpp
@@ -125,14 +125,17 @@ ModuleLoaderResult ModuleLoader::load(const QString &filePath,
class PropertyDeclarationCheck : public ValueHandler
{
+ const BuiltinDeclarations *m_builtins;
const QHash<Item *, QSet<QString> > &m_validItemPropertyNamesPerItem;
const QSet<Item *> &m_disabledItems;
Item *m_parentItem;
QString m_currentName;
public:
- PropertyDeclarationCheck(const QHash<Item *, QSet<QString> > &validItemPropertyNamesPerItem,
+ PropertyDeclarationCheck(const BuiltinDeclarations *builtins,
+ const QHash<Item *, QSet<QString> > &validItemPropertyNamesPerItem,
const QSet<Item *> &disabledItems)
- : m_validItemPropertyNamesPerItem(validItemPropertyNamesPerItem)
+ : m_builtins(builtins)
+ , m_validItemPropertyNamesPerItem(validItemPropertyNamesPerItem)
, m_disabledItems(disabledItems)
, m_parentItem(0)
{
@@ -169,6 +172,12 @@ private:
void handleItem(Item *item)
{
+ if (Q_UNLIKELY(!item->typeName().isEmpty()
+ && !m_builtins->containsType(item->typeName()))) {
+ const QString msg = Tr::tr("Unexpected item type '%1'.");
+ throw ErrorInfo(msg.arg(item->typeName()), item->location());
+ }
+
if (m_disabledItems.contains(item) || item->typeName() == QLatin1String("SubProject"))
return;
@@ -249,7 +258,8 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, Item *item,
}
}
- PropertyDeclarationCheck check(m_validItemPropertyNamesPerItem, m_disabledItems);
+ PropertyDeclarationCheck check(m_reader->builtins(), m_validItemPropertyNamesPerItem,
+ m_disabledItems);
check(item);
m_reader->popExtraSearchPaths();
diff --git a/src/lib/language/projectresolver.cpp b/src/lib/language/projectresolver.cpp
index af6f0a164..b71f16f2f 100644
--- a/src/lib/language/projectresolver.cpp
+++ b/src/lib/language/projectresolver.cpp
@@ -840,13 +840,14 @@ void ProjectResolver::applyFileTaggers(const SourceArtifactPtr &artifact,
const ResolvedProductConstPtr &product) const
{
if (!artifact->overrideFileTags || artifact->fileTags.isEmpty()) {
- const FileTags fileTags = product->fileTagsForFileName(artifact->absoluteFilePath);
+ const QString fileName = FileInfo::fileName(artifact->absoluteFilePath);
+ const FileTags fileTags = product->fileTagsForFileName(fileName);
artifact->fileTags.unite(fileTags);
if (artifact->fileTags.isEmpty())
artifact->fileTags.insert(unknownFileTag());
if (m_logger.traceEnabled())
m_logger.qbsTrace() << "[PR] adding file tags " << artifact->fileTags
- << " to " << FileInfo::fileName(artifact->absoluteFilePath);
+ << " to " << fileName;
}
}
@@ -974,10 +975,7 @@ void ProjectResolver::callItemFunction(const ItemFuncMap &mappings, Item *item,
{
const QByteArray typeName = item->typeName().toLocal8Bit();
ItemFuncPtr f = mappings.value(typeName);
- if (Q_UNLIKELY(!f)) {
- const QString msg = Tr::tr("Unexpected item type '%1'.");
- throw ErrorInfo(msg.arg(item->typeName()), item->location());
- }
+ QBS_CHECK(f);
if (typeName == "Project") {
ProjectContext subProjectContext = createProjectContext(projectContext);
(this->*f)(item, &subProjectContext);
diff --git a/src/lib/language/testdata/Banana b/src/lib/language/testdata/Banana
new file mode 100644
index 000000000..53164be8a
--- /dev/null
+++ b/src/lib/language/testdata/Banana
@@ -0,0 +1 @@
+Peanut butter jelly time!
diff --git a/src/lib/language/testdata/erroneous/unknown_item_type.qbs b/src/lib/language/testdata/erroneous/unknown_item_type.qbs
new file mode 100644
index 000000000..9e34e9243
--- /dev/null
+++ b/src/lib/language/testdata/erroneous/unknown_item_type.qbs
@@ -0,0 +1,3 @@
+Narf {
+ zort: 1 // This invalid binding should not hide the "Unexpected item type" error.
+}
diff --git a/src/lib/language/testdata/filetags.qbs b/src/lib/language/testdata/filetags.qbs
index 97cccd510..38182e5f1 100644
--- a/src/lib/language/testdata/filetags.qbs
+++ b/src/lib/language/testdata/filetags.qbs
@@ -21,6 +21,15 @@ Project {
}
Product {
+ name: "filetagger_static_pattern"
+ files: "Banana"
+ FileTagger {
+ patterns: "Banana"
+ fileTags: ["yellow"]
+ }
+ }
+
+ Product {
name: "unknown_file_tag"
files: "narf.zort"
}
diff --git a/src/lib/language/tst_language.cpp b/src/lib/language/tst_language.cpp
index 268711ab0..bb984c3fc 100644
--- a/src/lib/language/tst_language.cpp
+++ b/src/lib/language/tst_language.cpp
@@ -347,6 +347,8 @@ void TestLanguage::erroneousFiles_data()
<< "Item 'cpp' is not declared.";
QTest::newRow("undeclared_property")
<< "Property 'doesntexist' is not declared.";
+ QTest::newRow("unknown_item_type")
+ << "Unexpected item type 'Narf'";
}
void TestLanguage::erroneousFiles()
@@ -1154,6 +1156,7 @@ void TestLanguage::fileTags_data()
QTest::newRow("init") << 0 << QStringList();
QTest::newRow("filetagger_project_scope") << 1 << (QStringList() << "cpp");
QTest::newRow("filetagger_product_scope") << 1 << (QStringList() << "asm");
+ QTest::newRow("filetagger_static_pattern") << 1 << (QStringList() << "yellow");
QTest::newRow("unknown_file_tag") << 1 << (QStringList() << "unknown-file-tag");
QTest::newRow("set_file_tag_via_group") << 2 << (QStringList() << "c++");
QTest::newRow("override_file_tag_via_group") << 2 << (QStringList() << "c++");