diff options
author | Qt Forward Merge Bot <[email protected]> | 2020-03-09 01:00:06 +0100 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2020-03-09 09:58:49 +0100 |
commit | d51d5ff3c187821929cf7b765e037423bcc90466 (patch) | |
tree | 0eed81eb1709759058ff2b3b4595ea18774a44c4 /src | |
parent | eacb1a08ee4dace7c12a6eed153b9ec69cf95966 (diff) | |
parent | 12ddd8da1b2dcfbbca10a6915547456601a726c0 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
src/qml/compiler/qqmlirbuilder_p.h
src/qml/qml/qqmlpropertycachecreator_p.h
src/qmltyperegistrar/qmltypesclassdescription.cpp
src/qmltyperegistrar/qmltypesclassdescription.h
src/qmltyperegistrar/qmltypescreator.cpp
src/quick/items/qquicktext_p.h
src/quick/util/qquickvaluetypes_p.h
Change-Id: Ic209741592e7b85820bf3845722023a190ebc1c5
Diffstat (limited to 'src')
98 files changed, 729 insertions, 457 deletions
diff --git a/src/qmltest/dependencies.json b/src/imports/testlib/dependencies.json index b2c4125178..b2c4125178 100644 --- a/src/qmltest/dependencies.json +++ b/src/imports/testlib/dependencies.json diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.cpp b/src/imports/wavefrontmesh/qwavefrontmesh.cpp index e973ef0103..1772c40c50 100644 --- a/src/imports/wavefrontmesh/qwavefrontmesh.cpp +++ b/src/imports/wavefrontmesh/qwavefrontmesh.cpp @@ -257,7 +257,7 @@ void QWavefrontMesh::readData() while (!stream.atEnd()) { stream.readLineInto(&buffer); - QVector<QStringRef> tokens = buffer.splitRef(space, QString::SkipEmptyParts); + QVector<QStringRef> tokens = buffer.splitRef(space, Qt::SkipEmptyParts); if (tokens.size() < 2) continue; @@ -316,7 +316,7 @@ void QWavefrontMesh::readData() if (tokens.size() >= 4 && tokens.size() <= 5) { { bool ok; - QVector<QStringRef> faceTokens = tokens.at(1).split(slash, QString::SkipEmptyParts); + QVector<QStringRef> faceTokens = tokens.at(1).split(slash, Qt::SkipEmptyParts); Q_ASSERT(!faceTokens.isEmpty()); p1 = faceTokens.at(0).toInt(&ok) - 1; @@ -336,7 +336,7 @@ void QWavefrontMesh::readData() { bool ok; - QVector<QStringRef> faceTokens = tokens.at(2).split(slash, QString::SkipEmptyParts); + QVector<QStringRef> faceTokens = tokens.at(2).split(slash, Qt::SkipEmptyParts); Q_ASSERT(!faceTokens.isEmpty()); p2 = faceTokens.at(0).toInt(&ok) - 1; @@ -356,7 +356,7 @@ void QWavefrontMesh::readData() { bool ok; - QVector<QStringRef> faceTokens = tokens.at(3).split(slash, QString::SkipEmptyParts); + QVector<QStringRef> faceTokens = tokens.at(3).split(slash, Qt::SkipEmptyParts); Q_ASSERT(!faceTokens.isEmpty()); p3 = faceTokens.at(0).toInt(&ok) - 1; @@ -394,7 +394,7 @@ void QWavefrontMesh::readData() if (tokens.size() == 5) { bool ok; - QVector<QStringRef> faceTokens = tokens.at(4).split(slash, QString::SkipEmptyParts); + QVector<QStringRef> faceTokens = tokens.at(4).split(slash, Qt::SkipEmptyParts); Q_ASSERT(!faceTokens.isEmpty()); int p4 = faceTokens.at(0).toInt(&ok) - 1; diff --git a/src/imports/window/plugin.h b/src/imports/window/plugin.h index 5497030bb0..625a77b12c 100644 --- a/src/imports/window/plugin.h +++ b/src/imports/window/plugin.h @@ -119,6 +119,13 @@ struct QQuickWindowQmlImplForeign QML_ADDED_IN_VERSION(2, 1) }; +struct QQuickRootItemForeign +{ + Q_GADGET + QML_FOREIGN(QQuickRootItem) + QML_ANONYMOUS +}; + QT_END_NAMESPACE #endif // PLUGIN_H diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp index bf73440a39..c504ea605a 100644 --- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp +++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp @@ -183,7 +183,7 @@ QQmlNativeDebugConnector::QQmlNativeDebugConnector() : m_blockingMode(false) { const QString args = commandLineArguments(); - const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts); + const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), Qt::SkipEmptyParts); QStringList services; for (const QStringRef &strArgument : lstjsDebugArguments) { if (strArgument == QLatin1String("block")) { diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index 33b6606b44..4d68a4508b 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -345,7 +345,7 @@ void QQmlDebugServerImpl::parseArguments() QString fileName; QStringList services; - const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), QString::SkipEmptyParts); + const auto lstjsDebugArguments = args.splitRef(QLatin1Char(','), Qt::SkipEmptyParts); for (auto argsIt = lstjsDebugArguments.begin(), argsItEnd = lstjsDebugArguments.end(); argsIt != argsItEnd; ++argsIt) { const QStringRef &strArgument = *argsIt; if (strArgument.startsWith(QLatin1String("port:"))) { diff --git a/src/qml/common/common.pri b/src/qml/common/common.pri index bcc3ea0fa0..b333c0f6d9 100644 --- a/src/qml/common/common.pri +++ b/src/qml/common/common.pri @@ -28,6 +28,7 @@ HEADERS += \ $$PWD/qqmljsdiagnosticmessage_p.h \ $$PWD/qqmljsfixedpoolarray_p.h \ $$PWD/qqmljsmemorypool_p.h \ + $$PWD/qqmljssourcelocation_p.h \ $$PWD/qv4alloca_p.h \ $$PWD/qv4calldata_p.h \ $$PWD/qv4compileddata_p.h \ diff --git a/src/qml/common/qqmlapiversion_p.h b/src/qml/common/qqmlapiversion_p.h index 4baf37e11c..44d8e3f236 100644 --- a/src/qml/common/qqmlapiversion_p.h +++ b/src/qml/common/qqmlapiversion_p.h @@ -51,6 +51,6 @@ // We mean it. // -#define Q_QML_PRIVATE_API_VERSION 7 +#define Q_QML_PRIVATE_API_VERSION 8 #endif // QQMLAPIVERSION_P_H diff --git a/src/qml/common/qqmljsdiagnosticmessage_p.h b/src/qml/common/qqmljsdiagnosticmessage_p.h index 763332ba76..9f5380ae0c 100644 --- a/src/qml/common/qqmljsdiagnosticmessage_p.h +++ b/src/qml/common/qqmljsdiagnosticmessage_p.h @@ -58,6 +58,8 @@ // QQmlSourceLocation -> line/column change. #include <private/qqmlapiversion_p.h> +#include "qqmljssourcelocation_p.h" + QT_BEGIN_NAMESPACE namespace QQmlJS { @@ -65,8 +67,7 @@ struct DiagnosticMessage { QString message; QtMsgType type = QtCriticalMsg; - quint32 line = 0; - quint32 column = 0; + SourceLocation loc; bool isError() const { diff --git a/src/qml/parser/qqmljssourcelocation_p.h b/src/qml/common/qqmljssourcelocation_p.h index d76e701d49..7c75541eb1 100644 --- a/src/qml/parser/qqmljssourcelocation_p.h +++ b/src/qml/common/qqmljssourcelocation_p.h @@ -40,8 +40,6 @@ #ifndef QQMLJSSOURCELOCATION_P_H #define QQMLJSSOURCELOCATION_P_H -#include "qqmljsglobal_p.h" - #include <QtCore/qglobal.h> // @@ -57,7 +55,7 @@ QT_BEGIN_NAMESPACE -namespace QQmlJS { namespace AST { +namespace QQmlJS { class SourceLocation { @@ -80,7 +78,7 @@ public: quint32 startColumn; }; -} } // namespace AST +} // namespace QQmlJS QT_END_NAMESPACE diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 4de7734ecf..5217e11115 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -169,7 +169,7 @@ QV4::CompiledData::BuiltinType Parameter::stringToBuiltinType(const QString &typ return QV4::CompiledData::BuiltinType::InvalidBuiltin; } -void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &loc) +void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &loc) { inheritedTypeNameIndex = typeNameIndex; @@ -193,7 +193,7 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons declarationsOverride = nullptr; } -QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation) +QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation) { QSet<int> functionNames; for (auto functionit = obj->functionsBegin(); functionit != obj->functionsEnd(); ++functionit) { @@ -249,7 +249,7 @@ QString Object::appendSignal(Signal *signal) return QString(); // no error } -QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation) +QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation) { Object *target = declarationsOverride; if (!target) @@ -273,7 +273,7 @@ QString Object::appendProperty(Property *prop, const QString &propertyName, bool return QString(); // no error } -QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation) +QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation) { Object *target = declarationsOverride; if (!target) @@ -358,8 +358,8 @@ QString Object::bindingAsString(Document *doc, int scriptIndex) const QQmlJS::AST::Node *node = foe->node; if (QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(node)) node = exprStmt->expression; - QQmlJS::AST::SourceLocation start = node->firstSourceLocation(); - QQmlJS::AST::SourceLocation end = node->lastSourceLocation(); + QQmlJS::SourceLocation start = node->firstSourceLocation(); + QQmlJS::SourceLocation end = node->lastSourceLocation(); return doc->code.mid(start.offset, end.offset + end.length - start.offset); } @@ -438,7 +438,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen // Extract errors from the parser for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { if (m.isWarning()) { - qWarning("%s:%d : %s", qPrintable(url), m.line, qPrintable(m.message)); + qWarning("%s:%d : %s", qPrintable(url), m.loc.startLine, qPrintable(m.message)); continue; } @@ -466,7 +466,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen accept(program->headers); if (program->members->next) { - QQmlJS::AST::SourceLocation loc = program->members->next->firstSourceLocation(); + QQmlJS::SourceLocation loc = program->members->next->firstSourceLocation(); recordError(loc, QCoreApplication::translate("QQmlParser", "Unexpected object definition")); return false; } @@ -531,7 +531,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node) int idx = 0; if (!defineQMLObject(&idx, node)) return false; - const QQmlJS::AST::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken; + const QQmlJS::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken; appendBinding(nameLocation, nameLocation, emptyStringIndex, idx); } else { int idx = 0; @@ -586,7 +586,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiScriptBinding *node) bool IRBuilder::visit(QQmlJS::AST::UiArrayBinding *node) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken; Object *object = nullptr; QQmlJS::AST::UiQualifiedId *name = node->qualifiedId; if (!resolveQualifiedId(&name, &object)) @@ -651,7 +651,7 @@ void IRBuilder::accept(QQmlJS::AST::Node *node) QQmlJS::AST::Node::accept(node, this); } -bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride) +bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride) { if (QQmlJS::AST::UiQualifiedId *lastName = qualifiedTypeNameId) { while (lastName->next) @@ -687,7 +687,7 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu if (!errors.isEmpty()) return false; - QQmlJS::AST::SourceLocation loc; + QQmlJS::SourceLocation loc; QString error = sanityCheckFunctionNames(obj, illegalNames, &loc); if (!error.isEmpty()) { recordError(loc, error); @@ -865,7 +865,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) const QString signalName = node->name.toString(); signal->nameIndex = registerString(signalName); - QQmlJS::AST::SourceLocation loc = node->typeToken; + QQmlJS::SourceLocation loc = node->typeToken; signal->location.line = loc.startLine; signal->location.column = loc.startColumn; @@ -948,11 +948,11 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) const QString propName = name.toString(); property->nameIndex = registerString(propName); - QQmlJS::AST::SourceLocation loc = node->firstSourceLocation(); + QQmlJS::SourceLocation loc = node->firstSourceLocation(); property->location.line = loc.startLine; property->location.column = loc.startColumn; - QQmlJS::AST::SourceLocation errorLocation; + QQmlJS::SourceLocation errorLocation; QString error; if (illegalNames.contains(propName)) @@ -993,7 +993,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) const int index = _object->functionsAndExpressions->append(foe); Function *f = New<Function>(); - QQmlJS::AST::SourceLocation loc = funDecl->identifierToken; + QQmlJS::SourceLocation loc = funDecl->identifierToken; f->location.line = loc.startLine; f->location.column = loc.startColumn; f->index = index; @@ -1060,14 +1060,14 @@ QTypeRevision IRBuilder::extractVersion(const QStringRef &string) : QTypeRevision::fromVersion(string.left(dot).toInt(), string.mid(dot + 1).toInt()); } -QStringRef IRBuilder::textRefAt(const QQmlJS::AST::SourceLocation &first, const QQmlJS::AST::SourceLocation &last) const +QStringRef IRBuilder::textRefAt(const QQmlJS::SourceLocation &first, const QQmlJS::SourceLocation &last) const { return QStringRef(&sourceCode, first.offset, last.offset + last.length - first.offset); } void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode) { - QQmlJS::AST::SourceLocation loc = statement->firstSourceLocation(); + QQmlJS::SourceLocation loc = statement->firstSourceLocation(); binding->valueLocation.line = loc.startLine; binding->valueLocation.column = loc.startColumn; binding->type = QV4::CompiledData::Binding::Type_Invalid; @@ -1244,7 +1244,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken; Object *object = nullptr; if (!resolveQualifiedId(&name, &object)) return; @@ -1259,7 +1259,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Sta void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken; Object *object = nullptr; if (!resolveQualifiedId(&name, &object, isOnAssignment)) return; @@ -1268,7 +1268,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, qSwap(_object, object); } -void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, +void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode) { Binding *binding = New<Binding>(); @@ -1284,7 +1284,7 @@ void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLo } } -void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment) +void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment) { if (stringAt(propertyNameIndex) == QLatin1String("id")) { recordError(nameLocation, tr("Invalid component id specification")); @@ -1333,7 +1333,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) const QString propName = node->name.toString(); alias->nameIndex = registerString(propName); - QQmlJS::AST::SourceLocation loc = node->firstSourceLocation(); + QQmlJS::SourceLocation loc = node->firstSourceLocation(); alias->location.line = loc.startLine; alias->location.column = loc.startColumn; @@ -1342,7 +1342,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) if (!node->statement && !node->binding) COMPILE_EXCEPTION(loc, tr("No property alias location")); - QQmlJS::AST::SourceLocation rhsLoc; + QQmlJS::SourceLocation rhsLoc; if (node->binding) rhsLoc = node->binding->firstSourceLocation(); else if (node->statement) @@ -1377,7 +1377,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) propertyValue += QLatin1Char('.') + aliasReference.at(2); alias->propertyNameIndex = registerString(propertyValue); - QQmlJS::AST::SourceLocation errorLocation; + QQmlJS::SourceLocation errorLocation; QString error; if (illegalNames.contains(propName)) @@ -1403,9 +1403,9 @@ Object *IRBuilder::bindingsTarget() const return _object; } -bool IRBuilder::setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value) +bool IRBuilder::setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value) { - QQmlJS::AST::SourceLocation loc = value->firstSourceLocation(); + QQmlJS::SourceLocation loc = value->firstSourceLocation(); QStringRef str; QQmlJS::AST::Node *node = value; @@ -1507,7 +1507,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O binding->type = QV4::CompiledData::Binding::Type_GroupProperty; int objIndex = 0; - if (!defineQMLObject(&objIndex, nullptr, QQmlJS::AST::SourceLocation(), nullptr, nullptr)) + if (!defineQMLObject(&objIndex, nullptr, QQmlJS::SourceLocation(), nullptr, nullptr)) return false; binding->value.objectIndex = objIndex; @@ -1530,11 +1530,10 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O return true; } -void IRBuilder::recordError(const QQmlJS::AST::SourceLocation &location, const QString &description) +void IRBuilder::recordError(const QQmlJS::SourceLocation &location, const QString &description) { QQmlJS::DiagnosticMessage error; - error.line = location.startLine; - error.column = location.startColumn; + error.loc = location; error.message = description; errors << error; } diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index ae74254a42..1f2c11f7f3 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -371,12 +371,12 @@ public: // specified object. Used for declarations inside group properties. Object *declarationsOverride; - void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &location = QQmlJS::AST::SourceLocation()); + void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &location = QQmlJS::SourceLocation()); QString appendEnum(Enum *enumeration); QString appendSignal(Signal *signal); - QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation); - QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation); + QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); + QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); void appendFunction(QmlIR::Function *f); void appendInlineComponent(InlineComponent *ic); void appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData); @@ -485,24 +485,24 @@ public: void throwRecursionDepthError() override { - recordError(QQmlJS::AST::SourceLocation(), + recordError(QQmlJS::SourceLocation(), QStringLiteral("Maximum statement or expression depth exceeded")); } void accept(QQmlJS::AST::Node *node); // returns index in _objects - bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr); + bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr); bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = nullptr) { return defineQMLObject(objectIndex, node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); } static QString asString(QQmlJS::AST::UiQualifiedId *node); QStringRef asStringRef(QQmlJS::AST::Node *node); static QTypeRevision extractVersion(const QStringRef &string); - QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const + QStringRef textRefAt(const QQmlJS::SourceLocation &loc) const { return QStringRef(&sourceCode, loc.offset, loc.length); } - QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first, - const QQmlJS::AST::SourceLocation &last) const; + QStringRef textRefAt(const QQmlJS::SourceLocation &first, + const QQmlJS::SourceLocation &last) const; void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode); @@ -511,24 +511,24 @@ public: void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode); void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false); - void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, - const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, + void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, + const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode); - void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, - const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, + void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, + const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem = false, bool isOnAssignment = false); bool appendAlias(QQmlJS::AST::UiPublicMember *node); Object *bindingsTarget() const; - bool setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value); + bool setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value); // resolves qualified name (font.pixelSize for example) and returns the last name along // with the object any right-hand-side of a binding should apply to. bool resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, Object **object, bool onAssignment = false); - void recordError(const QQmlJS::AST::SourceLocation &location, const QString &description); + void recordError(const QQmlJS::SourceLocation &location, const QString &description); quint32 registerString(const QString &str) const { return jsGenerator->registerString(str); } template <typename _Tp> _Tp *New() { return pool->New<_Tp>(); } @@ -538,7 +538,7 @@ public: static bool isStatementNodeScript(QQmlJS::AST::Statement *statement); static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement); - QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation); + QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation); QList<QQmlJS::DiagnosticMessage> errors; diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 7df1614ffe..f8a41edb6a 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -45,7 +45,7 @@ QT_USE_NAMESPACE using namespace QV4; using namespace Moth; -void BytecodeGenerator::setLocation(const QQmlJS::AST::SourceLocation &loc) +void BytecodeGenerator::setLocation(const QQmlJS::SourceLocation &loc) { currentLine = static_cast<int>(loc.startLine); } diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h index 8c509dd9f1..1895a34a68 100644 --- a/src/qml/compiler/qv4bytecodegenerator_p.h +++ b/src/qml/compiler/qv4bytecodegenerator_p.h @@ -56,10 +56,8 @@ QT_BEGIN_NAMESPACE namespace QQmlJS { -namespace AST { class SourceLocation; } -} namespace QV4 { @@ -244,7 +242,7 @@ QT_WARNING_POP - void setLocation(const QQmlJS::AST::SourceLocation &loc); + void setLocation(const QQmlJS::SourceLocation &loc); ExceptionHandler *exceptionHandler() const { return currentExceptionHandler; diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index d61456f38d..4588690307 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -3821,8 +3821,7 @@ void Codegen::throwError(ErrorType errorType, const SourceLocation &loc, const Q _errorType = errorType; _error.message = detail; - _error.line = loc.startLine; - _error.column = loc.startColumn; + _error.loc = loc; } void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) @@ -4105,7 +4104,7 @@ Codegen::Reference Codegen::Reference::asLValue() const case Accumulator: Q_UNREACHABLE(); case Super: - codegen->throwSyntaxError(AST::SourceLocation(), QStringLiteral("Super lvalues not implemented.")); + codegen->throwSyntaxError(SourceLocation(), QStringLiteral("Super lvalues not implemented.")); return *this; case Member: if (!propertyBase.isStackSlot()) { diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index 82a4fc3289..255698d790 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -661,12 +661,12 @@ protected: bool visit(QQmlJS::AST::UiSourceElement *ast) override; bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, - const QQmlJS::AST::SourceLocation &loc); - virtual void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail); - virtual void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail); + const QQmlJS::SourceLocation &loc); + virtual void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail); + virtual void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail); void throwRecursionDepthError() override { - throwSyntaxError(QQmlJS::AST::SourceLocation(), + throwSyntaxError(QQmlJS::SourceLocation(), QStringLiteral("Maximum statement or expression depth exceeded")); } @@ -700,7 +700,7 @@ public: Reference referenceForName( const QString &name, bool lhs, - const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation()); + const QQmlJS::SourceLocation &accessLocation = QQmlJS::SourceLocation()); QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData = true); static QV4::CompiledData::CompilationUnit compileModule( @@ -810,7 +810,7 @@ protected: private: VolatileMemoryLocations scanVolatileMemoryLocations(QQmlJS::AST::Node *ast); void handleConstruct(const Reference &base, QQmlJS::AST::ArgumentList *args); - void throwError(ErrorType errorType, const QQmlJS::AST::SourceLocation &loc, + void throwError(ErrorType errorType, const QQmlJS::SourceLocation &loc, const QString &detail); }; diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp index 88837b0feb..872fc94dc9 100644 --- a/src/qml/compiler/qv4compilercontext.cpp +++ b/src/qml/compiler/qv4compilercontext.cpp @@ -45,6 +45,7 @@ QT_USE_NAMESPACE using namespace QV4; using namespace QV4::Compiler; using namespace QQmlJS::AST; +using namespace QQmlJS; QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ bool Context::Member::requiresTDZCheck(const SourceLocation &accessLocation, boo } bool Context::addLocalVar(const QString &name, Context::MemberType type, VariableScope scope, FunctionExpression *function, - const QQmlJS::AST::SourceLocation &endOfInitializer) + const QQmlJS::SourceLocation &endOfInitializer) { // ### can this happen? if (name.isEmpty()) @@ -122,7 +123,7 @@ bool Context::addLocalVar(const QString &name, Context::MemberType type, Variabl return true; } -Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation) +Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation) { int scope = 0; Context *c = this; diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h index 8c124ac409..4a14009c35 100644 --- a/src/qml/compiler/qv4compilercontext_p.h +++ b/src/qml/compiler/qv4compilercontext_p.h @@ -183,10 +183,10 @@ struct Context { QQmlJS::AST::VariableScope scope = QQmlJS::AST::VariableScope::Var; mutable bool canEscape = false; QQmlJS::AST::FunctionExpression *function = nullptr; - QQmlJS::AST::SourceLocation endOfInitializerLocation; + QQmlJS::SourceLocation endOfInitializerLocation; bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableScope::Var; } - bool requiresTDZCheck(const QQmlJS::AST::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const; + bool requiresTDZCheck(const QQmlJS::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const; }; typedef QMap<QString, Member> MemberMap; @@ -227,7 +227,7 @@ struct Context { bool isWithBlock = false; bool isCatchBlock = false; QString caughtVariable; - QQmlJS::AST::SourceLocation lastBlockInitializerLocation; + QQmlJS::SourceLocation lastBlockInitializerLocation; enum UsesArgumentsObject { ArgumentsObjectUnknown, @@ -331,7 +331,7 @@ struct Context { } bool addLocalVar(const QString &name, MemberType contextType, QQmlJS::AST::VariableScope scope, QQmlJS::AST::FunctionExpression *function = nullptr, - const QQmlJS::AST::SourceLocation &endOfInitializer = QQmlJS::AST::SourceLocation()); + const QQmlJS::SourceLocation &endOfInitializer = QQmlJS::SourceLocation()); struct ResolvedName { enum Type { @@ -348,10 +348,10 @@ struct Context { bool requiresTDZCheck = false; int scope = -1; int index = -1; - QQmlJS::AST::SourceLocation endOfDeclarationLocation; + QQmlJS::SourceLocation endOfDeclarationLocation; bool isValid() const { return type != Unresolved; } }; - ResolvedName resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation); + ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation); void emitBlockHeader(Compiler::Codegen *codegen); void emitBlockFooter(Compiler::Codegen *codegen); diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index ab0ebf3d4b..a1ddee8234 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -55,7 +55,7 @@ using namespace QV4::Compiler; using namespace QQmlJS; using namespace QQmlJS::AST; -static CompiledData::Location location(const QQmlJS::AST::SourceLocation &astLocation) +static CompiledData::Location location(const QQmlJS::SourceLocation &astLocation) { CompiledData::Location target; target.line = astLocation.startLine; @@ -129,7 +129,7 @@ void ScanFunctions::checkDirectivePrologue(StatementList *ast) } } -void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc) +void ScanFunctions::checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc) { if (_context->isStrict) { if (name == QLatin1String("implements") @@ -330,7 +330,7 @@ bool ScanFunctions::visit(PatternElement *ast) BoundNames names; ast->boundNames(&names); - QQmlJS::AST::SourceLocation lastInitializerLocation = ast->lastSourceLocation(); + QQmlJS::SourceLocation lastInitializerLocation = ast->lastSourceLocation(); if (_context->lastBlockInitializerLocation.isValid()) lastInitializerLocation = _context->lastBlockInitializerLocation; diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index 2de80eac44..e39aa2454e 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -97,7 +97,7 @@ protected: void checkDirectivePrologue(QQmlJS::AST::StatementList *ast); - void checkName(const QStringRef &name, const QQmlJS::AST::SourceLocation &loc); + void checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc); bool visit(QQmlJS::AST::Program *ast) override; void endVisit(QQmlJS::AST::Program *) override; diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 4095cd22ea..9dfb7837e5 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -197,6 +197,25 @@ type or method parameter, the value can be created as a JavaScript array or object in QML, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++. +Mind that QVariantList and QVariantMap properties of C++ types are stored as +values and cannot be changed in place by QML code. You can only replace the +whole map or list, but not manipulate its contents. The following code does +not work if the property \c l is a QVariantList: + +\code +MyListExposingItem { + l: [1, 2, 3] + Component.onCompleted: l[0] = 10 +} +\endcode + +The following code does work: +\code +MyListExposingItem { + l: [1, 2, 3] + Component.onCompleted: l = [10, 2, 3] +} +\endcode \section2 QDateTime to JavaScript Date diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f1b20ce53b..1efe09c59f 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1266,20 +1266,15 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file) void ExecutionEngine::markObjects(MarkStack *markStack) { - for (int i = 0; i < NClasses; ++i) - if (classes[i]) { - classes[i]->mark(markStack); - if (markStack->top >= markStack->limit) - markStack->drain(); - } - markStack->drain(); + for (int i = 0; i < NClasses; ++i) { + if (Heap::InternalClass *c = classes[i]) + c->mark(markStack); + } identifierTable->markObjects(markStack); - for (auto compilationUnit: compilationUnits) { + for (auto compilationUnit: compilationUnits) compilationUnit->markObjects(markStack); - markStack->drain(); - } } ReturnedValue ExecutionEngine::throwError(const Value &value) @@ -1915,10 +1910,10 @@ QQmlRefPointer<ExecutableCompilationUnit> ExecutionEngine::compileModule( sourceCode, sourceTimeStamp, &diagnostics); for (const QQmlJS::DiagnosticMessage &m : diagnostics) { if (m.isError()) { - throwSyntaxError(m.message, url.toString(), m.line, m.column); + throwSyntaxError(m.message, url.toString(), m.loc.startLine, m.loc.startColumn); return nullptr; } else { - qWarning() << url << ':' << m.line << ':' << m.column + qWarning() << url << ':' << m.loc.startLine << ':' << m.loc.startColumn << ": warning: " << m.message; } } @@ -2360,9 +2355,11 @@ int ExecutionEngine::registerExtension() return registrationData()->extensionCount++; } +#if QT_CONFIG(qml_network) QNetworkAccessManager *QV4::detail::getNetworkAccessManager(ExecutionEngine *engine) { return engine->qmlEngine()->networkAccessManager(); } +#endif // qml_network QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index e0025feb00..efe44a324c 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -91,6 +91,7 @@ class PageAllocation; QT_BEGIN_NAMESPACE +#if QT_CONFIG(qml_network) class QNetworkAccessManager; namespace QV4 { @@ -99,6 +100,9 @@ namespace detail { QNetworkAccessManager *getNetworkAccessManager(ExecutionEngine *engine); } } +#else +namespace QV4 { struct QObjectMethod; } +#endif // qml_network // Used to allow a QObject method take and return raw V4 handles without having to expose // 48 in the public API. @@ -355,7 +359,9 @@ public: FunctionObject *getStackFunction() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetStack_Function); } FunctionObject *thrower() const { return reinterpret_cast<FunctionObject *>(jsObjects + ThrowerObject); } +#if QT_CONFIG(qml_network) QNetworkAccessManager* (*networkAccessManager)(ExecutionEngine*) = detail::getNetworkAccessManager; +#endif enum JSStrings { String_Empty, diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 64ca719e29..92face6f94 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -163,7 +163,7 @@ void QV4Include::finished() QV4::Scope scope(v4); QV4::ScopedObject resultObj(scope, m_resultObject.value()); QV4::ScopedString status(scope, v4->newString(QStringLiteral("status"))); - if (m_reply->networkError() == QNetworkReply::NoError) { + if (m_reply->error() == QNetworkReply::NoError) { QByteArray data = m_reply->readAll(); QString code = QString::fromUtf8(data); diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp index 79c372348f..f4901e3e4d 100644 --- a/src/qml/jsruntime/qv4persistent.cpp +++ b/src/qml/jsruntime/qv4persistent.cpp @@ -240,7 +240,6 @@ void PersistentValueStorage::mark(MarkStack *markStack) if (Managed *m = p->values[i].as<Managed>()) m->mark(markStack); } - markStack->drain(); p = p->header.next; } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 9613d064c4..66b79aa0e8 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -638,10 +638,11 @@ void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack) if (!ddata) return; - if (ddata->jsEngineId == markStack->engine->m_engineId) + const QV4::ExecutionEngine *engine = markStack->engine(); + if (ddata->jsEngineId == engine->m_engineId) ddata->jsWrapper.markOnce(markStack); - else if (markStack->engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object) - markStack->engine->m_multiplyWrappedQObjects->mark(object, markStack); + else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object) + engine->m_multiplyWrappedQObjects->mark(object, markStack); } void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value) diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp index 162d75db63..b7737982b7 100644 --- a/src/qml/jsruntime/qv4runtimecodegen.cpp +++ b/src/qml/jsruntime/qv4runtimecodegen.cpp @@ -67,7 +67,7 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName, _module->rootContext = _module->functions.at(index); } -void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QString &detail) +void RuntimeCodegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) { if (hasError()) return; @@ -76,7 +76,7 @@ void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QStr engine->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn); } -void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const QString &detail) +void RuntimeCodegen::throwReferenceError(const SourceLocation &loc, const QString &detail) { if (hasError()) return; diff --git a/src/qml/jsruntime/qv4runtimecodegen_p.h b/src/qml/jsruntime/qv4runtimecodegen_p.h index 71aaf1fb55..d3a30ce35d 100644 --- a/src/qml/jsruntime/qv4runtimecodegen_p.h +++ b/src/qml/jsruntime/qv4runtimecodegen_p.h @@ -69,8 +69,8 @@ public: QQmlJS::AST::FunctionExpression *ast, Compiler::Module *module); - void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override; - void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override; + void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail) override; + void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail) override; private: ExecutionEngine *engine; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 2fab9e4b7b..2add1222ea 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -52,6 +52,7 @@ #include <private/qqmljsparser_p.h> #include <private/qqmljsast_p.h> #include <private/qqmlengine_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <private/qv4profiling_p.h> #include <qv4runtimecodegen_p.h> @@ -109,10 +110,10 @@ void Script::parse() const auto diagnosticMessages = parser.diagnosticMessages(); for (const DiagnosticMessage &m : diagnosticMessages) { if (m.isError()) { - valueScope.engine->throwSyntaxError(m.message, sourceFile, m.line, m.column); + valueScope.engine->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn); return; } else { - qWarning() << sourceFile << ':' << m.line << ':' << m.column + qWarning() << sourceFile << ':' << m.loc.startLine << ':' << m.loc.startColumn << ": warning: " << m.message; } } @@ -209,8 +210,8 @@ QV4::CompiledData::CompilationUnit Script::precompile( const auto v4Error = cg.error(); QQmlError error; error.setUrl(cg.url()); - error.setLine(v4Error.line); - error.setColumn(v4Error.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(v4Error.loc.startLine)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(v4Error.loc.startColumn)); error.setDescription(v4Error.message); reportedErrors->append(error); } diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index ae12033eb4..42e97b1d36 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -537,29 +537,8 @@ struct ValueArray { } void mark(MarkStack *markStack) { - Value *v = values; - const Value *end = v + alloc; - if (alloc > 32*1024) { - // drain from time to time to avoid overflows in the js stack - Value::HeapBasePtr *currentBase = markStack->top; - while (v < end) { - v->mark(markStack); - ++v; - if (markStack->top >= currentBase + 32*1024) { - Value::HeapBasePtr *oldBase = markStack->base; - markStack->base = currentBase; - markStack->drain(); - markStack->base = oldBase; - } - } - } else { - while (v < end) { - v->mark(markStack); - if (markStack->top >= markStack->limit) - markStack->drain(); - ++v; - } - } + for (Value *v = values, *end = values + alloc; v < end; ++v) + v->mark(markStack); } }; diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 35b2ff2749..3ed1bc48fd 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -848,16 +848,18 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable static uint markStackSize = 0; MarkStack::MarkStack(ExecutionEngine *engine) - : engine(engine) + : m_engine(engine) { - base = (Heap::Base **)engine->gcStack->base(); - top = base; - limit = base + engine->maxGCStackSize()/sizeof(Heap::Base)*3/4; + m_base = (Heap::Base **)engine->gcStack->base(); + m_top = m_base; + const size_t size = engine->maxGCStackSize() / sizeof(Heap::Base); + m_hardLimit = m_base + size; + m_softLimit = m_base + size * 3 / 4; } void MarkStack::drain() { - while (top > base) { + while (m_top > m_base) { Heap::Base *h = pop(); ++markStackSize; Q_ASSERT(h); // at this point we should only have Heap::Base objects in this area on the stack. If not, weird things might happen. @@ -904,20 +906,15 @@ void MemoryManager::collectRoots(MarkStack *markStack) if (keepAlive) qobjectWrapper->mark(markStack); - - if (markStack->top >= markStack->limit) - markStack->drain(); } } void MemoryManager::mark() { markStackSize = 0; - MarkStack markStack(engine); collectRoots(&markStack); - - markStack.drain(); + // dtor of MarkStack drains } void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPtr) @@ -1220,8 +1217,6 @@ void MemoryManager::collectFromJSStack(MarkStack *markStack) const Q_ASSERT(m->inUse()); // Skip pointers to already freed objects, they are bogus as well m->mark(markStack); - if (markStack->top >= markStack->limit) - markStack->drain(); } ++v; } diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h index 8a53492822..117e8f4360 100644 --- a/src/qml/memory/qv4mmdefs_p.h +++ b/src/qml/memory/qv4mmdefs_p.h @@ -53,6 +53,7 @@ #include <private/qv4global_p.h> #include <private/qv4runtimeapi_p.h> #include <QtCore/qalgorithms.h> +#include <QtCore/qmath.h> #include <qdebug.h> QT_BEGIN_NAMESPACE @@ -270,22 +271,41 @@ Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize); Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits); Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits); -struct MarkStack { +struct Q_QML_PRIVATE_EXPORT MarkStack { MarkStack(ExecutionEngine *engine); - Heap::Base **top = nullptr; - Heap::Base **base = nullptr; - Heap::Base **limit = nullptr; - ExecutionEngine *engine; + ~MarkStack() { drain(); } + void push(Heap::Base *m) { - *top = m; - ++top; - } - Heap::Base *pop() { - --top; - return *top; + *(m_top++) = m; + + if (m_top < m_softLimit) + return; + + // If at or above soft limit, partition the remaining space into at most 64 segments and + // allow one C++ recursion of drain() per segment, plus one for the fence post. + const quintptr segmentSize = qNextPowerOfTwo(quintptr(m_hardLimit - m_softLimit) / 64u); + if (m_drainRecursion * segmentSize <= quintptr(m_top - m_softLimit)) { + ++m_drainRecursion; + drain(); + --m_drainRecursion; + } else if (m_top == m_hardLimit) { + qFatal("GC mark stack overrun. Either simplify your application or" + "increase QV4_GC_MAX_STACK_SIZE"); + } } + + ExecutionEngine *engine() const { return m_engine; } + +private: + Heap::Base *pop() { return *(--m_top); } void drain(); + Heap::Base **m_top = nullptr; + Heap::Base **m_base = nullptr; + Heap::Base **m_softLimit = nullptr; + Heap::Base **m_hardLimit = nullptr; + ExecutionEngine *m_engine = nullptr; + quintptr m_drainRecursion = 0; }; // Some helper to automate the generation of our diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri index e15730f5d1..57855a82f9 100644 --- a/src/qml/parser/parser.pri +++ b/src/qml/parser/parser.pri @@ -5,9 +5,7 @@ HEADERS += \ $$PWD/qqmljsengine_p.h \ $$PWD/qqmljslexer_p.h \ $$PWD/qqmljsglobal_p.h \ - $$PWD/qqmljskeywords_p.h \ - $$PWD/qqmljsengine_p.h \ - $$PWD/qqmljssourcelocation_p.h + $$PWD/qqmljskeywords_p.h SOURCES += \ $$PWD/qqmljsast.cpp \ diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index a246dfba7a..ef814a57b0 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -390,10 +390,10 @@ public: { return diagnosticMessage().message; } inline int errorLineNumber() const - { return diagnosticMessage().line; } + { return diagnosticMessage().loc.startLine; } inline int errorColumnNumber() const - { return diagnosticMessage().column; } + { return diagnosticMessage().loc.startColumn; } protected: bool parse(int startToken); @@ -409,7 +409,7 @@ protected: inline QStringRef &rawStringRef(int index) { return rawString_stack [tos + index - 1]; } - inline AST::SourceLocation &loc(int index) + inline SourceLocation &loc(int index) { return location_stack [tos + index - 1]; } AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); @@ -417,21 +417,20 @@ protected: void pushToken(int token); int lookaheadToken(Lexer *lexer); - static DiagnosticMessage compileError(const AST::SourceLocation &location, + static DiagnosticMessage compileError(const SourceLocation &location, const QString &message, QtMsgType kind = QtCriticalMsg) { DiagnosticMessage error; - error.line = location.startLine; - error.column = location.startColumn; + error.loc = location; error.message = message; error.type = kind; return error; } - void syntaxError(const AST::SourceLocation &location, const char *message) { + void syntaxError(const SourceLocation &location, const char *message) { diagnostic_messages.append(compileError(location, QLatin1String(message))); } - void syntaxError(const AST::SourceLocation &location, const QString &message) { + void syntaxError(const SourceLocation &location, const QString &message) { diagnostic_messages.append(compileError(location, message)); } @@ -444,7 +443,7 @@ protected: int stack_size = 0; Value *sym_stack = nullptr; int *state_stack = nullptr; - AST::SourceLocation *location_stack = nullptr; + SourceLocation *location_stack = nullptr; QVector<QStringRef> string_stack; QVector<QStringRef> rawString_stack; @@ -456,7 +455,7 @@ protected: struct SavedToken { int token; double dval; - AST::SourceLocation loc; + SourceLocation loc; QStringRef spell; QStringRef raw; }; @@ -465,8 +464,8 @@ protected: double yylval = 0.; QStringRef yytokenspell; QStringRef yytokenraw; - AST::SourceLocation yylloc; - AST::SourceLocation yyprevlloc; + SourceLocation yylloc; + SourceLocation yyprevlloc; SavedToken token_buffer[TOKEN_BUFFER_SIZE]; SavedToken *first_token = nullptr; @@ -479,7 +478,7 @@ protected: CE_ParenthesizedExpression, CE_FormalParameterList }; - AST::SourceLocation coverExpressionErrorLocation; + SourceLocation coverExpressionErrorLocation; CoverExpressionType coverExpressionType = CE_Invalid; QList<DiagnosticMessage> diagnostic_messages; @@ -524,7 +523,7 @@ void Parser::reallocateStack() sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); - location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); + location_stack = reinterpret_cast<SourceLocation*> (realloc(location_stack, stack_size * sizeof(SourceLocation))); string_stack.resize(stack_size); rawString_stack.resize(stack_size); } @@ -544,9 +543,9 @@ Parser::~Parser() } } -static inline AST::SourceLocation location(Lexer *lexer) +static inline SourceLocation location(Lexer *lexer) { - AST::SourceLocation loc; + SourceLocation loc; loc.offset = lexer->tokenOffset(); loc.length = lexer->tokenLength(); loc.startLine = lexer->tokenStartLine(); @@ -557,7 +556,7 @@ static inline AST::SourceLocation location(Lexer *lexer) AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) { QVarLengthArray<QStringRef, 4> nameIds; - QVarLengthArray<AST::SourceLocation, 4> locations; + QVarLengthArray<SourceLocation, 4> locations; AST::ExpressionNode *it = expr; while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) { @@ -2857,7 +2856,7 @@ AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In; case $rule_number: { // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral if (AST::Pattern *p = sym(1).Expression->patternCast()) { - AST::SourceLocation errorLoc; + SourceLocation errorLoc; QString errorMsg; if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { syntaxError(errorLoc, errorMsg); @@ -3523,7 +3522,7 @@ IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T case $rule_number: { // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral if (AST::Pattern *p = sym(3).Expression->patternCast()) { - AST::SourceLocation errorLoc; + SourceLocation errorLoc; QString errorMsg; if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { syntaxError(errorLoc, errorMsg); diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index b92a635228..de554a53af 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -1071,7 +1071,7 @@ public: PatternPropertyList *next; }; -class QML_PARSER_EXPORT IdentifierPropertyName : public PropertyName +class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName { public: QQMLJS_DECLARE_AST_NODE(IdentifierPropertyName) diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h index 8df0be7590..ef37e8072f 100644 --- a/src/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/parser/qqmljsastfwd_p.h @@ -41,7 +41,7 @@ #define QQMLJSAST_FWD_P_H #include "qqmljsglobal_p.h" -#include "qqmljssourcelocation_p.h" +#include <private/qqmljssourcelocation_p.h> #include <QtCore/qglobal.h> diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp index bb27f3992e..cb6b0375e6 100644 --- a/src/qml/parser/qqmljsengine_p.cpp +++ b/src/qml/parser/qqmljsengine_p.cpp @@ -123,9 +123,9 @@ void Engine::setCode(const QString &code) { _code = code; } void Engine::addComment(int pos, int len, int line, int col) -{ if (len > 0) _comments.append(QQmlJS::AST::SourceLocation(pos, len, line, col)); } +{ if (len > 0) _comments.append(QQmlJS::SourceLocation(pos, len, line, col)); } -QList<QQmlJS::AST::SourceLocation> Engine::comments() const +QList<QQmlJS::SourceLocation> Engine::comments() const { return _comments; } Lexer *Engine::lexer() const diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h index 8a3e2db6a1..a34922fa1e 100644 --- a/src/qml/parser/qqmljsengine_p.h +++ b/src/qml/parser/qqmljsengine_p.h @@ -52,7 +52,7 @@ // #include "qqmljsglobal_p.h" -#include "qqmljssourcelocation_p.h" +#include <private/qqmljssourcelocation_p.h> #include <private/qqmljsmemorypool_p.h> @@ -97,7 +97,7 @@ class QML_PARSER_EXPORT Engine Lexer *_lexer; Directives *_directives; MemoryPool _pool; - QList<AST::SourceLocation> _comments; + QList<SourceLocation> _comments; QString _extraCode; QString _code; @@ -109,7 +109,7 @@ public: const QString &code() const { return _code; } void addComment(int pos, int len, int line, int col); - QList<AST::SourceLocation> comments() const; + QList<SourceLocation> comments() const; Lexer *lexer() const; void setLexer(Lexer *lexer); diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp index 0c61679f0b..243fc5bd30 100644 --- a/src/qml/parser/qqmljslexer.cpp +++ b/src/qml/parser/qqmljslexer.cpp @@ -1480,8 +1480,8 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error) { auto setError = [error, this](QString message) { error->message = std::move(message); - error->line = tokenStartLine(); - error->column = tokenStartColumn(); + error->loc.startLine = tokenStartLine(); + error->loc.startColumn = tokenStartColumn(); }; QScopedValueRollback<bool> directivesGuard(_handlingDirectives, true); @@ -1596,8 +1596,8 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error) else setError(QCoreApplication::translate("QQmlParser", "Module import requires a qualifier")); if (tokenStartLine() != lineNumber) { - error->line = lineNumber; - error->line = column; + error->loc.startLine = lineNumber; + error->loc.startColumn = column; } return false; // expected `as' } diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index b9445e48a8..c617f81006 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -855,6 +855,38 @@ void qmlRegisterTypesAndRevisions(const char *uri, int versionMajor) template<> inline void qmlRegisterTypesAndRevisions<>(const char *, int) {} +inline void qmlRegisterNamespaceAndRevisions(const QMetaObject *metaObject, + const char *uri, int versionMajor) +{ + QQmlPrivate::RegisterTypeAndRevisions type = { + 0, + 0, + 0, + 0, + nullptr, + + uri, + QTypeRevision::fromMajorVersion(versionMajor), + + metaObject, + metaObject, + + nullptr, + nullptr, + + -1, + -1, + -1, + + nullptr, + nullptr, + + &qmlCreateCustomParser<void> + }; + + qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type); +} + int Q_QML_EXPORT qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *qmlName); QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 279998b5de..ede2816d5f 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -50,6 +50,7 @@ #include "qqmlincubator.h" #include "qqmlincubator_p.h" #include <private/qqmljavascriptexpression_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <private/qv4functionobject_p.h> #include <private/qv4script_p.h> @@ -1424,8 +1425,8 @@ QQmlError QQmlComponentPrivate::unsetRequiredPropertyToQQmlError(const RequiredP } error.setDescription(description); error.setUrl(unsetRequiredProperty.fileUrl); - error.setLine(unsetRequiredProperty.location.line); - error.setColumn(unsetRequiredProperty.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(unsetRequiredProperty.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(unsetRequiredProperty.location.column)); return error; } diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index 02c2b87a6e..b0df4f26dc 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -40,6 +40,7 @@ #include "qqmlcustomparser_p.h" #include <private/qv4compileddata_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtCore/qdebug.h> @@ -100,10 +101,10 @@ void QQmlCustomParser::clearErrors() */ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description) { - QQmlJS::DiagnosticMessage error; - error.line = location.line; - error.column = location.column; - error.message = description; + QQmlError error; + error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column)); + error.setDescription(description); exceptions << error; } diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index abac90d6ad..4eb709228e 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -83,7 +83,7 @@ public: virtual void verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0; virtual void applyBindings(QObject *, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0; - QVector<QQmlJS::DiagnosticMessage> errors() const { return exceptions; } + QVector<QQmlError> errors() const { return exceptions; } protected: void error(const QV4::CompiledData::Binding *binding, const QString& description) @@ -97,7 +97,7 @@ protected: const QMetaObject *resolveType(const QString&) const; private: - QVector<QQmlJS::DiagnosticMessage> exceptions; + QVector<QQmlError> exceptions; QQmlEnginePrivate *engine; const QQmlPropertyValidator *validator; Flags m_flags; diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp index 1ab6002f0a..c29f207ae3 100644 --- a/src/qml/qml/qqmldatablob.cpp +++ b/src/qml/qml/qqmldatablob.cpp @@ -42,6 +42,7 @@ #include <private/qqmlprofiler_p.h> #include <private/qqmltypeloader_p.h> #include <private/qqmltypeloaderthread_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtQml/qqmlengine.h> @@ -289,7 +290,18 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors) Q_ASSERT(status() != Error); Q_ASSERT(m_errors.isEmpty()); - m_errors = errors; // Must be set before the m_data fence + // m_errors must be set before the m_data fence + m_errors.reserve(errors.count()); + for (const QQmlError &error : errors) { + if (error.url().isEmpty()) { + QQmlError mutableError = error; + mutableError.setUrl(url()); + m_errors.append(mutableError); + } else { + m_errors.append(error); + } + } + m_data.setStatus(Error); if (dumpErrors()) { @@ -306,28 +318,13 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors) void QQmlDataBlob::setError(const QQmlJS::DiagnosticMessage &error) { QQmlError e; - e.setColumn(error.column); - e.setLine(error.line); + e.setColumn(qmlConvertSourceCoordinate<quint32, int>(error.loc.startColumn)); + e.setLine(qmlConvertSourceCoordinate<quint32, int>(error.loc.startLine)); e.setDescription(error.message); e.setUrl(url()); setError(e); } -void QQmlDataBlob::setError(const QVector<QQmlJS::DiagnosticMessage> &errors) -{ - QList<QQmlError> finalErrors; - finalErrors.reserve(errors.count()); - for (const auto &error : errors) { - QQmlError e; - e.setColumn(error.column); - e.setLine(error.line); - e.setDescription(error.message); - e.setUrl(url()); - finalErrors << e; - } - setError(finalErrors); -} - void QQmlDataBlob::setError(const QString &description) { QQmlError e; diff --git a/src/qml/qml/qqmldatablob_p.h b/src/qml/qml/qqmldatablob_p.h index 0450e94c02..17db8f2dfe 100644 --- a/src/qml/qml/qqmldatablob_p.h +++ b/src/qml/qml/qqmldatablob_p.h @@ -132,7 +132,6 @@ protected: void setError(const QQmlError &); void setError(const QList<QQmlError> &errors); void setError(const QQmlJS::DiagnosticMessage &error); - void setError(const QVector<QQmlJS::DiagnosticMessage> &errors); void setError(const QString &description); void addDependency(QQmlDataBlob *); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 76be865c9f..58bdd3da2d 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -57,6 +57,7 @@ #include "qqmlnotifier_p.h" #include "qqmlincubator.h" #include "qqmlabstracturlinterceptor.h" +#include "qqmlsourcecoordinate_p.h" #include <private/qqmldirparser_p.h> #include <private/qqmlboundsignal_p.h> #include <private/qqmljsdiagnosticmessage_p.h> @@ -1330,12 +1331,16 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled) \code class MySingleton : public QObject { Q_OBJECT + + // Register as default constructed singleton. + QML_ELEMENT + QML_SINGLETON + static int typeId; // ... }; - // Register with QObject* callback - MySingleton::typeId = qmlRegisterSingletonType<MySingleton>(...); + MySingleton::typeId = qmlTypeId(...); // Retrieve as QObject* QQmlEngine engine; @@ -1352,11 +1357,10 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled) QJSValue instance = engine.singletonInstance<QJSValue>(typeId); \endcode - It is recommended to store the QML type id during registration, e.g. as a static member - in the singleton class. Otherwise, a costly lookup via qmlTypeId() has to be performed - at run-time. + It is recommended to store the QML type id, e.g. as a static member in the + singleton class. The lookup via qmlTypeId() is costly. - \sa qmlRegisterSingletonType(), qmlTypeId() + \sa QML_SINGLETON, qmlRegisterSingletonType(), qmlTypeId() \since 5.12 */ template<> @@ -2091,15 +2095,15 @@ QList<QQmlError> QQmlEnginePrivate::qmlErrorFromDiagnostics( QList<QQmlError> errors; for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { if (m.isWarning()) { - qWarning("%s:%d : %s", qPrintable(fileName), m.line, qPrintable(m.message)); + qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message)); continue; } QQmlError error; error.setUrl(QUrl(fileName)); error.setDescription(m.message); - error.setLine(m.line); - error.setColumn(m.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(m.loc.startLine)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(m.loc.startColumn)); errors << error; } return errors; diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp index 0b94ed3b49..da585d2126 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qml/qqmlerror.cpp @@ -77,12 +77,15 @@ QT_BEGIN_NAMESPACE \sa QQuickView::errors(), QQmlComponent::errors() */ -class QQmlErrorPrivate : public QQmlJS::DiagnosticMessage +class QQmlErrorPrivate { public: - QQmlErrorPrivate() { type = QtWarningMsg; } QUrl url; QPointer<QObject> object; + QString message; + QtMsgType type = QtWarningMsg; + int line = -1; + int column = -1; }; /*! @@ -185,7 +188,7 @@ void QQmlError::setDescription(const QString &description) int QQmlError::line() const { if (d) - return qmlConvertSourceCoordinate<quint32, int>(d->line); + return d->line; return -1; } @@ -196,7 +199,7 @@ void QQmlError::setLine(int line) { if (!d) d = new QQmlErrorPrivate; - d->line = qmlConvertSourceCoordinate<int, quint32>(line); + d->line = line; } /*! @@ -205,7 +208,7 @@ void QQmlError::setLine(int line) int QQmlError::column() const { if (d) - return qmlConvertSourceCoordinate<quint32, int>(d->column); + return d->column; return -1; } @@ -216,7 +219,7 @@ void QQmlError::setColumn(int column) { if (!d) d = new QQmlErrorPrivate; - d->column = qmlConvertSourceCoordinate<int, quint32>(column); + d->column = column; } /*! diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp index ee54359d0f..465a342129 100644 --- a/src/qml/qml/qqmlfile.cpp +++ b/src/qml/qml/qqmlfile.cpp @@ -187,7 +187,7 @@ void QQmlFileNetworkReply::networkFinished() } } - if (m_reply->networkError()) { + if (m_reply->error()) { m_p->errorString = m_reply->errorString(); m_p->error = QQmlFilePrivate::Network; } else { diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index ee512a5137..076a23c1dd 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -533,7 +533,7 @@ static QString joinStringRefs(const QVector<QStringRef> &refs, const QChar &sep) QStringList QQmlImports::completeQmldirPaths(const QString &uri, const QStringList &basePaths, QTypeRevision version) { - const QVector<QStringRef> parts = uri.splitRef(Dot, QString::SkipEmptyParts); + const QVector<QStringRef> parts = uri.splitRef(Dot, Qt::SkipEmptyParts); QStringList qmlDirPathsPaths; // fully & partially versioned parts + 1 unversioned for each base path @@ -1884,7 +1884,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) #else QLatin1Char pathSep(':'); #endif - QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts); + QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts); for (int ii = paths.count() - 1; ii >= 0; --ii) addImportPath(paths.at(ii)); } @@ -1896,7 +1896,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_BUNDLED_LIBS_PATH"))) { const QString envImportPath = qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"); QLatin1Char pathSep(':'); - QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts); + QStringList paths = envImportPath.split(pathSep, Qt::SkipEmptyParts); for (int ii = paths.count() - 1; ii >= 0; --ii) addPluginPath(paths.at(ii)); } diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp index dd401bdb20..7204d5ccd2 100644 --- a/src/qml/qml/qqmlinfo.cpp +++ b/src/qml/qml/qqmlinfo.cpp @@ -44,6 +44,7 @@ #include "qqmlcontext_p.h" #include "qqmlmetatype_p.h" #include "qqmlengine_p.h" +#include "qqmlsourcecoordinate_p.h" #include <QCoreApplication> @@ -218,8 +219,8 @@ QQmlInfo::~QQmlInfo() QQmlData *ddata = QQmlData::get(object, false); if (ddata && ddata->outerContext) { error.setUrl(ddata->outerContext->url()); - error.setLine(ddata->lineNumber); - error.setColumn(ddata->columnNumber); + error.setLine(qmlConvertSourceCoordinate<quint16, int>(ddata->lineNumber)); + error.setColumn(qmlConvertSourceCoordinate<quint16, int>(ddata->columnNumber)); } } diff --git a/src/qml/qml/qqmlirloader.cpp b/src/qml/qml/qqmlirloader.cpp index b284e44fdf..f66094fad7 100644 --- a/src/qml/qml/qqmlirloader.cpp +++ b/src/qml/qml/qqmlirloader.cpp @@ -78,14 +78,14 @@ struct FakeExpression : public QQmlJS::AST::NullExpression : location(start, length) {} - virtual QQmlJS::AST::SourceLocation firstSourceLocation() const + virtual QQmlJS::SourceLocation firstSourceLocation() const { return location; } - virtual QQmlJS::AST::SourceLocation lastSourceLocation() const + virtual QQmlJS::SourceLocation lastSourceLocation() const { return location; } private: - QQmlJS::AST::SourceLocation location; + QQmlJS::SourceLocation location; }; QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *serializedObject) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 8661ebcc13..6a9ef06159 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -50,6 +50,7 @@ #include <private/qqmlglobal_p.h> #include <private/qv4qobjectwrapper_p.h> #include <private/qqmlbuiltinfunctions_p.h> +#include <private/qqmlsourcecoordinate_p.h> QT_BEGIN_NAMESPACE @@ -72,8 +73,8 @@ bool QQmlDelayedError::addError(QQmlEnginePrivate *e) void QQmlDelayedError::setErrorLocation(const QQmlSourceLocation &sourceLocation) { m_error.setUrl(QUrl(sourceLocation.sourceFile)); - m_error.setLine(sourceLocation.line); - m_error.setColumn(sourceLocation.column); + m_error.setLine(qmlConvertSourceCoordinate<quint16, int>(sourceLocation.line)); + m_error.setColumn(qmlConvertSourceCoordinate<quint16, int>(sourceLocation.column)); } void QQmlDelayedError::setErrorDescription(const QString &description) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index aff982012d..76f387bbdc 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -56,6 +56,7 @@ #include <private/qqmldebugconnector_p.h> #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmlscriptdata_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <private/qjsvalue_p.h> #include <private/qv4generatorobject_p.h> @@ -1135,8 +1136,8 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location, { QQmlError error; error.setUrl(compilationUnit->url()); - error.setLine(location.line); - error.setColumn(location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column)); error.setDescription(description); errors << error; } diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 5e26eb1ea7..2d99ea9fd5 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -56,19 +56,20 @@ #include <private/qqmlpropertyresolver_p.h> #include <private/qqmltypedata_p.h> #include <private/inlinecomponentutils_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QScopedValueRollback> #include <vector> QT_BEGIN_NAMESPACE -inline QQmlJS::DiagnosticMessage qQmlCompileError(const QV4::CompiledData::Location &location, +inline QQmlError qQmlCompileError(const QV4::CompiledData::Location &location, const QString &description) { - QQmlJS::DiagnosticMessage error; - error.line = location.line; - error.column = location.column; - error.message = description; + QQmlError error; + error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column)); + error.setDescription(description); return error; } @@ -117,16 +118,16 @@ public: const ObjectContainer *objectContainer, const QQmlImports *imports, const QByteArray &typeClassName); - QQmlJS::DiagnosticMessage buildMetaObjects(); + QQmlError buildMetaObjects(); enum class VMEMetaObjectIsRequired { Maybe, Always }; protected: - QQmlJS::DiagnosticMessage buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired); - QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const; - QQmlJS::DiagnosticMessage createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache); + QQmlError buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired); + QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlError *error) const; + QQmlError createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache); int metaTypeForParameter(const QV4::CompiledData::ParameterType ¶m, QString *customTypeName = nullptr); @@ -159,7 +160,7 @@ inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlP } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects() +inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects() { using namespace icutils; QQmlBindingInstantiationContext context; @@ -186,8 +187,8 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil auto nodesSorted = topoSort(nodes, adjacencyList, hasCycle); if (hasCycle) { - QQmlJS::DiagnosticMessage diag; - diag.message = QLatin1String("Inline components form a cycle!"); + QQmlError diag; + diag.setDescription(QLatin1String("Inline components form a cycle!")); return diag; } @@ -201,7 +202,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil QByteArray icTypeName { objectContainer->stringAt(ic.nameIndex).toUtf8() }; QScopedValueRollback<QByteArray> nameChange {typeClassName, icTypeName}; QScopedValueRollback<unsigned int> rootChange {currentRoot, ic.objectIndex}; - QQmlJS::DiagnosticMessage diag = buildMetaObjectRecursively(ic.objectIndex, context, VMEMetaObjectIsRequired::Always); + QQmlError diag = buildMetaObjectRecursively(ic.objectIndex, context, VMEMetaObjectIsRequired::Always); if (diag.isValid()) { return diag; } @@ -213,7 +214,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired) +inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context, VMEMetaObjectIsRequired isVMERequired) { auto isAddressable = [](const QUrl &url) { const QString fileName = url.fileName(); @@ -242,7 +243,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex); Q_ASSERT(typeRef); QQmlRefPointer<QQmlPropertyCache> baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate)); - QQmlJS::DiagnosticMessage error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache); + QQmlError error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache); if (error.isValid()) return error; } @@ -257,7 +258,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil QQmlRefPointer<QQmlPropertyCache> baseTypeCache; { - QQmlJS::DiagnosticMessage error; + QQmlError error; baseTypeCache = propertyCacheForObject(obj, context, &error); if (error.isValid()) return error; @@ -265,7 +266,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil if (baseTypeCache) { if (needVMEMetaObject) { - QQmlJS::DiagnosticMessage error = createMetaObject(objectIndex, obj, baseTypeCache); + QQmlError error = createMetaObject(objectIndex, obj, baseTypeCache); if (error.isValid()) return error; } else { @@ -287,18 +288,18 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buil if (!context.resolveInstantiatingProperty()) pendingGroupPropertyBindings->append(context); - QQmlJS::DiagnosticMessage error = buildMetaObjectRecursively(binding->value.objectIndex, context, VMEMetaObjectIsRequired::Maybe); + QQmlError error = buildMetaObjectRecursively(binding->value.objectIndex, context, VMEMetaObjectIsRequired::Maybe); if (error.isValid()) return error; } } - QQmlJS::DiagnosticMessage noError; + QQmlError noError; return noError; } template <typename ObjectContainer> -inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const +inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlError *error) const { if (context.instantiatingProperty) { return context.instantiatingPropertyCache(enginePrivate); @@ -344,7 +345,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache) +inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache) { QQmlRefPointer<QQmlPropertyCache> cache; cache.adopt(baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(), @@ -622,7 +623,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::crea effectiveSignalIndex++; } - QQmlJS::DiagnosticMessage noError; + QQmlError noError; return noError; } @@ -670,11 +671,11 @@ public: void appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv); - QQmlJS::DiagnosticMessage appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv); + QQmlError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv); private: void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv); - QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); + QQmlError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; @@ -785,8 +786,10 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QTypeRevision *version, - QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv) +inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias( + const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, + QTypeRevision *version, QQmlPropertyData::Flags *propertyFlags, + QQmlEnginePrivate *enginePriv) { *type = 0; bool writable = false; @@ -896,16 +899,16 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: propertyFlags->setIsWritable(!(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable); propertyFlags->setIsResettable(resettable); - return QQmlJS::DiagnosticMessage(); + return QQmlError(); } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache( +inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache( const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv) { const CompiledObject &object = *objectContainer->objectAt(objectIndex); if (!object.aliasCount()) - return QQmlJS::DiagnosticMessage(); + return QQmlError(); QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex); Q_ASSERT(propertyCache); @@ -922,8 +925,8 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: int type = 0; QTypeRevision version = QTypeRevision::zero(); QQmlPropertyData::Flags propertyFlags; - QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &version, - &propertyFlags, enginePriv); + QQmlError error = propertyDataForAlias(component, *alias, &type, &version, + &propertyFlags, enginePriv); if (error.isValid()) return error; @@ -936,7 +939,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: type, version, effectiveSignalIndex++); } - return QQmlJS::DiagnosticMessage(); + return QQmlError(); } template <typename ObjectContainer> diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index 3fb2eb399f..312153576a 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -73,7 +73,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c bindingPropertyDataPerObject->resize(compilationUnit->objectCount()); } -QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validate() +QVector<QQmlError> QQmlPropertyValidator::validate() { return validateObject(/*root object*/0, /*instantiatingBinding*/nullptr); } @@ -96,7 +96,7 @@ struct BindingFinder } }; -QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( +QVector<QQmlError> QQmlPropertyValidator::validateObject( int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty) const { const QV4::CompiledData::Object *obj = compilationUnit->objectAt(objectIndex); @@ -113,7 +113,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex); if (!propertyCache) - return QVector<QQmlJS::DiagnosticMessage>(); + return QVector<QQmlError>(); QQmlCustomParser *customParser = nullptr; if (auto typeRef = resolvedType(obj->inheritedTypeNameIndex)) { @@ -226,7 +226,7 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( = pd && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType()) && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment); - const QVector<QQmlJS::DiagnosticMessage> subObjectValidatorErrors + const QVector<QQmlError> subObjectValidatorErrors = validateObject(binding->value.objectIndex, binding, populatingValueTypeGroupProperty); if (!subObjectValidatorErrors.isEmpty()) @@ -283,11 +283,11 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( } if (binding->type < QV4::CompiledData::Binding::Type_Script) { - QQmlJS::DiagnosticMessage bindingError = validateLiteralBinding(propertyCache, pd, binding); + QQmlError bindingError = validateLiteralBinding(propertyCache, pd, binding); if (bindingError.isValid()) return recordError(bindingError); } else if (binding->type == QV4::CompiledData::Binding::Type_Object) { - QQmlJS::DiagnosticMessage bindingError = validateObjectBinding(pd, name, binding); + QQmlError bindingError = validateObjectBinding(pd, name, binding); if (bindingError.isValid()) return recordError(bindingError); } else if (binding->isGroupProperty()) { @@ -349,24 +349,24 @@ QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject( customParser->validator = nullptr; customParser->engine = nullptr; customParser->imports = (QQmlImports*)nullptr; - QVector<QQmlJS::DiagnosticMessage> parserErrors = customParser->errors(); + QVector<QQmlError> parserErrors = customParser->errors(); if (!parserErrors.isEmpty()) return parserErrors; } (*bindingPropertyDataPerObject)[objectIndex] = collectedBindingPropertyData; - QVector<QQmlJS::DiagnosticMessage> noError; + QVector<QQmlError> noError; return noError; } -QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const +QQmlError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const { if (property->isQList()) { return qQmlCompileError(binding->valueLocation, tr("Cannot assign primitives to lists")); } - QQmlJS::DiagnosticMessage noError; + QQmlError noError; if (property->isEnum()) { if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum) @@ -390,8 +390,8 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlProp if (binding->type == QV4::CompiledData::Binding::Type_Null) { QQmlError warning; warning.setUrl(compilationUnit->url()); - warning.setLine(binding->valueLocation.line); - warning.setColumn(binding->valueLocation.column); + warning.setLine(qmlConvertSourceCoordinate<quint32, int>(binding->valueLocation.line)); + warning.setColumn(qmlConvertSourceCoordinate<quint32, int>(binding->valueLocation.column)); warning.setDescription(error + tr(" - Assigning null to incompatible properties in QML " "is deprecated. This will become a compile error in " "future versions of Qt.")); @@ -662,23 +662,23 @@ bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const return false; } -QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const +QVector<QQmlError> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const { - QVector<QQmlJS::DiagnosticMessage> errors; + QVector<QQmlError> errors; errors.append(qQmlCompileError(location, description)); return errors; } -QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QQmlJS::DiagnosticMessage &error) const +QVector<QQmlError> QQmlPropertyValidator::recordError(const QQmlError &error) const { - QVector<QQmlJS::DiagnosticMessage> errors; + QVector<QQmlError> errors; errors.append(error); return errors; } -QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const +QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const { - QQmlJS::DiagnosticMessage noError; + QQmlError noError; if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) { Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Object); diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h index 74a1281927..281472981c 100644 --- a/src/qml/qml/qqmlpropertyvalidator_p.h +++ b/src/qml/qml/qqmlpropertyvalidator_p.h @@ -66,25 +66,24 @@ class QQmlPropertyValidator public: QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports &imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit); - QVector<QQmlJS::DiagnosticMessage> validate(); + QVector<QQmlError> validate(); private: - QVector<QQmlJS::DiagnosticMessage> validateObject( + QVector<QQmlError> validateObject( int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty = false) const; - QQmlJS::DiagnosticMessage validateLiteralBinding( + QQmlError validateLiteralBinding( QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const; - QQmlJS::DiagnosticMessage validateObjectBinding( + QQmlError validateObjectBinding( QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const; bool canCoerce(int to, QQmlPropertyCache *fromMo) const; - Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError( + Q_REQUIRED_RESULT QVector<QQmlError> recordError( const QV4::CompiledData::Location &location, const QString &description) const; - Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError( - const QQmlJS::DiagnosticMessage &error) const; + Q_REQUIRED_RESULT QVector<QQmlError> recordError(const QQmlError &error) const; QString stringAt(int index) const { return compilationUnit->stringAt(index); } QV4::ResolvedTypeReference *resolvedType(int id) const { diff --git a/src/qml/qml/qqmlscriptblob.cpp b/src/qml/qml/qqmlscriptblob.cpp index eb103dc434..dac21f7ee7 100644 --- a/src/qml/qml/qqmlscriptblob.cpp +++ b/src/qml/qml/qqmlscriptblob.cpp @@ -41,6 +41,7 @@ #include <private/qqmlirbuilder_p.h> #include <private/qqmlscriptblob_p.h> #include <private/qqmlscriptdata_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <private/qv4runtimecodegen_p.h> #include <private/qv4script_p.h> @@ -167,8 +168,8 @@ void QQmlScriptBlob::done() QList<QQmlError> errors = script.script->errors(); QQmlError error; error.setUrl(url()); - error.setLine(script.location.line); - error.setColumn(script.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column)); error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString())); errors.prepend(error); setError(errors); diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index 3518b21a70..5c04abf367 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -82,7 +82,7 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile() { QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings, engine, this, imports(), typeData->typeClassName()); - QQmlJS::DiagnosticMessage error = propertyCacheBuilder.buildMetaObjects(); + QQmlError error = propertyCacheBuilder.buildMetaObjects(); if (error.isValid()) { recordError(error); return nullptr; @@ -174,8 +174,8 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile() void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location, const QString &description) { QQmlError error; - error.setLine(location.line); - error.setColumn(location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column)); error.setDescription(description); error.setUrl(url()); errors << error; @@ -185,8 +185,15 @@ void QQmlTypeCompiler::recordError(const QQmlJS::DiagnosticMessage &message) { QQmlError error; error.setDescription(message.message); - error.setLine(message.line); - error.setColumn(message.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(message.loc.startLine)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(message.loc.startColumn)); + error.setUrl(url()); + errors << error; +} + +void QQmlTypeCompiler::recordError(const QQmlError &e) +{ + QQmlError error = e; error.setUrl(url()); errors << error; } @@ -1016,7 +1023,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) for (int objectIndex: qAsConst(_objectsWithAliases)) { - QQmlJS::DiagnosticMessage error; + QQmlError error; const auto result = resolveAliasesInObject(objectIndex, &error); if (error.isValid()) { @@ -1025,7 +1032,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) } if (result == AllAliasesResolved) { - QQmlJS::DiagnosticMessage error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex, enginePrivate); + QQmlError error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex, enginePrivate); if (error.isValid()) { recordError(error); return false; @@ -1056,7 +1063,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, - QQmlJS::DiagnosticMessage *error) + QQmlError *error) { const QmlIR::Object * const obj = qmlObjects->at(objectIndex); if (!obj->aliasCount()) diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h index 050c75b30d..883fbf0d68 100644 --- a/src/qml/qml/qqmltypecompiler_p.h +++ b/src/qml/qml/qqmltypecompiler_p.h @@ -100,7 +100,8 @@ public: QList<QQmlError> compilationErrors() const { return errors; } void recordError(const QV4::CompiledData::Location &location, const QString &description); - void recordError(const QQmlJS::DiagnosticMessage &error); + void recordError(const QQmlJS::DiagnosticMessage &message); + void recordError(const QQmlError &e); int registerString(const QString &str); int registerConstant(QV4::ReturnedValue v); @@ -157,7 +158,7 @@ struct QQmlCompilePass protected: void recordError(const QV4::CompiledData::Location &location, const QString &description) const { compiler->recordError(location, description); } - void recordError(const QQmlJS::DiagnosticMessage &error) + void recordError(const QQmlError &error) { compiler->recordError(error); } QV4::ResolvedTypeReference *resolvedType(int id) const @@ -280,7 +281,7 @@ protected: AllAliasesResolved }; - AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlJS::DiagnosticMessage *error); + AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlError *error); QQmlEnginePrivate *enginePrivate; QQmlJS::MemoryPool *pool; diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 30d50b911e..9d44e85ba4 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -203,8 +203,8 @@ bool QQmlTypeData::tryLoadFromDiskCache() Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); error.setUrl(m_importCache.baseUrl()); - error.setLine(import->location.line); - error.setColumn(import->location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); errors.prepend(error); // put it back on the list after filling out information. setError(errors); return false; @@ -244,7 +244,7 @@ void QQmlTypeData::createTypeAndPropertyCaches( QQmlPropertyCacheCreator<QV4::ExecutableCompilationUnit> propertyCacheCreator( &m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine, m_compiledData.data(), &m_importCache, typeClassName()); - QQmlJS::DiagnosticMessage error = propertyCacheCreator.buildMetaObjects(); + QQmlError error = propertyCacheCreator.buildMetaObjects(); if (error.isValid()) { setError(error); return; @@ -325,8 +325,8 @@ void QQmlTypeData::done() QList<QQmlError> errors = script.script->errors(); QQmlError error; error.setUrl(url()); - error.setLine(script.location.line); - error.setColumn(script.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column)); error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString())); errors.prepend(error); setError(errors); @@ -349,8 +349,8 @@ void QQmlTypeData::done() QList<QQmlError> errors = type.typeData ? type.typeData->errors() : QList<QQmlError>{}; QQmlError error; error.setUrl(url()); - error.setLine(type.location.line); - error.setColumn(type.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column)); error.setDescription(QQmlTypeLoader::tr("Type %1 has no inline component type called %2").arg(typeName.leftRef(lastDot), type.type.pendingResolutionName())); errors.prepend(error); setError(errors); @@ -365,8 +365,8 @@ void QQmlTypeData::done() QList<QQmlError> errors = type.typeData->errors(); QQmlError error; error.setUrl(url()); - error.setLine(type.location.line); - error.setColumn(type.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column)); error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName)); errors.prepend(error); setError(errors); @@ -384,8 +384,8 @@ void QQmlTypeData::done() QList<QQmlError> errors = type.typeData->errors(); QQmlError error; error.setUrl(url()); - error.setLine(type.location.line); - error.setColumn(type.location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column)); error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName)); errors.prepend(error); setError(errors); @@ -414,7 +414,7 @@ void QQmlTypeData::done() QV4::ResolvedTypeReferenceMap resolvedTypeCache; QQmlRefPointer<QQmlTypeNameCache> typeNameCache; { - QQmlJS::DiagnosticMessage error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache); + QQmlError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache); if (error.isValid()) { setError(error); qDeleteAll(resolvedTypeCache); @@ -461,7 +461,7 @@ void QQmlTypeData::done() { // Sanity check property bindings QQmlPropertyValidator validator(enginePrivate, m_importCache, m_compiledData); - QVector<QQmlJS::DiagnosticMessage> errors = validator.validate(); + QVector<QQmlError> errors = validator.validate(); if (!errors.isEmpty()) { setError(errors); return; @@ -625,8 +625,8 @@ bool QQmlTypeData::loadFromSource() for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) { QQmlError e; e.setUrl(url()); - e.setLine(msg.line); - e.setColumn(msg.column); + e.setLine(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startLine)); + e.setColumn(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startColumn)); e.setDescription(msg.message); errors << e; } @@ -696,8 +696,8 @@ void QQmlTypeData::continueLoadFromIR() Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); error.setUrl(m_importCache.baseUrl()); - error.setLine(import->location.line); - error.setColumn(import->location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); errors.prepend(error); // put it back on the list after filling out information. setError(errors); return; @@ -723,8 +723,8 @@ void QQmlTypeData::allDependenciesDone() QQmlError error; error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri)); error.setUrl(m_importCache.baseUrl()); - error.setLine(import->location.line); - error.setColumn(import->location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); errors.prepend(error); } } @@ -888,7 +888,7 @@ void QQmlTypeData::resolveTypes() loadImplicitImport(); } -QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( +QQmlError QQmlTypeData::buildTypeResolutionCaches( QQmlRefPointer<QQmlTypeNameCache> *typeNameCache, QV4::ResolvedTypeReferenceMap *resolvedTypeCache ) const @@ -964,7 +964,7 @@ QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches( ref->doDynamicTypeCheck(); resolvedTypeCache->insert(resolvedType.key(), ref.take()); } - QQmlJS::DiagnosticMessage noError; + QQmlError noError; return noError; } diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h index 1506ee2010..c3b0faa5b4 100644 --- a/src/qml/qml/qqmltypedata_p.h +++ b/src/qml/qml/qqmltypedata_p.h @@ -124,7 +124,7 @@ private: void restoreIR(QV4::CompiledData::CompilationUnit &&unit); void continueLoadFromIR(); void resolveTypes(); - QQmlJS::DiagnosticMessage buildTypeResolutionCaches( + QQmlError buildTypeResolutionCaches( QQmlRefPointer<QQmlTypeNameCache> *typeNameCache, QV4::ResolvedTypeReferenceMap *resolvedTypeCache ) const; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index c5218bee33..75dc9d15a5 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -45,6 +45,7 @@ #include <private/qqmltypedata_p.h> #include <private/qqmltypeloaderqmldircontent_p.h> #include <private/qqmltypeloaderthread_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtQml/qqmlabstracturlinterceptor.h> #include <QtQml/qqmlengine.h> @@ -357,8 +358,8 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply) } } - if (reply->networkError()) { - blob->networkError(reply->networkError()); + if (reply->error()) { + blob->networkError(reply->error()); } else { QByteArray data = reply->readAll(); setData(blob, data); @@ -698,8 +699,8 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob) Q_ASSERT(errors.size()); QQmlError error(errors.takeFirst()); error.setUrl(m_importCache.baseUrl()); - error.setLine(import->location.line); - error.setColumn(import->location.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column)); errors.prepend(error); // put it back on the list after filling out information. setError(errors); } diff --git a/src/qml/qml/qqmltypeloaderqmldircontent.cpp b/src/qml/qml/qqmltypeloaderqmldircontent.cpp index 860971d296..714ea79e67 100644 --- a/src/qml/qml/qqmltypeloaderqmldircontent.cpp +++ b/src/qml/qml/qqmltypeloaderqmldircontent.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include <private/qqmltypeloaderqmldircontent_p.h> +#include <private/qqmlsourcecoordinate_p.h> #include <QtQml/qqmlerror.h> QT_BEGIN_NAMESPACE @@ -59,8 +60,8 @@ QList<QQmlError> QQmlTypeLoaderQmldirContent::errors(const QString &uri) const for (const auto &parseError : parseErrors) { QQmlError error; error.setUrl(url); - error.setLine(parseError.line); - error.setColumn(parseError.column); + error.setLine(qmlConvertSourceCoordinate<quint32, int>(parseError.loc.startLine)); + error.setColumn(qmlConvertSourceCoordinate<quint32, int>(parseError.loc.startColumn)); error.setDescription(parseError.message); errors.append(error); } @@ -83,8 +84,8 @@ void QQmlTypeLoaderQmldirContent::setContent(const QString &location, const QStr void QQmlTypeLoaderQmldirContent::setError(const QQmlError &error) { QQmlJS::DiagnosticMessage parseError; - parseError.line = error.line(); - parseError.column = error.column(); + parseError.loc.startLine = error.line(); + parseError.loc.startColumn = error.column(); parseError.message = error.description(); m_parser.setError(parseError); } diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h index 97956fa982..dbd37ace2a 100644 --- a/src/qml/qml/qqmltypenotavailable_p.h +++ b/src/qml/qml/qqmltypenotavailable_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QQmlTypeNotAvailable : public QObject { Q_OBJECT QML_NAMED_ELEMENT(TypeNotAvailable) - QML_ADDED_IN_VERSION(2, 0) + QML_ADDED_IN_VERSION(2, 15) QML_UNCREATABLE("Type not available.") }; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index edf9657f53..aa9f4bc1bd 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1238,7 +1238,7 @@ void QQmlVMEMetaObject::ensureQObjectWrapper() void QQmlVMEMetaObject::mark(QV4::MarkStack *markStack) { - if (engine != markStack->engine) + if (engine != markStack->engine()) return; propertyAndMethodStorage.markOnce(markStack); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index c23542dd44..61070113cc 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1281,7 +1281,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url) if (m_network->bytesAvailable() > 0) readyRead(); - QNetworkReply::NetworkError networkError = m_network->networkError(); + QNetworkReply::NetworkError networkError = m_network->error(); if (networkError != QNetworkReply::NoError) { error(networkError); } else { diff --git a/src/qml/qmldirparser/qqmldirparser.cpp b/src/qml/qmldirparser/qqmldirparser.cpp index 8d20490d5e..161d902854 100644 --- a/src/qml/qmldirparser/qqmldirparser.cpp +++ b/src/qml/qmldirparser/qqmldirparser.cpp @@ -302,8 +302,8 @@ bool QQmlDirParser::parse(const QString &source) void QQmlDirParser::reportError(quint16 line, quint16 column, const QString &description) { QQmlJS::DiagnosticMessage error; - error.line = line; - error.column = column; + error.loc.startLine = line; + error.loc.startColumn = column; error.message = description; _errors.append(error); } @@ -319,7 +319,7 @@ bool QQmlDirParser::hasError() const void QQmlDirParser::setError(const QQmlJS::DiagnosticMessage &e) { _errors.clear(); - reportError(e.line, e.column, e.message); + reportError(e.loc.startLine, e.loc.startColumn, e.message); } QList<QQmlJS::DiagnosticMessage> QQmlDirParser::errors(const QString &uri) const diff --git a/src/imports/models/dependencies.json b/src/qmlmodels/dependencies.json index 0d4f101c7a..0d4f101c7a 100644 --- a/src/imports/models/dependencies.json +++ b/src/qmlmodels/dependencies.json diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index c32caafaa6..3a05bf1689 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -1211,11 +1211,13 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ } Compositor::iterator it = m_compositor.find(group, index); + const auto flags = it->flags; + const auto modelIndex = it.modelIndex(); QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0; if (!cacheItem || !cacheItem->delegate) { - QQmlComponent *delegate = resolveDelegate(it.modelIndex()); + QQmlComponent *delegate = resolveDelegate(modelIndex); if (!delegate) return nullptr; @@ -1226,17 +1228,17 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ // all related properties, and return the object (which // has already been incubated, otherwise it wouldn't be in the pool). addCacheItem(cacheItem, it); - reuseItem(cacheItem, index, it->flags); + reuseItem(cacheItem, index, flags); cacheItem->referenceObject(); return cacheItem->object; } // Since we could't find an available item in the pool, we create a new one - cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex()); + cacheItem = m_adaptorModel.createItem(m_cacheMetaType, modelIndex); if (!cacheItem) return nullptr; - cacheItem->groups = it->flags; + cacheItem->groups = flags; addCacheItem(cacheItem, it); } diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h index 5b3423b480..761e9c73ec 100644 --- a/src/qmlmodels/qqmlobjectmodel_p.h +++ b/src/qmlmodels/qqmlobjectmodel_p.h @@ -105,8 +105,8 @@ Q_SIGNALS: void createdItem(int index, QObject *object); void initItem(int index, QObject *object); void destroyingItem(QObject *object); - void itemPooled(int index, QObject *object); - void itemReused(int index, QObject *object); + Q_REVISION(2, 15) void itemPooled(int index, QObject *object); + Q_REVISION(2, 15) void itemReused(int index, QObject *object); protected: QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr) diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index c1f9df3114..8c034356f3 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -150,7 +150,7 @@ QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index) } // Create a new item from scratch - modelItem = m_adaptorModel.createItem(m_metaType, index); + modelItem = m_adaptorModel.createItem(m_metaType.data(), index); if (modelItem) { modelItem->delegate = delegate; m_modelItems.insert(index, modelItem); @@ -243,6 +243,25 @@ void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem) delete modelItem; } +void QQmlTableInstanceModel::dispose(QObject *object) +{ + Q_ASSERT(object); + auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag)); + Q_ASSERT(modelItem); + + modelItem->releaseObject(); + + // The item is not referenced by anyone + Q_ASSERT(!modelItem->isObjectReferenced()); + Q_ASSERT(!modelItem->isReferenced()); + + m_modelItems.remove(modelItem->index); + + emit destroyingItem(object); + delete object; + delete modelItem; +} + void QQmlTableInstanceModel::cancel(int index) { auto modelItem = m_modelItems.value(index); diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 80ba7ddaaf..57b9b26e43 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -110,6 +110,7 @@ public: QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override; ReleaseFlags release(QObject *object, ReusableFlag reusable = NotReusable) override; + void dispose(QObject *object); void cancel(int) override; void drainReusableItemsPool(int maxPoolTime) override; diff --git a/src/qmltyperegistrar/qmltyperegistrar.cpp b/src/qmltyperegistrar/qmltyperegistrar.cpp index 697f96959f..ec75289cd6 100644 --- a/src/qmltyperegistrar/qmltyperegistrar.cpp +++ b/src/qmltyperegistrar/qmltyperegistrar.cpp @@ -47,14 +47,32 @@ struct ScopedPointerFileCloser static inline void cleanup(FILE *handle) { if (handle) fclose(handle); } }; -static bool acceptClassForQmlTypeRegistration(const QJsonObject &classDef) +enum RegistrationMode { + NoRegistration, + ObjectRegistration, + GadgetRegistration, + NamespaceRegistration +}; + +static RegistrationMode qmlTypeRegistrationMode(const QJsonObject &classDef) { const QJsonArray classInfos = classDef[QLatin1String("classInfos")].toArray(); for (const QJsonValue &info: classInfos) { - if (info[QLatin1String("name")].toString() == QLatin1String("QML.Element")) - return true; + const QString name = info[QLatin1String("name")].toString(); + if (name == QLatin1String("QML.Element")) { + if (classDef[QLatin1String("object")].toBool()) + return ObjectRegistration; + if (classDef[QLatin1String("gadget")].toBool()) + return GadgetRegistration; + if (classDef[QLatin1String("namespace")].toBool()) + return NamespaceRegistration; + qWarning() << "Not registering classInfo which is neither an object, " + "nor a gadget, nor a namespace:" + << name; + break; + } } - return false; + return NoRegistration; } static QVector<QJsonObject> foreignRelatedTypes(const QVector<QJsonObject> &types, @@ -284,7 +302,10 @@ int main(int argc, char **argv) const QJsonArray classes = metaObject[QLatin1String("classes")].toArray(); for (const auto &cls : classes) { QJsonObject classDef = cls.toObject(); - if (acceptClassForQmlTypeRegistration(classDef)) { + switch (qmlTypeRegistrationMode(classDef)) { + case NamespaceRegistration: + case GadgetRegistration: + case ObjectRegistration: { const QString include = metaObject[QLatin1String("inputFile")].toString(); const bool declaredInHeader = include.endsWith(QLatin1String(".h")); if (declaredInHeader) { @@ -296,9 +317,13 @@ int main(int argc, char **argv) qPrintable(classDef.value(QLatin1String("qualifiedClassName")) .toString())); } + types.append(classDef); - } else { + break; + } + case NoRegistration: foreignTypes.append(classDef); + break; } } }; @@ -360,8 +385,14 @@ int main(int argc, char **argv) continue; const QString className = classDef[QLatin1String("qualifiedClassName")].toString(); - fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", qPrintable(className), - qPrintable(module), qPrintable(majorVersion)); + + if (classDef.value(QLatin1String("namespace")).toBool()) { + fprintf(output, "\n qmlRegisterNamespaceAndRevisions(&%s::staticMetaObject, \"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } else { + fprintf(output, "\n qmlRegisterTypesAndRevisions<%s>(\"%s\", %s);", + qPrintable(className), qPrintable(module), qPrintable(majorVersion)); + } } fprintf(output, "\n qmlRegisterModule(\"%s\", %s, %s);", diff --git a/src/qmltyperegistrar/qmltypesclassdescription.cpp b/src/qmltyperegistrar/qmltypesclassdescription.cpp index f1ec700c50..e21abd97bc 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.cpp +++ b/src/qmltyperegistrar/qmltypesclassdescription.cpp @@ -61,7 +61,7 @@ const QJsonObject *QmlTypesClassDescription::findType(const QVector<QJsonObject> void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, const QVector<QJsonObject> &foreign, - bool topLevel, QTypeRevision defaultRevision) + CollectMode mode, QTypeRevision defaultRevision) { const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); for (const QJsonValue &classInfo : classInfos) { @@ -70,11 +70,11 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QString value = obj[QLatin1String("value")].toString(); if (name == QLatin1String("DefaultProperty")) { - if (defaultProp.isEmpty()) + if (mode != AttachedType && defaultProp.isEmpty()) defaultProp = value; } else if (name == QLatin1String("QML.AddedInVersion")) { const QTypeRevision revision = QTypeRevision::fromEncodedVersion(value.toInt()); - if (topLevel) { + if (mode == TopLevel) { addedInRevision = revision; revisions.append(revision); } else if (!elementName.isEmpty()) { @@ -82,7 +82,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } } - if (!topLevel) + if (mode != TopLevel) continue; // These only apply to the original class @@ -96,27 +96,23 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } else if (name == QLatin1String("QML.Creatable")) { isCreatable = (value != QLatin1String("false")); } else if (name == QLatin1String("QML.Attached")) { - attachedType = value; - if (const QJsonObject *other = findType(types, attachedType)) - collect(other, types, foreign, false, defaultRevision); - else if (const QJsonObject *other = findType(foreign, attachedType)) - collect(other, types, foreign, false, defaultRevision); + collectAttached(value, types, foreign, defaultRevision); } else if (name == QLatin1String("QML.Singleton")) { if (value == QLatin1String("true")) isSingleton = true; } else if (name == QLatin1String("QML.Foreign")) { if (const QJsonObject *other = findType(foreign, value)) { classDef = other; - if (defaultProp.isEmpty()) { - // Foreign type can have a default property - const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); - for (const QJsonValue &classInfo : classInfos) { - QJsonObject obj = classInfo.toObject(); - if (obj[QLatin1String("name")].toString() == QLatin1String("DefaultProperty")) { - defaultProp = obj[QLatin1String("value")].toString(); - break; - } - } + // Foreign type can have a default property or an attached types + const auto classInfos = classDef->value(QLatin1String("classInfos")).toArray(); + for (const QJsonValue &classInfo : classInfos) { + const QJsonObject obj = classInfo.toObject(); + const QString foreignName = obj[QLatin1String("name")].toString(); + const QString foreignValue = obj[QLatin1String("value")].toString(); + if (defaultProp.isEmpty() && foreignName == QLatin1String("DefaultProperty")) + defaultProp = foreignValue; + else if (foreignName == QLatin1String("QML.Attached")) + collectAttached(foreignValue, types, foreign, defaultRevision); } } } else if (name == QLatin1String("QML.Root")) { @@ -127,7 +123,7 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, } } - if (!elementName.isEmpty()) { + if (mode == AttachedType || !elementName.isEmpty()) { collectExtraVersions(classDef, QString::fromLatin1("properties"), revisions); collectExtraVersions(classDef, QString::fromLatin1("slots"), revisions); collectExtraVersions(classDef, QString::fromLatin1("methods"), revisions); @@ -139,13 +135,14 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, const QJsonObject superObject = supers.first().toObject(); if (superObject[QLatin1String("access")].toString() == QLatin1String("public")) { const QString superName = superObject[QLatin1String("name")].toString(); - if (topLevel && superClass.isEmpty()) + if (mode == TopLevel && superClass.isEmpty()) superClass = superName; + const CollectMode superMode = (mode == TopLevel) ? SuperClass : AttachedType; if (const QJsonObject *other = findType(types, superName)) - collect(other, types, foreign, false, defaultRevision); + collect(other, types, foreign, superMode, defaultRevision); else if (const QJsonObject *other = findType(foreign, superName)) - collect(other, types, foreign, false, defaultRevision); + collect(other, types, foreign, superMode, defaultRevision); } } @@ -161,4 +158,19 @@ void QmlTypesClassDescription::collect(const QJsonObject *classDef, revisions.erase(end, revisions.end()); resolvedClass = classDef; + + // If it's not a QObject, it's not creatable + isCreatable = isCreatable && classDef->value(QLatin1String("object")).toBool(); +} + +void QmlTypesClassDescription::collectAttached(const QString &attached, + const QVector<QJsonObject> &types, + const QVector<QJsonObject> &foreign, + QTypeRevision defaultRevision) +{ + attachedType = attached; + if (const QJsonObject *other = findType(types, attachedType)) + collect(other, types, foreign, AttachedType, defaultRevision); + else if (const QJsonObject *other = findType(foreign, attachedType)) + collect(other, types, foreign, AttachedType, defaultRevision); } diff --git a/src/qmltyperegistrar/qmltypesclassdescription.h b/src/qmltyperegistrar/qmltypesclassdescription.h index 6f391ba45c..e4ae37a84e 100644 --- a/src/qmltyperegistrar/qmltypesclassdescription.h +++ b/src/qmltyperegistrar/qmltypesclassdescription.h @@ -50,8 +50,17 @@ struct QmlTypesClassDescription bool isRootClass = false; bool isBuiltin = false; + enum CollectMode { + TopLevel, + SuperClass, + AttachedType + }; + void collect(const QJsonObject *classDef, const QVector<QJsonObject> &types, - const QVector<QJsonObject> &foreign, bool topLevel, QTypeRevision defaultRevision); + const QVector<QJsonObject> &foreign, CollectMode mode, + QTypeRevision defaultRevision); + void collectAttached(const QString &attached, const QVector<QJsonObject> &types, + const QVector<QJsonObject> &foreign, QTypeRevision defaultRevision); static const QJsonObject *findType(const QVector<QJsonObject> &types, const QString &name); }; diff --git a/src/qmltyperegistrar/qmltypescreator.cpp b/src/qmltyperegistrar/qmltypescreator.cpp index d34740eaa0..3569bbe253 100644 --- a/src/qmltyperegistrar/qmltypescreator.cpp +++ b/src/qmltyperegistrar/qmltypescreator.cpp @@ -246,7 +246,8 @@ void QmlTypesCreator::writeComponents() m_qml.writeStartObject(componentElement); QmlTypesClassDescription collector; - collector.collect(&component, m_ownTypes, m_foreignTypes, true, m_version); + collector.collect(&component, m_ownTypes, m_foreignTypes, + QmlTypesClassDescription::TopLevel, m_version); writeClassProperties(collector); diff --git a/src/imports/workerscript/dependencies.json b/src/qmlworkerscript/dependencies.json index 0d4f101c7a..0d4f101c7a 100644 --- a/src/imports/workerscript/dependencies.json +++ b/src/qmlworkerscript/dependencies.json diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index 4a79027234..0bdbbabadc 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -130,7 +130,9 @@ struct WorkerScript : public QV4::ExecutionEngine { QQuickWorkerScriptEnginePrivate *p = nullptr; QUrl source; QQuickWorkerScript *owner = nullptr; +#if QT_CONFIG(qml_network) QScopedPointer<QNetworkAccessManager> scriptLocalNAM; +#endif int id = -1; }; @@ -390,6 +392,7 @@ WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) QV4::ScopedValue sendMessage(scope, QV4::FunctionObject::createBuiltinFunction(this, name, QQuickWorkerScriptEnginePrivate::method_sendMessage, 1)); api->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("sendMessage"))), sendMessage); globalObject->put(QV4::ScopedString(scope, scope.engine->newString(QStringLiteral("WorkerScript"))), api); +#if QT_CONFIG(qml_network) networkAccessManager = [](QV4::ExecutionEngine *engine){ auto *workerScript = static_cast<WorkerScript *>(engine); if (workerScript->scriptLocalNAM) @@ -400,6 +403,7 @@ WorkerScript::WorkerScript(int id, QQuickWorkerScriptEnginePrivate *parent) workerScript->scriptLocalNAM.reset(new QNetworkAccessManager(workerScript->p)); return workerScript->scriptLocalNAM.get(); }; +#endif // qml_network } int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) diff --git a/src/qmlworkerscript/qquickworkerscript_p.h b/src/qmlworkerscript/qquickworkerscript_p.h index 50eb8353b4..d1ea34422a 100644 --- a/src/qmlworkerscript/qquickworkerscript_p.h +++ b/src/qmlworkerscript/qquickworkerscript_p.h @@ -88,7 +88,7 @@ class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserSt { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(bool ready READ ready NOTIFY readyChanged) + Q_PROPERTY(bool ready READ ready NOTIFY readyChanged REVISION(2, 15)) QML_NAMED_ELEMENT(WorkerScript); QML_ADDED_IN_VERSION(2, 0) @@ -108,7 +108,7 @@ public Q_SLOTS: Q_SIGNALS: void sourceChanged(); - void readyChanged(); + Q_REVISION(2, 15) void readyChanged(); void message(const QJSValue &messageObject); protected: diff --git a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp index ea9f76f131..a8a37f80af 100644 --- a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp +++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.cpp @@ -48,56 +48,19 @@ ** ****************************************************************************/ -//![0] +#include "cpp-tablemodel.h" #include <QGuiApplication> -#include <QQmlApplicationEngine> -#include <QAbstractTableModel> - -class TableModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - - int rowCount(const QModelIndex & = QModelIndex()) const override - { - return 200; - } - - int columnCount(const QModelIndex & = QModelIndex()) const override - { - return 200; - } - - QVariant data(const QModelIndex &index, int role) const override - { - switch (role) { - case Qt::DisplayRole: - return QString("%1, %2").arg(index.column()).arg(index.row()); - default: - break; - } - - return QVariant(); - } - - QHash<int, QByteArray> roleNames() const override - { - return { {Qt::DisplayRole, "display"} }; - } -}; +#include <QQuickView> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); - qmlRegisterType<TableModel>("TableModel", 0, 1, "TableModel"); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + QQuickView view; + view.setSource(QStringLiteral("qrc:/cpp-tablemodel.qml")); + view.show(); return app.exec(); } -#include "main.moc" //![0] diff --git a/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h new file mode 100644 index 0000000000..4a3c46b573 --- /dev/null +++ b/src/quick/doc/snippets/qml/tableview/cpp-tablemodel.h @@ -0,0 +1,94 @@ +/**************************************************************************** + ** + ** Copyright (C) 2020 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the documentation of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and The Qt Company. For licensing terms + ** and conditions see https://www.qt.io/terms-conditions. For further + ** information use the contact form at https://www.qt.io/contact-us. + ** + ** BSD License Usage + ** Alternatively, you may use this file under the terms of the BSD license + ** as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of The Qt Company Ltd nor the names of its + ** contributors may be used to endorse or promote products derived + ** from this software without specific prior written permission. + ** + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef CPPTABLEMODEL_H +#define CPPTABLEMODEL_H + +//![0] +#include <qqml.h> +#include <QAbstractTableModel> + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + QML_ELEMENT + QML_ADDED_IN_MINOR_VERSION(1) + +public: + int rowCount(const QModelIndex & = QModelIndex()) const override + { + return 200; + } + + int columnCount(const QModelIndex & = QModelIndex()) const override + { + return 200; + } + + QVariant data(const QModelIndex &index, int role) const override + { + switch (role) { + case Qt::DisplayRole: + return QString("%1, %2").arg(index.column()).arg(index.row()); + default: + break; + } + + return QVariant(); + } + + QHash<int, QByteArray> roleNames() const override + { + return { {Qt::DisplayRole, "display"} }; + } +}; +//![0] + +#endif // CPPTABLEMODEL_H diff --git a/src/quick/doc/snippets/qml/tableview/tableview.pro b/src/quick/doc/snippets/qml/tableview/tableview.pro new file mode 100644 index 0000000000..0821f1b5d3 --- /dev/null +++ b/src/quick/doc/snippets/qml/tableview/tableview.pro @@ -0,0 +1,20 @@ +TEMPLATE = app + +QT += qml quick + +CONFIG += qmltypes +QML_IMPORT_NAME = TableModel +QML_IMPORT_MAJOR_VERSION = 0 + +SOURCES += \ + cpp-tablemodel.cpp + +HEADERS += \ + cpp-tablemodel.h + +RESOURCES += \ + cpp-tablemodel.qml \ + qml-tablemodel.qml \ + reusabledelegate.qml \ + tableviewwithheader.qml \ + tableviewwithprovider.qml diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index afdf8f5ea4..77147add16 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -125,6 +125,7 @@ public: bool paused() const; int currentFrame() const; FinishBehavior finishBehavior() const; + void setFinishBehavior(FinishBehavior arg); Q_SIGNALS: @@ -173,7 +174,6 @@ public Q_SLOTS: void resetFrameDuration(); void setLoops(int arg); void setCurrentFrame(int arg); - void setFinishBehavior(FinishBehavior arg); private Q_SLOTS: void createEngine(); diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 32407a474f..3679df37d1 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -478,7 +478,7 @@ void QQuickBorderImage::sciRequestFinished() } d->redirectCount=0; - if (d->sciReply->networkError() != QNetworkReply::NoError) { + if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; d->sciReply->deleteLater(); d->sciReply = nullptr; diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index a598c13113..804c3a081e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -680,7 +680,7 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a // QTabletDevice populated with capabilities provided by QPA plugins - switch (event->device()) { + switch (event->deviceType()) { case QTabletEvent::Stylus: type = QQuickPointerDevice::Stylus; buttonCount = 3; diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index fe8df6fb64..4d9e3de859 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2569,6 +2569,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo bool skip = false; QQuickItem *startItem = item; + QQuickItem *originalStartItem = startItem; // Protect from endless loop: // If we start on an invisible item we will not find it again. // If there is no other item which can become the focus item, we have a forever loop, @@ -2644,7 +2645,12 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo } } from = last; - if (current == startItem && from == firstFromItem) { + // if [from] item is equal to [firstFromItem], means we have traversed one path and + // jump back to parent of the chain, and then we have to check whether we have + // traversed all of the chain (by compare the [current] item with [startItem]) + // Since the [startItem] might be promoted to its parent if it is invisible, + // we still have to check [current] item with original start item + if ((current == startItem || current == originalStartItem) && from == firstFromItem) { // wrapped around, avoid endless loops if (item == contentItem) { qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem"; @@ -8254,6 +8260,10 @@ bool QQuickItem::event(QEvent *ev) ev->ignore(); break; #endif // gestures + case QEvent::LanguageChange: + for (QQuickItem *item : d->childItems) + QCoreApplication::sendEvent(item, ev); + break; default: return QObject::event(ev); } diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index f298803c7f..00e84536e9 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -195,6 +195,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName) const } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#if QT_DEPRECATED_SINCE(5, 15) /*! * \overload * \internal @@ -203,6 +204,7 @@ bool QQuickItemGrabResult::saveToFile(const QString &fileName) { return qAsConst(*this).saveToFile(fileName); } +#endif #endif // < Qt 6 QUrl QQuickItemGrabResult::url() const diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h index 48e217f61d..96d18b907b 100644 --- a/src/quick/items/qquickitemgrabresult.h +++ b/src/quick/items/qquickitemgrabresult.h @@ -69,7 +69,10 @@ public: QUrl url() const; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - Q_INVOKABLE bool saveToFile(const QString &fileName); // ### Qt 6: remove +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_X("This overload is deprecated. Use the const member function instead") + Q_INVOKABLE bool saveToFile(const QString &fileName); +#endif #endif Q_INVOKABLE bool saveToFile(const QString &fileName) const; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 3e3a2c262b..7fb392233e 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -2419,7 +2419,7 @@ void QQuickItemView::destroyingItem(QObject *object) Q_D(QQuickItemView); QQuickItem* item = qmlobject_cast<QQuickItem*>(object); if (item) { - QQuickItemPrivate::get(item)->setCulled(true); + item->setParentItem(nullptr); d->unrequestedItems.remove(item); } } diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index 8d928aa3af..d8d5678ad0 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -303,8 +303,8 @@ protected Q_SLOTS: virtual void initItem(int index, QObject *item); void modelUpdated(const QQmlChangeSet &changeSet, bool reset); void destroyingItem(QObject *item); - void onItemPooled(int modelIndex, QObject *object); - void onItemReused(int modelIndex, QObject *object); + Q_REVISION(2, 15) void onItemPooled(int modelIndex, QObject *object); + Q_REVISION(2, 15) void onItemReused(int modelIndex, QObject *object); void animStopped(); void trackedPositionChanged(); diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 56c5bedd4d..9b1704421c 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -82,7 +82,7 @@ The following example shows how to create a model from C++ with multiple columns: - \snippet qml/tableview/cpp-tablemodel.cpp 0 + \snippet qml/tableview/cpp-tablemodel.h 0 And then how to use it from QML: @@ -441,7 +441,16 @@ QQuickTableViewPrivate::QQuickTableViewPrivate() QQuickTableViewPrivate::~QQuickTableViewPrivate() { - releaseLoadedItems(QQmlTableInstanceModel::NotReusable); + for (auto *fxTableItem : loadedItems) { + if (auto item = fxTableItem->item) { + if (fxTableItem->ownItem) + delete item; + else if (tableModel) + tableModel->dispose(item); + } + delete fxTableItem; + } + if (tableModel) delete tableModel; } diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 816b48b190..c8f3f113dd 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2649,6 +2649,12 @@ void QQuickText::setLineHeightMode(LineHeightMode mode) If the text does not fit within the item bounds with the minimum font size the text will be elided as per the \l elide property. + + If the \l textFormat property is set to \l Text.RichText, this will have no effect at all as the + property will be ignored completely. If \l textFormat is set to \l Text.StyledText, then the + property will be respected provided there is no font size tags inside the text. If there are + font size tags, the property will still respect those. This can cause it to not fully comply with + the fontSizeMode setting. */ QQuickText::FontSizeMode QQuickText::fontSizeMode() const @@ -2968,6 +2974,8 @@ void QQuickText::setRenderType(QQuickText::RenderType renderType) d->updateLayout(); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#if QT_DEPRECATED_SINCE(5, 15) /*! \qmlmethod QtQuick::Text::doLayout() \deprecated @@ -2979,6 +2987,8 @@ void QQuickText::doLayout() forceLayout(); } +#endif +#endif /*! \qmlmethod QtQuick::Text::forceLayout() \since 5.9 diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index cb6d0e260d..6c04f63ca9 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -224,7 +224,12 @@ public: QRectF boundingRect() const override; QRectF clipRect() const override; - Q_INVOKABLE void doLayout(); // ### Qt 6: remove +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_X("Use forceLayout() instead") + Q_INVOKABLE void doLayout(); +#endif +#endif Q_REVISION(2, 9) Q_INVOKABLE void forceLayout(); RenderType renderType() const; @@ -331,8 +336,8 @@ class QQuickTextLine : public QObject Q_PROPERTY(qreal height READ height WRITE setHeight) Q_PROPERTY(qreal x READ x WRITE setX) Q_PROPERTY(qreal y READ y WRITE setY) - Q_PROPERTY(qreal implicitWidth READ implicitWidth) - Q_PROPERTY(bool isLast READ isLast) + Q_PROPERTY(qreal implicitWidth READ implicitWidth REVISION(2, 15)) + Q_PROPERTY(bool isLast READ isLast REVISION(2, 15)) QML_ANONYMOUS QML_ADDED_IN_VERSION(2, 0) diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 4b4ecd6acc..39f238e4ed 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1770,6 +1770,10 @@ bool QQuickWindow::event(QEvent *e) if (d->activeFocusItem) QCoreApplication::sendEvent(d->activeFocusItem, e); return true; + case QEvent::LanguageChange: + if (d->contentItem) + QCoreApplication::sendEvent(d->contentItem, e); + break; default: break; } @@ -4437,7 +4441,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const OpenGL context is actually created. QQuickWindow::openglContext() will still return 0 for this window - until after the QQuickWindow::sceneGraphInitialize() has been + until after the QQuickWindow::sceneGraphInitialized() has been emitted. \note diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index efc5e0007e..8e4ecbc178 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -85,7 +85,7 @@ class QRhiRenderBuffer; class QRhiRenderPassDescriptor; //Make it easy to identify and customize the root item if needed -class QQuickRootItem : public QQuickItem +class Q_QUICK_PRIVATE_EXPORT QQuickRootItem : public QQuickItem { Q_OBJECT public: diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp index ac21ec2ed9..45d7a65555 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp @@ -136,12 +136,12 @@ Texture::Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, { float w = atlas->size().width(); float h = atlas->size().height(); - QRect nopad = atlasSubRect(); + const QRect &r = atlasSubRect(); // offset by half-pixel to prevent bleeding when scaling - m_texture_coords_rect = QRectF((nopad.x() + .5) / w, - (nopad.y() + .5) / h, - (nopad.width() - 1.) / w, - (nopad.height() - 1.) / h); + m_texture_coords_rect = QRectF((r.x() + .5) / w, + (r.y() + .5) / h, + (size.width() - 1.) / w, + (size.height() - 1.) / h); } Texture::~Texture() diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp index 9194d3e730..cf30cb3f9a 100644 --- a/src/quick/scenegraph/qsgrhisupport.cpp +++ b/src/quick/scenegraph/qsgrhisupport.cpp @@ -157,6 +157,8 @@ void QSGRhiSupport::applySettings() } else if (rhiBackend == QByteArrayLiteral("null")) { m_rhiBackend = QRhi::Null; } else { + if (!rhiBackend.isEmpty()) + qWarning("Unknown key \"%s\" for QSG_RHI_BACKEND, falling back to default backend.", qPrintable(rhiBackend)); #if defined(Q_OS_WIN) m_rhiBackend = QRhi::D3D11; #elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index addf8b0c18..63aba04c34 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -121,7 +121,7 @@ void QQuickFontObject::replyFinished() } redirectCount = 0; - if (!reply->networkError()) { + if (!reply->error()) { id = QFontDatabase::addApplicationFontFromData(reply->readAll()); if (id != -1) emit fontDownloaded(QFontDatabase::applicationFontFamilies(id).at(0), QQuickFontLoader::Ready); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 8846edcd44..d96ebe70b2 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -578,7 +578,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply) QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError; QString errorString; QSize readSize; - if (reply->networkError()) { + if (reply->error()) { error = QQuickPixmapReply::Loading; errorString = reply->errorString(); } else { |