aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2018-01-11 14:43:31 +0100
committerJoerg Bornemann <joerg.bornemann@qt.io>2018-01-17 06:37:46 +0000
commit712c5474b08af11b34c37b545f4e2b7baab27a9f (patch)
treef1794f9951b96f2e10222b80d0bf73fba7ebfb50 /src
parent45a1fab55d3330bc8b581e68023e4cea8fd5065c (diff)
Fix id pointer of base items
In the following example the name of the derived product should be "derived", but it was "base". ---BaseProduct.qbs--- Product { id: baseProduct property string foo: "base" name: baseProduct.foo } --derived.qbs-- BaseProduct { foo: "derived" } The id baseProduct still pointed to the Product item originally imported from BaseProduct.qbs. Fix the item pointers in the base id scopes when handling item inheritance. Task-number: QBS-1016 Task-number: QBS-1262 Change-Id: Id11b98aa6780f8bbbda86fda5a7d11a0e006d889 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/lib/corelib/language/itemreaderastvisitor.cpp38
-rw-r--r--src/lib/corelib/language/itemreadervisitorstate.cpp10
-rw-r--r--src/lib/corelib/language/itemreadervisitorstate.h4
3 files changed, 49 insertions, 3 deletions
diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp
index 86274b1c2..d6b89a2d5 100644
--- a/src/lib/corelib/language/itemreaderastvisitor.cpp
+++ b/src/lib/corelib/language/itemreaderastvisitor.cpp
@@ -59,6 +59,8 @@
#include <tools/stringconstants.h>
#include <logging/translator.h>
+#include <algorithm>
+
using namespace QbsQmlJS;
namespace qbs {
@@ -81,11 +83,29 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList)
return false;
}
+static ItemValuePtr findItemProperty(const Item *container, const Item *item)
+{
+ ItemValuePtr itemValue;
+ const auto &srcprops = container->properties();
+ auto it = std::find_if(srcprops.begin(), srcprops.end(), [item] (const ValuePtr &v) {
+ return v->type() == Value::ItemValueType
+ && std::static_pointer_cast<ItemValue>(v)->item() == item;
+ });
+ if (it != srcprops.end())
+ itemValue = std::static_pointer_cast<ItemValue>(it.value());
+ return itemValue;
+}
+
bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
{
const QString typeName = ast->qualifiedTypeNameId->name.toString();
const CodeLocation itemLocation = toCodeLocation(ast->qualifiedTypeNameId->identifierToken);
const Item *baseItem = nullptr;
+ Item *mostDerivingItem = nullptr;
+
+ Item *item = Item::create(m_itemPool, ItemType::Unknown);
+ item->setFile(m_file);
+ item->setLocation(itemLocation);
// Inheritance resolving, part 1: Find out our actual type name (needed for setting
// up children and alternatives).
@@ -93,7 +113,13 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
const QString baseTypeFileName = m_typeNameToFile.value(fullTypeName);
ItemType itemType;
if (!baseTypeFileName.isEmpty()) {
+ const bool isMostDerivingItem = (m_visitorState.mostDerivingItem() == nullptr);
+ if (isMostDerivingItem)
+ m_visitorState.setMostDerivingItem(item);
+ mostDerivingItem = m_visitorState.mostDerivingItem();
baseItem = m_visitorState.readFile(baseTypeFileName, m_file->searchPaths(), m_itemPool);
+ if (isMostDerivingItem)
+ m_visitorState.setMostDerivingItem(nullptr);
QBS_CHECK(baseItem->type() <= ItemType::LastActualItem);
itemType = baseItem->type();
} else {
@@ -107,9 +133,7 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
itemType = ItemType::PropertiesInSubProject;
}
- Item *item = Item::create(m_itemPool, itemType);
- item->setFile(m_file);
- item->setLocation(itemLocation);
+ item->m_type = itemType;
if (m_item)
Item::addChild(m_item, item); // Add this item to the children of the parent item.
@@ -117,9 +141,12 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
m_item = item; // This is the root item.
if (ast->initializer) {
+ Item *mdi = m_visitorState.mostDerivingItem();
+ m_visitorState.setMostDerivingItem(nullptr);
qSwap(m_item, item);
ast->initializer->accept(this);
qSwap(m_item, item);
+ m_visitorState.setMostDerivingItem(mdi);
}
ASTPropertiesItemHandler(item).handlePropertiesItems();
@@ -132,6 +159,11 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
// ### Do we want to turn off this feature? It's QMLish but kind of strange.
item->file()->ensureIdScope(m_itemPool);
baseItem->file()->idScope()->setPrototype(item->file()->idScope());
+
+ // Replace the base item with the most deriving item.
+ ItemValuePtr baseItemIdValue = findItemProperty(baseItem->file()->idScope(), baseItem);
+ if (baseItemIdValue)
+ baseItemIdValue->setItem(mostDerivingItem);
}
} else {
// Only the item at the top of the inheritance chain is a built-in item.
diff --git a/src/lib/corelib/language/itemreadervisitorstate.cpp b/src/lib/corelib/language/itemreadervisitorstate.cpp
index a48f081ff..ca6ba2e12 100644
--- a/src/lib/corelib/language/itemreadervisitorstate.cpp
+++ b/src/lib/corelib/language/itemreadervisitorstate.cpp
@@ -186,6 +186,16 @@ bool ItemReaderVisitorState::findDirectoryEntries(const QString &dirPath, QStrin
return true;
}
+Item *ItemReaderVisitorState::mostDerivingItem() const
+{
+ return m_mostDerivingItem;
+}
+
+void ItemReaderVisitorState::setMostDerivingItem(Item *item)
+{
+ m_mostDerivingItem = item;
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/language/itemreadervisitorstate.h b/src/lib/corelib/language/itemreadervisitorstate.h
index a72d5fe3a..0eab34dbb 100644
--- a/src/lib/corelib/language/itemreadervisitorstate.h
+++ b/src/lib/corelib/language/itemreadervisitorstate.h
@@ -64,10 +64,14 @@ public:
void cacheDirectoryEntries(const QString &dirPath, const QStringList &entries);
bool findDirectoryEntries(const QString &dirPath, QStringList *entries) const;
+ Item *mostDerivingItem() const;
+ void setMostDerivingItem(Item *item);
+
private:
Logger &m_logger;
Set<QString> m_filesRead;
QHash<QString, QStringList> m_directoryEntries;
+ Item *m_mostDerivingItem = nullptr;
class ASTCache;
ASTCache * const m_astCache;