aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 18:46:38 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 19:02:37 +0200
commitc2f8b9535d34da6948ccf45b7d5fd90de2f1bc9e (patch)
treec6f7e058a985d7c18b51cadc76283caf555071c9 /tools
parent9e633bbda7608ac0231809e2a6a97ae8f2d849d6 (diff)
parent803f18f02e5609a1ca00a5b78ea6d3613d44e1a0 (diff)
Merge remote-tracking branch 'origin/dev' into wip/cmake
Removed dependencies.yaml because we don't use it yet in wip/cmake. Fixed conflict in qmlcachegen.cpp. Change-Id: Ie1060c737bee1daa85779903598e5b6d5020d922
Diffstat (limited to 'tools')
-rw-r--r--tools/qml/conf.h3
-rw-r--r--tools/qml/main.cpp17
-rw-r--r--tools/qmlcachegen/Qt5QuickCompilerConfig.cmake.in10
-rw-r--r--tools/qmlcachegen/generateloader.cpp233
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp16
-rw-r--r--tools/qmlcachegen/qtquickcompiler.prf45
-rw-r--r--tools/qmlcachegen/resourcefilter.cpp51
-rw-r--r--tools/qmllint/fakemetaobject.cpp14
-rw-r--r--tools/qmllint/fakemetaobject.h3
-rw-r--r--tools/qmllint/findunqualified.cpp205
-rw-r--r--tools/qmllint/findunqualified.h7
-rw-r--r--tools/qmllint/main.cpp9
-rw-r--r--tools/qmllint/qcoloroutput.cpp11
-rw-r--r--tools/qmllint/qcoloroutput_p.h2
-rw-r--r--tools/qmllint/qmljstypedescriptionreader.cpp67
-rw-r--r--tools/qmllint/scopetree.cpp44
-rw-r--r--tools/qmllint/scopetree.h5
-rw-r--r--tools/qmlplugindump/main.cpp74
-rw-r--r--tools/qmlplugindump/qmlstreamwriter.cpp16
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.cpp4
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp1
-rw-r--r--tools/qmltime/qmltime.cpp2
22 files changed, 349 insertions, 490 deletions
diff --git a/tools/qml/conf.h b/tools/qml/conf.h
index 0c9d8613a0..e83d63cba5 100644
--- a/tools/qml/conf.h
+++ b/tools/qml/conf.h
@@ -30,6 +30,7 @@
#include <QtQml/QQmlContext>
#include <QtQml/QQmlListProperty>
+#include <QtQml/qqml.h>
#include <QObject>
#include <QUrl>
@@ -38,6 +39,7 @@ class PartialScene : public QObject
Q_OBJECT
Q_PROPERTY(QUrl container READ container WRITE setContainer NOTIFY containerChanged)
Q_PROPERTY(QString itemType READ itemType WRITE setItemType NOTIFY itemTypeChanged)
+ QML_ELEMENT
public:
PartialScene(QObject *parent = 0) : QObject(parent)
{}
@@ -72,6 +74,7 @@ class Config : public QObject
Q_OBJECT
Q_PROPERTY(QQmlListProperty<PartialScene> sceneCompleters READ sceneCompleters)
Q_CLASSINFO("DefaultProperty", "sceneCompleters")
+ QML_NAMED_ELEMENT(Configuration)
public:
Config (QObject* parent=0) : QObject(parent)
{}
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 9edc90e050..f7d7b98277 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -60,6 +60,7 @@
#include <qqml.h>
#include <qqmldebug.h>
+#include <private/qmemory_p.h>
#include <private/qtqmlglobal_p.h>
#if QT_CONFIG(qml_animation)
#include <private/qabstractanimation_p.h>
@@ -68,6 +69,7 @@
#include <cstdio>
#include <cstring>
#include <cstdlib>
+#include <memory>
#define FILE_OPEN_EVENT_WAIT_TIME 3000 // ms
@@ -398,23 +400,23 @@ static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory)
int main(int argc, char *argv[])
{
getAppFlags(argc, argv);
- QCoreApplication *app = nullptr;
+ std::unique_ptr<QCoreApplication> app;
switch (applicationType) {
#ifdef QT_GUI_LIB
case QmlApplicationTypeGui:
- app = new LoaderApplication(argc, argv);
+ app = qt_make_unique<LoaderApplication>(argc, argv);
break;
#ifdef QT_WIDGETS_LIB
case QmlApplicationTypeWidget:
- app = new QApplication(argc, argv);
- static_cast<QApplication *>(app)->setWindowIcon(QIcon(iconResourcePath));
+ app = qt_make_unique<QApplication>(argc, argv);
+ static_cast<QApplication *>(app.get())->setWindowIcon(QIcon(iconResourcePath));
break;
#endif // QT_WIDGETS_LIB
#endif // QT_GUI_LIB
case QmlApplicationTypeCore:
Q_FALLTHROUGH();
default: // QmlApplicationTypeUnknown: not allowed, but we'll exit after checking apptypeOption below
- app = new QCoreApplication(argc, argv);
+ app = qt_make_unique<QCoreApplication>(argc, argv);
break;
}
@@ -423,8 +425,7 @@ int main(int argc, char *argv[])
app->setOrganizationDomain("qt-project.org");
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
- qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration");
- qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene");
+ qmlRegisterTypesAndRevisions<Config, PartialScene>("QmlRuntime.Config", 1);
QQmlApplicationEngine e;
QStringList files;
QString confFile;
@@ -598,7 +599,7 @@ int main(int argc, char *argv[])
if (files.count() <= 0) {
#if defined(Q_OS_DARWIN)
if (applicationType == QmlApplicationTypeGui)
- exitTimerId = static_cast<LoaderApplication *>(app)->startTimer(FILE_OPEN_EVENT_WAIT_TIME);
+ exitTimerId = static_cast<LoaderApplication *>(app.get())->startTimer(FILE_OPEN_EVENT_WAIT_TIME);
else
#endif
noFilesGiven();
diff --git a/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake.in b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake.in
index 75fbb0fcf3..be2113b258 100644
--- a/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake.in
+++ b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake.in
@@ -50,13 +50,9 @@ but not all the files it references.
get_filename_component(input_resource ${_resource} ABSOLUTE)
- execute_process(COMMAND ${compiler_path} -filter-resource-file ${input_resource} -o ${new_resource_file} OUTPUT_VARIABLE remaining_files)
- if(remaining_files)
- list(APPEND filtered_rcc_files ${new_resource_file})
- list(APPEND loader_flags \"--resource-file-mapping=${_resource}=${new_resource_file}\")
- else()
- list(APPEND loader_flags \"--resource-file-mapping=${_resource}\")
- endif()
+ execute_process(COMMAND ${compiler_path} --filter-resource-file ${input_resource} -o ${new_resource_file} OUTPUT_VARIABLE remaining_files)
+ list(APPEND filtered_rcc_files ${new_resource_file})
+ list(APPEND loader_flags \"--resource-file-mapping=${_resource}=${new_resource_file}\")
set(rcc_file_with_compilation_units)
diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp
index 1c8a5a016a..71286137eb 100644
--- a/tools/qmlcachegen/generateloader.cpp
+++ b/tools/qmlcachegen/generateloader.cpp
@@ -100,228 +100,6 @@ QString symbolNamespaceForPath(const QString &relativePath)
return mangledIdentifier(symbol);
}
-struct VirtualDirectoryEntry
-{
- QString name;
- QVector<VirtualDirectoryEntry*> dirEntries;
- int firstChildIndex = -1; // node index inside generated data
- bool isDirectory = true;
-
- VirtualDirectoryEntry()
- {}
-
- ~VirtualDirectoryEntry()
- {
- qDeleteAll(dirEntries);
- }
-
- VirtualDirectoryEntry *append(const QString &name)
- {
- for (QVector<VirtualDirectoryEntry*>::Iterator it = dirEntries.begin(), end = dirEntries.end();
- it != end; ++it) {
- if ((*it)->name == name)
- return *it;
- }
-
- VirtualDirectoryEntry *subEntry = new VirtualDirectoryEntry;
- subEntry->name = name;
- dirEntries.append(subEntry);
- return subEntry;
- }
-
- void appendEmptyFile(const QString &name)
- {
- VirtualDirectoryEntry *subEntry = new VirtualDirectoryEntry;
- subEntry->name = name;
- subEntry->isDirectory = false;
- dirEntries.append(subEntry);
- }
-
- bool isEmpty() const { return dirEntries.isEmpty(); }
-};
-
-struct DataStream
-{
- DataStream(QVector<unsigned char > *data = nullptr)
- : data(data)
- {}
-
- qint64 currentOffset() const { return data->size(); }
-
- DataStream &operator<<(quint16 value)
- {
- unsigned char d[2];
- qToBigEndian(value, d);
- data->append(d[0]);
- data->append(d[1]);
- return *this;
- }
- DataStream &operator<<(quint32 value)
- {
- unsigned char d[4];
- qToBigEndian(value, d);
- data->append(d[0]);
- data->append(d[1]);
- data->append(d[2]);
- data->append(d[3]);
- return *this;
- }
-private:
- QVector<unsigned char> *data;
-};
-
-static bool resource_sort_order(const VirtualDirectoryEntry *lhs, const VirtualDirectoryEntry *rhs)
-{
- return qt_hash(lhs->name) < qt_hash(rhs->name);
-}
-
-struct ResourceTree
-{
- ResourceTree()
- {}
-
- void serialize(VirtualDirectoryEntry &root, QVector<unsigned char> *treeData, QVector<unsigned char> *stringData)
- {
- treeStream = DataStream(treeData);
- stringStream = DataStream(stringData);
-
- QStack<VirtualDirectoryEntry *> directories;
-
- {
- directories.push(&root);
- while (!directories.isEmpty()) {
- VirtualDirectoryEntry *entry = directories.pop();
- registerString(entry->name);
- if (entry->isDirectory)
- directories << entry->dirEntries;
- }
- }
-
- {
- quint32 currentDirectoryIndex = 1;
- directories.push(&root);
- while (!directories.isEmpty()) {
- VirtualDirectoryEntry *entry = directories.pop();
- entry->firstChildIndex = currentDirectoryIndex;
- currentDirectoryIndex += entry->dirEntries.count();
- std::sort(entry->dirEntries.begin(), entry->dirEntries.end(), resource_sort_order);
-
- for (QVector<VirtualDirectoryEntry*>::ConstIterator child = entry->dirEntries.constBegin(), end = entry->dirEntries.constEnd();
- child != end; ++child) {
- if ((*child)->isDirectory)
- directories << *child;
- }
- }
- }
-
- {
- writeTreeEntry(&root);
- directories.push(&root);
- while (!directories.isEmpty()) {
- VirtualDirectoryEntry *entry = directories.pop();
-
- for (QVector<VirtualDirectoryEntry*>::ConstIterator child = entry->dirEntries.constBegin(), end = entry->dirEntries.constEnd();
- child != end; ++child) {
- writeTreeEntry(*child);
- if ((*child)->isDirectory)
- directories << (*child);
- }
- }
- }
- }
-
-private:
- DataStream treeStream;
- DataStream stringStream;
- QHash<QString, qint64> stringOffsets;
-
- void registerString(const QString &name)
- {
- if (stringOffsets.contains(name))
- return;
- const qint64 offset = stringStream.currentOffset();
- stringOffsets.insert(name, offset);
-
- stringStream << quint16(name.length())
- << quint32(qt_hash(name));
- for (int i = 0; i < name.length(); ++i)
- stringStream << quint16(name.at(i).unicode());
- }
-
- void writeTreeEntry(VirtualDirectoryEntry *entry)
- {
- treeStream << quint32(stringOffsets.value(entry->name))
- << quint16(entry->isDirectory ? 0x2 : 0x0); // Flags: File or Directory
-
- if (entry->isDirectory) {
- treeStream << quint32(entry->dirEntries.count())
- << quint32(entry->firstChildIndex);
- } else {
- treeStream << quint16(QLocale::AnyCountry) << quint16(QLocale::C)
- << quint32(0x0);
- }
- }
-};
-
-static QByteArray generateResourceDirectoryTree(QTextStream &code, const QStringList &qrcFiles,
- const QStringList &sortedRetainedFiles)
-{
- QByteArray call;
- if (qrcFiles.isEmpty())
- return call;
-
- VirtualDirectoryEntry resourceDirs;
- resourceDirs.name = QStringLiteral("/");
-
- for (const QString &entry : qrcFiles) {
- const QStringList segments = entry.split(QLatin1Char('/'), QString::SkipEmptyParts);
-
- VirtualDirectoryEntry *dirEntry = &resourceDirs;
-
- for (int i = 0; i < segments.count() - 1; ++i)
- dirEntry = dirEntry->append(segments.at(i));
- if (!std::binary_search(sortedRetainedFiles.begin(), sortedRetainedFiles.end(), entry))
- dirEntry->appendEmptyFile(segments.last());
- }
-
- if (resourceDirs.isEmpty())
- return call;
-
- QVector<unsigned char> names;
- QVector<unsigned char> tree;
- ResourceTree().serialize(resourceDirs, &tree, &names);
-
- code << "static const unsigned char qt_resource_tree[] = {\n";
- for (int i = 0; i < tree.count(); ++i) {
- code << uint(tree.at(i));
- if (i < tree.count() - 1)
- code << ',';
- if (i % 16 == 0)
- code << '\n';
- }
- code << "};\n";
-
- code << "static const unsigned char qt_resource_names[] = {\n";
- for (int i = 0; i < names.count(); ++i) {
- code << uint(names.at(i));
- if (i < names.count() - 1)
- code << ',';
- if (i % 16 == 0)
- code << '\n';
- }
- code << "};\n";
-
- code << "static const unsigned char qt_resource_empty_payout[] = { 0, 0, 0, 0, 0 };\n";
-
- code << "QT_BEGIN_NAMESPACE\n";
- code << "extern Q_CORE_EXPORT bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);\n";
- code << "QT_END_NAMESPACE\n";
-
- call = "QT_PREPEND_NAMESPACE(qRegisterResourceData)(/*version*/0x01, qt_resource_tree, qt_resource_names, qt_resource_empty_payout);\n";
-
- return call;
-}
-
static QString qtResourceNameForFile(const QString &fileName)
{
QFileInfo fi(fileName);
@@ -332,9 +110,8 @@ static QString qtResourceNameForFile(const QString &fileName)
return name;
}
-bool generateLoader(const QStringList &compiledFiles, const QStringList &sortedRetainedFiles,
- const QString &outputFileName, const QStringList &resourceFileMappings,
- QString *errorString)
+bool generateLoader(const QStringList &compiledFiles, const QString &outputFileName,
+ const QStringList &resourceFileMappings, QString *errorString)
{
QByteArray generatedLoaderCode;
@@ -345,9 +122,6 @@ bool generateLoader(const QStringList &compiledFiles, const QStringList &sortedR
stream << "#include <QtCore/qurl.h>\n";
stream << "\n";
- QByteArray resourceRegisterCall = generateResourceDirectoryTree(stream, compiledFiles,
- sortedRetainedFiles);
-
stream << "namespace QmlCacheGeneratedCode {\n";
for (int i = 0; i < compiledFiles.count(); ++i) {
const QString compiledFile = compiledFiles.at(i);
@@ -385,9 +159,6 @@ bool generateLoader(const QStringList &compiledFiles, const QStringList &sortedR
stream << " registration.lookupCachedQmlUnit = &lookupCachedUnit;\n";
stream << " QQmlPrivate::qmlregister(QQmlPrivate::QmlUnitCacheHookRegistration, &registration);\n";
- if (!resourceRegisterCall.isEmpty())
- stream << resourceRegisterCall;
-
stream << "}\n\n";
stream << "Registry::~Registry() {\n";
stream << " QQmlPrivate::qmlunregister(QQmlPrivate::QmlUnitCacheHookRegistration, quintptr(&lookupCachedUnit));\n";
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index 6e96b88c0c..d1b28c41f5 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -48,9 +48,8 @@
using namespace QQmlJS;
int filterResourceFile(const QString &input, const QString &output);
-bool generateLoader(const QStringList &compiledFiles, const QStringList &retainedFiles,
- const QString &output, const QStringList &resourceFileMappings,
- QString *errorString);
+bool generateLoader(const QStringList &compiledFiles, const QString &output,
+ const QStringList &resourceFileMappings, QString *errorString);
QString symbolNamespaceForPath(const QString &relativePath);
QSet<QString> illegalNames;
@@ -455,8 +454,6 @@ int main(int argc, char **argv)
parser.addOption(resourceFileMappingOption);
QCommandLineOption resourceOption(QStringLiteral("resource"), QCoreApplication::translate("main", "Qt resource file that might later contain one of the compiled files"), QCoreApplication::translate("main", "resource-file-name"));
parser.addOption(resourceOption);
- QCommandLineOption retainOption(QStringLiteral("retain"), QCoreApplication::translate("main", "Qt resource file the contents of which should not be replaced by empty stubs"), QCoreApplication::translate("main", "resource-file-name"));
- parser.addOption(retainOption);
QCommandLineOption resourcePathOption(QStringLiteral("resource-path"), QCoreApplication::translate("main", "Qt resource file path corresponding to the file being compiled"), QCoreApplication::translate("main", "resource-path"));
parser.addOption(resourcePathOption);
QCommandLineOption resourceNameOption(QStringLiteral("resource-name"),
@@ -517,12 +514,9 @@ int main(int argc, char **argv)
if (target == GenerateLoader) {
ResourceFileMapper mapper(sources);
- ResourceFileMapper retain(parser.values(retainOption));
Error error;
- QStringList retainedFiles = retain.qmlCompilerFiles();
- std::sort(retainedFiles.begin(), retainedFiles.end());
- if (!generateLoader(mapper.qmlCompilerFiles(), retainedFiles, outputFileName,
+ if (!generateLoader(mapper.qmlCompilerFiles(), outputFileName,
parser.values(resourceFileMappingOption), &error.message)) {
error.augment(QLatin1String("Error generating loader stub: ")).print();
return EXIT_FAILURE;
@@ -531,10 +525,8 @@ int main(int argc, char **argv)
}
if (target == GenerateLoaderStandAlone) {
- QStringList retainedFiles = parser.values(retainOption);
- retainedFiles.sort();
Error error;
- if (!generateLoader(sources, retainedFiles, outputFileName,
+ if (!generateLoader(sources, outputFileName,
parser.values(resourceNameOption), &error.message)) {
error.augment(QLatin1String("Error generating loader stub: ")).print();
return EXIT_FAILURE;
diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf
index 2f98aadefe..a31a7f5714 100644
--- a/tools/qmlcachegen/qtquickcompiler.prf
+++ b/tools/qmlcachegen/qtquickcompiler.prf
@@ -1,5 +1,15 @@
if(qtc_run|lupdate_run): return()
+!contains(QT, qml) {
+ qt_modules = \
+ $$replace(QT, -private$, _private) \
+ $$replace(QT_PRIVATE, -private$, _private)
+ qt_modules = $$resolve_depends(qt_modules, "QT.", ".depends" ".run_depends")
+ !contains(qt_modules, qml): \
+ return()
+ unset(qt_modules)
+}
+
qtPrepareTool(QML_CACHEGEN, qmlcachegen, _FILTER)
qtPrepareTool(QMAKE_RCC, rcc, _DEP)
@@ -16,20 +26,6 @@ defineReplace(qmlCacheResourceFileOutputName) {
return($${name})
}
-defineTest(qtQuickRetainSources) {
- for(retainedRes, QTQUICK_COMPILER_RETAINED_RESOURCES) {
- equals(1, $$retainedRes): return(true)
- }
- return(false)
-}
-
-defineTest(qtQuickSkippedResourceFile) {
- for(skippedRes, QTQUICK_COMPILER_SKIPPED_RESOURCES) {
- equals(1, $$skippedRes): return(true)
- }
- return(false)
-}
-
# Flatten RESOURCES that may contain individual files or objects
load(resources)
@@ -37,29 +33,14 @@ NEWRESOURCES =
QMLCACHE_RESOURCE_FILES =
for(res, RESOURCES) {
- qtQuickSkippedResourceFile($$res) {
- NEWRESOURCES += $$res
- next()
- }
-
absRes = $$absolute_path($$res, $$_PRO_FILE_PWD_)
rccContents = $$system($$QMAKE_RCC_DEP -list $$system_quote($$absRes),lines)
contains(rccContents,.*\\.js$)|contains(rccContents,.*\\.qml$)|contains(rccContents,.*\\.mjs$) {
new_resource = $$qmlCacheResourceFileOutputName($$res)
mkpath($$dirname(new_resource))
- qtQuickRetainSources($$res) {
- NEWRESOURCES += $$res
- QMLCACHE_LOADER_FLAGS += --retain=$$shell_quote($$absRes)
- } else {
- remaining_files = $$system($$QML_CACHEGEN_FILTER -filter-resource-file \
- -o $$system_quote($$new_resource) $$system_quote($$absRes),lines)
- !isEmpty(remaining_files) {
- NEWRESOURCES += $$new_resource
- QMLCACHE_LOADER_FLAGS += --resource-file-mapping=$$shell_quote($$absRes=$$new_resource)
- } else {
- QMLCACHE_LOADER_FLAGS += --resource-file-mapping=$$shell_quote($$absRes)
- }
- }
+ dummy = $$system($$QML_CACHEGEN_FILTER --filter-resource-file -o $$system_quote($$new_resource) $$system_quote($$absRes))
+ NEWRESOURCES += $$new_resource
+ QMLCACHE_LOADER_FLAGS += --resource-file-mapping=$$shell_quote($$absRes=$$new_resource)
QMLCACHE_RESOURCE_FILES += $$absRes
diff --git a/tools/qmlcachegen/resourcefilter.cpp b/tools/qmlcachegen/resourcefilter.cpp
index 3ad6e9ca0d..261102dcbe 100644
--- a/tools/qmlcachegen/resourcefilter.cpp
+++ b/tools/qmlcachegen/resourcefilter.cpp
@@ -57,8 +57,6 @@ int filterResourceFile(const QString &input, const QString &output)
QXmlStreamWriter writer(&outputString);
writer.setAutoFormatting(true);
- QStringList remainingFiles;
-
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
switch (reader.readNext()) {
@@ -139,47 +137,36 @@ int filterResourceFile(const QString &input, const QString &output)
if (currentFileName.isEmpty())
continue;
- if (!currentFileName.endsWith(QStringLiteral(".qml"))
- && !currentFileName.endsWith(QStringLiteral(".js"))
- && !currentFileName.endsWith(QStringLiteral(".mjs"))) {
- writer.writeStartElement(QStringLiteral("file"));
-
- if (!fileAttributes.hasAttribute(QStringLiteral("alias")))
- fileAttributes.append(QStringLiteral("alias"), currentFileName);
+ writer.writeStartElement(QStringLiteral("file"));
- currentFileName = inputDirectory.absoluteFilePath(currentFileName);
- currentFileName = outputDirectory.relativeFilePath(currentFileName);
+ if (!fileAttributes.hasAttribute(QStringLiteral("alias")))
+ fileAttributes.append(QStringLiteral("alias"), currentFileName);
- remainingFiles << currentFileName;
+ currentFileName = inputDirectory.absoluteFilePath(currentFileName);
+ currentFileName = outputDirectory.relativeFilePath(currentFileName);
- writer.writeAttributes(fileAttributes);
- writer.writeCharacters(currentFileName);
- writer.writeEndElement();
- }
+ writer.writeAttributes(fileAttributes);
+ writer.writeCharacters(currentFileName);
+ writer.writeEndElement();
continue;
default: break;
}
}
- if (!remainingFiles.isEmpty()) {
- QFile outputFile(output);
- if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- fprintf(stderr, "Cannot open %s for writing.\n", qPrintable(output));
- return EXIT_FAILURE;
- }
- const QByteArray outputStringUtf8 = outputString.toUtf8();
- if (outputFile.write(outputStringUtf8) != outputStringUtf8.size())
- return EXIT_FAILURE;
+ QFile outputFile(output);
+ if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ fprintf(stderr, "Cannot open %s for writing.\n", qPrintable(output));
+ return EXIT_FAILURE;
+ }
+ const QByteArray outputStringUtf8 = outputString.toUtf8();
+ if (outputFile.write(outputStringUtf8) != outputStringUtf8.size())
+ return EXIT_FAILURE;
- outputFile.close();
- if (outputFile.error() != QFileDevice::NoError)
- return EXIT_FAILURE;
+ outputFile.close();
+ if (outputFile.error() != QFileDevice::NoError)
+ return EXIT_FAILURE;
- // The build system expects this output if we wrote a qrc file and no output
- // if no files remain.
- fprintf(stdout, "New resource file written with %d files.\n", remainingFiles.count());
- }
return EXIT_SUCCESS;
}
diff --git a/tools/qmllint/fakemetaobject.cpp b/tools/qmllint/fakemetaobject.cpp
index 514bb2fe42..8319ae6713 100644
--- a/tools/qmllint/fakemetaobject.cpp
+++ b/tools/qmllint/fakemetaobject.cpp
@@ -46,8 +46,8 @@ QString FakeMetaEnum::name() const
void FakeMetaEnum::setName(const QString &name)
{ m_name = name; }
-void FakeMetaEnum::addKey(const QString &key, int value)
-{ m_keys.append(key); m_values.append(value); }
+void FakeMetaEnum::addKey(const QString &key)
+{ m_keys.append(key); }
QString FakeMetaEnum::key(int index) const
{ return m_keys.at(index); }
@@ -73,10 +73,6 @@ void FakeMetaEnum::addToHash(QCryptographicHash &hash) const
hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
hash.addData(reinterpret_cast<const char *>(key.constData()), len * sizeof(QChar));
}
- len = m_values.size();
- hash.addData(reinterpret_cast<const char *>(&len), sizeof(len));
- foreach (int value, m_values)
- hash.addData(reinterpret_cast<const char *>(&value), sizeof(value));
}
QString FakeMetaEnum::describe(int baseIndent) const
@@ -84,16 +80,14 @@ QString FakeMetaEnum::describe(int baseIndent) const
QString newLine = QString::fromLatin1("\n") + QString::fromLatin1(" ").repeated(baseIndent);
QString res = QLatin1String("Enum ");
res += name();
- res += QLatin1String(":{");
+ res += QLatin1String(": [");
for (int i = 0; i < keyCount(); ++i) {
res += newLine;
res += QLatin1String(" ");
res += key(i);
- res += QLatin1String(": ");
- res += QString::number(m_values.value(i, -1));
}
res += newLine;
- res += QLatin1Char('}');
+ res += QLatin1Char(']');
return res;
}
diff --git a/tools/qmllint/fakemetaobject.h b/tools/qmllint/fakemetaobject.h
index 4e0ea1f8b3..ae76596343 100644
--- a/tools/qmllint/fakemetaobject.h
+++ b/tools/qmllint/fakemetaobject.h
@@ -46,7 +46,6 @@ namespace LanguageUtils {
class FakeMetaEnum {
QString m_name;
QStringList m_keys;
- QList<int> m_values;
public:
FakeMetaEnum();
@@ -57,7 +56,7 @@ public:
QString name() const;
void setName(const QString &name);
- void addKey(const QString &key, int value);
+ void addKey(const QString &key);
QString key(int index) const;
int keyCount() const;
QStringList keys() const;
diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp
index 27939608d7..ee2a0c38c1 100644
--- a/tools/qmllint/findunqualified.cpp
+++ b/tools/qmllint/findunqualified.cpp
@@ -39,10 +39,18 @@
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qv4codegen_p.h>
+#include <private/qqmldirparser_p.h>
-QDebug operator<<(QDebug dbg, const QQmlJS::AST::SourceLocation &loc);
+static QQmlDirParser createQmldirParserForFile(const QString &filename)
+{
+ QFile f(filename);
+ f.open(QFile::ReadOnly);
+ QQmlDirParser parser;
+ parser.parse(f.readAll());
+ return parser;
+}
-static QQmlJS::TypeDescriptionReader createReaderForFile(QString const &filename)
+static QQmlJS::TypeDescriptionReader createQmltypesReaderForFile(QString const &filename)
{
QFile f(filename);
f.open(QFile::ReadOnly);
@@ -60,13 +68,12 @@ void FindUnqualifiedIDVisitor::leaveEnvironment()
m_currentScope = m_currentScope->parentScope();
}
-enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned };
+enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath };
-QStringList completeQmltypesPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin)
+QStringList completeImportPaths(const QString &uri, const QStringList &basePaths, int vmaj, int vmin)
{
static const QLatin1Char Slash('/');
static const QLatin1Char Backslash('\\');
- static const QLatin1String SlashPluginsDotQmltypes("/plugins.qmltypes");
const QVector<QStringRef> parts = uri.splitRef(QLatin1Char('.'), QString::SkipEmptyParts);
@@ -96,7 +103,7 @@ QStringList completeQmltypesPaths(const QString &uri, const QStringList &basePat
return str;
};
- for (int version = FullyVersioned; version <= Unversioned; ++version) {
+ for (int version = FullyVersioned; version <= BasePath; ++version) {
const QString ver = versionString(vmaj, vmin, static_cast<ImportVersion>(version));
for (const QString &path : basePaths) {
@@ -104,20 +111,23 @@ QStringList completeQmltypesPaths(const QString &uri, const QStringList &basePat
if (!dir.endsWith(Slash) && !dir.endsWith(Backslash))
dir += Slash;
- // append to the end
- qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver + SlashPluginsDotQmltypes;
+ if (version == BasePath) {
+ qmlDirPathsPaths += dir;
+ } else {
+ // append to the end
+ qmlDirPathsPaths += dir + joinStringRefs(parts, Slash) + ver;
+ }
- if (version != Unversioned) {
+ if (version < Unversioned) {
// insert in the middle
for (int index = parts.count() - 2; index >= 0; --index) {
qmlDirPathsPaths += dir + joinStringRefs(parts.mid(0, index + 1), Slash)
+ ver + Slash
- + joinStringRefs(parts.mid(index + 1), Slash) + SlashPluginsDotQmltypes;
+ + joinStringRefs(parts.mid(index + 1), Slash);
}
}
}
}
-
return qmlDirPathsPaths;
}
@@ -130,19 +140,50 @@ void FindUnqualifiedIDVisitor::importHelper(QString id, QString prefix, int majo
m_alreadySeenImports.insert(importId);
}
id = id.replace(QLatin1String("/"), QLatin1String("."));
- auto qmltypesPaths = completeQmltypesPaths(id, m_qmltypeDirs, major, minor);
+ auto qmltypesPaths = completeImportPaths(id, m_qmltypeDirs, major, minor);
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> objects;
QList<QQmlJS::ModuleApiInfo> moduleApis;
QStringList dependencies;
+ static const QLatin1String SlashPluginsDotQmltypes("/plugins.qmltypes");
+ static const QLatin1String SlashQmldir("/qmldir");
for (auto const &qmltypesPath : qmltypesPaths) {
- if (QFile::exists(qmltypesPath)) {
- auto reader = createReaderForFile(qmltypesPath);
- auto succ = reader(&objects, &moduleApis, &dependencies);
- if (!succ) {
- qDebug() << reader.errorMessage();
+ if (QFile::exists(qmltypesPath + SlashQmldir)) {
+ auto reader = createQmldirParserForFile(qmltypesPath + SlashQmldir);
+ const auto imports = reader.imports();
+ for (const QString &import : imports)
+ importHelper(import, prefix, major, minor);
+
+ QHash<QString, LanguageUtils::FakeMetaObject *> qmlComponents;
+ const auto components = reader.components();
+ for (auto it = components.begin(), end = components.end(); it != end; ++it) {
+ const QString filePath = qmltypesPath + QLatin1Char('/') + it->fileName;
+ if (!QFile::exists(filePath)) {
+ m_colorOut.write(QLatin1String("warning: "), Warning);
+ m_colorOut.write(it->fileName + QLatin1String(" is listed as component in ")
+ + qmltypesPath + SlashQmldir
+ + QLatin1String(" but does not exist.\n"));
+ continue;
+ }
+
+ auto mo = qmlComponents.find(it.key());
+ if (mo == qmlComponents.end())
+ mo = qmlComponents.insert(it.key(), localQmlFile2FakeMetaObject(filePath));
+
+ (*mo)->addExport(
+ it.key(), reader.typeNamespace(),
+ LanguageUtils::ComponentVersion(it->majorVersion, it->minorVersion));
}
- break;
+ for (auto it = qmlComponents.begin(), end = qmlComponents.end(); it != end; ++it) {
+ objects.insert(it.key(),
+ QSharedPointer<const LanguageUtils::FakeMetaObject>(it.value()));
+ }
+ }
+ if (QFile::exists(qmltypesPath + SlashPluginsDotQmltypes)) {
+ auto reader = createQmltypesReaderForFile(qmltypesPath + SlashPluginsDotQmltypes);
+ auto succ = reader(&objects, &moduleApis, &dependencies);
+ if (!succ)
+ m_colorOut.writeUncolored(reader.errorMessage());
}
}
for (auto const &dependency : qAsConst(dependencies)) {
@@ -170,7 +211,8 @@ FindUnqualifiedIDVisitor::localQmlFile2FakeMetaObject(QString filePath)
{
using namespace QQmlJS::AST;
auto fake = new LanguageUtils::FakeMetaObject;
- fake->setClassName(QFileInfo { filePath }.baseName());
+ QString baseName = QFileInfo { filePath }.baseName();
+ fake->setClassName(baseName.endsWith(".ui") ? baseName.chopped(3) : baseName);
QFile file(filePath);
if (!file.open(QFile::ReadOnly)) {
return fake;
@@ -273,6 +315,7 @@ FindUnqualifiedIDVisitor::localQmlFile2FakeMetaObject(QString filePath)
auto sourceElement = static_cast<UiSourceElement *>(initMembers->member);
if (FunctionExpression *fexpr = sourceElement->sourceElement->asFunctionDefinition()) {
LanguageUtils::FakeMetaMethod method;
+ method.setMethodName(fexpr->name.toString());
method.setMethodType(LanguageUtils::FakeMetaMethod::Method);
FormalParameterList *parameters = fexpr->formals;
while (parameters) {
@@ -290,13 +333,17 @@ FindUnqualifiedIDVisitor::localQmlFile2FakeMetaObject(QString filePath)
} else if (cast<VariableStatement *>(sourceElement->sourceElement)) {
// nothing to do
} else {
- qDebug() << "unsupportedd sourceElement at" << sourceElement->firstSourceLocation()
- << sourceElement->sourceElement->kind;
+ const auto loc = sourceElement->firstSourceLocation();
+ m_colorOut.writeUncolored(
+ "unsupportedd sourceElement at "
+ + QString::fromLatin1("%1:%2: ").arg(loc.startLine).arg(loc.startColumn)
+ + QString::number(sourceElement->sourceElement->kind));
}
break;
}
default: {
- qDebug() << "unsupported element of kind" << initMembers->member->kind;
+ m_colorOut.writeUncolored("unsupported element of kind "
+ + QString::number(initMembers->member->kind));
}
}
initMembers = initMembers->next;
@@ -304,6 +351,22 @@ FindUnqualifiedIDVisitor::localQmlFile2FakeMetaObject(QString filePath)
return fake;
}
+void FindUnqualifiedIDVisitor::importDirectory(const QString &directory, const QString &prefix)
+{
+ QString dirname = directory;
+ QFileInfo info { dirname };
+ if (info.isRelative())
+ dirname = QDir(QFileInfo { m_filePath }.path()).filePath(dirname);
+
+ QDirIterator it { dirname, QStringList() << QLatin1String("*.qml"), QDir::NoFilter };
+ while (it.hasNext()) {
+ LanguageUtils::FakeMetaObject *fake = localQmlFile2FakeMetaObject(it.next());
+ m_exportedName2MetaObject.insert(
+ prefix + fake->className(),
+ QSharedPointer<const LanguageUtils::FakeMetaObject>(fake));
+ }
+}
+
void FindUnqualifiedIDVisitor::importExportedNames(QStringRef prefix, QString name)
{
for (;;) {
@@ -348,11 +411,10 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiProgram *)
QDirIterator it { dir, QStringList() << QLatin1String("builtins.qmltypes"), QDir::NoFilter,
QDirIterator::Subdirectories };
while (it.hasNext()) {
- auto reader = createReaderForFile(it.next());
+ auto reader = createQmltypesReaderForFile(it.next());
auto succ = reader(&objects, &moduleApis, &dependencies);
- if (!succ) {
- qDebug() << reader.errorMessage();
- }
+ if (!succ)
+ m_colorOut.writeUncolored(reader.errorMessage());
}
}
// add builtins
@@ -377,6 +439,8 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiProgram *)
meta->addProperty(LanguageUtils::FakeMetaProperty {"ignoreUnknownSignals", "bool", false, false, false, 0});
meta->addProperty(LanguageUtils::FakeMetaProperty {"target", "QObject", false, false, false, 0});
m_exportedName2MetaObject["Connections"] = LanguageUtils::FakeMetaObject::ConstPtr { meta };
+
+ importDirectory(".", QString());
return true;
}
@@ -476,6 +540,23 @@ void FindUnqualifiedIDVisitor::endVisit(QQmlJS::AST::WithStatement *)
leaveEnvironment();
}
+static QString signalName(const QStringRef &handlerName)
+{
+ if (handlerName.startsWith("on") && handlerName.size() > 2) {
+ QString signal = handlerName.mid(2).toString();
+ for (int i = 0; i < signal.length(); ++i) {
+ QCharRef ch = signal[i];
+ if (ch.isLower())
+ return QString();
+ if (ch.isUpper()) {
+ ch = ch.toLower();
+ return signal;
+ }
+ }
+ }
+ return QString();
+}
+
bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiScriptBinding *uisb)
{
using namespace QQmlJS::AST;
@@ -489,8 +570,17 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiScriptBinding *uisb)
if (m_currentScope->isVisualRootScope()) {
m_rootId = identexp->name.toString();
}
- } else if (name.startsWith("on") && name.size() > 2 && name.at(2).isUpper()) {
- auto statement = uisb->statement;
+ } else {
+ const QString signal = signalName(name);
+ if (signal.isEmpty())
+ return true;
+
+ if (!m_currentScope->methods().contains(signal)) {
+ m_currentScope->addUnmatchedSignalHandler(name.toString(), uisb->firstSourceLocation());
+ return true;
+ }
+
+ const auto statement = uisb->statement;
if (statement->kind == Node::Kind::Kind_ExpressionStatement) {
if (static_cast<ExpressionStatement *>(statement)->expression->asFunctionDefinition()) {
// functions are already handled
@@ -499,17 +589,14 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiScriptBinding *uisb)
return true;
}
}
- QString signal = name.mid(2).toString();
- signal[0] = signal[0].toLower();
- if (!m_currentScope->methods().contains(signal)) {
- qDebug() << "Info file does not contain signal" << signal;
- } else {
- auto method = m_currentScope->methods()[signal];
- for (auto const &param : method.parameterNames()) {
- auto firstSourceLocation = uisb->statement->firstSourceLocation();
- bool hasMultilineStatementBody = uisb->statement->lastSourceLocation().startLine > firstSourceLocation.startLine;
- m_currentScope->insertSignalIdentifier(param, method, firstSourceLocation, hasMultilineStatementBody);
- }
+
+ auto method = m_currentScope->methods()[signal];
+ for (auto const &param : method.parameterNames()) {
+ const auto firstSourceLocation = statement->firstSourceLocation();
+ bool hasMultilineStatementBody
+ = statement->lastSourceLocation().startLine > firstSourceLocation.startLine;
+ m_currentScope->insertSignalIdentifier(param, method, firstSourceLocation,
+ hasMultilineStatementBody);
}
return true;
}
@@ -535,13 +622,15 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::IdentifierExpression *idexp)
}
FindUnqualifiedIDVisitor::FindUnqualifiedIDVisitor(QStringList const &qmltypeDirs,
- const QString &code, const QString &fileName)
+ const QString &code, const QString &fileName,
+ bool silent)
: m_rootScope(new ScopeTree { ScopeType::JSFunctionScope, "global" }),
m_currentScope(m_rootScope.get()),
m_qmltypeDirs(qmltypeDirs),
m_code(code),
m_rootId(QLatin1String("<id>")),
- m_filePath(fileName)
+ m_filePath(fileName),
+ m_colorOut(silent)
{
// setup color output
m_colorOut.insertColorMapping(Error, ColorOutput::RedForeground);
@@ -649,18 +738,9 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import)
prefix += import->importId + QLatin1Char('.');
}
auto dirname = import->fileName.toString();
- if (!dirname.isEmpty()) {
- QFileInfo info { dirname };
- if (info.isRelative()) {
- dirname = QDir(QFileInfo { m_filePath }.path()).filePath(dirname);
- }
- QDirIterator it { dirname, QStringList() << QLatin1String("*.qml"), QDir::NoFilter };
- while (it.hasNext()) {
- LanguageUtils::FakeMetaObject *fake = localQmlFile2FakeMetaObject(it.next());
- m_exportedName2MetaObject.insert(
- fake->className(), QSharedPointer<const LanguageUtils::FakeMetaObject>(fake));
- }
- }
+ if (!dirname.isEmpty())
+ importDirectory(dirname, prefix);
+
QString path {};
if (!import->importId.isEmpty()) {
m_qmlid2meta.insert(import->importId.toString(), {}); // TODO: do not put imported ids into the same space as qml IDs
@@ -768,16 +848,19 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiObjectDefinition *uiod)
return true;
}
-void FindUnqualifiedIDVisitor::endVisit(QQmlJS::AST::UiObjectDefinition *)
+bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::PatternElement *element)
{
- leaveEnvironment();
+ if (element->isVariableDeclaration()) {
+ QQmlJS::AST::BoundNames names;
+ element->boundNames(&names);
+ for (const auto &name : names)
+ m_currentScope->insertJSIdentifier(name.id, element->scope);
+ }
+
+ return true;
}
-QDebug operator<<(QDebug dbg, const QQmlJS::AST::SourceLocation &loc)
+void FindUnqualifiedIDVisitor::endVisit(QQmlJS::AST::UiObjectDefinition *)
{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << loc.startLine;
- dbg.nospace() << ":";
- dbg.nospace() << loc.startColumn;
- return dbg.maybeSpace();
+ leaveEnvironment();
}
diff --git a/tools/qmllint/findunqualified.h b/tools/qmllint/findunqualified.h
index 181f42f265..80413bd402 100644
--- a/tools/qmllint/findunqualified.h
+++ b/tools/qmllint/findunqualified.h
@@ -43,7 +43,8 @@ enum class ScopeType;
class FindUnqualifiedIDVisitor : public QQmlJS::AST::Visitor {
public:
- explicit FindUnqualifiedIDVisitor(QStringList const &qmltypeDirs, const QString& code, const QString& fileName);
+ explicit FindUnqualifiedIDVisitor(QStringList const &qmltypeDirs, const QString& code,
+ const QString& fileName, bool silent);
~FindUnqualifiedIDVisitor() override;
bool check();
@@ -70,7 +71,7 @@ private:
void importHelper(QString id, QString prefix, int major, int minor);
LanguageUtils::FakeMetaObject* localQmlFile2FakeMetaObject(QString filePath);
-
+ void importDirectory(const QString &directory, const QString &prefix);
void importExportedNames(QStringRef prefix, QString name);
void throwRecursionDepthError() override;
@@ -125,6 +126,8 @@ private:
// expression handling
bool visit(QQmlJS::AST::IdentifierExpression *idexp) override;
+
+ bool visit(QQmlJS::AST::PatternElement *) override;
};
diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp
index 235ec16c6e..56f72dd020 100644
--- a/tools/qmllint/main.cpp
+++ b/tools/qmllint/main.cpp
@@ -50,7 +50,8 @@ static bool lint_file(const QString &filename, const bool silent, const bool war
{
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
- qWarning() << "Failed to open file" << filename << file.error();
+ if (!silent)
+ qWarning() << "Failed to open file" << filename << file.error();
return false;
}
@@ -76,7 +77,7 @@ static bool lint_file(const QString &filename, const bool silent, const bool war
if (success && !isJavaScript && warnUnqualied) {
auto root = parser.rootNode();
- FindUnqualifiedIDVisitor v { qmltypeDirs, code, filename};
+ FindUnqualifiedIDVisitor v { qmltypeDirs, code, filename, silent };
root->accept(&v);
success = v.check();
}
@@ -122,9 +123,9 @@ int main(int argv, char *argc[])
// use host qml import path as a sane default if nothing else has been provided
QStringList qmltypeDirs = parser.isSet(qmltypesDirsOption) ? parser.values(qmltypesDirsOption)
#ifndef QT_BOOTSTRAPPED
- : QStringList{QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath)};
+ : QStringList{QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath), QLatin1String(".")};
#else
- : QStringList{};
+ : QStringList{QLatin1String(".")};
#endif
#else
bool silent = false;
diff --git a/tools/qmllint/qcoloroutput.cpp b/tools/qmllint/qcoloroutput.cpp
index d2e723700a..eb4c721663 100644
--- a/tools/qmllint/qcoloroutput.cpp
+++ b/tools/qmllint/qcoloroutput.cpp
@@ -39,7 +39,7 @@
class ColorOutputPrivate
{
public:
- ColorOutputPrivate() : currentColorID(-1)
+ ColorOutputPrivate(bool silent) : currentColorID(-1), silent(silent)
{
/* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance
@@ -53,6 +53,7 @@ public:
ColorOutput::ColorMapping colorMapping;
int currentColorID;
bool coloringEnabled;
+ bool silent;
static const char *const foregrounds[];
static const char *const backgrounds[];
@@ -238,7 +239,7 @@ ColorOutput::ColorMapping ColorOutput::colorMapping() const
/*!
Constructs a ColorOutput instance, ready for use.
*/
-ColorOutput::ColorOutput() : d(new ColorOutputPrivate())
+ColorOutput::ColorOutput(bool silent) : d(new ColorOutputPrivate(silent))
{
}
@@ -258,7 +259,8 @@ ColorOutput::~ColorOutput() = default; // must be here so that QScopedPointer ha
*/
void ColorOutput::write(const QString &message, int colorID)
{
- d->write(colorify(message, colorID));
+ if (!d->silent)
+ d->write(colorify(message, colorID));
}
/*!
@@ -269,7 +271,8 @@ void ColorOutput::write(const QString &message, int colorID)
*/
void ColorOutput::writeUncolored(const QString &message)
{
- d->write(message + QLatin1Char('\n'));
+ if (!d->silent)
+ d->write(message + QLatin1Char('\n'));
}
/*!
diff --git a/tools/qmllint/qcoloroutput_p.h b/tools/qmllint/qcoloroutput_p.h
index 710bf5db74..aefa765a87 100644
--- a/tools/qmllint/qcoloroutput_p.h
+++ b/tools/qmllint/qcoloroutput_p.h
@@ -89,7 +89,7 @@ public:
typedef QFlags<ColorCodeComponent> ColorCode;
typedef QHash<int, ColorCode> ColorMapping;
- ColorOutput();
+ ColorOutput(bool silent);
~ColorOutput();
void setColorMapping(const ColorMapping &cMapping);
diff --git a/tools/qmllint/qmljstypedescriptionreader.cpp b/tools/qmllint/qmljstypedescriptionreader.cpp
index 542cdf99eb..b8aecdddb1 100644
--- a/tools/qmllint/qmljstypedescriptionreader.cpp
+++ b/tools/qmllint/qmljstypedescriptionreader.cpp
@@ -123,15 +123,13 @@ void TypeDescriptionReader::readDocument(UiProgram *ast)
return;
}
- ComponentVersion version;
- const QString versionString = _source.mid(import->versionToken.offset, import->versionToken.length);
- const int dotIdx = versionString.indexOf(QLatin1Char('.'));
- if (dotIdx != -1) {
- version = ComponentVersion(versionString.leftRef(dotIdx).toInt(),
- versionString.midRef(dotIdx + 1).toInt());
- }
- if (version.majorVersion() != 1) {
- addError(import->versionToken, tr("Major version different from 1 not supported."));
+ if (!import->version) {
+ addError(import->firstSourceLocation(), tr("Import statement without version."));
+ return;
+ }
+
+ if (import->version->majorVersion != 1) {
+ addError(import->version->firstSourceLocation(), tr("Major version different from 1 not supported."));
return;
}
@@ -666,39 +664,34 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
return;
}
- ExpressionStatement *expStmt = AST::cast<ExpressionStatement *>(ast->statement);
+ auto *expStmt = AST::cast<ExpressionStatement *>(ast->statement);
if (!expStmt) {
- addError(ast->statement->firstSourceLocation(), tr("Expected object literal after colon."));
+ addError(ast->statement->firstSourceLocation(), tr("Expected expression after colon."));
return;
}
- ObjectPattern *objectLit = AST::cast<ObjectPattern *>(expStmt->expression);
- if (!objectLit) {
- addError(expStmt->firstSourceLocation(), tr("Expected object literal after colon."));
- return;
- }
-
- for (PatternPropertyList *it = objectLit->properties; it; it = it->next) {
- PatternProperty *assignement = AST::cast<PatternProperty *>(it->property);
- if (assignement) {
- StringLiteralPropertyName *propName = AST::cast<StringLiteralPropertyName *>(assignement->name);
- NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->initializer);
- UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->initializer);
- if (minus)
- value = AST::cast<NumericLiteral *>(minus->expression);
- if (!propName || !value) {
- addError(objectLit->firstSourceLocation(), tr("Expected object literal to contain only 'string: number' elements."));
- continue;
+ if (auto *objectLit = AST::cast<ObjectPattern *>(expStmt->expression)) {
+ for (PatternPropertyList *it = objectLit->properties; it; it = it->next) {
+ if (PatternProperty *assignement = it->property) {
+ if (auto *name = AST::cast<StringLiteralPropertyName *>(assignement->name)) {
+ fme->addKey(name->id.toString());
+ continue;
+ }
}
-
- double v = value->value;
- if (minus)
- v = -v;
- fme->addKey(propName->id.toString(), v);
- continue;
+ addError(it->firstSourceLocation(), tr("Expected strings as enum keys."));
+ }
+ } else if (auto *arrayLit = AST::cast<ArrayPattern *>(expStmt->expression)) {
+ for (PatternElementList *it = arrayLit->elements; it; it = it->next) {
+ if (PatternElement *element = it->element) {
+ if (auto *name = AST::cast<StringLiteral *>(element->initializer)) {
+ fme->addKey(name->value.toString());
+ continue;
+ }
+ }
+ addError(it->firstSourceLocation(), tr("Expected strings as enum keys."));
}
- PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
- if (getterSetter)
- addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements."));
+ } else {
+ addError(ast->statement->firstSourceLocation(),
+ tr("Expected either array or object literal as enum definition."));
}
}
diff --git a/tools/qmllint/scopetree.cpp b/tools/qmllint/scopetree.cpp
index 2eff3fa319..1e873cca8f 100644
--- a/tools/qmllint/scopetree.cpp
+++ b/tools/qmllint/scopetree.cpp
@@ -81,6 +81,12 @@ void ScopeTree::insertPropertyIdentifier(QString id)
this->addMethod(method);
}
+void ScopeTree::addUnmatchedSignalHandler(const QString &handler,
+ const QQmlJS::AST::SourceLocation &location)
+{
+ m_unmatchedSignalHandlers.append(qMakePair(handler, location));
+}
+
bool ScopeTree::isIdInCurrentScope(const QString &id) const
{
return isIdInCurrentQMlScopes(id) || isIdInCurrentJSScopes(id);
@@ -132,6 +138,15 @@ bool ScopeTree::recheckIdentifiers(const QString& code, const QHash<QString, Lan
workQueue.enqueue(this);
while (!workQueue.empty()) {
const ScopeTree* currentScope = workQueue.dequeue();
+ for (const auto &handler : currentScope->m_unmatchedSignalHandlers) {
+ colorOut.write("Warning: ", Warning);
+ colorOut.write(QString::fromLatin1(
+ "no matching signal found for handler \"%1\" at %2:%3\n")
+ .arg(handler.first).arg(handler.second.startLine)
+ .arg(handler.second.startColumn), Normal);
+ printContext(colorOut, code, handler.second);
+ }
+
for (auto idLocationPair : currentScope->m_accessedIdentifiers) {
if (qmlIDs.contains(idLocationPair.first))
continue;
@@ -141,13 +156,11 @@ bool ScopeTree::recheckIdentifiers(const QString& code, const QHash<QString, Lan
noUnqualifiedIdentifier = false;
colorOut.write("Warning: ", Warning);
auto location = idLocationPair.second;
- colorOut.write(QString::asprintf("unqualified access at %d:%d\n", location.startLine, location.startColumn), Normal);
- IssueLocationWithContext issueLocationWithContext {code, location};
- colorOut.write(issueLocationWithContext.beforeText.toString(), Normal);
- colorOut.write(issueLocationWithContext.issueText.toString(), Error);
- colorOut.write(issueLocationWithContext.afterText.toString() + QLatin1Char('\n'), Normal);
- int tabCount = issueLocationWithContext.beforeText.count(QLatin1Char('\t'));
- colorOut.write(QString(" ").repeated(issueLocationWithContext.beforeText.length() - tabCount) + QString("\t").repeated(tabCount) + QString("^").repeated(location.length) + QLatin1Char('\n'), Normal);
+ colorOut.write(QString::asprintf("unqualified access at %d:%d\n", location.startLine,
+ location.startColumn), Normal);
+
+ printContext(colorOut, code, location);
+
// root(JS) --> program(qml) --> (first element)
if (root->m_childScopes[0]->m_childScopes[0]->m_currentScopeQMLIdentifiers.contains(idLocationPair.first)) {
ScopeTree *parentScope = currentScope->m_parentScope;
@@ -161,6 +174,7 @@ bool ScopeTree::recheckIdentifiers(const QString& code, const QHash<QString, Lan
colorOut.write("Note: ", Warning);
colorOut.write(("You first have to give the root element an id\n"));
}
+ IssueLocationWithContext issueLocationWithContext {code, location};
colorOut.write(issueLocationWithContext.beforeText.toString(), Normal);
colorOut.write(rootId + QLatin1Char('.'), Hint);
colorOut.write(issueLocationWithContext.issueText.toString(), Normal);
@@ -212,7 +226,7 @@ QMap<QString, LanguageUtils::FakeMetaMethod>const &ScopeTree::methods() const
bool ScopeTree::isIdInCurrentQMlScopes(QString id) const
{
auto qmlScope = getCurrentQMLScope();
- return qmlScope->m_currentScopeQMLIdentifiers.contains(id);
+ return qmlScope->m_currentScopeQMLIdentifiers.contains(id) || qmlScope->m_methods.contains(id);
}
bool ScopeTree::isIdInCurrentJSScopes(QString id) const
@@ -250,6 +264,20 @@ ScopeTree *ScopeTree::getCurrentQMLScope()
return qmlScope;
}
+void ScopeTree::printContext(ColorOutput &colorOut, const QString &code,
+ const QQmlJS::AST::SourceLocation &location) const
+{
+ IssueLocationWithContext issueLocationWithContext {code, location};
+ colorOut.write(issueLocationWithContext.beforeText.toString(), Normal);
+ colorOut.write(issueLocationWithContext.issueText.toString(), Error);
+ colorOut.write(issueLocationWithContext.afterText.toString() + QLatin1Char('\n'), Normal);
+ int tabCount = issueLocationWithContext.beforeText.count(QLatin1Char('\t'));
+ colorOut.write(QString(" ").repeated(issueLocationWithContext.beforeText.length() - tabCount)
+ + QString("\t").repeated(tabCount)
+ + QString("^").repeated(location.length)
+ + QLatin1Char('\n'), Normal);
+}
+
ScopeType ScopeTree::scopeType() {return m_scopeType;}
void ScopeTree::addMethod(LanguageUtils::FakeMetaMethod method)
diff --git a/tools/qmllint/scopetree.h b/tools/qmllint/scopetree.h
index 872a509123..52cdc45e96 100644
--- a/tools/qmllint/scopetree.h
+++ b/tools/qmllint/scopetree.h
@@ -73,6 +73,8 @@ public:
void insertQMLIdentifier(QString id);
void insertSignalIdentifier(QString id, LanguageUtils::FakeMetaMethod method, QQmlJS::AST::SourceLocation loc, bool hasMultilineHandlerBody);
void insertPropertyIdentifier(QString id); // inserts property as qml identifier as well as the corresponding
+ void addUnmatchedSignalHandler(const QString &handler,
+ const QQmlJS::AST::SourceLocation &location);
bool isIdInCurrentScope(QString const &id) const;
void addIdToAccssedIfNotInParentScopes(QPair<QString, QQmlJS::AST::SourceLocation> const& id_loc_pair, const QSet<QString>& unknownImports);
@@ -96,11 +98,14 @@ private:
ScopeTree *m_parentScope;
QString m_name;
ScopeType m_scopeType;
+ QVector<QPair<QString, QQmlJS::AST::SourceLocation>> m_unmatchedSignalHandlers;
bool isIdInCurrentQMlScopes(QString id) const;
bool isIdInCurrentJSScopes(QString id) const;
bool isIdInjectedFromSignal(QString id) const;
const ScopeTree* getCurrentQMLScope() const;
ScopeTree* getCurrentQMLScope();
+ void printContext(ColorOutput& colorOut, const QString &code,
+ const QQmlJS::AST::SourceLocation &location) const;
};
#endif // SCOPETREE_H
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index f0ed1f8ebe..5e999c557a 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -105,12 +105,18 @@ struct QmlVersionInfo
QString pluginImportUri;
int majorVersion;
int minorVersion;
+ bool strict;
};
static bool matchingImportUri(const QQmlType &ty, const QmlVersionInfo& versionInfo) {
- return (versionInfo.pluginImportUri == ty.module()
- && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1))
- || ty.module().isEmpty();
+ if (versionInfo.strict) {
+ return (versionInfo.pluginImportUri == ty.module()
+ && (ty.majorVersion() == versionInfo.majorVersion || ty.majorVersion() == -1))
+ || ty.module().isEmpty();
+ }
+ return ty.module().isEmpty()
+ || versionInfo.pluginImportUri == ty.module()
+ || ty.module().startsWith(versionInfo.pluginImportUri + QLatin1Char('.'));
}
void collectReachableMetaObjects(const QMetaObject *meta, QSet<const QMetaObject *> *metas, const QmlVersionInfo &info, bool extended = false, bool alreadyChangedModule = false)
@@ -230,14 +236,14 @@ QByteArray convertToId(const QMetaObject *mo)
// Collect all metaobjects for types registered with qmlRegisterType() without parameters
void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<const QMetaObject *>& metas,
- QMap<QString, QSet<QQmlType>> &compositeTypes, const QmlVersionInfo &info) {
+ QMap<QString, QList<QQmlType>> &compositeTypes, const QmlVersionInfo &info) {
const auto qmlAllTypes = QQmlMetaType::qmlAllTypes();
for (const QQmlType &ty : qmlAllTypes) {
if (!metas.contains(ty.baseMetaObject())) {
if (!ty.isComposite()) {
collectReachableMetaObjects(engine, ty, &metas, info);
} else if (matchingImportUri(ty, info)) {
- compositeTypes[ty.elementName()].insert(ty);
+ compositeTypes[ty.elementName()].append(ty);
}
}
}
@@ -246,7 +252,7 @@ void collectReachableMetaObjectsWithoutQmlName(QQmlEnginePrivate *engine, QSet<c
QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
QSet<const QMetaObject *> &noncreatables,
QSet<const QMetaObject *> &singletons,
- QMap<QString, QSet<QQmlType>> &compositeTypes,
+ QMap<QString, QList<QQmlType>> &compositeTypes,
const QmlVersionInfo &info,
const QList<QQmlType> &skip = QList<QQmlType>()
)
@@ -266,7 +272,7 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
qmlTypesByCppName[ty.baseMetaObject()->className()].insert(ty);
collectReachableMetaObjects(QQmlEnginePrivate::get(engine), ty, &metas, info);
} else {
- compositeTypes[ty.elementName()].insert(ty);
+ compositeTypes[ty.elementName()].append(ty);
}
}
@@ -436,10 +442,11 @@ public:
}
QString getPrototypeNameForCompositeType(const QMetaObject *metaObject, QSet<QByteArray> &defaultReachableNames,
- QList<const QMetaObject *> *objectsToMerge)
+ QList<const QMetaObject *> *objectsToMerge, const QmlVersionInfo &versionInfo)
{
+ auto ty = QQmlMetaType::qmlType(metaObject);
QString prototypeName;
- if (!defaultReachableNames.contains(metaObject->className())) {
+ if (matchingImportUri(ty, versionInfo)) {
// dynamic meta objects can break things badly
// but extended types are usually fine
const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate *>(metaObject->d.data);
@@ -451,20 +458,20 @@ public:
prototypeName = "QObject";
else
prototypeName = getPrototypeNameForCompositeType(
- superMetaObject, defaultReachableNames, objectsToMerge);
+ superMetaObject, defaultReachableNames, objectsToMerge, versionInfo);
} else {
prototypeName = convertToId(metaObject->className());
}
return prototypeName;
}
- void dumpComposite(QQmlEngine *engine, const QSet<QQmlType> &compositeType, QSet<QByteArray> &defaultReachableNames)
+ void dumpComposite(QQmlEngine *engine, const QList<QQmlType> &compositeType, QSet<QByteArray> &defaultReachableNames, const QmlVersionInfo &versionInfo)
{
for (const QQmlType &type : compositeType)
- dumpCompositeItem(engine, type, defaultReachableNames);
+ dumpCompositeItem(engine, type, defaultReachableNames, versionInfo);
}
- void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet<QByteArray> &defaultReachableNames)
+ void dumpCompositeItem(QQmlEngine *engine, const QQmlType &compositeType, QSet<QByteArray> &defaultReachableNames, const QmlVersionInfo &versionInfo)
{
QQmlComponent e(engine, compositeType.sourceUrl());
if (!e.isReady()) {
@@ -486,7 +493,7 @@ public:
KnownAttributes knownAttributes;
// Get C++ base class name for the composite type
QString prototypeName = getPrototypeNameForCompositeType(mainMeta, defaultReachableNames,
- &objectsToMerge);
+ &objectsToMerge, versionInfo);
qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
QString qmlTyName = compositeType.qmlTypeName();
@@ -991,6 +998,16 @@ void printDebugMessage(QtMsgType, const QMessageLogContext &, const QString &msg
// In case of QtFatalMsg the calling code will abort() when appropriate.
}
+QT_BEGIN_NAMESPACE
+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())));
+}
+QT_END_NAMESPACE
int main(int argc, char *argv[])
{
@@ -1056,6 +1073,7 @@ int main(int argc, char *argv[])
QString dependenciesFile;
QString mergeFile;
bool forceQtQuickDependency = true;
+ bool strict = false;
enum Action { Uri, Path, Builtins };
Action action = Uri;
{
@@ -1120,6 +1138,10 @@ int main(int argc, char *argv[])
} else if (arg == QLatin1String("--qapp")
|| arg == QLatin1String("-qapp")) {
continue;
+ } else if (arg == QLatin1String("--strict")
+ || arg == QLatin1String("-strict")) {
+ strict = true;
+ continue;
} else {
std::cerr << "Invalid argument: " << qPrintable(arg) << std::endl;
return EXIT_INVALIDARGUMENTS;
@@ -1216,7 +1238,6 @@ int main(int argc, char *argv[])
// find all QMetaObjects reachable from the builtin module
QSet<const QMetaObject *> uncreatableMetas;
QSet<const QMetaObject *> singletonMetas;
- QMap<QString, QSet<QQmlType>> defaultCompositeTypes;
// QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
QSet<QByteArray> defaultReachableNames;
@@ -1225,11 +1246,13 @@ int main(int argc, char *argv[])
QSet<const QMetaObject *> metas;
// composite types we want to dump information of
- QMap<QString, QSet<QQmlType>> compositeTypes;
+ QMap<QString, QList<QQmlType>> compositeTypes;
int majorVersion = qtQmlMajorVersion, minorVersion = qtQmlMinorVersion;
+ QmlVersionInfo info;
if (action == Builtins) {
- QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion});
+ QMap<QString, QList<QQmlType>> defaultCompositeTypes;
+ QSet<const QMetaObject *> builtins = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, defaultCompositeTypes, {QLatin1String("Qt"), majorVersion, minorVersion, strict});
Q_ASSERT(builtins.size() == 1);
metas.insert(*builtins.begin());
} else {
@@ -1289,15 +1312,12 @@ int main(int argc, char *argv[])
return EXIT_IMPORTERROR;
}
}
+ info = {pluginImportUri, majorVersion, minorVersion, strict};
+ QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, info, defaultTypes);
- QSet<const QMetaObject *> candidates = collectReachableMetaObjects(&engine, uncreatableMetas, singletonMetas, compositeTypes, {pluginImportUri, majorVersion, minorVersion}, defaultTypes);
-
- for (QString iter: compositeTypes.keys()) {
- if (defaultCompositeTypes.contains(iter)) {
- QSet<QQmlType> compositeTypesByName = compositeTypes.value(iter);
- compositeTypesByName.subtract(defaultCompositeTypes.value(iter));
- compositeTypes[iter] = compositeTypesByName;
- }
+ for (auto it = compositeTypes.begin(), end = compositeTypes.end(); it != end; ++it) {
+ std::sort(it->begin(), it->end());
+ it->erase(std::unique(it->begin(), it->end()), it->end());
}
for (const QMetaObject *mo : qAsConst(candidates)) {
@@ -1348,9 +1368,9 @@ int main(int argc, char *argv[])
dumper.dump(QQmlEnginePrivate::get(&engine), meta, uncreatableMetas.contains(meta), singletonMetas.contains(meta));
}
- QMap<QString, QSet<QQmlType> >::const_iterator iter = compositeTypes.constBegin();
+ QMap<QString, QList<QQmlType>>::const_iterator iter = compositeTypes.constBegin();
for (; iter != compositeTypes.constEnd(); ++iter)
- dumper.dumpComposite(&engine, iter.value(), defaultReachableNames);
+ dumper.dumpComposite(&engine, iter.value(), defaultReachableNames, info);
// define QEasingCurve as an extension of QQmlEasingValueType, this way
// properties using the QEasingCurve type get useful type information.
diff --git a/tools/qmlplugindump/qmlstreamwriter.cpp b/tools/qmlplugindump/qmlstreamwriter.cpp
index 3632cee60d..b0fbc4e443 100644
--- a/tools/qmlplugindump/qmlstreamwriter.cpp
+++ b/tools/qmlplugindump/qmlstreamwriter.cpp
@@ -50,9 +50,9 @@ void QmlStreamWriter::writeEndDocument()
void QmlStreamWriter::writeLibraryImport(const QString &uri, int majorVersion, int minorVersion, const QString &as)
{
- m_stream->write(QString("import %1 %2.%3").arg(uri, QString::number(majorVersion), QString::number(minorVersion)).toUtf8());
+ m_stream->write(QString::fromLatin1("import %1 %2.%3").arg(uri, QString::number(majorVersion), QString::number(minorVersion)).toUtf8());
if (!as.isEmpty())
- m_stream->write(QString(" as %1").arg(as).toUtf8());
+ m_stream->write(QString::fromLatin1(" as %1").arg(as).toUtf8());
m_stream->write("\n");
}
@@ -60,7 +60,7 @@ void QmlStreamWriter::writeStartObject(const QString &component)
{
flushPotentialLinesWithNewlines();
writeIndent();
- m_stream->write(QString("%1 {").arg(component).toUtf8());
+ m_stream->write(QString::fromLatin1("%1 {").arg(component).toUtf8());
++m_indentDepth;
m_maybeOneline = true;
}
@@ -89,7 +89,7 @@ void QmlStreamWriter::writeEndObject()
void QmlStreamWriter::writeScriptBinding(const QString &name, const QString &rhs)
{
- writePotentialLine(QString("%1: %2").arg(name, rhs).toUtf8());
+ writePotentialLine(QString::fromLatin1("%1: %2").arg(name, rhs).toUtf8());
}
void QmlStreamWriter::writeBooleanBinding(const QString &name, bool value)
@@ -104,7 +104,7 @@ void QmlStreamWriter::writeArrayBinding(const QString &name, const QStringList &
// try to use a single line
QString singleLine;
- singleLine += QString("%1: [").arg(name);
+ singleLine += QString::fromLatin1("%1: [").arg(name);
for (int i = 0; i < elements.size(); ++i) {
singleLine += elements.at(i);
if (i != elements.size() - 1)
@@ -117,7 +117,7 @@ void QmlStreamWriter::writeArrayBinding(const QString &name, const QStringList &
}
// write multi-line
- m_stream->write(QString("%1: [\n").arg(name).toUtf8());
+ m_stream->write(QString::fromLatin1("%1: [\n").arg(name).toUtf8());
++m_indentDepth;
for (int i = 0; i < elements.size(); ++i) {
writeIndent();
@@ -143,13 +143,13 @@ void QmlStreamWriter::writeScriptObjectLiteralBinding(const QString &name, const
{
flushPotentialLinesWithNewlines();
writeIndent();
- m_stream->write(QString("%1: {\n").arg(name).toUtf8());
+ m_stream->write(QString::fromLatin1("%1: {\n").arg(name).toUtf8());
++m_indentDepth;
for (int i = 0; i < keyValue.size(); ++i) {
const QString key = keyValue.at(i).first;
const QString value = keyValue.at(i).second;
writeIndent();
- m_stream->write(QString("%1: %2").arg(key, value).toUtf8());
+ m_stream->write(QString::fromLatin1("%1: %2").arg(key, value).toUtf8());
if (i != keyValue.size() - 1) {
m_stream->write(",\n");
} else {
diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp
index f92ffa9ff5..7b010546c3 100644
--- a/tools/qmlprofiler/qmlprofilerapplication.cpp
+++ b/tools/qmlprofiler/qmlprofilerapplication.cpp
@@ -302,7 +302,7 @@ void QmlProfilerApplication::flush()
{
if (m_recording) {
m_pendingRequest = REQUEST_FLUSH;
- m_qmlProfilerClient->sendRecordingStatus(false);
+ m_qmlProfilerClient->setRecording(false);
} else {
if (m_profilerData->save(m_interactiveOutputFile)) {
m_profilerData->clear();
@@ -392,7 +392,7 @@ void QmlProfilerApplication::userCommand(const QString &command)
if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) {
m_pendingRequest = REQUEST_TOGGLE_RECORDING;
- m_qmlProfilerClient->sendRecordingStatus(!m_recording);
+ m_qmlProfilerClient->setRecording(!m_recording);
} else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) {
m_pendingRequest = REQUEST_QUIT;
if (m_recording) {
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index d5662a0182..9ec143975e 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -101,7 +101,6 @@ QmlProfilerData::~QmlProfilerData()
void QmlProfilerData::clear()
{
- d->eventTypes.clear();
d->events.clear();
d->traceEndTime = std::numeric_limits<qint64>::min();
diff --git a/tools/qmltime/qmltime.cpp b/tools/qmltime/qmltime.cpp
index 7baedff611..b0761a54d4 100644
--- a/tools/qmltime/qmltime.cpp
+++ b/tools/qmltime/qmltime.cpp
@@ -207,7 +207,7 @@ int main(int argc, char ** argv)
QGuiApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
- qmlRegisterType<Timer>("QmlTime", 1, 0, "Timer");
+ qmlRegisterTypesAndRevisions<Timer>("QmlTime", 1);
uint iterations = 1024;
QString filename;