diff options
author | Sami Shalayel <[email protected]> | 2024-09-13 19:18:28 +0200 |
---|---|---|
committer | Sami Shalayel <[email protected]> | 2024-09-20 18:55:30 +0200 |
commit | 09236b1101574c1a009d3cee0c979286f497e466 (patch) | |
tree | 899f01e3445a700a70adfce623c0de7024851079 | |
parent | 511f1f0fe508d28cebf8ec4fe8e026dac752f602 (diff) |
qmlformat: extract settings logic into library
Move the code from tools/qmlformat.cpp that parses .qmlformat.ini files
into a newly created qmlformat library under src/qmlformat.
This would allow qmlls to reuse the same code.
Task-number: QTBUG-128866
Change-Id: Ibf7e52be744ea11c235d0b853ffa80f778c14a2b
Reviewed-by: Ulf Hermann <[email protected]>
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/qmlformat/CMakeLists.txt | 14 | ||||
-rw-r--r-- | src/qmlformat/qqmlformatoptions.cpp | 87 | ||||
-rw-r--r-- | src/qmlformat/qqmlformatoptions_p.h | 137 | ||||
-rw-r--r-- | src/qmlformat/qqmlformatsettings.cpp | 14 | ||||
-rw-r--r-- | src/qmlformat/qqmlformatsettings_p.h | 35 | ||||
-rw-r--r-- | tools/qmlformat/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tools/qmlformat/qmlformat.cpp | 192 |
8 files changed, 291 insertions, 190 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9e5eba23d2..02e1011cd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -96,6 +96,7 @@ add_subdirectory(labs) add_subdirectory(qmlcompiler) add_subdirectory(qmldom) +add_subdirectory(qmlformat) # Build qmlcachegen now, so that we can use it in src/imports. if(QT_FEATURE_xmlstreamwriter) diff --git a/src/qmlformat/CMakeLists.txt b/src/qmlformat/CMakeLists.txt new file mode 100644 index 0000000000..f43f5dd8c5 --- /dev/null +++ b/src/qmlformat/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_module(QmlFormatPrivate + STATIC + INTERNAL_MODULE + SOURCES + qqmlformatoptions.cpp qqmlformatoptions_p.h + qqmlformatsettings.cpp qqmlformatsettings_p.h + PUBLIC_LIBRARIES + Qt::Core + Qt::QmlDomPrivate + Qt::QmlToolingSettingsPrivate +) diff --git a/src/qmlformat/qqmlformatoptions.cpp b/src/qmlformat/qqmlformatoptions.cpp new file mode 100644 index 0000000000..14ea69d818 --- /dev/null +++ b/src/qmlformat/qqmlformatoptions.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qqmlformatoptions_p.h" + +QQmlFormatOptions::QQmlFormatOptions() +{ + m_options.updateOptions = QQmlJS::Dom::LineWriterOptions::Update::None; + + setTabsEnabled(false); + setNormalizeEnabled(false); + setObjectsSpacing(false); + setFunctionsSpacing(false); + setIndentWidth(4); +} + +QQmlFormatOptions::LineEndings QQmlFormatOptions::detectLineEndings(const QString &code) +{ + const QQmlJS::Dom::LineWriterOptions::LineEndings defaultEndings = +#if defined(Q_OS_WIN) + LineEndings::Windows; +#else + LineEndings::Unix; +#endif + // find out current line endings... + int newlineIndex = code.indexOf(QChar(u'\n')); + int crIndex = code.indexOf(QChar(u'\r')); + if (newlineIndex >= 0) { + if (crIndex >= 0) { + if (crIndex + 1 == newlineIndex) + return LineEndings::Windows; + + qWarning().noquote() << "Invalid line ending in file, using default"; + return defaultEndings; + } + return LineEndings::Unix; + } + if (crIndex >= 0) { + return LineEndings::OldMacOs; + } + + qWarning().noquote() << "Unknown line ending in file, using default"; + return defaultEndings; +} + +QQmlFormatOptionLineEndings QQmlFormatOptions::parseEndings(const QString &endings) +{ + if (endings == u"unix") + return Unix; + if (endings == u"windows") + return Windows; + if (endings == u"macos") + return OldMacOs; + if (endings == u"native") + return Native; + + qWarning().noquote() << "Unknown line ending type" << endings << ", using default"; +#if defined(Q_OS_WIN) + return Windows; +#else + return Unix; +#endif +} + +void QQmlFormatOptions::applySettings(const QQmlFormatSettings &settings) +{ + // Allow for tab settings to be overwritten by the command line + if (!indentWidthSet()) { + if (settings.isSet(QQmlFormatSettings::s_indentWidthSetting)) + setIndentWidth(settings.value(QQmlFormatSettings::s_indentWidthSetting).toInt()); + if (settings.isSet(QQmlFormatSettings::s_useTabsSetting)) + setTabsEnabled(settings.value(QQmlFormatSettings::s_useTabsSetting).toBool()); + } + + if (settings.isSet(QQmlFormatSettings::s_normalizeSetting)) + setNormalizeEnabled(settings.value(QQmlFormatSettings::s_normalizeSetting).toBool()); + + if (settings.isSet(QQmlFormatSettings::s_newlineSetting)) + setNewline(QQmlFormatOptions::parseEndings( + settings.value(QQmlFormatSettings::s_newlineSetting).toString())); + + if (settings.isSet(QQmlFormatSettings::s_objectsSpacingSetting)) + setObjectsSpacing(settings.value(QQmlFormatSettings::s_objectsSpacingSetting).toBool()); + + if (settings.isSet(QQmlFormatSettings::s_functionsSpacingSetting)) + setFunctionsSpacing(settings.value(QQmlFormatSettings::s_functionsSpacingSetting).toBool()); +} diff --git a/src/qmlformat/qqmlformatoptions_p.h b/src/qmlformat/qqmlformatoptions_p.h new file mode 100644 index 0000000000..8a0ba451e3 --- /dev/null +++ b/src/qmlformat/qqmlformatoptions_p.h @@ -0,0 +1,137 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#ifndef QQmlFormatOptions_P_H +#define QQmlFormatOptions_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 <QtCore/qstring.h> +#include <QtQmlDom/private/qqmldomoutwriter_p.h> +#include <QtQmlDom/private/qqmldomlinewriter_p.h> +#include <QtQmlToolingSettings/private/qqmltoolingsettings_p.h> + +#include "qqmlformatsettings_p.h" + +QT_BEGIN_NAMESPACE + +enum QQmlFormatOptionLineEndings { + Native, + Windows, + Unix, + OldMacOs, +}; + +class QQmlFormatOptions +{ +public: + QQmlFormatOptions(); + + using LineEndings = QQmlJS::Dom::LineWriterOptions::LineEndings; + using AttributesSequence = QQmlJS::Dom::LineWriterOptions::AttributesSequence; + + static LineEndings detectLineEndings(const QString &code); + + static LineEndings lineEndings(QQmlFormatOptionLineEndings endings, const QString &code) + { + switch (endings) { + case Native: + return detectLineEndings(code); + case OldMacOs: + return LineEndings::OldMacOs; + case Windows: + return LineEndings::Windows; + case Unix: + return LineEndings::Unix; + } + Q_UNREACHABLE_RETURN(LineEndings::Unix); + } + + bool tabsEnabled() const { return m_options.formatOptions.useTabs; } + void setTabsEnabled(bool tabs) { m_options.formatOptions.useTabs = tabs; } + bool normalizeEnabled() const + { + return m_options.attributesSequence == AttributesSequence::Normalize; + } + void setNormalizeEnabled(bool normalize) + { + m_options.attributesSequence = + (normalize ? AttributesSequence::Normalize : AttributesSequence::Preserve); + } + bool objectsSpacing() const { return m_options.objectsSpacing; } + void setObjectsSpacing(bool spacing) { m_options.objectsSpacing = spacing; } + bool functionsSpacing() const { return m_options.functionsSpacing; } + void setFunctionsSpacing(bool spacing) { m_options.functionsSpacing = spacing; } + + int indentWidth() const { return m_options.formatOptions.indentSize; } + void setIndentWidth(int width) { m_options.formatOptions.indentSize = width; } + + QQmlJS::Dom::LineWriterOptions optionsForCode(const QString &code) const + { + QQmlJS::Dom::LineWriterOptions result = m_options; + result.lineEndings = lineEndings(m_newline, code); + return result; + } + + static QQmlFormatOptionLineEndings parseEndings(const QString &endings); + + QQmlFormatOptionLineEndings newline() const { return m_newline; } + void setNewline(const QQmlFormatOptionLineEndings &endings) { m_newline = endings; } + + QStringList files() const { return m_files; } + void setFiles(const QStringList &newFiles) { m_files = newFiles; } + QStringList arguments() const { return m_arguments; } + void setArguments(const QStringList &newArguments) { m_arguments = newArguments; } + bool isVerbose() const { return m_verbose; } + void setIsVerbose(bool newVerbose) { m_verbose = newVerbose; } + bool isValid() const { return m_valid; } + void setIsValid(bool newValid) { m_valid = newValid; } + bool isInplace() const { return m_inplace; } + void setIsInplace(bool newInplace) { m_inplace = newInplace; } + bool forceEnabled() const { return m_force; } + void setForceEnabled(bool newForce) { m_force = newForce; } + bool ignoreSettingsEnabled() const { return m_ignoreSettings; } + void setIgnoreSettingsEnabled(bool newIgnoreSettings) { m_ignoreSettings = newIgnoreSettings; } + bool writeDefaultSettingsEnabled() const { return m_writeDefaultSettings; } + void setWriteDefaultSettingsEnabled(bool newWriteDefaultSettings) + { + m_writeDefaultSettings = newWriteDefaultSettings; + } + + bool indentWidthSet() const { return m_indentWidthSet; } + void setIndentWidthSet(bool newIndentWidthSet) { m_indentWidthSet = newIndentWidthSet; } + QStringList errors() const { return m_errors; } + void addError(const QString &newError) { m_errors.append(newError); }; + + void applySettings(const QQmlFormatSettings &settings); + +private: + QQmlJS::Dom::LineWriterOptions m_options; + + QQmlFormatOptionLineEndings m_newline = Native; + + QStringList m_files; + QStringList m_arguments; + QStringList m_errors; + + bool m_verbose = false; + bool m_valid = false; + bool m_inplace = false; + bool m_force = false; + bool m_ignoreSettings = false; + bool m_writeDefaultSettings = false; + bool m_indentWidthSet = false; +}; + +QT_END_NAMESPACE +#endif // QQmlFormatOptions_P_H diff --git a/src/qmlformat/qqmlformatsettings.cpp b/src/qmlformat/qqmlformatsettings.cpp new file mode 100644 index 0000000000..e9a880b848 --- /dev/null +++ b/src/qmlformat/qqmlformatsettings.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qqmlformatsettings_p.h" + +QQmlFormatSettings::QQmlFormatSettings(const QString &toolName) : QQmlToolingSettings(toolName) +{ + addOption(s_useTabsSetting); + addOption(s_indentWidthSetting, 4); + addOption(s_normalizeSetting); + addOption(s_newlineSetting, QStringLiteral("native")); + addOption(s_objectsSpacingSetting); + addOption(s_functionsSpacingSetting); +} diff --git a/src/qmlformat/qqmlformatsettings_p.h b/src/qmlformat/qqmlformatsettings_p.h new file mode 100644 index 0000000000..544fd0b5b3 --- /dev/null +++ b/src/qmlformat/qqmlformatsettings_p.h @@ -0,0 +1,35 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QQMLFORMATSETTINGS_P_H +#define QQMLFORMATSETTINGS_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 <QtQmlToolingSettings/private/qqmltoolingsettings_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlFormatSettings : public QQmlToolingSettings +{ +public: + QQmlFormatSettings(const QString &toolName = QLatin1String("qmlformat")); + static const inline QLatin1StringView s_useTabsSetting = QLatin1String("UseTabs"); + static const inline QLatin1StringView s_indentWidthSetting = QLatin1String("IndentWidth"); + static const inline QLatin1StringView s_normalizeSetting = QLatin1String("NormalizeOrder"); + static const inline QLatin1StringView s_newlineSetting = QLatin1String("NewlineType"); + static const inline QLatin1StringView s_objectsSpacingSetting = QLatin1String("ObjectsSpacing"); + static const inline QLatin1StringView s_functionsSpacingSetting = QLatin1String("FunctionsSpacing"); +}; + +QT_END_NAMESPACE +#endif // QQMLFORMATSETTINGS_P_H diff --git a/tools/qmlformat/CMakeLists.txt b/tools/qmlformat/CMakeLists.txt index 908901b9f5..04c0c5bc22 100644 --- a/tools/qmlformat/CMakeLists.txt +++ b/tools/qmlformat/CMakeLists.txt @@ -17,6 +17,7 @@ qt_internal_add_tool(${target_name} Qt::Core Qt::QmlDomPrivate Qt::QmlToolingSettingsPrivate + Qt::QmlFormatPrivate ) qt_internal_return_unless_building_tools() diff --git a/tools/qmlformat/qmlformat.cpp b/tools/qmlformat/qmlformat.cpp index 1bb52f6cae..8767941ccd 100644 --- a/tools/qmlformat/qmlformat.cpp +++ b/tools/qmlformat/qmlformat.cpp @@ -20,199 +20,11 @@ #endif #include <QtQmlToolingSettings/private/qqmltoolingsettings_p.h> +#include <QtQmlFormat/private/qqmlformatsettings_p.h> +#include <QtQmlFormat/private/qqmlformatoptions_p.h> using namespace QQmlJS::Dom; -enum QQmlFormatOptionLineEndings { - Native, - Windows, - Unix, - OldMacOs, -}; - -class QQmlFormatSettings : public QQmlToolingSettings -{ -public: - QQmlFormatSettings(const QString &toolName = u"qmlformat"_s); - static const inline QLatin1StringView s_useTabsSetting = QLatin1String("UseTabs"); - static const inline QLatin1StringView s_indentWidthSetting = QLatin1String("IndentWidth"); - static const inline QLatin1StringView s_normalizeSetting = QLatin1String("NormalizeOrder"); - static const inline QLatin1StringView s_newlineSetting = QLatin1String("NewlineType"); - static const inline QLatin1StringView s_objectsSpacingSetting = QLatin1String("ObjectsSpacing"); - static const inline QLatin1StringView s_functionsSpacingSetting = QLatin1String("FunctionsSpacing"); -}; - -QQmlFormatSettings::QQmlFormatSettings(const QString &toolName) : QQmlToolingSettings(toolName) -{ - addOption(s_useTabsSetting); - addOption(s_indentWidthSetting, 4); - addOption(s_normalizeSetting); - addOption(s_newlineSetting, QStringLiteral("native")); - addOption(s_objectsSpacingSetting); - addOption(s_functionsSpacingSetting); -} - -class QQmlFormatOptions -{ -public: - QQmlFormatOptions(); - using LineEndings = QQmlJS::Dom::LineWriterOptions::LineEndings; - using AttributesSequence = QQmlJS::Dom::LineWriterOptions::AttributesSequence; - static LineEndings detectLineEndings(const QString &code); - static LineEndings lineEndings(QQmlFormatOptionLineEndings endings, const QString &code) - { - switch (endings) { - case Native: - return detectLineEndings(code); - case OldMacOs: - return LineEndings::OldMacOs; - case Windows: - return LineEndings::Windows; - case Unix: - return LineEndings::Unix; - } - Q_UNREACHABLE_RETURN(LineEndings::Unix); - } - bool tabsEnabled() const { return m_options.formatOptions.useTabs; } - void setTabsEnabled(bool tabs) { m_options.formatOptions.useTabs = tabs; } - bool normalizeEnabled() const - { - return m_options.attributesSequence == AttributesSequence::Normalize; - } - void setNormalizeEnabled(bool normalize) - { - m_options.attributesSequence = - (normalize ? AttributesSequence::Normalize : AttributesSequence::Preserve); - } - bool objectsSpacing() const { return m_options.objectsSpacing; } - void setObjectsSpacing(bool spacing) { m_options.objectsSpacing = spacing; } - bool functionsSpacing() const { return m_options.functionsSpacing; } - void setFunctionsSpacing(bool spacing) { m_options.functionsSpacing = spacing; } - int indentWidth() const { return m_options.formatOptions.indentSize; } - void setIndentWidth(int width) { m_options.formatOptions.indentSize = width; } - QQmlJS::Dom::LineWriterOptions optionsForCode(const QString &code) const - { - QQmlJS::Dom::LineWriterOptions result = m_options; - result.lineEndings = lineEndings(m_newline, code); - return result; - } - static QQmlFormatOptionLineEndings parseEndings(const QString &endings); - QQmlFormatOptionLineEndings newline() const { return m_newline; } - void setNewline(const QQmlFormatOptionLineEndings &endings) { m_newline = endings; } - QStringList files() const { return m_files; } - void setFiles(const QStringList &newFiles) { m_files = newFiles; } - QStringList arguments() const { return m_arguments; } - void setArguments(const QStringList &newArguments) { m_arguments = newArguments; } - bool isVerbose() const { return m_verbose; } - void setIsVerbose(bool newVerbose) { m_verbose = newVerbose; } - bool isValid() const { return m_valid; } - void setIsValid(bool newValid) { m_valid = newValid; } - bool isInplace() const { return m_inplace; } - void setIsInplace(bool newInplace) { m_inplace = newInplace; } - bool forceEnabled() const { return m_force; } - void setForceEnabled(bool newForce) { m_force = newForce; } - bool ignoreSettingsEnabled() const { return m_ignoreSettings; } - void setIgnoreSettingsEnabled(bool newIgnoreSettings) { m_ignoreSettings = newIgnoreSettings; } - bool writeDefaultSettingsEnabled() const { return m_writeDefaultSettings; } - void setWriteDefaultSettingsEnabled(bool newWriteDefaultSettings) - { - m_writeDefaultSettings = newWriteDefaultSettings; - } - bool indentWidthSet() const { return m_indentWidthSet; } - void setIndentWidthSet(bool newIndentWidthSet) { m_indentWidthSet = newIndentWidthSet; } - QStringList errors() const { return m_errors; } - void addError(const QString &newError) { m_errors.append(newError); }; - void applySettings(const QQmlFormatSettings &settings); - -private: - QQmlJS::Dom::LineWriterOptions m_options; - QQmlFormatOptionLineEndings m_newline = Native; - QStringList m_files; - QStringList m_arguments; - QStringList m_errors; - bool m_verbose = false; - bool m_valid = false; - bool m_inplace = false; - bool m_force = false; - bool m_ignoreSettings = false; - bool m_writeDefaultSettings = false; - bool m_indentWidthSet = false; -}; - -QQmlFormatOptions::QQmlFormatOptions() -{ - m_options.updateOptions = QQmlJS::Dom::LineWriterOptions::Update::None; - setTabsEnabled(false); - setNormalizeEnabled(false); - setObjectsSpacing(false); - setFunctionsSpacing(false); - setIndentWidth(4); -} - -QQmlFormatOptions::LineEndings QQmlFormatOptions::detectLineEndings(const QString &code) -{ - const QQmlJS::Dom::LineWriterOptions::LineEndings defaultEndings = -#if defined(Q_OS_WIN) - LineEndings::Windows; -#else - LineEndings::Unix; -#endif - // find out current line endings... - int newlineIndex = code.indexOf(QChar(u'\n')); - int crIndex = code.indexOf(QChar(u'\r')); - if (newlineIndex >= 0) { - if (crIndex >= 0) { - if (crIndex + 1 == newlineIndex) - return LineEndings::Windows; - qWarning().noquote() << "Invalid line ending in file, using default"; - return defaultEndings; - } - return LineEndings::Unix; - } - if (crIndex >= 0) { - return LineEndings::OldMacOs; - } - qWarning().noquote() << "Unknown line ending in file, using default"; - return defaultEndings; -} - -QQmlFormatOptionLineEndings QQmlFormatOptions::parseEndings(const QString &endings) -{ - if (endings == u"unix") - return Unix; - if (endings == u"windows") - return Windows; - if (endings == u"macos") - return OldMacOs; - if (endings == u"native") - return Native; - qWarning().noquote() << "Unknown line ending type" << endings << ", using default"; -#if defined (Q_OS_WIN) - return Windows; -#else - return Unix; -#endif -} - -void QQmlFormatOptions::applySettings(const QQmlFormatSettings &settings) -{ - // Don't overwrite tab settings that were already set. - if (!indentWidthSet()) { - if (settings.isSet(QQmlFormatSettings::s_indentWidthSetting)) - setIndentWidth(settings.value(QQmlFormatSettings::s_indentWidthSetting).toInt()); - if (settings.isSet(QQmlFormatSettings::s_useTabsSetting)) - setTabsEnabled(settings.value(QQmlFormatSettings::s_useTabsSetting).toBool()); - } - if (settings.isSet(QQmlFormatSettings::s_normalizeSetting)) - setNormalizeEnabled(settings.value(QQmlFormatSettings::s_normalizeSetting).toBool()); - if (settings.isSet(QQmlFormatSettings::s_newlineSetting)) - setNewline(QQmlFormatOptions::parseEndings(settings.value(QQmlFormatSettings::s_newlineSetting).toString())); - if (settings.isSet(QQmlFormatSettings::s_objectsSpacingSetting)) - setObjectsSpacing(settings.value(QQmlFormatSettings::s_objectsSpacingSetting).toBool()); - if (settings.isSet(QQmlFormatSettings::s_functionsSpacingSetting)) - setFunctionsSpacing(settings.value(QQmlFormatSettings::s_functionsSpacingSetting).toBool()); -} - static void logParsingErrors(const DomItem &fileItem, const QString &filename) { fileItem.iterateErrors( |