diff options
author | Thomas Hartmann <thomas.hartmann@qt.io> | 2021-09-28 15:23:42 +0200 |
---|---|---|
committer | Thomas Hartmann <thomas.hartmann@qt.io> | 2021-11-12 20:04:19 +0000 |
commit | 39738dee7737c539c94f0c7aa022126cd8e94f28 (patch) | |
tree | b59ccdd4d38947f271917250fddd21af0ff49801 | |
parent | ebc753cf9bcf58918efe5282449966af3a37d132 (diff) |
QmlJS: Add error message for Component with multiple children
Component is only allowed to have a single child element, that will
be the root element of the component.
If there is no child at all we create a warning. Having no child is
temporarily required.
Change-Id: I5c0d9d9cdf1be106b20ed4f1134a973d58126498
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r-- | src/libs/qmljs/qmljscheck.cpp | 27 | ||||
-rw-r--r-- | src/libs/qmljs/qmljscheck.h | 1 | ||||
-rw-r--r-- | src/libs/qmljs/qmljsstaticanalysismessage.cpp | 4 | ||||
-rw-r--r-- | src/libs/qmljs/qmljsstaticanalysismessage.h | 2 |
4 files changed, 31 insertions, 3 deletions
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index bd5d25834e..1bfd9e9701 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -794,8 +794,10 @@ bool Check::visit(UiObjectInitializer *) UiQualifiedId *qualifiedTypeId = qualifiedTypeNameId(parent()); if (qualifiedTypeId) { typeName = qualifiedTypeId->name.toString(); - if (typeName == "Component") + if (typeName == "Component") { m_idStack.push(StringSet()); + _componentChildCount = 0; + } } m_typeStack.push(typeName); @@ -806,10 +808,23 @@ bool Check::visit(UiObjectInitializer *) return true; } -void Check::endVisit(UiObjectInitializer *) +void Check::endVisit(UiObjectInitializer *uiObjectInitializer) { m_propertyStack.pop(); - m_typeStack.pop(); + + const QString type = m_typeStack.pop(); + + if (type == "Component" && _componentChildCount == 0) { + SourceLocation loc; + UiObjectDefinition *objectDefinition = cast<UiObjectDefinition *>(parent()); + if (objectDefinition) + loc = objectDefinition->qualifiedTypeNameId->identifierToken; + UiObjectBinding *objectBinding = cast<UiObjectBinding *>(parent()); + if (objectBinding) + loc = objectBinding->qualifiedTypeNameId->identifierToken; + addMessage(WarnComponentRequiresChildren, loc); + } + UiObjectDefinition *objectDefinition = cast<UiObjectDefinition *>(parent()); if (objectDefinition && objectDefinition->qualifiedTypeNameId->name == QLatin1String("Component")) m_idStack.pop(); @@ -962,6 +977,12 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, addMessage(ErrUnsupportedRootTypeInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation()), typeName); + if (!m_typeStack.isEmpty() && m_typeStack.last() == "Component") { + _componentChildCount++; + if (_componentChildCount > 1) + addMessage(ErrToManyComponentChildren, typeErrorLocation); + } + bool typeError = false; if (_importsOk) { const ObjectValue *prototype = _context->lookupType(_doc.data(), typeId); diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h index 362c0cc0ac..10019a9794 100644 --- a/src/libs/qmljs/qmljscheck.h +++ b/src/libs/qmljs/qmljscheck.h @@ -158,6 +158,7 @@ private: bool _importsOk; bool _inStatementBinding; + int _componentChildCount = 0; const Imports *_imports; TranslationFunction lastTransLationfunction = noTranslationfunction; }; diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index 24bb70c186..c65508bdfa 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -251,6 +251,10 @@ StaticAnalysisMessages::StaticAnalysisMessages() tr("Type cannot be instantiated recursively (%1)."), 1); newMsg(WarnLogicalValueDoesNotDependOnValues, Warning, tr("Logical value does not depend on actual values")); + newMsg(ErrToManyComponentChildren, Error, + tr("Components are only allowed to have a single child element.")); + newMsg(WarnComponentRequiresChildren, Warning, + tr("Components require a child element.")); } } // anonymous namespace diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h index e651533fd7..51a517d235 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.h +++ b/src/libs/qmljs/qmljsstaticanalysismessage.h @@ -132,6 +132,8 @@ enum Type { ErrInvalidArrayValueLength = 323, ErrHitMaximumRecursion = 324, WarnLogicalValueDoesNotDependOnValues = 325, + ErrToManyComponentChildren = 326, + WarnComponentRequiresChildren = 327, WarnDuplicateImport = 400 }; |