diff options
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/qmldom/CMakeLists.txt | 22 | ||||
-rw-r--r-- | src/qmldom/qmldom.pro | 16 | ||||
-rw-r--r-- | src/qmldom/qqmldom_global.h | 57 | ||||
-rw-r--r-- | src/qmldom/qqmldomconstants_p.h | 87 | ||||
-rw-r--r-- | src/qmldom/qqmldomstringdumper.cpp | 238 | ||||
-rw-r--r-- | src/qmldom/qqmldomstringdumper_p.h | 152 | ||||
-rw-r--r-- | src/src.pro | 2 | ||||
-rw-r--r-- | sync.profile | 1 | ||||
-rw-r--r-- | tests/auto/.prev_CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/auto.pro | 1 | ||||
-rw-r--r-- | tests/auto/qmldom/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tests/auto/qmldom/qmldom.pro | 4 | ||||
-rw-r--r-- | tests/auto/qmldom/stringdumper/CMakeLists.txt | 20 | ||||
-rw-r--r-- | tests/auto/qmldom/stringdumper/stringdumper.pro | 26 | ||||
-rw-r--r-- | tests/auto/qmldom/stringdumper/tst_qmldomstringdumper.cpp | 115 |
17 files changed, 747 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bac92c5a38..18c5f50c01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,6 +38,7 @@ add_subdirectory(plugins) if(QT_FEATURE_qml_devtools) add_subdirectory(qmldevtools) + add_subdirectory(qmldom) add_subdirectory(qmlcompiler) # Build qmlcachegen now, so that we can use it in src/imports. diff --git a/src/qmldom/CMakeLists.txt b/src/qmldom/CMakeLists.txt new file mode 100644 index 0000000000..2e7134dd40 --- /dev/null +++ b/src/qmldom/CMakeLists.txt @@ -0,0 +1,22 @@ +# Generated from qmldom.pro. + +##################################################################### +## QmlCompiler Module: +##################################################################### + +qt_internal_add_module(QmlDom + STATIC + INTERNAL_MODULE + SOURCES + qqmldom_global.h + qqmldomconstants_p.h + qqmldomstringdumper.cpp qqmldomstringdumper_p.h + DEFINES + QMLDOM_LIBRARY + PUBLIC_LIBRARIES + Qt::CorePrivate + Qt::QmlDevToolsPrivate +) + +#### Keys ignored in scope 1:.:.:qmlcompiler.pro:<TRUE>: +# _OPTION = "host_build" diff --git a/src/qmldom/qmldom.pro b/src/qmldom/qmldom.pro new file mode 100644 index 0000000000..282566cc9d --- /dev/null +++ b/src/qmldom/qmldom.pro @@ -0,0 +1,16 @@ +option(host_build) +TARGET = QtQmlDom +QT = core-private qmldevtools-private +CONFIG += minimal_syncqt internal_module generated_privates + +DEFINES += QMLDOM_LIBRARY + +SOURCES += \ + $$PWD/qqmldomstringdumper.cpp + +HEADERS += \ + $$PWD/qqmldom_global.h \ + $$PWD/qqmldomconstants_p.h \ + $$PWD/qqmldomstringdumper_p.h + +load(qt_module) diff --git a/src/qmldom/qqmldom_global.h b/src/qmldom/qqmldom_global.h new file mode 100644 index 0000000000..d76f6efeac --- /dev/null +++ b/src/qmldom/qqmldom_global.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#ifndef QMLDOM_GLOBAL_H +#define QMLDOM_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(QMLDOM_DYNAMIC) +#if defined(QMLDOM_LIBRARY) +# define QMLDOM_EXPORT Q_DECL_EXPORT +#else +# define QMLDOM_EXPORT Q_DECL_IMPORT +#endif +#else +# define QMLDOM_EXPORT +#endif + +QT_BEGIN_NAMESPACE +// avoid annoying warning about missing QT_BEGIN_NAMESPACE... +QT_END_NAMESPACE + +#endif // QMLDOM_GLOBAL_H diff --git a/src/qmldom/qqmldomconstants_p.h b/src/qmldom/qqmldomconstants_p.h new file mode 100644 index 0000000000..43cbbdda28 --- /dev/null +++ b/src/qmldom/qqmldomconstants_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#ifndef QQMLDOMCONSTANTS_P_H +#define QQMLDOMCONSTANTS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qqmldom_global.h" + +#include <QtCore/QObject> +#include <QtCore/QMetaObject> + +QT_BEGIN_NAMESPACE + +namespace QQmlJS{ +namespace Dom { + +Q_NAMESPACE_EXPORT(QMLDOM_EXPORT) + +enum class EscapeOptions{ + OuterQuotes, + NoOuterQuotes +}; +Q_ENUM_NS(EscapeOptions) + +enum class ErrorLevel{ + Debug, + Info, + Hint, // cosmetic or convention + MaybeWarning, // possibly a warning, insufficient information + Warning, + MaybeError, + Error, + Fatal +}; +Q_ENUM_NS(ErrorLevel) + +} // end namespace Dom +} // end namespace QQmlJS + +QT_END_NAMESPACE + +#endif // QQMLDOMCONSTANTS_P_H diff --git a/src/qmldom/qqmldomstringdumper.cpp b/src/qmldom/qqmldomstringdumper.cpp new file mode 100644 index 0000000000..1788d79d3d --- /dev/null +++ b/src/qmldom/qqmldomstringdumper.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#include "qqmldomstringdumper_p.h" +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +namespace QQmlJS { +namespace Dom { + +/*! + * \internal + * \tn QQmlJS::Dom::Sink + * \brief A Sink is a function that accepts a QStringView as input + * + * A Sink it the core element of a text based stream oriented output. + * It is simply a function accepting a QStringView as input. + */ + +/*! + * \internal + * \tn QQmlJS::Dom::sinkInt + * \brief writes an integer to a sink without any axtra heap allocation + * \param sink where to write + * \param i the integer to write out + * + * mainly for debugging/fatal errors + */ + +/*! + * \internal + * \class QQmlJS::Dom::Dumper + * \brief Helper class to accept eithe a string or a dumper (a function that writes to a sink) + * + * Using a Dumper as input parameter one always obtains a dumper (i.e. a + * std::function<void(std::function<void(QStringView)>)> , but can pass in any + * object accepted by QStringView, and it is automatically converted to a dumper. + */ + +/*! + * \internal + * \brief Converts a dumper to a string + * \param writer The dumper convert to a string + */ +QString dumperToString(Dumper writer) +{ + QString s; + QTextStream d(&s); + writer([&d](QStringView s){ d << s; }); + d.flush(); + return s; +} + +/*! + * \internal + * \brief dumps a string as quoted string (escaping things like quotes or newlines) + * \param sink The sink to write the quoted string to + * \param s The string to sink + * \param options If quotes should be outputted around the string (defaults to yes) + */ +void sinkEscaped(Sink sink, QStringView s, EscapeOptions options) { + if (options == EscapeOptions::OuterQuotes) + sink(u"\""); + int it0=0; + for (int it = 0; it < s.length();++it) { + QChar c=s[it]; + bool noslash = c != QLatin1Char('\\'); + bool noquote = c != QLatin1Char('"'); + bool nonewline = c != QLatin1Char('\n'); + bool noreturn = c != QLatin1Char('\r'); + if (noslash && noquote && nonewline && noreturn) + continue; + sink(s.mid(it0, it - it0)); + it0 = it + 1; + if (!noslash) + sink(u"\\\\"); + else if (!noquote) + sink(u"\\\""); + else if (!nonewline) + sink(u"\\n"); + else if (!noreturn) + sink(u"\\r"); + else + Q_ASSERT(0); + } + sink(s.mid(it0, s.length() - it0)); + if (options == EscapeOptions::OuterQuotes) + sink(u"\""); +} + +/*! + * \internal + * \brief Dumps a string describing the given error level (ErrorLevel::Error -> Error,...) + * \param s the sink to write to + * \param level the level to describe + */ +void dumpErrorLevel(Sink s, ErrorLevel level) +{ + switch (level) { + case ErrorLevel::Debug: + s(u"Debug"); + break; + case ErrorLevel::Info: + s(u"Info"); + break; + case ErrorLevel::Hint: + s(u"Hint"); + break; + case ErrorLevel::MaybeWarning: + s(u"MaybeWarn"); + break; + case ErrorLevel::Warning: + s(u"Warning"); + break; + case ErrorLevel::MaybeError: + s(u"MaybeErr"); + break; + case ErrorLevel::Error: + s(u"Error"); + break; + case ErrorLevel::Fatal: + s(u"Fatal"); + break; + } + +} + +void dumperToQDebug(Dumper dumper, QDebug debug) +{ + QDebug & d = debug.noquote().nospace(); + dumper([&d](QStringView s){ + d << s; + }); +} + +/*! + * \internal + * \brief writes the dumper to the QDebug object corrsponding to the given error level + * \param level the error level of the message + * \param dumper the dumper that writes a message + */ +void dumperToQDebug(Dumper dumper, ErrorLevel level) +{ + QDebug d = qDebug().noquote().nospace(); + switch (level) { + case ErrorLevel::Debug: + break; + case ErrorLevel::Info: + case ErrorLevel::Hint: + d = qInfo().noquote().nospace(); + break; + case ErrorLevel::MaybeWarning: + case ErrorLevel::Warning: + d = qWarning().noquote().nospace(); + break; + case ErrorLevel::MaybeError: + case ErrorLevel::Error: + case ErrorLevel::Fatal: // should be handled differently (avoid allocations...), we try to catch them before ending up here + d = qCritical().noquote().nospace(); + break; + } + dumper([&d](QStringView s){ + d << s; + }); +} + +/*! + * \internal + * \brief sinks the requested amount of spaces + */ +void sinkIndent(Sink s, int indent) +{ + if (indent > 0) { + QStringView spaces = u" "; + while (indent > spaces.length()) { + s(spaces); + indent -= spaces.length(); + } + s(spaces.left(indent)); + } +} + +/*! + * \internal + * \brief sinks a neline and indents by the given amount + */ +void sinkNewline(Sink s, int indent) +{ + s(u"\n"); + if (indent > 0) + sinkIndent(s, indent); +} + +/*! + * \internal + * \fn QQmlJS::Dom::devNull + * \brief A sink that ignores whatever it receives + */ + +} // end namespace Dom +} // end namespace QQmlJS + +QT_END_NAMESPACE diff --git a/src/qmldom/qqmldomstringdumper_p.h b/src/qmldom/qqmldomstringdumper_p.h new file mode 100644 index 0000000000..7669bfc882 --- /dev/null +++ b/src/qmldom/qqmldomstringdumper_p.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#ifndef DUMPER_H +#define DUMPER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qqmldom_global.h" +#include "qqmldomconstants_p.h" + +#include <QtCore/QString> +#include <QtCore/QStringView> +#include <QtCore/QDebug> + +#include <type_traits> + +QT_BEGIN_NAMESPACE + +namespace QQmlJS { +namespace Dom { + +using Sink = std::function<void(QStringView)>; +using DumperFunction = std::function<void(Sink)>; + +class Dumper{ +public: + DumperFunction dumper; +private: + // We want to avoid the limit of one user conversion: + // after doing (* -> QStringView) we cannot have QStringView -> Dumper, as it + // would be the second user defined conversion. + // For a similar reason we have a template to accept function<void(Sink)> . + // The end result is that void f(Dumper) can be called nicely, and avoid overloads: + // f(u"bla"), f(QLatin1String("bla")), f(QString()), f([](Sink s){...}),... + template <typename T> + using if_compatible_dumper = typename + std::enable_if<std::is_convertible<T, DumperFunction>::value, bool>::type; + + template<typename T> + using if_string_view_convertible = typename + std::enable_if<std::is_convertible_v<T, QStringView>, bool>::type; + +public: + Dumper(QStringView s): + dumper([s](Sink sink){ sink(s); }) {} + + Dumper(std::nullptr_t): Dumper(QStringView(nullptr)) {} + + template <typename Stringy, if_string_view_convertible<Stringy> = true> + Dumper(Stringy string): + Dumper(QStringView(string)) {} + + template <typename U, if_compatible_dumper<U> = true> + Dumper(U f): dumper(f) {} + + void operator()(Sink s) { dumper(s); } +}; + +template <typename T> +void sinkInt(Sink s, T i) { + const int BUFSIZE = 42; // safe up to 128 bits + QChar buf[BUFSIZE]; + int ibuf = BUFSIZE; + buf[--ibuf] = QChar(0); + bool neg = false; + if (i < 0) + neg=true; + int digit = i % 10; + i = i / 10; + if constexpr (std::is_signed_v<T>) { + if (neg) { // we change the sign here because -numeric_limits<T>::min() == numeric_limits<T>::min() + i = -i; + digit = - digit; + } + } + buf[--ibuf] = QChar::fromLatin1('0' + digit); + while (i > 0 && ibuf > 0) { + digit = i % 10; + buf[--ibuf] = QChar::fromLatin1('0' + digit); + i = i / 10; + } + if (neg && ibuf > 0) + buf[--ibuf] = QChar::fromLatin1('-'); + s(QStringView(&buf[ibuf], BUFSIZE - ibuf -1)); +} + +QMLDOM_EXPORT QString dumperToString(Dumper writer); + +QMLDOM_EXPORT void sinkEscaped(Sink sink, QStringView s, + EscapeOptions options = EscapeOptions::OuterQuotes); + +inline void devNull(QStringView) {} + +QMLDOM_EXPORT void sinkIndent(Sink s, int indent); + +QMLDOM_EXPORT void sinkNewline(Sink s, int indent = 0); + +QMLDOM_EXPORT void dumpErrorLevel(Sink s, ErrorLevel level); + +QMLDOM_EXPORT void dumperToQDebug(Dumper dumper, QDebug debug); + +QMLDOM_EXPORT void dumperToQDebug(Dumper dumper, ErrorLevel level = ErrorLevel::Debug); + +} // end namespace Dom +} // end namespace QQmlJS +QT_END_NAMESPACE + +#endif // DUMPER_H diff --git a/src/src.pro b/src/src.pro index d4e66be413..bd62073bd2 100644 --- a/src/src.pro +++ b/src/src.pro @@ -41,10 +41,12 @@ SUBDIRS += \ qtConfig(qml-devtools) { SUBDIRS += \ qmldevtools \ + qmldom \ qmlcompiler qmldevtools.depends = qml qmlcompiler.depends = qmldevtools + qmldom.depends = qmldevtools } diff --git a/sync.profile b/sync.profile index eac24770f1..2ec61fb90d 100644 --- a/sync.profile +++ b/sync.profile @@ -10,6 +10,7 @@ "QtQmlModels" => "$basedir/src/qmlmodels", "QtQmlWorkerScript" => "$basedir/src/qmlworkerscript", "QtQmlCompiler" => "$basedir/src/qmlcompiler", + "QtQmlDom" => "$basedir/src/qmldom", ); %inject_headers = ( "$basedir/src/qml" => [ "^qqmljsgrammar_p.h", "^qqmljsparser_p.h", "^qml_compile_hash_p.h" ], diff --git a/tests/auto/.prev_CMakeLists.txt b/tests/auto/.prev_CMakeLists.txt index addaaa6bde..c9bc48d151 100644 --- a/tests/auto/.prev_CMakeLists.txt +++ b/tests/auto/.prev_CMakeLists.txt @@ -1,6 +1,7 @@ # Generated from auto.pro. add_subdirectory(qml) +add_subdirectory(qmldom) add_subdirectory(quick) add_subdirectory(quicktest) add_subdirectory(qmldevtools) diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index cdec7346eb..e3102d18c4 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -1,6 +1,7 @@ # Generated from auto.pro. add_subdirectory(qml) +add_subdirectory(qmldom) add_subdirectory(quick) add_subdirectory(quicktest) add_subdirectory(qmldevtools) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 35dfe5dfbd..071d67f4f2 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -11,6 +11,7 @@ SUBDIRS=\ qtHaveModule(gui): SUBDIRS += particles qtHaveModule(widgets): SUBDIRS += quickwidgets +qtHaveModule(qmldom): SUBDIRS += qmldom # console applications not supported uikit: SUBDIRS -= qmltest diff --git a/tests/auto/qmldom/CMakeLists.txt b/tests/auto/qmldom/CMakeLists.txt new file mode 100644 index 0000000000..897069f608 --- /dev/null +++ b/tests/auto/qmldom/CMakeLists.txt @@ -0,0 +1,3 @@ +# Generated from qmldom.pro. + +add_subdirectory(stringdumper) diff --git a/tests/auto/qmldom/qmldom.pro b/tests/auto/qmldom/qmldom.pro new file mode 100644 index 0000000000..6a7b30274c --- /dev/null +++ b/tests/auto/qmldom/qmldom.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + stringdumper diff --git a/tests/auto/qmldom/stringdumper/CMakeLists.txt b/tests/auto/qmldom/stringdumper/CMakeLists.txt new file mode 100644 index 0000000000..c72467caf9 --- /dev/null +++ b/tests/auto/qmldom/stringdumper/CMakeLists.txt @@ -0,0 +1,20 @@ +# Generated from stringdumper.pro. + +##################################################################### +## tst_qmldomstringdumper Binary: +##################################################################### + +qt_internal_add_test(tst_qmldomstringdumper + SOURCES + tst_qmldomstringdumper.cpp + DEFINES + QT_DEPRECATED_WARNINGS + PUBLIC_LIBRARIES + Qt::Core + Qt::QmlDevToolsPrivate + Qt::QmlDomPrivate + Qt::Test +) + +## Scopes: +##################################################################### diff --git a/tests/auto/qmldom/stringdumper/stringdumper.pro b/tests/auto/qmldom/stringdumper/stringdumper.pro new file mode 100644 index 0000000000..dc9f1a4257 --- /dev/null +++ b/tests/auto/qmldom/stringdumper/stringdumper.pro @@ -0,0 +1,26 @@ +QT = core qmldevtools-private testlib +TARGET = tst_qmldomstringdumper + + +INCLUDEPATH += ../../../../src/qmldom + + +CONFIG += c++11 console +CONFIG -= app_bundle + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + tst_qmldomstringdumper.cpp + + +load(qt_common) diff --git a/tests/auto/qmldom/stringdumper/tst_qmldomstringdumper.cpp b/tests/auto/qmldom/stringdumper/tst_qmldomstringdumper.cpp new file mode 100644 index 0000000000..04b9899d0f --- /dev/null +++ b/tests/auto/qmldom/stringdumper/tst_qmldomstringdumper.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +**/ +#include <QtQmlDom/private/qqmldomstringdumper_p.h> + +#include <QtTest/QtTest> +#include <QTextStream> +#include <QDebug> + +#include <limits> + +QT_BEGIN_NAMESPACE +namespace QQmlJS { +namespace Dom { + +class TestStringDumper: public QObject +{ + Q_OBJECT +private slots: + void testDumperToString() { + QCOMPARE(dumperToString(u"bla"), QStringLiteral(u"bla")); + QCOMPARE(dumperToString([](Sink s) { s(u"bla"); s(u"bla"); }), QStringLiteral(u"blabla")); + } + + void testSinkInt() { + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, 1); }), QStringLiteral(u"1")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, 0); }), QStringLiteral(u"0")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, -1); }), QStringLiteral(u"-1")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<qint32>::max()); }), QStringLiteral(u"2147483647")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<qint32>::min()); }), QStringLiteral(u"-2147483648")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<quint32>::max()); }), QStringLiteral(u"4294967295")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<qint64>::min()); }), QStringLiteral(u"-9223372036854775808")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<qint64>::max()); }), QStringLiteral(u"9223372036854775807")); + QCOMPARE(dumperToString([](Sink s) { sinkInt(s, std::numeric_limits<quint64>::max()); }), QStringLiteral(u"18446744073709551615")); + } + + void testSinkEscaped() { + QCOMPARE(dumperToString([](Sink s) { sinkEscaped(s, u""); }), QStringLiteral(u"\"\"")); + QStringView s1 = u"bla:\"bla\\\""; // uR"(bla:"bla\")"; + QStringView s1Escaped = u"\"bla:\\\"bla\\\\\\\"\""; + QCOMPARE(dumperToString([s1](Sink s) { sinkEscaped(s, s1); }), s1Escaped); + QCOMPARE(dumperToString([](Sink s) { sinkEscaped(s, u"", EscapeOptions::NoOuterQuotes); }), QStringLiteral(u"")); + QStringView s2 = u"bla:\"bla\\\"\n"; + QStringView s2Escaped = u"bla:\\\"bla\\\\\\\"\\n"; // uR"(bla:\"bla\\\"\n)" + QCOMPARE(dumperToString([s2](Sink s) { sinkEscaped(s, s2, EscapeOptions::NoOuterQuotes); }), s2Escaped); + } + + void testDevNull() { + sinkEscaped(devNull, u""); + sinkEscaped(devNull, u"bla:\"bla\\\"\n"); + } + + void testSinkIndent() { + QCOMPARE(dumperToString([](Sink s) { sinkIndent(s, 0); }), QStringLiteral(u"")); + QCOMPARE(dumperToString([](Sink s) { sinkIndent(s, 1); }), QStringLiteral(u" ")); + QCOMPARE(dumperToString([](Sink s) { sinkIndent(s, 10); }), QStringLiteral(u" ")); + QCOMPARE(dumperToString([](Sink s) { sinkIndent(s, 40); }), QStringLiteral(u" ").repeated(4)); + } + + + void testSinkNewline(){ + QCOMPARE(dumperToString([](Sink s) { sinkNewline(s); }), QStringLiteral(u"\n")); + QCOMPARE(dumperToString([](Sink s) { sinkNewline(s, 0); }), QStringLiteral(u"\n")); + QCOMPARE(dumperToString([](Sink s) { sinkNewline(s, 1); }), QStringLiteral(u"\n ")); + QCOMPARE(dumperToString([](Sink s) { sinkNewline(s, 10); }), QStringLiteral(u"\n ")); + QCOMPARE(dumperToString([](Sink s) { sinkNewline(s, 40); }), QStringLiteral(u"\n") + QStringLiteral(u" ").repeated(4)); + } + + void testDumpErrorLevel(){ + QCOMPARE(dumperToString([](Sink s) { dumpErrorLevel(s, ErrorLevel::Hint); }), QStringLiteral(u"Hint")); + QCOMPARE(dumperToString([](Sink s) { dumpErrorLevel(s, ErrorLevel::Error); }), QStringLiteral(u"Error")); + QCOMPARE(dumperToString([](Sink s) { dumpErrorLevel(s, ErrorLevel::Warning); }), QStringLiteral(u"Warning")); + } +}; + +} // namespace Dom +} // namespace QQmlJS +QT_END_NAMESPACE + +QTEST_MAIN(QQmlJS::Dom::TestStringDumper) +#include "tst_qmldomstringdumper.moc" |