qmllint: Do basic type checking on script bindings

Do basic type checking on script bindings. We already check types for object bindings.
This sadly does not include support for type checking literals as they do not generate bytecode.
This will be addressed separately.

Task-number: QTBUG-91633
Change-Id: I9dadbf106b395e9b702b0a803a7fc9a1e1805cf4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Maximilian Goldstein 2021-08-06 16:03:25 +02:00
parent cde314d388
commit 03ef433efd
5 changed files with 32 additions and 0 deletions

View File

@ -104,6 +104,11 @@ void QQmlJSTypePropagator::generate_Ret()
setError(u"cannot convert from %1 to %2"_qs
.arg(m_state.accumulatorIn.descriptiveName(),
m_returnType.descriptiveName()));
m_logger->logWarning(u"Cannot assign binding of type %1 to %2"_qs.arg(
m_typeResolver->containedTypeName(m_state.accumulatorIn),
m_typeResolver->containedTypeName(m_returnType)),
Log_Type, getCurrentBindingSourceLocation());
return;
}
@ -250,6 +255,15 @@ QQmlJS::SourceLocation QQmlJSTypePropagator::getCurrentSourceLocation() const
return location;
}
QQmlJS::SourceLocation QQmlJSTypePropagator::getCurrentBindingSourceLocation() const
{
Q_ASSERT(m_currentContext->sourceLocationTable);
const auto &entries = m_currentContext->sourceLocationTable->entries;
Q_ASSERT(!entries.isEmpty());
return combine(entries.constFirst().location, entries.constLast().location);
}
void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name) const
{
auto location = getCurrentSourceLocation();

View File

@ -264,6 +264,7 @@ private:
void checkDeprecated(QQmlJSScope::ConstPtr scope, const QString &name, bool isMethod) const;
bool checkRestricted(const QString &propertyName) const;
QQmlJS::SourceLocation getCurrentSourceLocation() const;
QQmlJS::SourceLocation getCurrentBindingSourceLocation() const;
void propagateBinaryOperation(QSOperator::Op op, int lhs);
void propagateCall(const QList<QQmlJSMetaMethod> &methods, int argc, int argv);

View File

@ -0,0 +1,5 @@
import QtQuick
Item {
property int number: 3 + "Hello"
}

View File

@ -0,0 +1,6 @@
import QtQuick
Item {
function returnsString() : string {}
property int number: returnsString()
}

View File

@ -620,6 +620,12 @@ void TestQmllint::dirtyQmlCode_data()
QTest::newRow("WithStatement")
<< QStringLiteral("WithStatement.qml")
<< QStringLiteral("with statements are strongly discouraged") << QString() << false;
QTest::newRow("BindingTypeMismatch")
<< QStringLiteral("bindingTypeMismatch.qml")
<< QStringLiteral("Cannot assign binding of type QString to int") << QString() << false;
QTest::newRow("BindingTypeMismatchFunction")
<< QStringLiteral("bindingTypeMismatchFunction.qml")
<< QStringLiteral("Cannot assign binding of type QString to int") << QString() << false;
}
void TestQmllint::dirtyQmlCode()