QmlDesigner: Use span for static property names

Since we change much of the API to PropertyNameView we can generate it
at compile time.

Change-Id: Ifb4482c346b6e50af74987a9c2ec03a6e75e6e1d
Reviewed-by: Aleksei German <aleksei.german@qt.io>
This commit is contained in:
Marco Bubke
2025-04-12 01:56:47 +02:00
parent 3fb47c674a
commit e257904359
15 changed files with 116 additions and 92 deletions

View File

@@ -12,7 +12,7 @@ AddObjectVisitor::AddObjectVisitor(QmlDesigner::TextModifier &modifier,
quint32 parentLocation,
quint32 nodeLocation,
const QString &content,
const PropertyNameList &propertyOrder)
Utils::span<const PropertyNameView> propertyOrder)
: QMLRewriter(modifier)
, m_parentLocation(parentLocation)
, m_nodeLocation(nodeLocation)

View File

@@ -15,7 +15,7 @@ public:
quint32 parentLocation,
quint32 nodeLocation,
const QString &content,
const PropertyNameList &propertyOrder);
Utils::span<const PropertyNameView> propertyOrder);
protected:
bool visit(QmlJS::AST::UiObjectBinding *ast) override;
@@ -28,7 +28,7 @@ private:
quint32 m_parentLocation;
quint32 m_nodeLocation;
QString m_content;
PropertyNameList m_propertyOrder;
Utils::span<const PropertyNameView> m_propertyOrder;
};
} // namespace Internal

View File

@@ -13,7 +13,7 @@ AddPropertyVisitor::AddPropertyVisitor(TextModifier &modifier,
PropertyNameView name,
const QString &value,
QmlRefactoring::PropertyType propertyType,
const PropertyNameList &propertyOrder,
Utils::span<const PropertyNameView> propertyOrder,
const TypeName &dynamicTypeName)
: QMLRewriter(modifier)
, m_parentLocation(parentLocation)

View File

@@ -18,7 +18,7 @@ public:
PropertyNameView name,
const QString &value,
QmlRefactoring::PropertyType propertyType,
const PropertyNameList &propertyOrder,
Utils::span<const PropertyNameView> propertyOrder,
const TypeName &dynamicTypeName);
protected:
@@ -33,7 +33,7 @@ private:
PropertyNameView m_name;
QString m_value;
QmlRefactoring::PropertyType m_propertyType;
PropertyNameList m_propertyOrder;
Utils::span<const PropertyNameView> m_propertyOrder;
TypeName m_dynamicTypeName;
};

View File

@@ -21,7 +21,7 @@ public:
PropertyNameView targetPropertyName,
bool targetIsArrayBinding,
TextModifier::MoveInfo moveInfo,
const PropertyNameList &propertyOrder)
Utils::span<const PropertyNameView> propertyOrder)
: QMLRewriter(modifier)
, targetParentObjectLocation(targetParentObjectLocation)
, targetPropertyName(targetPropertyName)
@@ -127,7 +127,7 @@ private:
PropertyNameView targetPropertyName;
bool targetIsArrayBinding;
TextModifier::MoveInfo moveInfo;
PropertyNameList propertyOrder;
Utils::span<const PropertyNameView> propertyOrder;
};
MoveObjectVisitor::MoveObjectVisitor(TextModifier &modifier,
@@ -135,7 +135,7 @@ MoveObjectVisitor::MoveObjectVisitor(TextModifier &modifier,
PropertyNameView targetPropertyName,
bool targetIsArrayBinding,
quint32 targetParentObjectLocation,
const PropertyNameList &propertyOrder)
Utils::span<const PropertyNameView> propertyOrder)
: QMLRewriter(modifier)
, objectLocation(objectLocation)
, targetPropertyName(targetPropertyName)

View File

@@ -16,7 +16,7 @@ public:
PropertyNameView targetPropertyName,
bool targetIsArrayBinding,
quint32 targetParentObjectLocation,
const PropertyNameList &propertyOrder);
Utils::span<const PropertyNameView> propertyOrder);
bool operator ()(QmlJS::AST::UiProgram *ast) override;
@@ -34,7 +34,7 @@ private:
PropertyNameView targetPropertyName;
bool targetIsArrayBinding;
quint32 targetParentObjectLocation;
PropertyNameList propertyOrder;
Utils::span<const PropertyNameView> propertyOrder;
QmlJS::AST::UiProgram *program;
};

View File

@@ -20,10 +20,12 @@ using namespace QmlJS;
using namespace QmlDesigner;
using namespace QmlDesigner::Internal;
QmlRefactoring::QmlRefactoring(const Document::Ptr &doc, TextModifier &modifier, const PropertyNameList &propertyOrder):
qmlDocument(doc),
textModifier(&modifier),
m_propertyOrder(propertyOrder)
QmlRefactoring::QmlRefactoring(const Document::Ptr &doc,
TextModifier &modifier,
Utils::span<const PropertyNameView> propertyOrder)
: qmlDocument(doc)
, textModifier(&modifier)
, m_propertyOrder(propertyOrder)
{
}

View File

@@ -25,7 +25,9 @@ public:
};
public:
QmlRefactoring(const QmlJS::Document::Ptr &doc, QmlDesigner::TextModifier &modifier, const PropertyNameList &propertyOrder);
QmlRefactoring(const QmlJS::Document::Ptr &doc,
QmlDesigner::TextModifier &modifier,
Utils::span<const PropertyNameView> propertyOrder);
bool reparseDocument();
@@ -57,7 +59,7 @@ public:
private:
QmlJS::Document::Ptr qmlDocument;
TextModifier *textModifier;
PropertyNameList m_propertyOrder;
Utils::span<const PropertyNameView> m_propertyOrder;
};
} // namespace QmlDesigner

View File

@@ -197,10 +197,23 @@ void QMLRewriter::includeLeadingEmptyLine(int &start) const
start = prevBlock.position();
}
// FIXME: duplicate code in the QmlJS::Rewriter class, remove this
QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const QmlDesigner::PropertyNameList &propertyOrder)
namespace {
int indexOf(Utils::span<const QmlDesigner::PropertyNameView> properties,
QmlDesigner::PropertyNameView name)
{
const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName()); // XXX ????
auto found = std::ranges::find(properties, name);
if (found == properties.end())
return -1;
return static_cast<int>(std::distance(properties.begin(), found));
}
} // namespace
// FIXME: duplicate code in the QmlJS::Rewriter class, remove this
QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(
QmlJS::AST::UiObjectMemberList *members, Utils::span<const PropertyNameView> propertyOrder)
{
const int objectDefinitionInsertionPoint = indexOf(propertyOrder, ""); // XXX ????
QmlJS::AST::UiObjectMemberList *lastObjectDef = nullptr;
QmlJS::AST::UiObjectMemberList *lastNonObjectDef = nullptr;
@@ -212,13 +225,13 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AS
if (QmlJS::AST::cast<QmlJS::AST::UiObjectDefinition*>(member))
lastObjectDef = iter;
else if (auto arrayBinding = QmlJS::AST::cast<QmlJS::AST::UiArrayBinding*>(member))
idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(arrayBinding->qualifiedId).toUtf8());
else if (auto objectBinding = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding*>(member))
idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(objectBinding->qualifiedId).toUtf8());
else if (auto scriptBinding = QmlJS::AST::cast<QmlJS::AST::UiScriptBinding*>(member))
idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(scriptBinding->qualifiedId).toUtf8());
else if (QmlJS::AST::cast<QmlJS::AST::UiPublicMember*>(member))
idx = propertyOrder.indexOf("property");
idx = indexOf(propertyOrder, "property");
if (idx < objectDefinitionInsertionPoint)
lastNonObjectDef = iter;
@@ -234,7 +247,7 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(QmlJS::AS
QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(
QmlJS::AST::UiObjectMemberList *members,
PropertyNameView propertyName,
const QmlDesigner::PropertyNameList &propertyOrder)
Utils::span<const PropertyNameView> propertyOrder)
{
if (!members)
return nullptr; // empty members
@@ -256,15 +269,15 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(
orderedMembers[QStringLiteral("property")] = iter;
}
int idx = propertyOrder.indexOf(propertyName);
int idx = indexOf(propertyOrder, propertyName);
if (idx == -1)
idx = propertyOrder.indexOf(PropertyName());
idx = indexOf(propertyOrder, "");
if (idx == -1)
idx = propertyOrder.size() - 1;
idx = static_cast<int>(propertyOrder.size()) - 1;
for (; idx > 0; --idx) {
const QString prop = QString::fromLatin1(propertyOrder.at(idx - 1));
QmlJS::AST::UiObjectMemberList *candidate = orderedMembers.value(prop, 0);
const QString prop = QString::fromLatin1(propertyOrder[static_cast<std::size_t>(idx - 1)]);
QmlJS::AST::UiObjectMemberList *candidate = orderedMembers.value(prop, nullptr);
if (candidate != nullptr)
return candidate;
}
@@ -273,14 +286,14 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(
}
QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter(
QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos)
QmlJS::AST::UiObjectMemberList *members, Utils::span<const PropertyNameView> propertyOrder, int pos)
{
if (pos < 0)
return searchMemberToInsertAfter(members, propertyOrder);
// An empty property name should be available in the propertyOrder List, which is the right place
// to define the objects there.
const int objectDefinitionInsertionPoint = propertyOrder.indexOf(PropertyName());
const int objectDefinitionInsertionPoint = indexOf(propertyOrder, "");
QmlJS::AST::UiObjectMemberList *lastObjectDef = nullptr;
QmlJS::AST::UiObjectMemberList *lastNonObjectDef = nullptr;
@@ -295,13 +308,13 @@ QmlJS::AST::UiObjectMemberList *QMLRewriter::searchChildrenToInsertAfter(
if (objectPos++ == pos)
break;
} else if (auto arrayBinding = QmlJS::AST::cast<QmlJS::AST::UiArrayBinding *>(member))
idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(arrayBinding->qualifiedId).toUtf8());
else if (auto objectBinding = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding *>(member))
idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(objectBinding->qualifiedId).toUtf8());
else if (auto scriptBinding = QmlJS::AST::cast<QmlJS::AST::UiScriptBinding *>(member))
idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId).toUtf8());
idx = indexOf(propertyOrder, toString(scriptBinding->qualifiedId).toUtf8());
else if (QmlJS::AST::cast<QmlJS::AST::UiPublicMember *>(member))
idx = propertyOrder.indexOf("property");
idx = indexOf(propertyOrder, "property");
if (idx < objectDefinitionInsertionPoint)
lastNonObjectDef = iter;

View File

@@ -51,13 +51,16 @@ protected:
bool includeSurroundingWhitespace(int &start, int &end) const;
void includeLeadingEmptyLine(int &start) const;
static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder);
static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(
QmlJS::AST::UiObjectMemberList *members, Utils::span<const PropertyNameView> propertyOrder);
static QmlJS::AST::UiObjectMemberList *searchMemberToInsertAfter(
QmlJS::AST::UiObjectMemberList *members,
PropertyNameView propertyName,
const PropertyNameList &propertyOrder);
Utils::span<const PropertyNameView> propertyOrder);
static QmlJS::AST::UiObjectMemberList *searchChildrenToInsertAfter(
QmlJS::AST::UiObjectMemberList *members, const PropertyNameList &propertyOrder, int pos = -1);
QmlJS::AST::UiObjectMemberList *members,
Utils::span<const PropertyNameView> propertyOrder,
int pos = -1);
protected:
bool didRewriting() const

View File

@@ -16,6 +16,8 @@
#include <qmljs/parser/qmljsengine_p.h>
#include <utils/algorithm.h>
#include <utils/array.h>
#include <utils/span.h>
namespace {
enum {
@@ -355,52 +357,53 @@ QmlRefactoring::PropertyType ModelToTextMerger::propertyType(const AbstractPrope
return QmlRefactoring::Invalid;
}
PropertyNameList ModelToTextMerger::propertyOrder()
Utils::span<const PropertyNameView> ModelToTextMerger::propertyOrder()
{
static const PropertyNameList properties = {PropertyName("id"),
PropertyName("name"),
PropertyName("target"),
PropertyName("property"),
PropertyName("x"),
PropertyName("y"),
PropertyName("width"),
PropertyName("height"),
PropertyName("opacity"),
PropertyName("visible"),
PropertyName("position"),
PropertyName("color"),
PropertyName("radius"),
PropertyName("text"),
PropertyName("elide"),
PropertyName("value"),
PropertyName("border.color"),
PropertyName("border.width"),
PropertyName("anchors.verticalCenter"),
PropertyName("anchors.left"),
PropertyName("anchors.right"),
PropertyName("anchors.top"),
PropertyName("anchors.bottom"),
PropertyName("anchors.fill"),
PropertyName("anchors.margins"),
PropertyName("anchors.leftMargin"),
PropertyName("anchors.rightMargin"),
PropertyName("anchors.topMargin"),
PropertyName("anchors.bottomMargin"),
PropertyName("font.letterSpacing"),
PropertyName("font.pixelSize"),
PropertyName("horizontalAlignment"),
PropertyName("verticalAlignment"),
PropertyName("source"),
PropertyName("lineHeight"),
PropertyName("lineHeightMode"),
PropertyName("wrapMode"),
PropertyName(),
PropertyName("states"),
PropertyName("to"),
PropertyName("from"),
PropertyName("transitions")};
static constexpr auto propertyNames = Utils::to_array<PropertyNameView>(
"id",
"name",
"target",
"property",
"x",
"y",
"width",
"height",
"opacity",
"visible",
"position",
"color",
"radius",
"text",
"elide",
"value",
"border.color",
"border.width",
"anchors.verticalCenter",
"anchors.left",
"anchors.right",
"anchors.top",
"anchors.bottom",
"anchors.fill",
"anchors.margins",
"anchors.leftMargin",
"anchors.rightMargin",
"anchors.topMargin",
"anchors.bottomMargin",
"font.letterSpacing",
"font.pixelSize",
"horizontalAlignment",
"verticalAlignment",
"source",
"lineHeight",
"lineHeightMode",
"wrapMode",
"",
"states",
"to",
"from",
"transitions");
return properties;
return propertyNames;
}
bool ModelToTextMerger::isInHierarchy(const AbstractProperty &property) {

View File

@@ -52,7 +52,7 @@ protected:
{ return m_rewriteActions; }
static QmlDesigner::QmlRefactoring::PropertyType propertyType(const AbstractProperty &property, const QString &textValue = QString());
static PropertyNameList propertyOrder();
static Utils::span<const PropertyNameView> propertyOrder();
static bool isInHierarchy(const AbstractProperty &property);

View File

@@ -72,7 +72,7 @@ static QString unicodeEscape(const QString &stringValue)
return stringValue;
}
QmlTextGenerator::QmlTextGenerator(const PropertyNameList &propertyOrder,
QmlTextGenerator::QmlTextGenerator(Utils::span<const PropertyNameView> propertyOrder,
const TextEditor::TabSettings &tabSettings,
const int startIndentDepth)
: m_propertyOrder(propertyOrder)
@@ -220,7 +220,7 @@ QString QmlTextGenerator::propertiesToQml(const ModelNode &node, int indentDepth
PropertyNameList nodePropertyNames = node.propertyNames();
bool addToTop = true;
for (const PropertyName &propertyName : std::as_const(m_propertyOrder)) {
for (const auto propertyName : m_propertyOrder) {
if (propertyName == "id") {
// the model handles the id property special, so:
if (!node.id().isEmpty()) {

View File

@@ -16,7 +16,7 @@ namespace Internal {
class QmlTextGenerator
{
public:
explicit QmlTextGenerator(const PropertyNameList &propertyOrder,
explicit QmlTextGenerator(Utils::span<const PropertyNameView> propertyOrder,
const TextEditor::TabSettings &tabSettings,
const int startIndentDepth = 0);
@@ -33,7 +33,7 @@ private:
QString propertyToQml(const AbstractProperty &property, int indentDepth) const;
private:
PropertyNameList m_propertyOrder;
Utils::span<const PropertyNameView> m_propertyOrder;
TextEditor::TabSettings m_tabSettings;
const int m_startIndentDepth;
};

View File

@@ -11,9 +11,10 @@ namespace Internal {
class RewriteActionCompressor
{
public:
RewriteActionCompressor(const PropertyNameList &propertyOrder, ModelNodePositionStorage *positionStore) :
m_propertyOrder(propertyOrder),
m_positionStore(positionStore)
RewriteActionCompressor(Utils::span<const PropertyNameView> propertyOrder,
ModelNodePositionStorage *positionStore)
: m_propertyOrder(propertyOrder)
, m_positionStore(positionStore)
{}
void operator()(QList<RewriteAction *> &actions, const TextEditor::TabSettings &tabSettings) const;
@@ -31,7 +32,7 @@ private:
void compressSlidesIntoNewNode(QList<RewriteAction *> &actions) const;
private:
PropertyNameList m_propertyOrder;
Utils::span<const PropertyNameView> m_propertyOrder;
ModelNodePositionStorage *m_positionStore;
};