aboutsummaryrefslogtreecommitdiffstats
path: root/examples/qmlcompiler/tutorials/helloworld
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2023-09-01 17:57:19 +0200
committerOlivier De Cannière <olivier.decanniere@qt.io>2023-11-28 09:45:24 +0100
commitf4c13d1b738d25c563d00c0bc25e720775d985a3 (patch)
tree8fa5485d45b05c5b7201215abf391266ed357de6 /examples/qmlcompiler/tutorials/helloworld
parentf8b6cdf63400103a6ca53c19bb845577e94b41be (diff)
QQmlSA: Add initial fixit section
FixSuggestion unfortunately still lacks class documentation, and we probably need to rework the API before moving the module out of TP. However, we should still show the basic usage of the module, including fixit suggestions. Consequently, add a small example on how to write FixSuggestions, and add a warning note that they should only be marked as auto-applicable if the resulting code is still valid. Pick-to: 6.6 Change-Id: I260021163e3afe2cda97fd82a9bf4e9c26a910e2 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'examples/qmlcompiler/tutorials/helloworld')
-rw-r--r--examples/qmlcompiler/tutorials/helloworld/chapter3/CMakeLists.txt22
-rw-r--r--examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.cpp64
-rw-r--r--examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.h21
-rw-r--r--examples/qmlcompiler/tutorials/helloworld/chapter3/plugin.json13
-rw-r--r--examples/qmlcompiler/tutorials/helloworld/chapter3/test.qml26
5 files changed, 146 insertions, 0 deletions
diff --git a/examples/qmlcompiler/tutorials/helloworld/chapter3/CMakeLists.txt b/examples/qmlcompiler/tutorials/helloworld/chapter3/CMakeLists.txt
new file mode 100644
index 0000000000..b9466b61b3
--- /dev/null
+++ b/examples/qmlcompiler/tutorials/helloworld/chapter3/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.21)
+
+project(hello_world_plugin VERSION 1.0.0 LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 REQUIRED COMPONENTS QmlCompiler)
+
+qt_standard_project_setup(
+ REQUIRES 6.6
+)
+
+qt_add_plugin(HelloWorldPlugin)
+
+target_sources(HelloWorldPlugin
+ PRIVATE
+ helloplugin.h
+ helloplugin.cpp
+)
+
+target_link_libraries(HelloWorldPlugin PRIVATE Qt::QmlCompiler)
diff --git a/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.cpp b/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.cpp
new file mode 100644
index 0000000000..93ee6d80c4
--- /dev/null
+++ b/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "helloplugin.h"
+#include <QDebug>
+
+using namespace Qt::StringLiterals;
+
+static constexpr QQmlSA::LoggerWarningId helloWorld { "Plugin.HelloWorld.hello-world" };
+
+class HelloWorldElementPass : public QQmlSA::ElementPass
+{
+public:
+ HelloWorldElementPass(QQmlSA::PassManager *manager);
+ bool shouldRun(const QQmlSA::Element &element) override;
+ void run(const QQmlSA::Element &element) override;
+private:
+ QQmlSA::Element m_textType;
+};
+
+HelloWorldElementPass::HelloWorldElementPass(QQmlSA::PassManager *manager)
+ : QQmlSA::ElementPass(manager)
+{
+ m_textType = resolveType("QtQuick", "Text");
+}
+
+bool HelloWorldElementPass::shouldRun(const QQmlSA::Element &element)
+{
+ if (!element.inherits(m_textType))
+ return false;
+ if (!element.hasOwnPropertyBindings(u"text"_s))
+ return false;
+ return true;
+}
+
+void HelloWorldElementPass::run(const QQmlSA::Element &element)
+{
+ auto textBindings = element.ownPropertyBindings(u"text"_s);
+ for (const auto &textBinding: textBindings) {
+ if (textBinding.bindingType() != QQmlSA::BindingType::StringLiteral)
+ continue;
+ QString currentBinding = textBinding.stringValue();
+ if (currentBinding == u"Hello world!"_s)
+ continue;
+ if (currentBinding == u"Goodbye world!"_s) {
+ QQmlSA::FixSuggestion suggestion(u"Replace 'Goodbye' with 'Hello'"_s,
+ textBinding.sourceLocation(), u"\"Hello world!\""_s);
+ suggestion.setAutoApplicable(true);
+ emitWarning("Incorrect greeting", helloWorld, textBinding.sourceLocation(), suggestion);
+ }
+ }
+}
+
+
+void HelloWorldPlugin::registerPasses(QQmlSA::PassManager *manager, const QQmlSA::Element &rootElement)
+{
+ const bool pluginIsEnabled = manager->isCategoryEnabled(helloWorld);
+ qDebug() << "Hello World plugin is" << (pluginIsEnabled ? "enabled" : "disabled");
+ if (!pluginIsEnabled)
+ return; // skip registration if the plugin is disabled anyway
+ manager->registerElementPass(std::make_unique<HelloWorldElementPass>(manager));
+}
+
+#include "moc_helloplugin.cpp"
diff --git a/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.h b/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.h
new file mode 100644
index 0000000000..6666c78be0
--- /dev/null
+++ b/examples/qmlcompiler/tutorials/helloworld/chapter3/helloplugin.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef HELLO_PLUGIN_H
+#define HELLO_PLUGIN_H
+
+#include <QtCore/qobject.h>
+#include <QtQmlCompiler/qqmlsa.h>
+
+class HelloWorldPlugin : public QObject, public QQmlSA::LintPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QmlLintPluginInterface_iid FILE "plugin.json")
+ Q_INTERFACES(QQmlSA::LintPlugin)
+
+public:
+ void registerPasses(QQmlSA::PassManager *manager, const QQmlSA::Element &rootElement) override;
+};
+
+#endif
+
diff --git a/examples/qmlcompiler/tutorials/helloworld/chapter3/plugin.json b/examples/qmlcompiler/tutorials/helloworld/chapter3/plugin.json
new file mode 100644
index 0000000000..3d8c1ff206
--- /dev/null
+++ b/examples/qmlcompiler/tutorials/helloworld/chapter3/plugin.json
@@ -0,0 +1,13 @@
+{
+ "name": "HelloWorld",
+ "author": "Qt Example",
+ "description": "Demonstrates how to write a qmllint plugin",
+ "version": "1.0",
+ "loggingCategories": [
+ {
+ "name": "hello-world",
+ "settingsName": "HelloWorld",
+ "description": "Used to create test messages"
+ }
+ ]
+}
diff --git a/examples/qmlcompiler/tutorials/helloworld/chapter3/test.qml b/examples/qmlcompiler/tutorials/helloworld/chapter3/test.qml
new file mode 100644
index 0000000000..42fbaa108f
--- /dev/null
+++ b/examples/qmlcompiler/tutorials/helloworld/chapter3/test.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+// [0]
+import QtQuick
+
+Item {
+ id: root
+
+ property string greeting: "Hello"
+
+ component MyText : Text {}
+
+ component NotText : Item {
+ property string text
+ }
+
+ Text { text: "Hello world!" }
+ Text { text: root.greeting }
+ Text { text: "Goodbye world!" }
+ NotText {
+ text: "Does not trigger"
+ MyText { text: "Goodbye world!" }
+ }
+}
+// [0]