QShaderGenerator: stop abusing from auto everywhere

Leads to a huge loss of context for people trying to understand
and maintain that code. Replacing with proper types to ensure
better readability and maintenance.

Change-Id: I9900b743e8b7fe11bcc7db9ce3191c89f8718afc
Reviewed-by: Mike Krus <mike.krus@kdab.com>
bb10
Paul Lemire 2019-03-29 09:29:58 +01:00
parent 4b445481c3
commit d92f63122b
4 changed files with 137 additions and 133 deletions

View File

@ -260,21 +260,22 @@ namespace
QByteArray replaceParameters(const QByteArray &original, const QShaderNode &node, const QShaderFormat &format)
{
auto result = original;
QByteArray result = original;
for (const auto &parameterName : node.parameterNames()) {
const auto placeholder = QByteArray(QByteArrayLiteral("$") + parameterName.toUtf8());
const auto parameter = node.parameter(parameterName);
const QStringList parameterNames = node.parameterNames();
for (const QString &parameterName : parameterNames) {
const QByteArray placeholder = QByteArray(QByteArrayLiteral("$") + parameterName.toUtf8());
const QVariant parameter = node.parameter(parameterName);
if (parameter.userType() == qMetaTypeId<QShaderLanguage::StorageQualifier>()) {
const auto qualifier = parameter.value<QShaderLanguage::StorageQualifier>();
const auto value = toGlsl(qualifier, format);
const QShaderLanguage::StorageQualifier qualifier = parameter.value<QShaderLanguage::StorageQualifier>();
const QByteArray value = toGlsl(qualifier, format);
result.replace(placeholder, value);
} else if (parameter.userType() == qMetaTypeId<QShaderLanguage::VariableType>()) {
const auto type = parameter.value<QShaderLanguage::VariableType>();
const auto value = toGlsl(type);
const QShaderLanguage::VariableType type = parameter.value<QShaderLanguage::VariableType>();
const QByteArray value = toGlsl(type);
result.replace(placeholder, value);
} else {
const auto value = parameter.toString().toUtf8();
const QByteArray value = parameter.toString().toUtf8();
result.replace(placeholder, value);
}
}
@ -288,20 +289,20 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
auto code = QByteArrayList();
if (format.isValid()) {
const auto isGLES = format.api() == QShaderFormat::OpenGLES;
const auto major = format.version().majorVersion();
const auto minor = format.version().minorVersion();
const bool isGLES = format.api() == QShaderFormat::OpenGLES;
const int major = format.version().majorVersion();
const int minor = format.version().minorVersion();
const auto version = major == 2 && isGLES ? 100
: major == 3 && isGLES ? 300
: major == 2 ? 100 + 10 * (minor + 1)
: major == 3 && minor <= 2 ? 100 + 10 * (minor + 3)
: major * 100 + minor * 10;
const int version = major == 2 && isGLES ? 100
: major == 3 && isGLES ? 300
: major == 2 ? 100 + 10 * (minor + 1)
: major == 3 && minor <= 2 ? 100 + 10 * (minor + 3)
: major * 100 + minor * 10;
const auto profile = isGLES && version > 100 ? QByteArrayLiteral(" es")
: version >= 150 && format.api() == QShaderFormat::OpenGLCoreProfile ? QByteArrayLiteral(" core")
: version >= 150 && format.api() == QShaderFormat::OpenGLCompatibilityProfile ? QByteArrayLiteral(" compatibility")
: QByteArray();
const QByteArray profile = isGLES && version > 100 ? QByteArrayLiteral(" es")
: version >= 150 && format.api() == QShaderFormat::OpenGLCoreProfile ? QByteArrayLiteral(" core")
: version >= 150 && format.api() == QShaderFormat::OpenGLCompatibilityProfile ? QByteArrayLiteral(" compatibility")
: QByteArray();
code << (QByteArrayLiteral("#version ") + QByteArray::number(version) + profile);
code << QByteArray();
@ -313,9 +314,11 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
[enabledLayers] (const QString &s) { return enabledLayers.contains(s); });
};
for (const auto &node : graph.nodes()) {
const QVector<QShaderNode> nodes = graph.nodes();
for (const QShaderNode &node : nodes) {
if (intersectsEnabledLayers(node.layers())) {
for (const auto &snippet : node.rule(format).headerSnippets) {
const QByteArrayList headerSnippets = node.rule(format).headerSnippets;
for (const QByteArray &snippet : headerSnippets) {
code << replaceParameters(snippet, node, format);
}
}
@ -325,17 +328,18 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
code << QByteArrayLiteral("void main()");
code << QByteArrayLiteral("{");
for (const auto &statement : graph.createStatements(enabledLayers)) {
const auto node = statement.node;
auto line = node.rule(format).substitution;
for (const auto &port : node.ports()) {
const auto portName = port.name;
const auto portDirection = port.direction;
const auto isInput = port.direction == QShaderNodePort::Input;
for (const QShaderGraph::Statement &statement : graph.createStatements(enabledLayers)) {
const QShaderNode node = statement.node;
QByteArray line = node.rule(format).substitution;
const QVector<QShaderNodePort> ports = node.ports();
for (const QShaderNodePort &port : ports) {
const QString portName = port.name;
const QShaderNodePort::Direction portDirection = port.direction;
const bool isInput = port.direction == QShaderNodePort::Input;
const auto portIndex = statement.portIndex(portDirection, portName);
const auto variableIndex = isInput ? statement.inputs.at(portIndex)
: statement.outputs.at(portIndex);
const int portIndex = statement.portIndex(portDirection, portName);
const int variableIndex = isInput ? statement.inputs.at(portIndex)
: statement.outputs.at(portIndex);
if (variableIndex < 0)
continue;

View File

@ -82,8 +82,8 @@ namespace
auto statement = QShaderGraph::Statement();
statement.node = node;
const auto ports = node.ports();
for (const auto &port : ports) {
const QVector<QShaderNodePort> ports = node.ports();
for (const QShaderNodePort &port : ports) {
if (port.direction == QShaderNodePort::Input) {
statement.inputs.append(-1);
} else {
@ -99,19 +99,19 @@ namespace
const QUuid &uuid)
{
auto targetStatement = idHash.value(uuid);
for (const auto &edge : edges) {
for (const QShaderGraph::Edge &edge : edges) {
if (edge.targetNodeUuid != uuid)
continue;
const auto sourceStatement = idHash.value(edge.sourceNodeUuid);
const auto sourcePortIndex = sourceStatement.portIndex(QShaderNodePort::Output, edge.sourcePortName);
const auto targetPortIndex = targetStatement.portIndex(QShaderNodePort::Input, edge.targetPortName);
const QShaderGraph::Statement sourceStatement = idHash.value(edge.sourceNodeUuid);
const int sourcePortIndex = sourceStatement.portIndex(QShaderNodePort::Output, edge.sourcePortName);
const int targetPortIndex = targetStatement.portIndex(QShaderNodePort::Input, edge.targetPortName);
if (sourcePortIndex < 0 || targetPortIndex < 0)
continue;
const auto &sourceOutputs = sourceStatement.outputs;
auto &targetInputs = targetStatement.inputs;
const QVector<int> sourceOutputs = sourceStatement.outputs;
QVector<int> &targetInputs = targetStatement.inputs;
targetInputs[targetPortIndex] = sourceOutputs[sourcePortIndex];
}
return targetStatement;
@ -125,9 +125,9 @@ QUuid QShaderGraph::Statement::uuid() const Q_DECL_NOTHROW
int QShaderGraph::Statement::portIndex(QShaderNodePort::Direction direction, const QString &portName) const Q_DECL_NOTHROW
{
const auto ports = node.ports();
const QVector<QShaderNodePort> ports = node.ports();
int index = 0;
for (const auto &port : ports) {
for (const QShaderNodePort &port : ports) {
if (port.name == portName && port.direction == direction)
return index;
else if (port.direction == direction)
@ -180,7 +180,7 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
[enabledLayers] (const QString &s) { return enabledLayers.contains(s); });
};
const auto enabledNodes = [this, intersectsEnabledLayers] {
const QVector<QShaderNode> enabledNodes = [this, intersectsEnabledLayers] {
auto res = QVector<QShaderNode>();
std::copy_if(m_nodes.cbegin(), m_nodes.cend(),
std::back_inserter(res),
@ -190,7 +190,7 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
return res;
}();
const auto enabledEdges = [this, intersectsEnabledLayers] {
const QVector<Edge> enabledEdges = [this, intersectsEnabledLayers] {
auto res = QVector<Edge>();
std::copy_if(m_edges.cbegin(), m_edges.cend(),
std::back_inserter(res),
@ -200,18 +200,18 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
return res;
}();
const auto idHash = [enabledNodes] {
const QHash<QUuid, Statement> idHash = [enabledNodes] {
auto nextVarId = 0;
auto res = QHash<QUuid, Statement>();
for (const auto &node : enabledNodes)
for (const QShaderNode &node : enabledNodes)
res.insert(node.uuid(), nodeToStatement(node, nextVarId));
return res;
}();
auto result = QVector<Statement>();
auto currentEdges = enabledEdges;
auto currentUuids = [enabledNodes] {
const auto inputs = copyOutputNodes(enabledNodes);
QVector<Edge> currentEdges = enabledEdges;
QVector<QUuid> currentUuids = [enabledNodes] {
const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes);
auto res = QVector<QUuid>();
std::transform(inputs.cbegin(), inputs.cend(),
std::back_inserter(res),
@ -226,14 +226,14 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
// because we want to track the dependencies from the output nodes and not the
// input nodes
while (!currentUuids.isEmpty()) {
const auto uuid = currentUuids.takeFirst();
const QUuid uuid = currentUuids.takeFirst();
result.append(completeStatement(idHash, enabledEdges, uuid));
const auto outgoing = outgoingEdges(currentEdges, uuid);
for (const auto &outgoingEdge : outgoing) {
const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, uuid);
for (const QShaderGraph::Edge &outgoingEdge : outgoing) {
currentEdges.removeAll(outgoingEdge);
const QUuid nextUuid = outgoingEdge.sourceNodeUuid;
const auto incoming = incomingEdges(currentEdges, nextUuid);
const QVector<QShaderGraph::Edge> incoming = incomingEdges(currentEdges, nextUuid);
if (incoming.isEmpty()) {
currentUuids.append(nextUuid);
}

View File

@ -99,7 +99,7 @@ void QShaderGraphLoader::load()
return;
auto error = QJsonParseError();
const auto document = QJsonDocument::fromJson(m_device->readAll(), &error);
const QJsonDocument document = QJsonDocument::fromJson(m_device->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qWarning() << "Invalid JSON document:" << error.errorString();
@ -113,16 +113,16 @@ void QShaderGraphLoader::load()
return;
}
const auto root = document.object();
const QJsonObject root = document.object();
const auto nodesValue = root.value(QStringLiteral("nodes"));
const QJsonValue nodesValue = root.value(QStringLiteral("nodes"));
if (!nodesValue.isArray()) {
qWarning() << "Invalid nodes property, should be an array";
m_status = Error;
return;
}
const auto edgesValue = root.value(QStringLiteral("edges"));
const QJsonValue edgesValue = root.value(QStringLiteral("edges"));
if (!edgesValue.isArray()) {
qWarning() << "Invalid edges property, should be an array";
m_status = Error;
@ -131,7 +131,7 @@ void QShaderGraphLoader::load()
bool hasError = false;
const auto prototypesValue = root.value(QStringLiteral("prototypes"));
const QJsonValue prototypesValue = root.value(QStringLiteral("prototypes"));
if (!prototypesValue.isUndefined()) {
if (prototypesValue.isObject()) {
QShaderNodesLoader loader;
@ -144,60 +144,60 @@ void QShaderGraphLoader::load()
}
}
const auto nodes = nodesValue.toArray();
for (const auto &nodeValue : nodes) {
const QJsonArray nodes = nodesValue.toArray();
for (const QJsonValue &nodeValue : nodes) {
if (!nodeValue.isObject()) {
qWarning() << "Invalid node found";
hasError = true;
continue;
}
const auto nodeObject = nodeValue.toObject();
const QJsonObject nodeObject = nodeValue.toObject();
const auto uuidString = nodeObject.value(QStringLiteral("uuid")).toString();
const auto uuid = QUuid(uuidString);
const QString uuidString = nodeObject.value(QStringLiteral("uuid")).toString();
const QUuid uuid = QUuid(uuidString);
if (uuid.isNull()) {
qWarning() << "Invalid UUID found in node:" << uuidString;
hasError = true;
continue;
}
const auto type = nodeObject.value(QStringLiteral("type")).toString();
const QString type = nodeObject.value(QStringLiteral("type")).toString();
if (!m_prototypes.contains(type)) {
qWarning() << "Unsupported node type found:" << type;
hasError = true;
continue;
}
const auto layersArray = nodeObject.value(QStringLiteral("layers")).toArray();
const QJsonArray layersArray = nodeObject.value(QStringLiteral("layers")).toArray();
auto layers = QStringList();
for (const auto &layerValue : layersArray) {
for (const QJsonValue &layerValue : layersArray) {
layers.append(layerValue.toString());
}
auto node = m_prototypes.value(type);
QShaderNode node = m_prototypes.value(type);
node.setUuid(uuid);
node.setLayers(layers);
const auto parametersValue = nodeObject.value(QStringLiteral("parameters"));
const QJsonValue parametersValue = nodeObject.value(QStringLiteral("parameters"));
if (parametersValue.isObject()) {
const auto parametersObject = parametersValue.toObject();
for (const auto &parameterName : parametersObject.keys()) {
const auto parameterValue = parametersObject.value(parameterName);
const QJsonObject parametersObject = parametersValue.toObject();
for (const QString &parameterName : parametersObject.keys()) {
const QJsonValue parameterValue = parametersObject.value(parameterName);
if (parameterValue.isObject()) {
const auto parameterObject = parameterValue.toObject();
const auto type = parameterObject.value(QStringLiteral("type")).toString();
const auto typeId = QMetaType::type(type.toUtf8());
const QJsonObject parameterObject = parameterValue.toObject();
const QString type = parameterObject.value(QStringLiteral("type")).toString();
const int typeId = QMetaType::type(type.toUtf8());
const auto value = parameterObject.value(QStringLiteral("value")).toString();
const QString value = parameterObject.value(QStringLiteral("value")).toString();
auto variant = QVariant(value);
if (QMetaType::typeFlags(typeId) & QMetaType::IsEnumeration) {
const auto metaObject = QMetaType::metaObjectForType(typeId);
const auto className = metaObject->className();
const auto enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
const auto metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
const auto enumValue = metaEnum.keyToValue(value.toUtf8());
const QMetaObject *metaObject = QMetaType::metaObjectForType(typeId);
const char *className = metaObject->className();
const QByteArray enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
const QMetaEnum metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
const int enumValue = metaEnum.keyToValue(value.toUtf8());
variant = QVariant(enumValue);
variant.convert(typeId);
} else {
@ -213,39 +213,39 @@ void QShaderGraphLoader::load()
m_graph.addNode(node);
}
const auto edges = edgesValue.toArray();
for (const auto &edgeValue : edges) {
const QJsonArray edges = edgesValue.toArray();
for (const QJsonValue &edgeValue : edges) {
if (!edgeValue.isObject()) {
qWarning() << "Invalid edge found";
hasError = true;
continue;
}
const auto edgeObject = edgeValue.toObject();
const QJsonObject edgeObject = edgeValue.toObject();
const auto sourceUuidString = edgeObject.value(QStringLiteral("sourceUuid")).toString();
const auto sourceUuid = QUuid(sourceUuidString);
const QString sourceUuidString = edgeObject.value(QStringLiteral("sourceUuid")).toString();
const QUuid sourceUuid = QUuid(sourceUuidString);
if (sourceUuid.isNull()) {
qWarning() << "Invalid source UUID found in edge:" << sourceUuidString;
hasError = true;
continue;
}
const auto sourcePort = edgeObject.value(QStringLiteral("sourcePort")).toString();
const QString sourcePort = edgeObject.value(QStringLiteral("sourcePort")).toString();
const auto targetUuidString = edgeObject.value(QStringLiteral("targetUuid")).toString();
const auto targetUuid = QUuid(targetUuidString);
const QString targetUuidString = edgeObject.value(QStringLiteral("targetUuid")).toString();
const QUuid targetUuid = QUuid(targetUuidString);
if (targetUuid.isNull()) {
qWarning() << "Invalid target UUID found in edge:" << targetUuidString;
hasError = true;
continue;
}
const auto targetPort = edgeObject.value(QStringLiteral("targetPort")).toString();
const QString targetPort = edgeObject.value(QStringLiteral("targetPort")).toString();
const auto layersArray = edgeObject.value(QStringLiteral("layers")).toArray();
const QJsonArray layersArray = edgeObject.value(QStringLiteral("layers")).toArray();
auto layers = QStringList();
for (const auto &layerValue : layersArray) {
for (const QJsonValue &layerValue : layersArray) {
layers.append(layerValue.toString());
}

View File

@ -84,7 +84,7 @@ void QShaderNodesLoader::load()
return;
auto error = QJsonParseError();
const auto document = QJsonDocument::fromJson(m_device->readAll(), &error);
const QJsonDocument document = QJsonDocument::fromJson(m_device->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qWarning() << "Invalid JSON document:" << error.errorString();
@ -98,7 +98,7 @@ void QShaderNodesLoader::load()
return;
}
const auto root = document.object();
const QJsonObject root = document.object();
load(root);
}
@ -106,22 +106,22 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
{
bool hasError = false;
for (const auto &property : prototypesObject.keys()) {
const auto nodeValue = prototypesObject.value(property);
for (const QString &property : prototypesObject.keys()) {
const QJsonValue nodeValue = prototypesObject.value(property);
if (!nodeValue.isObject()) {
qWarning() << "Invalid node found";
hasError = true;
break;
}
const auto nodeObject = nodeValue.toObject();
const QJsonObject nodeObject = nodeValue.toObject();
auto node = QShaderNode();
const auto inputsValue = nodeObject.value(QStringLiteral("inputs"));
const QJsonValue inputsValue = nodeObject.value(QStringLiteral("inputs"));
if (inputsValue.isArray()) {
const auto inputsArray = inputsValue.toArray();
for (const auto &inputValue : inputsArray) {
const QJsonArray inputsArray = inputsValue.toArray();
for (const QJsonValue &inputValue : inputsArray) {
if (!inputValue.isString()) {
qWarning() << "Non-string value in inputs";
hasError = true;
@ -135,10 +135,10 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
}
}
const auto outputsValue = nodeObject.value(QStringLiteral("outputs"));
const QJsonValue outputsValue = nodeObject.value(QStringLiteral("outputs"));
if (outputsValue.isArray()) {
const auto outputsArray = outputsValue.toArray();
for (const auto &outputValue : outputsArray) {
const QJsonArray outputsArray = outputsValue.toArray();
for (const QJsonValue &outputValue : outputsArray) {
if (!outputValue.isString()) {
qWarning() << "Non-string value in outputs";
hasError = true;
@ -152,25 +152,25 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
}
}
const auto parametersValue = nodeObject.value(QStringLiteral("parameters"));
const QJsonValue parametersValue = nodeObject.value(QStringLiteral("parameters"));
if (parametersValue.isObject()) {
const auto parametersObject = parametersValue.toObject();
for (const auto &parameterName : parametersObject.keys()) {
const auto parameterValue = parametersObject.value(parameterName);
const QJsonObject parametersObject = parametersValue.toObject();
for (const QString &parameterName : parametersObject.keys()) {
const QJsonValue parameterValue = parametersObject.value(parameterName);
if (parameterValue.isObject()) {
const auto parameterObject = parameterValue.toObject();
const auto type = parameterObject.value(QStringLiteral("type")).toString();
const auto typeId = QMetaType::type(type.toUtf8());
const QJsonObject parameterObject = parameterValue.toObject();
const QString type = parameterObject.value(QStringLiteral("type")).toString();
const int typeId = QMetaType::type(type.toUtf8());
const auto value = parameterObject.value(QStringLiteral("value")).toString();
const QString value = parameterObject.value(QStringLiteral("value")).toString();
auto variant = QVariant(value);
if (QMetaType::typeFlags(typeId) & QMetaType::IsEnumeration) {
const auto metaObject = QMetaType::metaObjectForType(typeId);
const auto className = metaObject->className();
const auto enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
const auto metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
const auto enumValue = metaEnum.keyToValue(value.toUtf8());
const QMetaObject *metaObject = QMetaType::metaObjectForType(typeId);
const char *className = metaObject->className();
const QByteArray enumName = type.mid(static_cast<int>(qstrlen(className)) + 2).toUtf8();
const QMetaEnum metaEnum = metaObject->enumerator(metaObject->indexOfEnumerator(enumName));
const int enumValue = metaEnum.keyToValue(value.toUtf8());
variant = QVariant(enumValue);
variant.convert(typeId);
} else {
@ -183,36 +183,36 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
}
}
const auto rulesValue = nodeObject.value(QStringLiteral("rules"));
const QJsonValue rulesValue = nodeObject.value(QStringLiteral("rules"));
if (rulesValue.isArray()) {
const auto rulesArray = rulesValue.toArray();
for (const auto &ruleValue : rulesArray) {
const QJsonArray rulesArray = rulesValue.toArray();
for (const QJsonValue &ruleValue : rulesArray) {
if (!ruleValue.isObject()) {
qWarning() << "Rules should be objects";
hasError = true;
break;
}
const auto ruleObject = ruleValue.toObject();
const QJsonObject ruleObject = ruleValue.toObject();
const auto formatValue = ruleObject.value(QStringLiteral("format"));
const QJsonValue formatValue = ruleObject.value(QStringLiteral("format"));
if (!formatValue.isObject()) {
qWarning() << "Format is mandatory in rules and should be an object";
hasError = true;
break;
}
const auto formatObject = formatValue.toObject();
const QJsonObject formatObject = formatValue.toObject();
auto format = QShaderFormat();
const auto apiValue = formatObject.value(QStringLiteral("api"));
const QJsonValue apiValue = formatObject.value(QStringLiteral("api"));
if (!apiValue.isString()) {
qWarning() << "Format API must be a string";
hasError = true;
break;
}
const auto api = apiValue.toString();
const QString api = apiValue.toString();
format.setApi(api == QStringLiteral("OpenGLES") ? QShaderFormat::OpenGLES
: api == QStringLiteral("OpenGLNoProfile") ? QShaderFormat::OpenGLNoProfile
: api == QStringLiteral("OpenGLCoreProfile") ? QShaderFormat::OpenGLCoreProfile
@ -224,8 +224,8 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
break;
}
const auto majorValue = formatObject.value(QStringLiteral("major"));
const auto minorValue = formatObject.value(QStringLiteral("minor"));
const QJsonValue majorValue = formatObject.value(QStringLiteral("major"));
const QJsonValue minorValue = formatObject.value(QStringLiteral("minor"));
if (!majorValue.isDouble() || !minorValue.isDouble()) {
qWarning() << "Format major and minor version must be values";
hasError = true;
@ -233,28 +233,28 @@ void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
}
format.setVersion(QVersionNumber(majorValue.toInt(), minorValue.toInt()));
const auto extensionsValue = formatObject.value(QStringLiteral("extensions"));
const auto extensionsArray = extensionsValue.toArray();
const QJsonValue extensionsValue = formatObject.value(QStringLiteral("extensions"));
const QJsonArray extensionsArray = extensionsValue.toArray();
auto extensions = QStringList();
std::transform(extensionsArray.constBegin(), extensionsArray.constEnd(),
std::back_inserter(extensions),
[] (const QJsonValue &extensionValue) { return extensionValue.toString(); });
format.setExtensions(extensions);
const auto vendor = formatObject.value(QStringLiteral("vendor")).toString();
const QString vendor = formatObject.value(QStringLiteral("vendor")).toString();
format.setVendor(vendor);
const auto substitutionValue = ruleObject.value(QStringLiteral("substitution"));
const QJsonValue substitutionValue = ruleObject.value(QStringLiteral("substitution"));
if (!substitutionValue.isString()) {
qWarning() << "Substitution needs to be a string";
hasError = true;
break;
}
const auto substitution = substitutionValue.toString().toUtf8();
const QByteArray substitution = substitutionValue.toString().toUtf8();
const auto snippetsValue = ruleObject.value(QStringLiteral("headerSnippets"));
const auto snippetsArray = snippetsValue.toArray();
const QJsonValue snippetsValue = ruleObject.value(QStringLiteral("headerSnippets"));
const QJsonArray snippetsArray = snippetsValue.toArray();
auto snippets = QByteArrayList();
std::transform(snippetsArray.constBegin(), snippetsArray.constEnd(),
std::back_inserter(snippets),