qmllint: Warn about assigning numeric types to strings
While it is generally possible to assign a numeric to a value of string type, this is not the case for literal bindings: There, the engine's QQmlTypeValidator notices the mismatch, and rejects the program. Bring qmllint in line with that behavior. Additionally, teach parseLiteralBinding to treat constant UnaryMinusExpressions as NumberLiteral bindings. Change-Id: Iad221e90eb1de81cabdddf5d601cc30f53ef20d3 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
30251c0781
commit
7917b7ad64
|
@ -1335,7 +1335,8 @@ void QQmlJSImportVisitor::parseLiteralBinding(const QString name,
|
|||
QString literalType;
|
||||
QQmlJSMetaPropertyBinding::BindingType bindingType = QQmlJSMetaPropertyBinding::Invalid;
|
||||
|
||||
switch (exprStatement->expression->kind) {
|
||||
auto expr = exprStatement->expression;
|
||||
switch (expr->kind) {
|
||||
case Node::Kind_TrueLiteral:
|
||||
value = true;
|
||||
literalType = u"bool"_qs;
|
||||
|
@ -1356,21 +1357,21 @@ void QQmlJSImportVisitor::parseLiteralBinding(const QString name,
|
|||
break;
|
||||
case Node::Kind_NumericLiteral:
|
||||
literalType = u"double"_qs;
|
||||
value = cast<NumericLiteral *>(exprStatement->expression)->value;
|
||||
value = cast<NumericLiteral *>(expr)->value;
|
||||
bindingType = QQmlJSMetaPropertyBinding::NumberLiteral;
|
||||
break;
|
||||
case Node::Kind_StringLiteral:
|
||||
literalType = u"string"_qs;
|
||||
value = cast<StringLiteral *>(exprStatement->expression)->value.toString();
|
||||
value = cast<StringLiteral *>(expr)->value.toString();
|
||||
bindingType = QQmlJSMetaPropertyBinding::StringLiteral;
|
||||
break;
|
||||
case Node::Kind_RegExpLiteral:
|
||||
literalType = u"regexp"_qs;
|
||||
value = cast<RegExpLiteral *>(exprStatement->expression)->pattern.toString();
|
||||
value = cast<RegExpLiteral *>(expr)->pattern.toString();
|
||||
bindingType = QQmlJSMetaPropertyBinding::RegExpLiteral;
|
||||
break;
|
||||
case Node::Kind_TemplateLiteral: {
|
||||
auto templateLit = QQmlJS::AST::cast<QQmlJS::AST::TemplateLiteral *>(exprStatement->expression);
|
||||
auto templateLit = QQmlJS::AST::cast<QQmlJS::AST::TemplateLiteral *>(expr);
|
||||
Q_ASSERT(templateLit);
|
||||
value = templateLit->value.toString();
|
||||
if (templateLit->hasNoSubstitution) {
|
||||
|
@ -1382,7 +1383,14 @@ void QQmlJSImportVisitor::parseLiteralBinding(const QString name,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
if (QQmlJS::AST::UnaryMinusExpression *unaryMinus = QQmlJS::AST::cast<QQmlJS::AST::UnaryMinusExpression *>(expr)) {
|
||||
if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(unaryMinus->expression)) {
|
||||
literalType = u"double"_qs;
|
||||
bindingType = QQmlJSMetaPropertyBinding::NumberLiteral;
|
||||
value = -lit->value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!QQmlJSMetaPropertyBinding::isLiteralBinding(bindingType))
|
||||
|
|
|
@ -146,6 +146,9 @@ void QQmlJSTypeResolver::init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *p
|
|||
.arg(binding.literalTypeName())
|
||||
.arg(property.typeName()),
|
||||
Log_Type, binding.sourceLocation());
|
||||
} else if (property.type() == m_stringType && isNumeric(binding.literalType())) {
|
||||
m_logger->logWarning(u"Cannot assign a numeric constant to a string property"_qs,
|
||||
Log_Type, binding.sourceLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
property string i: 1
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
property string i: -1
|
||||
}
|
|
@ -515,6 +515,16 @@ void TestQmllint::dirtyQmlCode_data()
|
|||
<< QStringLiteral("Cannot assign binding of type QString to int")
|
||||
<< QString()
|
||||
<< false;
|
||||
QTest::newRow("bad constant number to string")
|
||||
<< QStringLiteral("numberToStringProperty.qml")
|
||||
<< QStringLiteral("Cannot assign a numeric constant to a string property")
|
||||
<< QString()
|
||||
<< false;
|
||||
QTest::newRow("bad unary minus to string")
|
||||
<< QStringLiteral("unaryMinusToStringProperty.qml")
|
||||
<< QStringLiteral("Cannot assign a numeric constant to a string property")
|
||||
<< QString()
|
||||
<< false;
|
||||
QTest::newRow("BadBinding")
|
||||
<< QStringLiteral("badBinding.qml")
|
||||
<< QStringLiteral("Binding assigned to \"doesNotExist\", but no property "
|
||||
|
|
Loading…
Reference in New Issue