diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2018-01-11 14:43:31 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2018-01-17 06:37:46 +0000 |
commit | 712c5474b08af11b34c37b545f4e2b7baab27a9f (patch) | |
tree | f1794f9951b96f2e10222b80d0bf73fba7ebfb50 /src | |
parent | 45a1fab55d3330bc8b581e68023e4cea8fd5065c (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.cpp | 38 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreadervisitorstate.cpp | 10 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreadervisitorstate.h | 4 |
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; |