aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp24
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h2
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp36
3 files changed, 48 insertions, 14 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 6f1558383d..6c1d22c90d 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -2398,6 +2398,19 @@ void QQmlJSImportVisitor::endVisit(UiArrayBinding *arrayBinding)
}
}
+void QQmlJSImportVisitor::handleDuplicateEnums(UiEnumMemberList *members, const QString &key,
+ const QQmlJS::SourceLocation &location)
+{
+ m_logger->log(u"Enum key '%1' has already been declared"_s.arg(key), qmlSyntax, location);
+ for (const auto *member = members; member; member = member->next) {
+ if (member->member.toString() == key) {
+ m_logger->log(u"Note: previous declaration of '%1' here"_s.arg(key), qmlSyntax,
+ member->memberToken);
+ return;
+ }
+ }
+}
+
bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiEnumDeclaration *uied)
{
if (m_currentScope->inlineComponentName()) {
@@ -2407,7 +2420,16 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiEnumDeclaration *uied)
QQmlJSMetaEnum qmlEnum(uied->name.toString());
qmlEnum.setIsQml(true);
for (const auto *member = uied->members; member; member = member->next) {
- qmlEnum.addKey(member->member.toString());
+ const QString key = member->member.toString();
+
+ if (!key.front().isUpper()) {
+ m_logger->log(u"Enum keys should start with an uppercase."_s, qmlSyntax,
+ member->memberToken);
+ }
+ if (qmlEnum.hasKey(key))
+ handleDuplicateEnums(uied->members, key, member->memberToken);
+
+ qmlEnum.addKey(key);
qmlEnum.addValue(int(member->value));
}
m_currentScope->addOwnEnumeration(qmlEnum);
diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h
index 0d12ea0b6a..5de1c80c32 100644
--- a/src/qmlcompiler/qqmljsimportvisitor_p.h
+++ b/src/qmlcompiler/qqmljsimportvisitor_p.h
@@ -109,6 +109,8 @@ protected:
bool visit(QQmlJS::AST::UiArrayBinding *) override;
void endVisit(QQmlJS::AST::UiArrayBinding *) override;
bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
+ void handleDuplicateEnums(QQmlJS::AST::UiEnumMemberList *members, const QString &key,
+ const QQmlJS::SourceLocation &location);
bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
void endVisit(QQmlJS::AST::FunctionExpression *) override;
bool visit(QQmlJS::AST::UiSourceElement *) override;
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index a151b70f13..5aaf05612b 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -1324,6 +1324,20 @@ void TestQmllint::dirtyQmlCode()
});
}
+static void addLocationOffsetTo(TestQmllint::Result *result, qsizetype lineOffset,
+ qsizetype columnOffset = 0)
+{
+ for (auto *messages :
+ { &result->expectedMessages, &result->badMessages, &result->expectedReplacements }) {
+ for (auto &message : *messages) {
+ if (message.line != 0)
+ message.line += lineOffset;
+ if (message.column != 0)
+ message.column += columnOffset;
+ }
+ }
+}
+
void TestQmllint::dirtyQmlSnippet_data()
{
QTest::addColumn<QString>("code");
@@ -1331,6 +1345,11 @@ void TestQmllint::dirtyQmlSnippet_data()
QTest::newRow("testSnippet") << u"property int qwer: \"Hello\""_s
<< Result{ { { "Cannot assign literal of type string to int"_L1 } } };
+
+ QTest::newRow("enum") << u"enum Hello { World, Kitty, World, dlrow }"_s
+ << Result{ { { "Enum key 'World' has already been declared"_L1, 1, 28 },
+ { "Note: previous declaration of 'World' here"_L1, 1, 14 },
+ { "Enum keys should start with an uppercase"_L1, 1, 35 } } };
}
void TestQmllint::dirtyQmlSnippet()
@@ -1338,7 +1357,9 @@ void TestQmllint::dirtyQmlSnippet()
QFETCH(QString, code);
QFETCH(Result, result);
- QString qmlCode = "import QtQuick\nItem {%1}"_L1.arg(code);
+ QString qmlCode = "import QtQuick\nItem {\n%1}"_L1.arg(code);
+
+ addLocationOffsetTo(&result, 2);
QJsonArray warnings;
callQmllint(QString(), result.flags.testFlag(Result::ExitsNormally), &warnings, {}, {}, {},
@@ -1353,6 +1374,7 @@ void TestQmllint::cleanQmlSnippet_data()
QTest::addColumn<QString>("code");
QTest::newRow("testSnippet") << u"property int qwer: 123"_s;
+ QTest::newRow("enum") << u"enum Hello { World, Kitty, DlroW }"_s;
}
void TestQmllint::cleanQmlSnippet()
@@ -1386,18 +1408,6 @@ void TestQmllint::dirtyJsSnippet_data()
};
}
-static void addLocationOffsetTo(TestQmllint::Result *result, qsizetype lineOffset,
- qsizetype columnOffset = 0)
-{
- for (auto *messages :
- { &result->expectedMessages, &result->badMessages, &result->expectedReplacements }) {
- for (auto &message : *messages) {
- message.line += lineOffset;
- message.column += columnOffset;
- }
- }
-}
-
void TestQmllint::dirtyJsSnippet()
{
QFETCH(QString, code);