QmlDesigner: Adapt PropertyMetaInfo::castedValue

It tries to avoid calls to propertyTypeName() because it is slow
and unreliable. Instead we use the builtin type ids. If there are more
common cases we should add more builtin type ids.

Change-Id: I7f6b6c4251fd275878c476526c75058a8580b4a7
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2022-08-10 12:06:00 +02:00
committed by Thomas Hartmann
parent c7b6d83f94
commit b99bc1a055
2 changed files with 146 additions and 39 deletions

View File

@@ -33,14 +33,17 @@
#include <propertyparser.h> #include <propertyparser.h>
#include <rewriterview.h> #include <rewriterview.h>
#include <QDir>
#include <QDebug> #include <QDebug>
#include <QDir>
#include <QVector2D>
#include <QVector3D>
#include <QVector4D>
#include <qmljs/qmljsscopechain.h> #include <languageutils/fakemetaobject.h>
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljs/qmljsscopechain.h>
#include <qmljs/qmljsvalueowner.h> #include <qmljs/qmljsvalueowner.h>
#include <languageutils/fakemetaobject.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
@@ -1136,7 +1139,7 @@ QVariant::Type NodeMetaInfoPrivate::variantTypeId(const PropertyName &propertyNa
if (typeName == "vector4d") if (typeName == "vector4d")
return QVariant::Vector4D; return QVariant::Vector4D;
return QVariant::nameToType(typeName.data()); return QVariant::nameToType(typeName.data()); // This is deprecated
} }
int NodeMetaInfoPrivate::majorVersion() const int NodeMetaInfoPrivate::majorVersion() const
@@ -1849,44 +1852,91 @@ bool PropertyMetaInfo::isPointer() const
QVariant PropertyMetaInfo::castedValue(const QVariant &value) const QVariant PropertyMetaInfo::castedValue(const QVariant &value) const
{ {
const QVariant variant = value; if constexpr (!useProjectStorage()) {
QVariant copyVariant = variant; const QVariant variant = value;
if (isEnumType() || variant.canConvert<Enumeration>()) QVariant copyVariant = variant;
return variant; if (isEnumType() || variant.canConvert<Enumeration>())
return variant;
const TypeName &typeName = propertyTypeName(); const TypeName &typeName = propertyTypeName();
QVariant::Type typeId = m_nodeMetaInfoPrivateData->variantTypeId(m_propertyName); QVariant::Type typeId = m_nodeMetaInfoPrivateData->variantTypeId(m_propertyName);
if (variant.type() == QVariant::UserType && variant.userType() == ModelNode::variantUserType()) { if (variant.type() == QVariant::UserType
return variant; && variant.userType() == ModelNode::variantUserType()) {
} else if (typeId == QVariant::UserType && typeName == "QVariant") { return variant;
return variant; } else if (typeId == QVariant::UserType && typeName == "QVariant") {
} else if (typeId == QVariant::UserType && typeName == "variant") { return variant;
return variant; } else if (typeId == QVariant::UserType && typeName == "variant") {
} else if (typeId == QVariant::UserType && typeName == "var") { return variant;
return variant; } else if (typeId == QVariant::UserType && typeName == "var") {
} else if (variant.type() == QVariant::List) { return variant;
// TODO: check the contents of the list } else if (variant.type() == QVariant::List) {
return variant; // TODO: check the contents of the list
} else if (typeName == "var" || typeName == "variant") { return variant;
return variant; } else if (typeName == "var" || typeName == "variant") {
} else if (typeName == "alias") { return variant;
// TODO: The QML compiler resolves the alias type. We probably should do the same. } else if (typeName == "alias") {
return variant; // TODO: The QML compiler resolves the alias type. We probably should do the same.
} else if (typeName == "<cpp>.double") { return variant;
return variant.toDouble(); } else if (typeName == "<cpp>.double") {
} else if (typeName == "<cpp>.float") { return variant.toDouble();
return variant.toFloat(); } else if (typeName == "<cpp>.float") {
} else if (typeName == "<cpp>.int") { return variant.toFloat();
return variant.toInt(); } else if (typeName == "<cpp>.int") {
} else if (typeName == "<cpp>.bool") { return variant.toInt();
return variant.toBool(); } else if (typeName == "<cpp>.bool") {
} else if (copyVariant.convert(typeId)) { return variant.toBool();
return copyVariant; } else if (copyVariant.convert(typeId)) {
return copyVariant;
}
} else {
if (isEnumType() || value.canConvert<Enumeration>())
return value;
const TypeId &typeId = propertyData().typeId;
if (value.type() == QVariant::UserType && value.userType() == ModelNode::variantUserType()) {
return value;
} else if (typeId == m_projectStorage->builtinTypeId<QVariant>()) {
return value;
} else if (value.type() == QVariant::List) {
// TODO: check the contents of the list
return value;
} else if (typeId == m_projectStorage->builtinTypeId<double>()) {
return value.toDouble();
} else if (typeId == m_projectStorage->builtinTypeId<float>()) {
return value.toFloat();
} else if (typeId == m_projectStorage->builtinTypeId<int>()) {
return value.toInt();
} else if (typeId == m_projectStorage->builtinTypeId<bool>()) {
return value.toBool();
} else if (typeId == m_projectStorage->builtinTypeId<QString>()) {
return value.toString();
} else if (typeId == m_projectStorage->builtinTypeId<QDateTime>()) {
return value.toDateTime();
} else if (typeId == m_projectStorage->builtinTypeId<QUrl>()) {
return value.toUrl();
} else if (typeId == m_projectStorage->builtinTypeId<QColor>()) {
return value.value<QColor>();
} else if (typeId == m_projectStorage->builtinTypeId<QVector2D>()) {
return value.value<QVector2D>();
} else if (typeId == m_projectStorage->builtinTypeId<QVector3D>()) {
return value.value<QVector3D>();
} else if (typeId == m_projectStorage->builtinTypeId<QVector4D>()) {
return value.value<QVector4D>();
} else {
const auto typeName = propertyTypeName();
const auto metaType = QMetaType::fromName(typeName);
auto copy = value;
bool converted = copy.convert(metaType);
if (converted)
return copy;
}
} }
return Internal::PropertyParser::variantFromString(variant.toString()); return Internal::PropertyParser::variantFromString(value.toString());
} }
const Storage::Info::PropertyDeclaration &PropertyMetaInfo::propertyData() const const Storage::Info::PropertyDeclaration &PropertyMetaInfo::propertyData() const

View File

@@ -30,13 +30,35 @@
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
QT_BEGIN_NAMESPACE
class QColor;
class QDateTime;
class QString;
class QUrl;
class QVariant;
class QVector2D;
class QVector3D;
class QVector4D;
QT_END_NAMESPACE
namespace QmlDesigner::Storage::Info { namespace QmlDesigner::Storage::Info {
inline constexpr char QtQuick[] = "QtQuick"; inline constexpr char QtQuick[] = "QtQuick";
inline constexpr char QML[] = "QML"; inline constexpr char QML[] = "QML";
inline constexpr char QMLNative[] = "QML-cppnative";
inline constexpr char Item[] = "Item"; inline constexpr char Item[] = "Item";
inline constexpr char DoubleType[] = "double"; inline constexpr char DoubleType[] = "double";
inline constexpr char IntType[] = "int";
inline constexpr char BoolType[] = "bool";
inline constexpr char FloatType[] = "float";
inline constexpr char var[] = "var"; inline constexpr char var[] = "var";
inline constexpr char string[] = "string";
inline constexpr char date[] = "date";
inline constexpr char url[] = "url";
inline constexpr char color[] = "color";
inline constexpr char vector2d[] = "vector2d";
inline constexpr char vector3d[] = "vector3d";
inline constexpr char vector4d[] = "vector4d";
template<const auto &moduleName_, const auto &typeName_> template<const auto &moduleName_, const auto &typeName_>
struct CacheType struct CacheType
@@ -48,7 +70,20 @@ struct CacheType
template<typename ProjectStorage> template<typename ProjectStorage>
class CommonTypeCache class CommonTypeCache
{ {
using CommonTypes = std::tuple<CacheType<QtQuick, Item>, CacheType<QML, DoubleType>, CacheType<QML, var>>; using CommonTypes = std::tuple<CacheType<QtQuick, Item>,
CacheType<QtQuick, color>,
CacheType<QtQuick, vector2d>,
CacheType<QtQuick, vector3d>,
CacheType<QtQuick, vector4d>,
CacheType<QML, DoubleType>,
CacheType<QML, var>,
CacheType<QML, IntType>,
CacheType<QML, BoolType>,
CacheType<QML, string>,
CacheType<QML, date>,
CacheType<QML, date>,
CacheType<QML, url>,
CacheType<QMLNative, FloatType>>;
public: public:
CommonTypeCache(const ProjectStorage &projectStorage) CommonTypeCache(const ProjectStorage &projectStorage)
@@ -87,7 +122,29 @@ public:
auto builtinTypeId() const auto builtinTypeId() const
{ {
if constexpr (std::is_same_v<Type, double>) if constexpr (std::is_same_v<Type, double>)
return builtinTypeId<DoubleType>(); return typeId<QML, DoubleType>();
if constexpr (std::is_same_v<Type, int>)
return typeId<QML, IntType>();
if constexpr (std::is_same_v<Type, bool>)
return typeId<QML, BoolType>();
if constexpr (std::is_same_v<Type, float>)
return typeId<QMLNative, FloatType>();
if constexpr (std::is_same_v<Type, QString>)
return typeId<QML, string>();
if constexpr (std::is_same_v<Type, QDateTime>)
return typeId<QML, date>();
if constexpr (std::is_same_v<Type, QUrl>)
return typeId<QML, url>();
if constexpr (std::is_same_v<Type, QVariant>)
return typeId<QML, var>();
if constexpr (std::is_same_v<Type, QColor>)
return typeId<QtQuick, color>();
if constexpr (std::is_same_v<Type, QVector2D>)
return typeId<QtQuick, vector2d>();
if constexpr (std::is_same_v<Type, QVector3D>)
return typeId<QtQuick, vector3d>();
if constexpr (std::is_same_v<Type, QVector4D>)
return typeId<QtQuick, vector4d>();
else else
return TypeId{}; return TypeId{};
} }