aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language/propertydeclaration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/language/propertydeclaration.cpp')
-rw-r--r--src/lib/corelib/language/propertydeclaration.cpp109
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 &params, 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 &params, Logger &logger)
+void checkPropertyDeclarations(Item *topLevelItem, LoaderState &loaderState)
{
- PropertyDeclarationCheck(disabledItems, params, logger)(topLevelItem);
+ (PropertyDeclarationCheck(loaderState))(topLevelItem);
}
} // namespace Internal