diff options
Diffstat (limited to 'src/lib/corelib/language/propertydeclaration.cpp')
-rw-r--r-- | src/lib/corelib/language/propertydeclaration.cpp | 109 |
1 files changed, 87 insertions, 22 deletions
diff --git a/src/lib/corelib/language/propertydeclaration.cpp b/src/lib/corelib/language/propertydeclaration.cpp index 215918462..d56ab3bb0 100644 --- a/src/lib/corelib/language/propertydeclaration.cpp +++ b/src/lib/corelib/language/propertydeclaration.cpp @@ -46,6 +46,7 @@ #include "value.h" #include <api/languageinfo.h> +#include <loader/loaderutils.h> #include <logging/translator.h> #include <tools/error.h> #include <tools/setupprojectparameters.h> @@ -105,7 +106,6 @@ public: DeprecationInfo deprecationInfo; }; - PropertyDeclaration::PropertyDeclaration() : d(new PropertyDeclarationData) { @@ -308,17 +308,78 @@ QVariant PropertyDeclaration::convertToPropertyType(const QVariant &v, Type t, return c; } +QVariant PropertyDeclaration::typedNullValue() const +{ + switch (type()) { + case PropertyDeclaration::Boolean: + return typedNullVariant<bool>(); + case PropertyDeclaration::Integer: + return typedNullVariant<int>(); + case PropertyDeclaration::VariantList: + return typedNullVariant<QVariantList>(); + case PropertyDeclaration::String: + case PropertyDeclaration::Path: + return typedNullVariant<QString>(); + case PropertyDeclaration::StringList: + case PropertyDeclaration::PathList: + return typedNullVariant<QStringList>(); + default: + return {}; + } +} + +bool PropertyDeclaration::shouldCheckAllowedValues() const +{ + return isValid() + && (d->type == PropertyDeclaration::String || d->type == PropertyDeclaration::StringList) + && !d->allowedValues.empty(); +} + +void PropertyDeclaration::checkAllowedValues( + const QVariant &value, + const CodeLocation &loc, + const QString &key, + LoaderState &loaderState) const +{ + const auto type = d->type; + if (!shouldCheckAllowedValues()) + return; + + if (value.isNull()) + return; + + const auto &allowedValues = d->allowedValues; + + const auto checkValue = [&loc, &allowedValues, &key, &loaderState](const QString &value) + { + if (!allowedValues.contains(value)) { + const auto message = Tr::tr("Value '%1' is not allowed for property '%2'.") + .arg(value, key); + ErrorInfo error(message, loc); + handlePropertyError(error, loaderState.parameters(), loaderState.logger()); + } + }; + + if (type == PropertyDeclaration::StringList) { + const auto strings = value.toStringList(); + for (const auto &string: strings) { + checkValue(string); + } + } else if (type == PropertyDeclaration::String) { + checkValue(value.toString()); + } +} + namespace { class PropertyDeclarationCheck : public ValueHandler { public: - PropertyDeclarationCheck(const Set<Item *> &disabledItems, - const SetupProjectParameters ¶ms, Logger &logger) - : m_disabledItems(disabledItems) - , m_params(params) - , m_logger(logger) - { } - void operator()(Item *item) { handleItem(item); } + PropertyDeclarationCheck(LoaderState &loaderState) : m_loaderState(loaderState) {} + void operator()(Item *item) + { + m_checkingProject = item->type() == ItemType::Project; + handleItem(item); + } private: void handle(JSSourceValue *value) override @@ -326,7 +387,7 @@ private: if (!value->createdByPropertiesBlock()) { const ErrorInfo error(Tr::tr("Property '%1' is not declared.") .arg(m_currentName), value->location()); - handlePropertyError(error, m_params, m_logger); + handlePropertyError(error, m_loaderState.parameters(), m_loaderState.logger()); } } void handle(ItemValue *value) override @@ -365,7 +426,7 @@ private: const ErrorInfo error(Tr::tr("Item '%1' is not declared. " "Did you forget to add a Depends item?") .arg(m_currentModuleName.toString()), location); - handlePropertyError(error, m_params, m_logger); + handlePropertyError(error, m_loaderState.parameters(), m_loaderState.logger()); return false; } @@ -373,16 +434,19 @@ private: } void handleItem(Item *item) { + if (m_checkingProject && item->type() == ItemType::Product) + return; if (!m_handledItems.insert(item).second) return; - if (m_disabledItems.contains(item) - || item->type() == ItemType::Module + if (item->type() == ItemType::Module || item->type() == ItemType::Export || (item->type() == ItemType::ModuleInstance && !item->isPresentModule()) || item->type() == ItemType::Properties // The Properties child of a SubProject item is not a regular item. - || item->type() == ItemType::PropertiesInSubProject) { + || item->type() == ItemType::PropertiesInSubProject + + || m_loaderState.topLevelProject().isDisabledItem(item)) { return; } @@ -395,9 +459,12 @@ private: const PropertyDeclaration decl = item->propertyDeclaration(it.key()); if (decl.isValid()) { const ErrorInfo deprecationError = decl.checkForDeprecation( - m_params.deprecationWarningMode(), it.value()->location(), m_logger); - if (deprecationError.hasError()) - handlePropertyError(deprecationError, m_params, m_logger); + m_loaderState.parameters().deprecationWarningMode(), it.value()->location(), + m_loaderState.logger()); + if (deprecationError.hasError()) { + handlePropertyError(deprecationError, m_loaderState.parameters(), + m_loaderState.logger()); + } continue; } m_currentName = it.key(); @@ -429,20 +496,18 @@ private: Item *parentItem() const { return m_parentItems.back(); } - const Set<Item *> &m_disabledItems; + LoaderState &m_loaderState; Set<Item *> m_handledItems; std::vector<Item *> m_parentItems; QualifiedId m_currentModuleName; QString m_currentName; - const SetupProjectParameters &m_params; - Logger &m_logger; + bool m_checkingProject = false; }; } // namespace -void checkPropertyDeclarations(Item *topLevelItem, const Set<Item *> &disabledItems, - const SetupProjectParameters ¶ms, Logger &logger) +void checkPropertyDeclarations(Item *topLevelItem, LoaderState &loaderState) { - PropertyDeclarationCheck(disabledItems, params, logger)(topLevelItem); + (PropertyDeclarationCheck(loaderState))(topLevelItem); } } // namespace Internal |