From eed525793aa22f24f9239f9953c95700ba972ef3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 21 Nov 2016 17:51:07 +0100 Subject: Prohibit use of ambiguous ids Like in QML, we now yield an error if the same item id is defined multiple times in one QBS file. Task-number: QBS-1042 Change-Id: Icdae0a95eff34c432cc1a15b310748dfdbab92eb Reviewed-by: Christian Kandeler --- src/lib/corelib/language/itemreaderastvisitor.cpp | 7 +++++++ src/lib/corelib/language/testdata/id-uniqueness.qbs | 12 ++++++++++++ src/lib/corelib/language/tst_language.cpp | 18 ++++++++++++++++++ src/lib/corelib/language/tst_language.h | 1 + 4 files changed, 38 insertions(+) create mode 100644 src/lib/corelib/language/testdata/id-uniqueness.qbs diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index 15d8768c7..79f66687a 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -204,6 +204,13 @@ bool ItemReaderASTVisitor::visit(AST::UiScriptBinding *ast) throw ErrorInfo(Tr::tr("id: must be followed by identifier")); m_item->m_id = idExp->name.toString(); m_file->ensureIdScope(m_itemPool); + ItemValueConstPtr existingId = m_file->idScope()->itemProperty(m_item->id()); + if (existingId) { + ErrorInfo e(Tr::tr("The id '%1' is not unique.").arg(m_item->id())); + e.append(Tr::tr("First occurrence is here."), existingId->item()->location()); + e.append(Tr::tr("Next occurrence is here."), m_item->location()); + throw e; + } m_file->idScope()->setProperty(m_item->id(), ItemValue::create(m_item)); return false; } diff --git a/src/lib/corelib/language/testdata/id-uniqueness.qbs b/src/lib/corelib/language/testdata/id-uniqueness.qbs new file mode 100644 index 000000000..cfbaf8548 --- /dev/null +++ b/src/lib/corelib/language/testdata/id-uniqueness.qbs @@ -0,0 +1,12 @@ +import qbs 1.0 +import "idusagebase.qbs" as DerivedProduct + +Project { + id: theProject + DerivedProduct { + id: baseProduct // OK - even though 'baseProduct' is used in the base item. + } + DerivedProduct { + id: baseProduct // ERROR + } +} diff --git a/src/lib/corelib/language/tst_language.cpp b/src/lib/corelib/language/tst_language.cpp index f865190eb..b985940df 100644 --- a/src/lib/corelib/language/tst_language.cpp +++ b/src/lib/corelib/language/tst_language.cpp @@ -931,6 +931,24 @@ void TestLanguage::idUsage() QVERIFY(!exceptionCaught); } +void TestLanguage::idUniqueness() +{ + bool exceptionCaught = false; + try { + defaultParameters.setProjectFilePath(testProject("id-uniqueness.qbs")); + loader->loadProject(defaultParameters); + } + catch (const ErrorInfo &e) { + exceptionCaught = true; + const QList items = e.items(); + QCOMPARE(items.count(), 3); + QCOMPARE(items.at(0).toString(), QString::fromUtf8("The id 'baseProduct' is not unique.")); + QVERIFY(items.at(1).toString().contains("id-uniqueness.qbs:6:5 First occurrence is here.")); + QVERIFY(items.at(2).toString().contains("id-uniqueness.qbs:9:5 Next occurrence is here.")); + } + QVERIFY(exceptionCaught); +} + void TestLanguage::importCollection() { bool exceptionCaught = false; diff --git a/src/lib/corelib/language/tst_language.h b/src/lib/corelib/language/tst_language.h index 995609180..c8d6e59f9 100644 --- a/src/lib/corelib/language/tst_language.h +++ b/src/lib/corelib/language/tst_language.h @@ -97,6 +97,7 @@ private slots: void identifierSearch_data(); void identifierSearch(); void idUsage(); + void idUniqueness(); void importCollection(); void invalidBindingInDisabledItem(); void itemPrototype(); -- cgit v1.2.3