diff options
| author | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-07-23 16:34:48 +0200 |
|---|---|---|
| committer | Christian Kandeler <christian.kandeler@digia.com> | 2013-07-23 17:56:07 +0200 |
| commit | 173762952caf40f9e6c852dbd63a4e68138b00c1 (patch) | |
| tree | e4df47c77aadd1b666e580c7fc204a4d58117659 | |
| parent | 327ad082299011c57145d0d6a5bc3bf70fdeeda9 (diff) | |
| download | qbs-173762952caf40f9e6c852dbd63a4e68138b00c1.tar.gz | |
adhere to property types in profiles
This amends 8a059586cc109f97b2cfc456cb4262009191ce2b.
Change-Id: Ib560bd1f72ce3020b1dacb384bfd007a964a6d51
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
| -rw-r--r-- | src/lib/language/moduleloader.cpp | 127 | ||||
| -rw-r--r-- | src/lib/language/testdata/profilevaluesandoverriddenvalues.qbs | 10 |
2 files changed, 74 insertions, 63 deletions
diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp index 7f51bc422..8d738123c 100644 --- a/src/lib/language/moduleloader.cpp +++ b/src/lib/language/moduleloader.cpp @@ -591,6 +591,67 @@ Item *ModuleLoader::searchAndLoadModuleFile(ProductContext *productContext, return 0; } +// returns QVariant::Invalid for types that do not need conversion +static QVariant::Type variantType(PropertyDeclaration::Type t) +{ + switch (t) { + case PropertyDeclaration::UnknownType: + break; + case PropertyDeclaration::Boolean: + return QVariant::Bool; + case PropertyDeclaration::Integer: + return QVariant::Int; + case PropertyDeclaration::Path: + return QVariant::String; + case PropertyDeclaration::PathList: + return QVariant::StringList; + case PropertyDeclaration::String: + return QVariant::String; + case PropertyDeclaration::StringList: + return QVariant::StringList; + case PropertyDeclaration::Variant: + break; + case PropertyDeclaration::Verbatim: + return QVariant::String; + } + return QVariant::Invalid; +} + +static QVariant convertToPropertyType(const QVariant &v, PropertyDeclaration::Type t, + const QStringList &namePrefix, const QString &key) +{ + if (v.isNull() || !v.isValid()) + return v; + const QVariant::Type vt = variantType(t); + if (vt == QVariant::Invalid) + return v; + + // Handle the foo,bar,bla stringlist syntax. + if (t == PropertyDeclaration::StringList && v.type() == QVariant::String) + return v.toString().split(QLatin1Char(',')); + + QVariant c = v; + if (!c.convert(vt)) { + QStringList name = namePrefix; + name << key; + throw ErrorInfo(Tr::tr("Value '%1' of property '%2' has incompatible type.") + .arg(v.toString(), name.join(QLatin1String(".")))); + } + return c; +} + +static PropertyDeclaration firstValidPropertyDeclaration(Item *item, const QString &name) +{ + PropertyDeclaration decl; + do { + decl = item->propertyDeclarations().value(name); + if (decl.isValid()) + return decl; + item = item->prototype(); + } while (item); + return decl; +} + Item *ModuleLoader::loadModuleFile(ProductContext *productContext, const QString &fullModuleName, bool isBaseModule, const QString &filePath) { @@ -628,7 +689,10 @@ Item *ModuleLoader::loadModuleFile(ProductContext *productContext, const QString { if (Q_UNLIKELY(!module->hasProperty(vmit.key()))) throw ErrorInfo(Tr::tr("Unknown property: %1.%2").arg(fullModuleName, vmit.key())); - module->setProperty(vmit.key(), VariantValue::create(vmit.value())); + const PropertyDeclaration decl = firstValidPropertyDeclaration(module, vmit.key()); + module->setProperty(vmit.key(), + VariantValue::create(convertToPropertyType(vmit.value(), decl.type, + QStringList(fullModuleName), vmit.key()))); } productContext->moduleItemCache.insert(filePath, module); @@ -667,67 +731,6 @@ static QList<Item *> collectItemsWithId(Item *item) return result; } -// returns QVariant::Invalid for types that do not need conversion -static QVariant::Type variantType(PropertyDeclaration::Type t) -{ - switch (t) { - case PropertyDeclaration::UnknownType: - break; - case PropertyDeclaration::Boolean: - return QVariant::Bool; - case PropertyDeclaration::Integer: - return QVariant::Int; - case PropertyDeclaration::Path: - return QVariant::String; - case PropertyDeclaration::PathList: - return QVariant::StringList; - case PropertyDeclaration::String: - return QVariant::String; - case PropertyDeclaration::StringList: - return QVariant::StringList; - case PropertyDeclaration::Variant: - break; - case PropertyDeclaration::Verbatim: - return QVariant::String; - } - return QVariant::Invalid; -} - -static QVariant convertToPropertyType(const QVariant &v, PropertyDeclaration::Type t, - const QStringList &namePrefix, const QString &key) -{ - if (v.isNull() || !v.isValid()) - return v; - const QVariant::Type vt = variantType(t); - if (vt == QVariant::Invalid) - return v; - - // Handle the foo,bar,bla stringlist syntax. - if (t == PropertyDeclaration::StringList && v.type() == QVariant::String) - return v.toString().split(QLatin1Char(',')); - - QVariant c = v; - if (!c.convert(vt)) { - QStringList name = namePrefix; - name << key; - throw ErrorInfo(Tr::tr("Value '%1' of property '%2' has incompatible type.") - .arg(v.toString(), name.join(QLatin1String(".")))); - } - return c; -} - -static PropertyDeclaration firstValidPropertyDeclaration(Item *item, const QString &name) -{ - PropertyDeclaration decl; - do { - decl = item->propertyDeclarations().value(name); - if (decl.isValid()) - return decl; - item = item->prototype(); - } while (item); - return decl; -} - void ModuleLoader::instantiateModule(ProductContext *productContext, Item *instanceScope, Item *moduleInstance, Item *modulePrototype, const QStringList &moduleName) diff --git a/src/lib/language/testdata/profilevaluesandoverriddenvalues.qbs b/src/lib/language/testdata/profilevaluesandoverriddenvalues.qbs index d3a18bcb5..cc1b7b2a2 100644 --- a/src/lib/language/testdata/profilevaluesandoverriddenvalues.qbs +++ b/src/lib/language/testdata/profilevaluesandoverriddenvalues.qbs @@ -2,7 +2,15 @@ import qbs 1.0 Project { Application { - name: "product1" + name: { + if (!(dummy.cFlags instanceof Array)) + throw new Error("dummy.cFlags: Array type expected."); + if (!(dummy.cxxFlags instanceof Array)) + throw new Error("dummy.cxxFlags: Array type expected."); + if (!(dummy.defines instanceof Array)) + throw new Error("dummy.defines: Array type expected."); + return "product1"; + } Depends { name: "dummy" } // dummy.cxxFlags is set via profile and is not overridden dummy.defines: ["IN_FILE"] // set in profile, overridden in file |
