diff options
Diffstat (limited to 'tools')
32 files changed, 681 insertions, 266 deletions
diff --git a/tools/qml/conf.h b/tools/qml/conf.h index 4ad45428ed..84167c9134 100644 --- a/tools/qml/conf.h +++ b/tools/qml/conf.h @@ -40,6 +40,7 @@ class PartialScene : public QObject Q_PROPERTY(QUrl container READ container WRITE setContainer NOTIFY containerChanged) Q_PROPERTY(QString itemType READ itemType WRITE setItemType NOTIFY itemTypeChanged) QML_ELEMENT + QML_ADDED_IN_VERSION(1, 0) public: PartialScene(QObject *parent = 0) : QObject(parent) {} @@ -75,6 +76,7 @@ class Config : public QObject Q_PROPERTY(QQmlListProperty<PartialScene> sceneCompleters READ sceneCompleters) Q_CLASSINFO("DefaultProperty", "sceneCompleters") QML_NAMED_ELEMENT(Configuration) + QML_ADDED_IN_VERSION(1, 0) public: Config (QObject* parent=0) : QObject(parent) {} diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 618dab6690..e8c471e22e 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -37,6 +37,7 @@ #include <QFileOpenEvent> #include <QOpenGLContext> #include <QOpenGLFunctions> +#include <QSurfaceFormat> #ifdef QT_WIDGETS_LIB #include <QApplication> #endif // QT_WIDGETS_LIB @@ -59,6 +60,7 @@ #include <QLibraryInfo> #include <qqml.h> #include <qqmldebug.h> +#include <qqmlfileselector.h> #include <private/qmemory_p.h> #include <private/qtqmlglobal_p.h> @@ -434,7 +436,6 @@ int main(int argc, char *argv[]) app->setOrganizationDomain("qt-project.org"); QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); - qmlRegisterTypesAndRevisions<Config, PartialScene>("QmlRuntime.Config", 1); QQmlApplicationEngine e; QStringList files; QString confFile; @@ -511,6 +512,9 @@ int main(int argc, char *argv[]) "Backend is one of: default, vulkan, metal, d3d11, gl"), QStringLiteral("backend")); parser.addOption(rhiOption); + QCommandLineOption selectorOption(QStringLiteral("S"), QCoreApplication::translate("main", + "Add selector to the list of QQmlFileSelectors."), QStringLiteral("selector")); + parser.addOption(selectorOption); // Positional arguments parser.addPositionalArgument("files", @@ -550,6 +554,26 @@ int main(int argc, char *argv[]) #endif for (const QString &importPath : parser.values(importOption)) e.addImportPath(importPath); + + QStringList customSelectors; + for (const QString &selector : parser.values(selectorOption)) + customSelectors.append(selector); + if (!customSelectors.isEmpty()) { + QQmlFileSelector *selector = QQmlFileSelector::get(&e); + selector->setExtraSelectors(customSelectors); + } + +#if defined(QT_GUI_LIB) && QT_CONFIG(opengl) + if (qEnvironmentVariableIsSet("QSG_CORE_PROFILE") || qEnvironmentVariableIsSet("QML_CORE_PROFILE")) { + QSurfaceFormat surfaceFormat; + surfaceFormat.setStencilBufferSize(8); + surfaceFormat.setDepthBufferSize(24); + surfaceFormat.setVersion(4, 1); + surfaceFormat.setProfile(QSurfaceFormat::CoreProfile); + QSurfaceFormat::setDefaultFormat(surfaceFormat); + } +#endif + files << parser.values(qmlFileOption); if (parser.isSet(configOption)) confFile = parser.value(configOption); diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 5dcbb3567a..83e2e1bf80 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -5,6 +5,10 @@ qtHaveModule(widgets): QT += widgets HEADERS += conf.h SOURCES += main.cpp RESOURCES += qml.qrc +CONFIG += qmltypes + +QML_IMPORT_NAME = QmlRuntime.Config +QML_IMPORT_VERSION = 1.0 QMAKE_TARGET_DESCRIPTION = QML Runtime diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 71286137eb..a8ec527299 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -155,7 +155,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN } stream << " QQmlPrivate::RegisterQmlUnitCacheHook registration;\n"; - stream << " registration.version = 0;\n"; + stream << " registration.structVersion = 0;\n"; stream << " registration.lookupCachedQmlUnit = &lookupCachedUnit;\n"; stream << " QQmlPrivate::qmlregister(QQmlPrivate::QmlUnitCacheHookRegistration, ®istration);\n"; diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index d1b28c41f5..174cd547f6 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -84,9 +84,9 @@ Error Error::augment(const QString &contextErrorMessage) const QString diagnosticErrorMessage(const QString &fileName, const QQmlJS::DiagnosticMessage &m) { QString message; - message = fileName + QLatin1Char(':') + QString::number(m.line) + QLatin1Char(':'); - if (m.column > 0) - message += QString::number(m.column) + QLatin1Char(':'); + message = fileName + QLatin1Char(':') + QString::number(m.loc.startLine) + QLatin1Char(':'); + if (m.loc.startColumn > 0) + message += QString::number(m.loc.startColumn) + QLatin1Char(':'); if (m.isError()) message += QLatin1String(" error: "); diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf index 8aac3b9e07..7353dfb17a 100644 --- a/tools/qmlcachegen/qtquickcompiler.prf +++ b/tools/qmlcachegen/qtquickcompiler.prf @@ -29,6 +29,7 @@ defineReplace(qmlCacheResourceFileOutputName) { # Flatten RESOURCES that may contain individual files or objects load(resources_functions) qtFlattenResources() +qtEnsurePluginResourcesCpp() NEWRESOURCES = QMLCACHE_RESOURCE_FILES = diff --git a/tools/qmleasing/splineeditor.cpp b/tools/qmleasing/splineeditor.cpp index 69850dc7a1..3657fe3f27 100644 --- a/tools/qmleasing/splineeditor.cpp +++ b/tools/qmleasing/splineeditor.cpp @@ -674,7 +674,7 @@ void SplineEditor::setEasingCurve(const QString &code) return; if (code.startsWith(QLatin1Char('[')) && code.endsWith(QLatin1Char(']'))) { const QStringRef cleanCode(&code, 1, code.size() - 2); - const auto stringList = cleanCode.split(QLatin1Char(','), QString::SkipEmptyParts); + const auto stringList = cleanCode.split(QLatin1Char(','), Qt::SkipEmptyParts); if (stringList.count() >= 6 && (stringList.count() % 6 == 0)) { QVector<qreal> realList; realList.reserve(stringList.count()); diff --git a/tools/qmlformat/commentastvisitor.cpp b/tools/qmlformat/commentastvisitor.cpp index 8264a6099e..4dd241ff93 100644 --- a/tools/qmlformat/commentastvisitor.cpp +++ b/tools/qmlformat/commentastvisitor.cpp @@ -268,3 +268,9 @@ bool CommentAstVisitor::visit(UiImport *node) attachComment(node); return true; } + +bool CommentAstVisitor::visit(UiPragma *node) +{ + attachComment(node); + return true; +} diff --git a/tools/qmlformat/commentastvisitor.h b/tools/qmlformat/commentastvisitor.h index 369784a5ba..d3de0a9b9d 100644 --- a/tools/qmlformat/commentastvisitor.h +++ b/tools/qmlformat/commentastvisitor.h @@ -38,6 +38,7 @@ #include <QVector> using namespace QQmlJS::AST; +using namespace QQmlJS; struct Comment { @@ -108,6 +109,7 @@ public: void endVisit(StatementList *node) override; bool visit(UiImport *node) override; + bool visit(UiPragma *node) override; bool visit(UiPublicMember *node) override; bool visit(FunctionDeclaration *node) override; private: diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp index 20ebef8927..75712975cc 100644 --- a/tools/qmlformat/dumpastvisitor.cpp +++ b/tools/qmlformat/dumpastvisitor.cpp @@ -35,10 +35,29 @@ DumpAstVisitor::DumpAstVisitor(Node *rootNode, CommentAstVisitor *comment): m_co // Add all completely orphaned comments m_result += getOrphanedComments(nullptr); + m_scope_properties.push(ScopeProperties {}); + rootNode->accept(this); // We need to get rid of one new-line so our output doesn't append an empty line m_result.chop(1); + + // Remove trailing whitespace + QStringList lines = m_result.split("\n"); + for (QString& line : lines) { + while (line.endsWith(" ")) + line.chop(1); + } + + m_result = lines.join("\n"); +} + +bool DumpAstVisitor::preVisit(Node *el) +{ + UiObjectMember *m = el->uiObjectMemberCast(); + if (m != 0) + Node::accept(m->annotations, this); + return true; } static QString parseUiQualifiedId(UiQualifiedId *id) @@ -185,7 +204,7 @@ QString DumpAstVisitor::parseUiParameterList(UiParameterList *list) { QString result = ""; for (auto *item = list; item != nullptr; item = item->next) - result += item->type->name + " " + item->name + (item->next != nullptr ? ", " : ""); + result += parseUiQualifiedId(item->type) + " " + item->name + (item->next != nullptr ? ", " : ""); return result; } @@ -218,20 +237,28 @@ QString DumpAstVisitor::parsePatternElement(PatternElement *element, bool scope) result += element->bindingIdentifier.toString(); + if (element->typeAnnotation != nullptr) + result += ": " + parseType(element->typeAnnotation->type); + if (!expr.isEmpty()) result += " = "+expr; return result; } default: + m_error = true; return "pe_unknown"; } } QString escapeString(QString string) { - // Escape \r, \n and \t - string = string.replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t"); + // Handle escape sequences + string = string.replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t") + .replace("\b","\\b").replace("\v", "\\v").replace("\f", "\\f"); + + // Escape backslash + string = string.replace("\\", "\\\\"); // Escape " string = string.replace("\"", "\\\""); @@ -261,7 +288,14 @@ QString DumpAstVisitor::parseFormalParameterList(FormalParameterList *list) QString DumpAstVisitor::parsePatternProperty(PatternProperty *property) { - return escapeString(property->name->asString())+": "+parsePatternElement(property, false); + switch (property->type) { + case PatternElement::Getter: + return "get "+parseFunctionExpression(cast<FunctionExpression *>(property->initializer), true); + case PatternElement::Setter: + return "set "+parseFunctionExpression(cast<FunctionExpression *>(property->initializer), true); + default: + return escapeString(property->name->asString())+": "+parsePatternElement(property, false); + } } QString DumpAstVisitor::parsePatternPropertyList(PatternPropertyList *list) @@ -275,6 +309,61 @@ QString DumpAstVisitor::parsePatternPropertyList(PatternPropertyList *list) return result; } +QString DumpAstVisitor::parseFunctionExpression(FunctionExpression *functExpr, bool omitFunction) +{ + m_indentLevel++; + QString result; + + if (!functExpr->isArrowFunction) { + result += omitFunction ? "" : "function"; + + if (functExpr->isGenerator) + result += "*"; + + if (!functExpr->name.isEmpty()) + result += (omitFunction ? "" : " ") + functExpr->name; + + result += "("+parseFormalParameterList(functExpr->formals)+")"; + + if (functExpr->typeAnnotation != nullptr) + result += " : " + parseType(functExpr->typeAnnotation->type); + + result += " {\n" + parseStatementList(functExpr->body); + } else { + result += "("+parseFormalParameterList(functExpr->formals)+")"; + + if (functExpr->typeAnnotation != nullptr) + result += " : " + parseType(functExpr->typeAnnotation->type); + + result += " => {\n" + parseStatementList(functExpr->body); + } + + m_indentLevel--; + + result += formatLine("}", false); + + return result; + +} + +QString DumpAstVisitor::parseType(Type *type) { + QString result = parseUiQualifiedId(type->typeId); + + if (type->typeArguments != nullptr) { + TypeArgumentList *list = cast<TypeArgumentList *>(type->typeArguments); + + result += "<"; + + for (auto *item = list; item != nullptr; item = item->next) { + result += parseType(item->typeId) + (item->next != nullptr ? ", " : ""); + } + + result += ">"; + } + + return result; +} + QString DumpAstVisitor::parseExpression(ExpressionNode *expression) { if (expression == nullptr) @@ -288,7 +377,15 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression) return cast<IdentifierExpression*>(expression)->name.toString(); case Node::Kind_FieldMemberExpression: { auto *fieldMemberExpr = cast<FieldMemberExpression *>(expression); - return parseExpression(fieldMemberExpr->base) + "." + fieldMemberExpr->name.toString(); + QString result = parseExpression(fieldMemberExpr->base); + + // If we're operating on a numeric literal, always put it in braces + if (fieldMemberExpr->base->kind == Node::Kind_NumericLiteral) + result = "(" + result + ")"; + + result += "." + fieldMemberExpr->name.toString(); + + return result; } case Node::Kind_ArrayMemberExpression: { auto *arrayMemberExpr = cast<ArrayMemberExpression *>(expression); @@ -304,31 +401,7 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression) case Node::Kind_FunctionExpression: { auto *functExpr = cast<FunctionExpression *>(expression); - - m_indentLevel++; - QString result; - - if (!functExpr->isArrowFunction) { - result += "function"; - - if (functExpr->isGenerator) - result += "*"; - - if (!functExpr->name.isEmpty()) - result += " " + functExpr->name; - - result += "("+parseFormalParameterList(functExpr->formals)+") {\n" - + parseStatementList(functExpr->body); - } else { - result += "("+parseFormalParameterList(functExpr->formals)+") => {\n"; - result += parseStatementList(functExpr->body); - } - - m_indentLevel--; - - result += formatLine("}", false); - - return result; + return parseFunctionExpression(functExpr); } case Node::Kind_NullExpression: return "null"; @@ -419,8 +492,7 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression) } case Node::Kind_Type: { auto* type = reinterpret_cast<Type*>(expression); - - return parseUiQualifiedId(type->typeId); + return parseType(type); } case Node::Kind_RegExpLiteral: { auto* regexpLiteral = cast<RegExpLiteral*>(expression); @@ -610,10 +682,14 @@ QString DumpAstVisitor::parseStatement(Statement *statement, bool blockHasNext, result += "; "; result += parseExpression(forStatement->condition) + "; "; - result += parseExpression(forStatement->expression)+") "; + result += parseExpression(forStatement->expression)+")"; - result += parseStatement(forStatement->statement); + const QString statement = parseStatement(forStatement->statement); + if (!statement.isEmpty()) + result += " "+statement; + else + result += ";"; return result; } @@ -639,9 +715,16 @@ QString DumpAstVisitor::parseStatement(Statement *statement, bool blockHasNext, break; } - result += parseExpression(forEachStatement->expression) + ") "; + result += parseExpression(forEachStatement->expression) + ")"; + + const QString statement = parseStatement(forEachStatement->statement); + + if (!statement.isEmpty()) + result += " "+statement; + else + result += ";"; + - result += parseStatement(forEachStatement->statement); return result; } @@ -652,9 +735,14 @@ QString DumpAstVisitor::parseStatement(Statement *statement, bool blockHasNext, auto statement = parseStatement(whileStatement->statement, false, true); - return "while ("+parseExpression(whileStatement->expression) + ")" - + (m_blockNeededBraces ? " " : "") - + statement; + QString result = "while ("+parseExpression(whileStatement->expression) + ")"; + + if (!statement.isEmpty()) + result += (m_blockNeededBraces ? " " : "") + statement; + else + result += ";"; + + return result; } case Node::Kind_DoWhileStatement: { auto *doWhileStatement = cast<DoWhileStatement *>(statement); @@ -762,31 +850,32 @@ bool DumpAstVisitor::visit(UiPublicMember *node) { switch (node->type) { case UiPublicMember::Signal: - if (m_firstSignal) { - if (m_firstOfAll) - m_firstOfAll = false; + if (scope().m_firstSignal) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); - m_firstSignal = false; + scope().m_firstSignal = false; } addLine("signal "+node->name.toString()+"("+parseUiParameterList(node->parameters) + ")" + commentBackInline); break; case UiPublicMember::Property: { - if (m_firstProperty) { - if (m_firstOfAll) - m_firstOfAll = false; + if (scope().m_firstProperty) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); - m_firstProperty = false; + scope().m_firstProperty = false; } const bool is_required = node->requiredToken.isValid(); const bool is_default = node->defaultToken.isValid(); const bool is_readonly = node->readonlyToken.isValid(); + const bool has_type_modifier = node->typeModifierToken.isValid(); QString prefix = ""; QString statement = parseStatement(node->statement); @@ -803,8 +892,20 @@ bool DumpAstVisitor::visit(UiPublicMember *node) { if (is_readonly) prefix += "readonly "; - addLine(prefix + "property " + node->memberType->name + " " - + node->name+statement + commentBackInline); + QString member_type = parseUiQualifiedId(node->memberType); + + if (has_type_modifier) + member_type = node->typeModifier + "<" + member_type + ">"; + + if (is_readonly && statement.isEmpty() + && scope().m_bindings.contains(node->name.toString())) { + m_result += formatLine(prefix + "property " + member_type + " ", false); + + scope().m_pendingBinding = true; + } else { + addLine(prefix + "property " + member_type + " " + + node->name+statement + commentBackInline); + } break; } } @@ -845,26 +946,70 @@ void DumpAstVisitor::addLine(QString line) { m_result += formatLine(line); } +QHash<QString, UiObjectMember*> findBindings(UiObjectMemberList *list) { + QHash<QString, UiObjectMember*> bindings; + + // This relies on RestructureASTVisitor having run beforehand + + for (auto *item = list; item != nullptr; item = item->next) { + switch (item->member->kind) { + case Node::Kind_UiPublicMember: { + UiPublicMember *member = cast<UiPublicMember *>(item->member); + + if (member->type != UiPublicMember::Property) + continue; + + bindings[member->name.toString()] = nullptr; + + break; + } + case Node::Kind_UiObjectBinding: { + UiObjectBinding *binding = cast<UiObjectBinding *>(item->member); + + const QString name = parseUiQualifiedId(binding->qualifiedId); + + if (bindings.contains(name)) + bindings[name] = binding; + + break; + } + case Node::Kind_UiArrayBinding: { + UiArrayBinding *binding = cast<UiArrayBinding *>(item->member); + + const QString name = parseUiQualifiedId(binding->qualifiedId); + + if (bindings.contains(name)) + bindings[name] = binding; + + break; + } + case Node::Kind_UiScriptBinding: + // We can ignore UiScriptBindings since those are actually properly attached to the property + break; + } + } + + return bindings; +} + bool DumpAstVisitor::visit(UiObjectDefinition *node) { - if (m_firstObject) { - if (m_firstOfAll) - m_firstOfAll = false; + if (scope().m_firstObject) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); - m_firstObject = false; + scope().m_firstObject = false; } addLine(getComment(node, Comment::Location::Front)); - addLine(node->qualifiedTypeNameId->name+" {"); + addLine(parseUiQualifiedId(node->qualifiedTypeNameId) + " {"); m_indentLevel++; - m_firstProperty = true; - m_firstSignal = true; - m_firstBinding = true; - m_firstObject = true; - m_firstOfAll = true; + ScopeProperties props; + props.m_bindings = findBindings(node->initializer->members); + m_scope_properties.push(props); m_result += getOrphanedComments(node); @@ -873,9 +1018,14 @@ bool DumpAstVisitor::visit(UiObjectDefinition *node) { void DumpAstVisitor::endVisit(UiObjectDefinition *node) { m_indentLevel--; - addLine(m_inArrayBinding && m_lastInArrayBinding != node ? "}," : "}"); + + m_scope_properties.pop(); + + bool need_comma = scope().m_inArrayBinding && scope().m_lastInArrayBinding != node; + + addLine(need_comma ? "}," : "}"); addLine(getComment(node, Comment::Location::Back)); - if (!m_inArrayBinding) + if (!scope().m_inArrayBinding) addNewLine(); } @@ -920,49 +1070,64 @@ bool DumpAstVisitor::visit(UiEnumMemberList *node) { } bool DumpAstVisitor::visit(UiScriptBinding *node) { - if (m_firstBinding) { - if (m_firstOfAll) - m_firstOfAll = false; + if (scope().m_firstBinding) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); if (parseUiQualifiedId(node->qualifiedId) != "id") - m_firstBinding = false; + scope().m_firstBinding = false; } addLine(getComment(node, Comment::Location::Front)); - addLine(parseUiQualifiedId(node->qualifiedId)+ ": " + parseStatement(node->statement) - + getComment(node, Comment::Location::Back_Inline)); + + QString statement = parseStatement(node->statement); + + QString result = parseUiQualifiedId(node->qualifiedId) + ":"; + + if (!statement.isEmpty()) + result += " "+statement; + else + result += ";"; + + result += getComment(node, Comment::Location::Back_Inline); + + addLine(result); + return true; } bool DumpAstVisitor::visit(UiArrayBinding *node) { - if (m_firstBinding) { - if (m_firstOfAll) - m_firstOfAll = false; + if (!scope().m_pendingBinding && scope().m_firstBinding) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); - m_firstBinding = false; + scope().m_firstBinding = false; } - addLine(getComment(node, Comment::Location::Front)); - addLine(parseUiQualifiedId(node->qualifiedId)+ ": ["); + if (scope().m_pendingBinding) { + m_result += parseUiQualifiedId(node->qualifiedId)+ ": [\n"; + scope().m_pendingBinding = false; + } else { + addLine(getComment(node, Comment::Location::Front)); + addLine(parseUiQualifiedId(node->qualifiedId)+ ": ["); + } m_indentLevel++; - m_inArrayBinding = true; - m_firstOfAll = true; - m_firstObject = true; - m_firstSignal = true; - m_firstBinding = true; - m_firstProperty = true; + ScopeProperties props; + props.m_inArrayBinding = true; for (auto *item = node->members; item != nullptr; item = item->next) { if (item->next == nullptr) - m_lastInArrayBinding = item->member; + props.m_lastInArrayBinding = item->member; } + m_scope_properties.push(props); + m_result += getOrphanedComments(node); return true; @@ -970,8 +1135,7 @@ bool DumpAstVisitor::visit(UiArrayBinding *node) { void DumpAstVisitor::endVisit(UiArrayBinding *) { m_indentLevel--; - m_inArrayBinding = false; - m_lastInArrayBinding = nullptr; + m_scope_properties.pop(); addLine("]"); } @@ -986,7 +1150,12 @@ bool DumpAstVisitor::visit(FunctionDeclaration *node) { if (node->isGenerator) head += "*"; - head += " "+node->name+"("+parseFormalParameterList(node->formals)+") {"; + head += " "+node->name+"("+parseFormalParameterList(node->formals)+")"; + + if (node->typeAnnotation != nullptr) + head += " : " + parseType(node->typeAnnotation->type); + + head += " {"; addLine(head); m_indentLevel++; @@ -1000,27 +1169,37 @@ bool DumpAstVisitor::visit(FunctionDeclaration *node) { } bool DumpAstVisitor::visit(UiObjectBinding *node) { - if (m_firstObject) { - if (m_firstOfAll) - m_firstOfAll = false; + if (!scope().m_pendingBinding && scope().m_firstObject) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; else addNewLine(); - m_firstObject = false; + scope().m_firstObject = false; } QString name = parseUiQualifiedId(node->qualifiedTypeNameId); QString result = name; + ScopeProperties props; + props.m_bindings = findBindings(node->initializer->members); + m_scope_properties.push(props); + if (node->hasOnToken) result += " on "+parseUiQualifiedId(node->qualifiedId); else result.prepend(parseUiQualifiedId(node->qualifiedId) + ": "); - addNewLine(); - addLine(getComment(node, Comment::Location::Front)); - addLine(result+" {"); + if (scope().m_pendingBinding) { + m_result += result + " {\n"; + + scope().m_pendingBinding = false; + } else { + addNewLine(); + addLine(getComment(node, Comment::Location::Front)); + addLine(result + " {"); + } m_indentLevel++; @@ -1029,6 +1208,8 @@ bool DumpAstVisitor::visit(UiObjectBinding *node) { void DumpAstVisitor::endVisit(UiObjectBinding *node) { m_indentLevel--; + m_scope_properties.pop(); + addLine("}"); addLine(getComment(node, Comment::Location::Back)); @@ -1036,6 +1217,8 @@ void DumpAstVisitor::endVisit(UiObjectBinding *node) { } bool DumpAstVisitor::visit(UiImport *node) { + scope().m_firstOfAll = false; + addLine(getComment(node, Comment::Location::Front)); QString result = "import "; @@ -1046,8 +1229,8 @@ bool DumpAstVisitor::visit(UiImport *node) { result += parseUiQualifiedId(node->importUri); if (node->version) { - result += " " + QString::number(node->version->majorVersion) + "." - + QString::number(node->version->minorVersion); + result += " " + QString::number(node->version->version.majorVersion()) + "." + + QString::number(node->version->version.minorVersion()); } if (node->asToken.isValid()) { @@ -1060,3 +1243,49 @@ bool DumpAstVisitor::visit(UiImport *node) { return true; } + +bool DumpAstVisitor::visit(UiPragma *node) { + scope().m_firstOfAll = false; + + addLine(getComment(node, Comment::Location::Front)); + QString result = "pragma "+ node->name; + result += getComment(node, Comment::Location::Back_Inline); + + addLine(result); + + return true; +} + +bool DumpAstVisitor::visit(UiAnnotation *node) +{ + if (scope().m_firstObject) { + if (scope().m_firstOfAll) + scope().m_firstOfAll = false; + else + addNewLine(); + + scope().m_firstObject = false; + } + + addLine(getComment(node, Comment::Location::Front)); + addLine(QLatin1String("@") + parseUiQualifiedId(node->qualifiedTypeNameId) + " {"); + + m_indentLevel++; + + ScopeProperties props; + props.m_bindings = findBindings(node->initializer->members); + m_scope_properties.push(props); + + m_result += getOrphanedComments(node); + + return true; +} + +void DumpAstVisitor::endVisit(UiAnnotation *node) { + m_indentLevel--; + + m_scope_properties.pop(); + + addLine("}"); + addLine(getComment(node, Comment::Location::Back)); +} diff --git a/tools/qmlformat/dumpastvisitor.h b/tools/qmlformat/dumpastvisitor.h index 2001f4366e..faf067d400 100644 --- a/tools/qmlformat/dumpastvisitor.h +++ b/tools/qmlformat/dumpastvisitor.h @@ -32,9 +32,13 @@ #include <QtQml/private/qqmljsastvisitor_p.h> #include <QtQml/private/qqmljsast_p.h> +#include <QHash> +#include <QStack> + #include "commentastvisitor.h" using namespace QQmlJS::AST; +using namespace QQmlJS; class DumpAstVisitor : protected Visitor { @@ -43,6 +47,8 @@ public: QString toString() const { return m_result; } + bool preVisit(Node *) override; + bool visit(UiScriptBinding *node) override; bool visit(UiArrayBinding *node) override; @@ -62,11 +68,28 @@ public: bool visit(UiEnumMemberList *node) override; bool visit(UiPublicMember *node) override; bool visit(UiImport *node) override; + bool visit(UiPragma *node) override; + + bool visit(UiAnnotation *node) override; + void endVisit(UiAnnotation *node) override; void throwRecursionDepthError() override {} bool error() const { return m_error; } private: + struct ScopeProperties { + bool m_firstOfAll = true; + bool m_firstSignal = true; + bool m_firstProperty = true; + bool m_firstBinding = true; + bool m_firstObject = true; + bool m_inArrayBinding = false; + bool m_pendingBinding = false; + + UiObjectMember* m_lastInArrayBinding = nullptr; + QHash<QString, UiObjectMember*> m_bindings; + }; + QString generateIndent() const; QString formatLine(QString line, bool newline = true) const; @@ -106,19 +129,19 @@ private: QString parseFormalParameterList(FormalParameterList *list); + QString parseType(Type *type); + + QString parseFunctionExpression(FunctionExpression *expression, bool omitFunction = false); + + ScopeProperties& scope() { return m_scope_properties.top(); } + int m_indentLevel = 0; bool m_error = false; bool m_blockNeededBraces = false; - bool m_inArrayBinding = false; - bool m_firstOfAll = false; - bool m_firstSignal = false; - bool m_firstProperty = false; - bool m_firstBinding = false; - bool m_firstObject = true; + QStack<ScopeProperties> m_scope_properties; - UiObjectMember* m_lastInArrayBinding = nullptr; QString m_result = ""; CommentAstVisitor *m_comment; }; diff --git a/tools/qmlformat/main.cpp b/tools/qmlformat/main.cpp index 036fbe9748..da58ffd5d0 100644 --- a/tools/qmlformat/main.cpp +++ b/tools/qmlformat/main.cpp @@ -67,7 +67,7 @@ bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImp const auto diagnosticMessages = parser.diagnosticMessages(); for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { qWarning().noquote() << QString::fromLatin1("%1:%2 : %3") - .arg(filename).arg(m.line).arg(m.message); + .arg(filename).arg(m.loc.startLine).arg(m.message); } qWarning().noquote() << "Failed to parse" << filename; @@ -101,11 +101,29 @@ bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImp DumpAstVisitor dump(parser.rootNode(), &comment); - if (dump.error()) { + QString dumpCode = dump.toString(); + + lexer.setCode(dumpCode, 1, true); + + bool dumpSuccess = parser.parse(); + + if (!dumpSuccess) { + if (verbose) { + const auto diagnosticMessages = parser.diagnosticMessages(); + for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { + qWarning().noquote() << QString::fromLatin1("<formatted>:%2 : %3") + .arg(m.loc.startLine).arg(m.message); + } + } + + qWarning().noquote() << "Failed to parse formatted code."; + } + + if (dump.error() || !dumpSuccess) { if (force) { qWarning().noquote() << "An error has occurred. The output may not be reliable."; } else { - qWarning().noquote() << "Am error has occurred. Aborting."; + qWarning().noquote() << "An error has occurred. Aborting."; return false; } } @@ -120,10 +138,10 @@ bool parseFile(const QString& filename, bool inplace, bool verbose, bool sortImp return false; } - file.write(dump.toString().toUtf8()); + file.write(dumpCode.toUtf8()); file.close(); } else { - QTextStream(stdout) << dump.toString(); + QTextStream(stdout) << dumpCode; } return true; diff --git a/tools/qmlformat/restructureastvisitor.cpp b/tools/qmlformat/restructureastvisitor.cpp index f9ac2a20c2..7cce0e8034 100644 --- a/tools/qmlformat/restructureastvisitor.cpp +++ b/tools/qmlformat/restructureastvisitor.cpp @@ -110,6 +110,11 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) { QList<UiObjectMember*> correctOrder; + QList<UiScriptBinding*> largeScriptBinding; + + UiObjectMember *states = nullptr; + UiObjectMember *transitions = nullptr; + auto enumDeclarations = findKind<UiEnumDeclaration>(node); auto scriptBindings = findKind<UiScriptBinding>(node); auto arrayBindings = findKind<UiArrayBinding>(node); @@ -117,11 +122,47 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) auto sourceElements = findKind<UiSourceElement>(node); auto objectDefinitions = findKind<UiObjectDefinition>(node); + // Look for transitions and states + for (auto *binding : findKind<UiObjectBinding>(node)) { + const QString name = parseUiQualifiedId(binding->qualifiedId); + + if (name == "transitions") + transitions = binding; + else if (name == "states") + states = binding; + } + + for (auto it = arrayBindings.begin(); it != arrayBindings.end();) { + const QString name = parseUiQualifiedId((*it)->qualifiedId); + + if (name == "transitions") { + transitions = *it; + it = arrayBindings.erase(it); + } else if (name == "states") { + states = *it; + it = arrayBindings.erase(it); + } else { + it++; + } + } + + // Find large script bindings + for (auto it = scriptBindings.begin(); it != scriptBindings.end();) { + // A binding is considered large if it uses a block + if ((*it)->statement->kind != Node::Kind_Block) { + it++; + continue; + } + + largeScriptBinding.push_back(*it); + it = scriptBindings.erase(it); + } + // This structure is based on https://doc.qt.io/qt-5/qml-codingconventions.html // 1st id for (auto *binding : scriptBindings) { - if (binding->qualifiedId->name == "id") { + if (parseUiQualifiedId(binding->qualifiedId) == "id") { correctOrder.append(binding); scriptBindings.removeOne(binding); @@ -154,9 +195,14 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) correctOrder.append(source); // 6th properties + // small script bindings... for (auto *binding : scriptBindings) correctOrder.append(binding); + // ...then large ones + for (auto *binding : largeScriptBinding) + correctOrder.append(binding); + for (auto *binding : arrayBindings) correctOrder.append(binding); @@ -170,6 +216,13 @@ void RestructureAstVisitor::endVisit(UiObjectMemberList *node) correctOrder.append(item->member); } + // 9th states and transitions + if (states != nullptr) + correctOrder.append(states); + + if (transitions != nullptr) + correctOrder.append(transitions); + // Rebuild member list from correctOrder for (auto *item = node; item != nullptr; item = item->next) { item->member = correctOrder.front(); diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index b563d7df95..f9f3cd90cf 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -123,7 +123,11 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con if (!name.isEmpty()) import[nameLiteral()] = name; import[typeLiteral()] = moduleLiteral(); - auto versionString = importNode->version ? QString::number(importNode->version->majorVersion) + QLatin1Char('.') + QString::number(importNode->version->minorVersion) : QString(); + auto versionString = importNode->version + ? QString::number(importNode->version->version.majorVersion()) + + QLatin1Char('.') + + QString::number(importNode->version->version.minorVersion()) + : QString(); import[versionLiteral()] = versionString; } @@ -179,7 +183,7 @@ QPair<QString, QString> resolveImportPath(const QString &uri, const QString &ver { const QLatin1Char dot('.'); const QLatin1Char slash('/'); - const QStringList parts = uri.split(dot, QString::SkipEmptyParts); + const QStringList parts = uri.split(dot, Qt::SkipEmptyParts); QString ver = version; while (true) { @@ -277,7 +281,7 @@ QVariantList findQmlImportsInQmlCode(const QString &filePath, const QString &cod const auto diagnosticMessages = parser.diagnosticMessages(); for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { std::cerr << QDir::toNativeSeparators(filePath).toStdString() << ':' - << m.line << ':' << m.message.toStdString() << std::endl; + << m.loc.startLine << ':' << m.message.toStdString() << std::endl; } return QVariantList(); } diff --git a/tools/qmlimportscanner/qmlimportscanner.pro b/tools/qmlimportscanner/qmlimportscanner.pro index d69f1a3b0b..33089a5c48 100644 --- a/tools/qmlimportscanner/qmlimportscanner.pro +++ b/tools/qmlimportscanner/qmlimportscanner.pro @@ -14,9 +14,9 @@ contains(CMAKE_BIN_DIR, "^\\.\\./.*") { CMAKE_BIN_DIR_IS_ABSOLUTE = True } -CMAKE_QML_DIR = $$cmakeRelativePath($$[QT_INSTALL_QML/get], $$[QT_INSTALL_PREFIX]) +CMAKE_QML_DIR = $$cmakeRelativePath($$[QT_INSTALL_QML], $$[QT_INSTALL_PREFIX]) contains(CMAKE_QML_DIR, "^\\.\\./.*") { - CMAKE_QML_DIR = $$[QT_INSTALL_QML/get]/ + CMAKE_QML_DIR = $$[QT_INSTALL_QML]/ CMAKE_QML_DIR_IS_ABSOLUTE = True } load(qt_build_paths) diff --git a/tools/qmllint/componentversion.cpp b/tools/qmllint/componentversion.cpp index e5047b8302..95403ec15f 100644 --- a/tools/qmllint/componentversion.cpp +++ b/tools/qmllint/componentversion.cpp @@ -41,21 +41,21 @@ ComponentVersion::ComponentVersion(const QString &versionString) const int maybeMinor = versionString.midRef(dotIdx + 1).toInt(&ok); if (!ok) return; - m_major = maybeMajor; - m_minor = maybeMinor; + m_version = QTypeRevision::fromVersion(maybeMajor, maybeMinor); } bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() && lhs.minorVersion() < rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() < rhs.version().minorVersion()); } bool operator<=(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() < rhs.majorVersion() - || (lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() <= rhs.minorVersion()); + return lhs.version().majorVersion() < rhs.version().majorVersion() + || (lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() <= rhs.version().minorVersion()); } bool operator>(const ComponentVersion &lhs, const ComponentVersion &rhs) @@ -70,8 +70,8 @@ bool operator>=(const ComponentVersion &lhs, const ComponentVersion &rhs) bool operator==(const ComponentVersion &lhs, const ComponentVersion &rhs) { - return lhs.majorVersion() == rhs.majorVersion() - && lhs.minorVersion() == rhs.minorVersion(); + return lhs.version().majorVersion() == rhs.version().majorVersion() + && lhs.version().minorVersion() == rhs.version().minorVersion(); } bool operator!=(const ComponentVersion &lhs, const ComponentVersion &rhs) diff --git a/tools/qmllint/componentversion.h b/tools/qmllint/componentversion.h index 9c4604b9a3..bbb039fc40 100644 --- a/tools/qmllint/componentversion.h +++ b/tools/qmllint/componentversion.h @@ -40,24 +40,20 @@ // We mean it. #include <QtCore/qglobal.h> +#include <QtCore/qversionnumber.h> class ComponentVersion { public: - static const int NoVersion = -1; - ComponentVersion() = default; - ComponentVersion(int major, int minor) : m_major(major), m_minor(minor) {} + ComponentVersion(QTypeRevision version) : m_version(version) {} explicit ComponentVersion(const QString &versionString); - int majorVersion() const { return m_major; } - int minorVersion() const { return m_minor; } - - bool isValid() const { return m_major >= 0 && m_minor >= 0; } + QTypeRevision version() const { return m_version; } + bool isValid() const { return m_version.hasMajorVersion() && m_version.hasMinorVersion(); } private: - int m_major = NoVersion; - int m_minor = NoVersion; + QTypeRevision m_version; }; bool operator<(const ComponentVersion &lhs, const ComponentVersion &rhs); diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp index 807110c3c1..6155ea4637 100644 --- a/tools/qmllint/findunqualified.cpp +++ b/tools/qmllint/findunqualified.cpp @@ -92,8 +92,7 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade if (import->asToken.isValid()) { prefix += import->importId + QLatin1Char('.'); } - importHelper(path, prefix, import->version->majorVersion, - import->version->minorVersion); + importHelper(path, prefix, import->version->version); } } header = header->next; @@ -119,26 +118,27 @@ ScopeTree *FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath }; -QStringList completeImportPaths(const QString &uri, const QString &basePath, int vmaj, int vmin) +QStringList completeImportPaths(const QString &uri, const QString &basePath, QTypeRevision version) { static const QLatin1Char Slash('/'); static const QLatin1Char Backslash('\\'); - const QVector<QStringRef> parts = uri.splitRef(QLatin1Char('.'), QString::SkipEmptyParts); + const QVector<QStringRef> parts = uri.splitRef(QLatin1Char('.'), Qt::SkipEmptyParts); QStringList qmlDirPathsPaths; // fully & partially versioned parts + 1 unversioned for each base path qmlDirPathsPaths.reserve(2 * parts.count() + 1); - auto versionString = [](int vmaj, int vmin, ImportVersion version) + auto versionString = [](QTypeRevision version, ImportVersion mode) { - if (version == FullyVersioned) { + if (mode == FullyVersioned) { // extension with fully encoded version number (eg. MyModule.3.2) - return QString::fromLatin1(".%1.%2").arg(vmaj).arg(vmin); + return QString::fromLatin1(".%1.%2").arg(version.majorVersion()) + .arg(version.minorVersion()); } - if (version == PartiallyVersioned) { + if (mode == PartiallyVersioned) { // extension with encoded version major (eg. MyModule.3) - return QString::fromLatin1(".%1").arg(vmaj); + return QString::fromLatin1(".%1").arg(version.majorVersion()); } // else extension without version number (eg. MyModule) return QString(); @@ -153,24 +153,24 @@ QStringList completeImportPaths(const QString &uri, const QString &basePath, int return str; }; - const ImportVersion initial = (vmin >= 0) + const ImportVersion initial = (version.hasMinorVersion()) ? FullyVersioned - : (vmaj >= 0 ? PartiallyVersioned : Unversioned); - for (int version = initial; version <= BasePath; ++version) { - const QString ver = versionString(vmaj, vmin, static_cast<ImportVersion>(version)); + : (version.hasMajorVersion() ? PartiallyVersioned : Unversioned); + for (int mode = initial; mode <= BasePath; ++mode) { + const QString ver = versionString(version, ImportVersion(mode)); QString dir = basePath; if (!dir.endsWith(Slash) && !dir.endsWith(Backslash)) dir += Slash; - if (version == BasePath) { + if (mode == BasePath) { qmlDirPathsPaths += dir; } else { // append to the end qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver; } - if (version < Unversioned) { + if (mode < Unversioned) { // insert in the middle for (int index = parts.count() - 2; index >= 0; --index) { qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash) @@ -222,7 +222,7 @@ FindUnqualifiedIDVisitor::Import FindUnqualifiedIDVisitor::readQmldir(const QStr (*mo)->addExport( it.key(), reader.typeNamespace(), - ComponentVersion(it->majorVersion, it->minorVersion)); + ComponentVersion(it->version)); } for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it) result.objects.insert( it.key(), ScopeTree::ConstPtr(it.value())); @@ -240,11 +240,11 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn auto const &id = split.at(0); if (split.length() > 1) { const auto version = split.at(1).split('.'); - importHelper(id, QString(), - version.at(0).toInt(), - version.length() > 1 ? version.at(1).toInt() : -1); + importHelper(id, QString(), QTypeRevision::fromVersion( + version.at(0).toInt(), + version.length() > 1 ? version.at(1).toInt() : -1)); } else { - importHelper(id, QString(), -1, -1); + importHelper(id, QString(), QTypeRevision()); } @@ -267,7 +267,7 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn } void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString &prefix, - int major, int minor) + QTypeRevision version) { const QString id = QString(module).replace(QLatin1Char('/'), QLatin1Char('.')); QPair<QString, QString> importId { id, prefix }; @@ -276,7 +276,7 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString m_alreadySeenImports.insert(importId); for (const QString &qmltypeDir : m_qmltypeDirs) { - auto qmltypesPaths = completeImportPaths(id, qmltypeDir, major, minor); + auto qmltypesPaths = completeImportPaths(id, qmltypeDir, version); for (auto const &qmltypesPath : qmltypesPaths) { if (QFile::exists(qmltypesPath + SlashQmldir)) { @@ -764,7 +764,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import) } path.chop(1); - importHelper(path, prefix, import->version->majorVersion, import->version->minorVersion); + importHelper(path, prefix, import->version->version); } return true; } diff --git a/tools/qmllint/findunqualified.h b/tools/qmllint/findunqualified.h index 6668b53b08..1c351e4fd9 100644 --- a/tools/qmllint/findunqualified.h +++ b/tools/qmllint/findunqualified.h @@ -91,7 +91,7 @@ private: void enterEnvironment(ScopeType type, const QString &name); void leaveEnvironment(); void importHelper(const QString &module, const QString &prefix = QString(), - int major = -1, int minor = -1); + QTypeRevision version = QTypeRevision()); void readQmltypes(const QString &filename, Import &result); Import readQmldir(const QString &dirname); diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp index 0a0e669e94..fa601986b2 100644 --- a/tools/qmllint/main.cpp +++ b/tools/qmllint/main.cpp @@ -78,7 +78,7 @@ static bool lint_file(const QString &filename, const bool silent, const bool war const auto diagnosticMessages = parser.diagnosticMessages(); for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { qWarning().noquote() << QString::fromLatin1("%1:%2 : %3") - .arg(filename).arg(m.line).arg(m.message); + .arg(filename).arg(m.loc.startLine).arg(m.message); } } diff --git a/tools/qmllint/scopetree.cpp b/tools/qmllint/scopetree.cpp index 2ca3ed9a67..e7e0113f35 100644 --- a/tools/qmllint/scopetree.cpp +++ b/tools/qmllint/scopetree.cpp @@ -62,7 +62,7 @@ void ScopeTree::insertJSIdentifier(const QString &id, QQmlJS::AST::VariableScope } void ScopeTree::insertSignalIdentifier(const QString &id, const MetaMethod &method, - const QQmlJS::AST::SourceLocation &loc, + const QQmlJS::SourceLocation &loc, bool hasMultilineHandlerBody) { Q_ASSERT(m_scopeType == ScopeType::QMLScope); @@ -77,7 +77,7 @@ void ScopeTree::insertPropertyIdentifier(const MetaProperty &property) } void ScopeTree::addUnmatchedSignalHandler(const QString &handler, - const QQmlJS::AST::SourceLocation &location) + const QQmlJS::SourceLocation &location) { m_unmatchedSignalHandlers.append(qMakePair(handler, location)); } @@ -87,13 +87,13 @@ bool ScopeTree::isIdInCurrentScope(const QString &id) const return isIdInCurrentQMlScopes(id) || isIdInCurrentJSScopes(id); } -void ScopeTree::addIdToAccessed(const QString &id, const QQmlJS::AST::SourceLocation &location) { +void ScopeTree::addIdToAccessed(const QString &id, const QQmlJS::SourceLocation &location) { m_currentFieldMember = new FieldMemberList {id, QString(), location, {}}; m_accessedIdentifiers.push_back(std::unique_ptr<FieldMemberList>(m_currentFieldMember)); } void ScopeTree::accessMember(const QString &name, const QString &parentType, - const QQmlJS::AST::SourceLocation &location) + const QQmlJS::SourceLocation &location) { Q_ASSERT(m_currentFieldMember); auto *fieldMember = new FieldMemberList {name, parentType, location, {}}; @@ -115,7 +115,7 @@ bool ScopeTree::isVisualRootScope() const class IssueLocationWithContext { public: - IssueLocationWithContext(const QString &code, const QQmlJS::AST::SourceLocation &location) { + IssueLocationWithContext(const QString &code, const QQmlJS::SourceLocation &location) { int before = std::max(0,code.lastIndexOf('\n', location.offset)); m_beforeText = code.midRef(before + 1, int(location.offset - (before + 1))); m_issueText = code.midRef(location.offset, location.length); @@ -440,7 +440,7 @@ const ScopeTree *ScopeTree::currentQMLScope() const } void ScopeTree::printContext(ColorOutput &colorOut, const QString &code, - const QQmlJS::AST::SourceLocation &location) const + const QQmlJS::SourceLocation &location) const { IssueLocationWithContext issueLocationWithContext {code, location}; colorOut.write(issueLocationWithContext.beforeText().toString(), Normal); diff --git a/tools/qmllint/scopetree.h b/tools/qmllint/scopetree.h index f5d1155a49..63f4310bf8 100644 --- a/tools/qmllint/scopetree.h +++ b/tools/qmllint/scopetree.h @@ -68,7 +68,7 @@ enum class ScopeType struct MethodUsage { MetaMethod method; - QQmlJS::AST::SourceLocation loc; + QQmlJS::SourceLocation loc; bool hasMultilineHandlerBody; }; @@ -112,16 +112,16 @@ public: void insertJSIdentifier(const QString &id, QQmlJS::AST::VariableScope scope); void insertSignalIdentifier(const QString &id, const MetaMethod &method, - const QQmlJS::AST::SourceLocation &loc, bool hasMultilineHandlerBody); + const QQmlJS::SourceLocation &loc, bool hasMultilineHandlerBody); // inserts property as qml identifier as well as the corresponding void insertPropertyIdentifier(const MetaProperty &prop); void addUnmatchedSignalHandler(const QString &handler, - const QQmlJS::AST::SourceLocation &location); + const QQmlJS::SourceLocation &location); bool isIdInCurrentScope(const QString &id) const; - void addIdToAccessed(const QString &id, const QQmlJS::AST::SourceLocation &location); + void addIdToAccessed(const QString &id, const QQmlJS::SourceLocation &location); void accessMember(const QString &name, const QString &parentType, - const QQmlJS::AST::SourceLocation &location); + const QQmlJS::SourceLocation &location); void resetMemberScope(); bool isVisualRootScope() const; @@ -174,7 +174,7 @@ private: { QString m_name; QString m_parentType; - QQmlJS::AST::SourceLocation m_location; + QQmlJS::SourceLocation m_location; std::unique_ptr<FieldMemberList> m_child; }; @@ -188,7 +188,7 @@ private: std::vector<std::unique_ptr<FieldMemberList>> m_accessedIdentifiers; FieldMemberList *m_currentFieldMember = nullptr; - QVector<QPair<QString, QQmlJS::AST::SourceLocation>> m_unmatchedSignalHandlers; + QVector<QPair<QString, QQmlJS::SourceLocation>> m_unmatchedSignalHandlers; QVector<ScopeTree::Ptr> m_childScopes; ScopeTree *m_parentScope; @@ -211,7 +211,7 @@ private: bool isIdInjectedFromSignal(const QString &id) const; const ScopeTree *currentQMLScope() const; void printContext(ColorOutput &colorOut, const QString &code, - const QQmlJS::AST::SourceLocation &location) const; + const QQmlJS::SourceLocation &location) const; bool checkMemberAccess( const QString &code, FieldMemberList *members, diff --git a/tools/qmllint/typedescriptionreader.cpp b/tools/qmllint/typedescriptionreader.cpp index 3dc87ffc8d..8734f349d5 100644 --- a/tools/qmllint/typedescriptionreader.cpp +++ b/tools/qmllint/typedescriptionreader.cpp @@ -102,7 +102,7 @@ void TypeDescriptionReader::readDocument(UiProgram *ast) return; } - if (import->version->majorVersion != 1) { + if (import->version->version.majorVersion() != 1) { addError(import->version->firstSourceLocation(), tr("Major version different from 1 not supported.")); return; diff --git a/tools/qmllint/typedescriptionreader.h b/tools/qmllint/typedescriptionreader.h index 5fcbe3abc9..48c33bee3c 100644 --- a/tools/qmllint/typedescriptionreader.h +++ b/tools/qmllint/typedescriptionreader.h @@ -90,8 +90,8 @@ private: void readMetaObjectRevisions(QQmlJS::AST::UiScriptBinding *ast, const ScopeTree::Ptr &scope); void readEnumValues(QQmlJS::AST::UiScriptBinding *ast, MetaEnum *metaEnum); - void addError(const QQmlJS::AST::SourceLocation &loc, const QString &message); - void addWarning(const QQmlJS::AST::SourceLocation &loc, const QString &message); + void addError(const QQmlJS::SourceLocation &loc, const QString &message); + void addWarning(const QQmlJS::SourceLocation &loc, const QString &message); QString m_fileName; QString m_source; diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 947b5dff27..3efa4dc605 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -103,15 +103,15 @@ static QString enquote(const QString &string) struct QmlVersionInfo { QString pluginImportUri; - int majorVersion; - int minorVersion; + QTypeRevision version; bool strict; }; static bool matchingImportUri(const QQmlType &ty, const QmlVersionInfo& versionInfo) { if (versionInfo.strict) { return (versionInfo.pluginImportUri == ty.module() - && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1)) + && (ty.version().majorVersion() == versionInfo.version.majorVersion() + || !ty.version().hasMajorVersion())) || ty.module().isEmpty(); } return ty.module().isEmpty() @@ -335,23 +335,23 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, } class KnownAttributes { - QHash<QByteArray, int> m_properties; - QHash<QByteArray, QHash<int, int> > m_methods; + QHash<QByteArray, QTypeRevision> m_properties; + QHash<QByteArray, QHash<int, QTypeRevision> > m_methods; public: - bool knownMethod(const QByteArray &name, int nArgs, int revision) + bool knownMethod(const QByteArray &name, int nArgs, QTypeRevision revision) { if (m_methods.contains(name)) { - QHash<int, int> overloads = m_methods.value(name); - if (overloads.contains(nArgs) && overloads.value(nArgs) <= revision) + QHash<int, QTypeRevision> overloads = m_methods.value(name); + if (overloads.contains(nArgs) && overloads.value(nArgs).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; } m_methods[name][nArgs] = revision; return false; } - bool knownProperty(const QByteArray &name, int revision) + bool knownProperty(const QByteArray &name, QTypeRevision revision) { - if (m_properties.contains(name) && m_properties.value(name) <= revision) + if (m_properties.contains(name) && m_properties.value(name).toEncodedVersion<quint16>() <= revision.toEncodedVersion<quint16>()) return true; m_properties[name] = revision; return false; @@ -375,13 +375,14 @@ public: { const QString module = type.module().isEmpty() ? versionInfo.pluginImportUri : type.module(); - const int majorVersion = type.majorVersion() >= 0 ? type.majorVersion() - : versionInfo.majorVersion; - const int minorVersion = type.minorVersion() >= 0 ? type.minorVersion() - : versionInfo.minorVersion; + QTypeRevision version = QTypeRevision::fromVersion( + type.version().hasMajorVersion() ? type.version().majorVersion() + : versionInfo.version.majorVersion(), + type.version().hasMinorVersion() ? type.version().minorVersion() + : versionInfo.version.minorVersion()); const QString versionedElement = type.elementName() - + QString::fromLatin1(" %1.%2").arg(majorVersion).arg(minorVersion); + + QString::fromLatin1(" %1.%2").arg(version.majorVersion()).arg(version.minorVersion()); return enquote((module == relocatableModuleUri) ? versionedElement @@ -390,7 +391,7 @@ public: void writeMetaContent(const QMetaObject *meta, KnownAttributes *knownAttributes = nullptr) { - QSet<QString> implicitSignals = dumpMetaProperties(meta, 0, knownAttributes); + QSet<QString> implicitSignals = dumpMetaProperties(meta, QTypeRevision::zero(), knownAttributes); if (meta == &QObject::staticMetaObject) { // for QObject, hide deleteLater() and onDestroyed @@ -405,17 +406,17 @@ public: } // and add toString(), destroy() and destroy(int) - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeEndObject(); } - if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, 0)) { + if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, QTypeRevision::zero())) { qml->writeStartObject(QLatin1String("Method")); qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy"))); qml->writeStartObject(QLatin1String("Parameter")); @@ -498,7 +499,12 @@ public: qml->writeScriptBinding(QLatin1String("name"), exportString); qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString); - qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType.minorVersion())); + + // TODO: shouldn't this be metaObjectRevision().value<quint16>() + // rather than version().minorVersion() + qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() + << QString::number(compositeType.version().minorVersion())); + qml->writeBooleanBinding(QLatin1String("isComposite"), true); if (compositeType.isSingleton()) { @@ -537,10 +543,10 @@ public: struct QmlTypeInfo { QmlTypeInfo() {} - QmlTypeInfo(const QString &exportString, int revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) + QmlTypeInfo(const QString &exportString, QTypeRevision revision, const QMetaObject *extendedObject, QByteArray attachedTypeId) : exportString(exportString), revision(revision), extendedObject(extendedObject), attachedTypeId(attachedTypeId) {} QString exportString; - int revision = 0; + QTypeRevision revision = QTypeRevision::zero(); const QMetaObject *extendedObject = nullptr; QByteArray attachedTypeId; }; @@ -563,11 +569,11 @@ public: if (attachedType != meta) attachedTypeId = convertToId(attachedType); } - const QString exportString = getExportString(type, { QString(), -1, -1, false }); - int metaObjectRevision = type.metaObjectRevision(); + const QString exportString = getExportString(type, { QString(), QTypeRevision(), false }); + QTypeRevision metaObjectRevision = type.metaObjectRevision(); if (extendedObject) { // emulate custom metaobjectrevision out of import - metaObjectRevision = type.majorVersion() * 100 + type.minorVersion(); + metaObjectRevision = type.version(); } QmlTypeInfo info = { exportString, metaObjectRevision, extendedObject, attachedTypeId }; @@ -576,7 +582,7 @@ public: // sort to ensure stable output std::sort(typeInfo.begin(), typeInfo.end(), [](const QmlTypeInfo &i1, const QmlTypeInfo &i2) { - return i1.revision < i2.revision; + return i1.revision.toEncodedVersion<quint16>() < i2.revision.toEncodedVersion<quint16>(); }); // determine default property @@ -600,7 +606,7 @@ public: if (!typeInfo.isEmpty()) { QMap<QString, QString> exports; // sort exports for (const QmlTypeInfo &iter : typeInfo) - exports.insert(iter.exportString, QString::number(iter.revision)); + exports.insert(iter.exportString, QString::number(iter.revision.toEncodedVersion<quint16>())); QStringList exportStrings = exports.keys(); QStringList metaObjectRevisions = exports.values(); @@ -681,22 +687,27 @@ private: qml->writeScriptBinding(QLatin1String("isPointer"), QLatin1String("true")); } - void dump(const QMetaProperty &prop, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + void dump(const QMetaProperty &prop, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { - int revision = metaRevision ? metaRevision : prop.revision(); + // TODO: should that not be metaRevision.isValid() rather than comparing to zero()? + QTypeRevision revision = (metaRevision == QTypeRevision::zero()) + ? QTypeRevision::fromEncodedVersion(prop.revision()) + : metaRevision; QByteArray propName = prop.name(); if (knownAttributes && knownAttributes->knownProperty(propName, revision)) return; qml->writeStartObject("Property"); qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(prop.name()))); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); writeTypeProperties(prop.typeName(), prop.isWritable()); qml->writeEndObject(); } - QSet<QString> dumpMetaProperties(const QMetaObject *meta, int metaRevision = -1, KnownAttributes *knownAttributes = nullptr) + QSet<QString> dumpMetaProperties(const QMetaObject *meta, QTypeRevision metaRevision = QTypeRevision(), + KnownAttributes *knownAttributes = nullptr) { QSet<QString> implicitSignals; for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) { @@ -704,7 +715,7 @@ private: dump(property, metaRevision, knownAttributes); if (knownAttributes) knownAttributes->knownMethod(QByteArray(property.name()).append("Changed"), - 0, property.revision()); + 0, QTypeRevision::fromEncodedVersion(property.revision())); implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name()))); } return implicitSignals; @@ -732,7 +743,7 @@ private: return; } - int revision = meth.revision(); + QTypeRevision revision = QTypeRevision::fromEncodedVersion(meth.revision()); if (knownAttributes && knownAttributes->knownMethod(name, meth.parameterNames().size(), revision)) return; if (meth.methodType() == QMetaMethod::Signal) @@ -742,8 +753,8 @@ private: qml->writeScriptBinding(QLatin1String("name"), enquote(name)); - if (revision) - qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision)); + if (revision != QTypeRevision::zero()) + qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision.toEncodedVersion<quint16>())); if (typeName != QLatin1String("void")) qml->writeScriptBinding(QLatin1String("type"), enquote(typeName)); @@ -1001,9 +1012,9 @@ static bool operator<(const QQmlType &a, const QQmlType &b) { return a.qmlTypeName() < b.qmlTypeName() || (a.qmlTypeName() == b.qmlTypeName() - && ((a.majorVersion() < b.majorVersion()) - || (a.majorVersion() == b.majorVersion() - && a.minorVersion() < b.minorVersion()))); + && ((a.version().majorVersion() < b.version().majorVersion()) + || (a.version().majorVersion() == b.version().majorVersion() + && a.version().minorVersion() < b.version().minorVersion()))); } QT_END_NAMESPACE @@ -1243,11 +1254,13 @@ int main(int argc, char *argv[]) // composite types we want to dump information of QMap<QString, QList<QQmlType>> compositeTypes; - int majorVersion = qtQmlMajorVersion, minorVersion = qtQmlMinorVersion; + QTypeRevision version = QTypeRevision::fromVersion(qtQmlMajorVersion, qtQmlMinorVersion); QmlVersionInfo info; if (action == Builtins) { QMap<QString, QList<QQmlType>> defaultCompositeTypes; - QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion, strict}); + QSet<const QMetaObject *> builtins = collectReachableMetaObjects( + &engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, + {QLatin1String("Qt"), version, strict}); Q_ASSERT(builtins.size() == 1); metas.insert(*builtins.begin()); } else { @@ -1256,12 +1269,13 @@ int main(int argc, char *argv[]) if (!ok) qCritical("Invalid version number"); else { - majorVersion = versionSplitted.at(0).toInt(&ok); + const int majorVersion = versionSplitted.at(0).toInt(&ok); if (!ok) qCritical("Invalid major version"); - minorVersion = versionSplitted.at(1).toInt(&ok); + const int minorVersion = versionSplitted.at(1).toInt(&ok); if (!ok) qCritical("Invalid minor version"); + version = QTypeRevision::fromVersion(majorVersion, minorVersion); } QList<QQmlType> defaultTypes = QQmlMetaType::qmlTypes(); // find a valid QtQuick import @@ -1273,9 +1287,9 @@ int main(int argc, char *argv[]) } else { QString module = qtObjectType.qmlTypeName(); module = module.mid(0, module.lastIndexOf(QLatin1Char('/'))); - importCode = QString("import %1 %2.%3").arg(module, - QString::number(qtObjectType.majorVersion()), - QString::number(qtObjectType.minorVersion())).toUtf8(); + importCode = QString("import %1 %2.%3").arg( + module, QString::number(qtObjectType.version().majorVersion()), + QString::number(qtObjectType.version().minorVersion())).toUtf8(); } // avoid importing dependencies? for (const QString &moduleToImport : qAsConst(dependencies)) { @@ -1307,7 +1321,7 @@ int main(int argc, char *argv[]) return EXIT_IMPORTERROR; } } - info = {pluginImportUri, majorVersion, minorVersion, strict}; + info = {pluginImportUri, version, strict}; QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, info, defaultTypes); for (auto it = compositeTypes.begin(), end = compositeTypes.end(); it != end; ++it) { diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index 7b010546c3..7c92f428ae 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -354,7 +354,7 @@ bool QmlProfilerApplication::checkOutputFile(PendingRequest pending) void QmlProfilerApplication::userCommand(const QString &command) { - auto args = command.splitRef(QChar::Space, QString::SkipEmptyParts); + auto args = command.splitRef(QChar::Space, Qt::SkipEmptyParts); if (args.isEmpty()) { prompt(); return; diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 28370cb522..b0635a7e87 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -500,7 +500,8 @@ int main(int argc, char ** argv) } } - if (qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE")) + if (qEnvironmentVariableIsSet("QMLSCENE_CORE_PROFILE") + || qEnvironmentVariableIsSet("QSG_CORE_PROFILE")) options.coreProfile = true; // Set default surface format before creating the window diff --git a/tools/qmltestrunner/main.cpp b/tools/qmltestrunner/main.cpp index 687d6fbb01..2463757282 100644 --- a/tools/qmltestrunner/main.cpp +++ b/tools/qmltestrunner/main.cpp @@ -28,9 +28,6 @@ #include <QtQuickTest/quicktest.h> #include <QtCore/qstring.h> -#ifdef QT_OPENGL_LIB -#include <QtOpenGL/qgl.h> -#endif int main(int argc, char **argv) { diff --git a/tools/qmltime/qmltime.cpp b/tools/qmltime/qmltime.cpp index b0761a54d4..ca10fdde53 100644 --- a/tools/qmltime/qmltime.cpp +++ b/tools/qmltime/qmltime.cpp @@ -25,47 +25,18 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + +#include "qmltime.h" + #include <QQmlEngine> -#include <QQmlComponent> #include <QDebug> #include <QGuiApplication> #include <QElapsedTimer> #include <QQmlContext> -#include <QQuickView> #include <QQuickItem> #include <private/qquickview_p.h> -class Timer : public QObject -{ - Q_OBJECT - Q_PROPERTY(QQmlComponent *component READ component WRITE setComponent) - -public: - Timer(); - - QQmlComponent *component() const; - void setComponent(QQmlComponent *); - - static Timer *timerInstance(); - - void run(uint); - - bool willParent() const; - void setWillParent(bool p); - -private: - void runTest(QQmlContext *, uint); - - QQmlComponent *m_component; - static Timer *m_timer; - - bool m_willparent; - QQuickView m_view; - QQuickItem *m_item; -}; -QML_DECLARE_TYPE(Timer); - Timer *Timer::m_timer = nullptr; Timer::Timer() @@ -207,8 +178,6 @@ int main(int argc, char ** argv) QGuiApplication app(argc, argv); QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); - qmlRegisterTypesAndRevisions<Timer>("QmlTime", 1); - uint iterations = 1024; QString filename; bool willParent = false; @@ -269,5 +238,3 @@ int main(int argc, char ** argv) return 0; } - -#include "qmltime.moc" diff --git a/tools/qmltime/qmltime.h b/tools/qmltime/qmltime.h new file mode 100644 index 0000000000..a23dc902e2 --- /dev/null +++ b/tools/qmltime/qmltime.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLTIME_H +#define QMLTIME_H + +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQuick/qquickview.h> + +class Timer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlComponent *component READ component WRITE setComponent) + QML_ELEMENT + +public: + Timer(); + + QQmlComponent *component() const; + void setComponent(QQmlComponent *); + + static Timer *timerInstance(); + + void run(uint); + + bool willParent() const; + void setWillParent(bool p); + +private: + void runTest(QQmlContext *, uint); + + QQmlComponent *m_component; + static Timer *m_timer; + + bool m_willparent; + QQuickView m_view; + QQuickItem *m_item; +}; +QML_DECLARE_TYPE(Timer); + +#endif // QMLTIME_H diff --git a/tools/qmltime/qmltime.pro b/tools/qmltime/qmltime.pro index 04a5fd5957..c915f6e8c1 100644 --- a/tools/qmltime/qmltime.pro +++ b/tools/qmltime/qmltime.pro @@ -4,5 +4,11 @@ QT += qml quick QT += quick-private macx:CONFIG -= app_bundle +CONFIG += qmltypes +QML_IMPORT_NAME = QmlTime +QML_IMPORT_VERSION = 1.0 + QMAKE_TARGET_DESCRIPTION = QML Time + SOURCES += qmltime.cpp +HEADERS += qmltime.h diff --git a/tools/tools.pro b/tools/tools.pro index d16f78071c..07eaa0be70 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -7,11 +7,11 @@ qtConfig(qml-devtools) { qmlimportscanner \ qmlformat - qtConfig(commandlineparser):qtConfig(xmlstreamwriter): SUBDIRS += qmlcachegen + qtConfig(xmlstreamwriter): SUBDIRS += qmlcachegen } qtConfig(thread):!android|android_app:!wasm:!rtems { - qtConfig(commandlineparser): SUBDIRS += qml + SUBDIRS += qml qtConfig(qml-profiler): SUBDIRS += qmlprofiler qtConfig(qml-preview): SUBDIRS += qmlpreview |