aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier De Cannière <[email protected]>2025-04-29 16:35:10 +0200
committerOlivier De Cannière <[email protected]>2025-05-08 12:31:35 +0200
commitfb61c6bb84100b47e6c9aaf59571b15371092c67 (patch)
tree2031d4208637b5c23ed45191fc197b04a170d5e7
parent230c1afe3e5c9b01bd2494b3eb9b90fec2844a50 (diff)
qmllint: Warn about duplicate inline components
Fixes: QTBUG-126715 Task-number: QTBUG-129307 Change-Id: I739587bf6d44131d9a0bdcec4df60ab3f53e1a12 Reviewed-by: Sami Shalayel <[email protected]>
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp11
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h1
-rw-r--r--src/qmlcompiler/qqmljslogger.cpp3
-rw-r--r--src/qmlcompiler/qqmljsloggingutils.h1
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp6
5 files changed, 22 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index df5d9cd5ab..8233aa1e61 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -1750,6 +1750,17 @@ bool QQmlJSImportVisitor::visit(UiInlineComponent *component)
return true;
}
+ const auto it = m_seenInlineComponents.constFind(component->name);
+ if (it != m_seenInlineComponents.cend()) {
+ m_logger->log("Duplicate inline component '%1'"_L1.arg(it.key()),
+ qmlDuplicateInlineComponent, component->firstSourceLocation());
+ m_logger->log("Note: previous component named '%1' here"_L1.arg(it.key()),
+ qmlDuplicateInlineComponent, it.value(), true, true, {}, {},
+ component->firstSourceLocation().startLine);
+ } else {
+ m_seenInlineComponents[component->name] = component->firstSourceLocation();
+ }
+
m_nextIsInlineComponent = true;
m_currentRootName = component->name.toString();
return true;
diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h
index c56f6a9f99..5573e1eff9 100644
--- a/src/qmlcompiler/qqmljsimportvisitor_p.h
+++ b/src/qmlcompiler/qqmljsimportvisitor_p.h
@@ -384,6 +384,7 @@ protected:
QSet<QQmlJSScope::ConstPtr> m_literalScopesToCheck;
QQmlJS::SourceLocation m_pendingSignalHandler;
QStringList m_seenModuleQualifiers;
+ QHash<QStringView, QQmlJS::SourceLocation> m_seenInlineComponents;
private:
void registerTargetIntoImporter(const QQmlJSScope::Ptr &target);
diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp
index 5b1c2fee9c..c729a623f5 100644
--- a/src/qmlcompiler/qqmljslogger.cpp
+++ b/src/qmlcompiler/qqmljslogger.cpp
@@ -43,6 +43,8 @@ using namespace Qt::StringLiterals;
true) \
X(qmlDeprecated, "deprecated", "Deprecated", "Warn about deprecated properties and types", \
QtWarningMsg, false, false) \
+ X(qmlDuplicateInlineComponent, "duplicate-inline-component", "DuplicateInlineComponent", \
+ "Warn about duplicate inline components", QtWarningMsg, false, false) \
X(qmlDuplicatePropertyBinding, "duplicate-property-binding", "DuplicatePropertyBinding", \
"Warn about duplicate property bindings", QtWarningMsg, false, false) \
X(qmlDuplicatedName, "duplicated-name", "DuplicatedName", \
@@ -119,6 +121,7 @@ using namespace Qt::StringLiterals;
"positives when checking for unqualified access", \
QtWarningMsg, false, false)
+
#define X(category, name, setting, description, level, ignored, isDefault) \
const QQmlSA::LoggerWarningId category{ name };
QMLLINT_DEFAULT_CATEGORIES
diff --git a/src/qmlcompiler/qqmljsloggingutils.h b/src/qmlcompiler/qqmljsloggingutils.h
index 0d2210bd80..4134a4a003 100644
--- a/src/qmlcompiler/qqmljsloggingutils.h
+++ b/src/qmlcompiler/qqmljsloggingutils.h
@@ -47,6 +47,7 @@ extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlAttachedPropertyReu
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlCompiler;
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlDeferredPropertyId;
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlDeprecated;
+extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlDuplicateInlineComponent;
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlDuplicatePropertyBinding;
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlDuplicatedName;
extern const Q_QMLCOMPILER_EXPORT QQmlSA::LoggerWarningId qmlEval;
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index ec408e96f7..4101d9f315 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -1255,6 +1255,12 @@ void TestQmllint::dirtyQmlSnippet_data()
<< Result{ { { "Duplicate binding on property 'pixelSize'"_L1, 1, 40 },
{ "Note: previous binding on 'pixelSize' here"_L1, 1, 26 } } }
<< defaultOptions;
+ QTest::newRow("duplicateInlineComponent")
+ << u"component A: QtObject {}\n"_s
+ u"Item { component A: Item {} }\n"_s
+ << Result{ { { "Duplicate inline component 'A'"_L1, 2, 8 },
+ { "Note: previous component named 'A' here"_L1, 1, 1 } } }
+ << defaultOptions;
QTest::newRow("duplicateObjectBinding")
<< u"property Item i; i: Item {} i: Item {}"_s
<< Result{ { { "Duplicate binding on property 'i'"_L1, 1, 29 },