QmlCompiler: Reject conversions via QJSValue
Those are generally less efficient than what the interpreter would do, they can have side effects, and they can throw exceptions. We don't want to deal with any of that. Most of those implicit conversions have explicit equivalents. For those that don't we can add them. Pick-to: 6.2 6.4 Fixes: QTBUG-104010 Change-Id: I62898db92219386c94f2a6c9b56f6fb0b7578832 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
48ae7468af
commit
fb3a81623a
|
@ -2060,8 +2060,8 @@ void QQmlJSCodeGenerator::generate_Mod(int lhs)
|
|||
const auto rhsVar = conversion(
|
||||
m_state.accumulatorIn().storedType(), m_typeResolver->jsPrimitiveType(),
|
||||
m_state.accumulatorVariableIn);
|
||||
Q_ASSERT(!lhsVar.isEmpty());
|
||||
Q_ASSERT(!rhsVar.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !lhsVar.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !rhsVar.isEmpty());
|
||||
|
||||
m_body += m_state.accumulatorVariableOut;
|
||||
m_body += u" = "_s;
|
||||
|
@ -2262,8 +2262,8 @@ void QQmlJSCodeGenerator::generateArithmeticOperation(int lhs, const QString &cp
|
|||
registerVariable(lhs));
|
||||
const auto rhsVar = conversion(m_state.accumulatorIn(), m_state.readAccumulator(),
|
||||
m_state.accumulatorVariableIn);
|
||||
Q_ASSERT(!lhsVar.isEmpty());
|
||||
Q_ASSERT(!rhsVar.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !lhsVar.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !rhsVar.isEmpty());
|
||||
|
||||
const QQmlJSRegisterContent originalOut = m_typeResolver->original(m_state.accumulatorOut());
|
||||
m_body += m_state.accumulatorVariableOut;
|
||||
|
@ -2611,10 +2611,10 @@ QString QQmlJSCodeGenerator::conversion(const QQmlJSScope::ConstPtr &from,
|
|||
return u"QJSPrimitiveValue("_s + variable + u')' + retrieve;
|
||||
}
|
||||
|
||||
// TODO: more efficient string conversions, possibly others
|
||||
// TODO: add more conversions
|
||||
|
||||
return u"aotContext->engine->fromScriptValue<"_s + castTargetName(to)
|
||||
+ u">(aotContext->engine->toScriptValue("_s + variable + u"))"_s;
|
||||
reject(u"conversion from "_s + from->internalName() + u" to "_s + to->internalName());
|
||||
return QString();
|
||||
}
|
||||
|
||||
int QQmlJSCodeGenerator::nextJSLine(uint line) const
|
||||
|
|
|
@ -133,6 +133,7 @@ set(qml_files
|
|||
text.qml
|
||||
themerbad.qml
|
||||
themergood.qml
|
||||
toString.qml
|
||||
typePropertyClash.qml
|
||||
typedArray.qml
|
||||
undefinedResets.qml
|
||||
|
|
|
@ -3,6 +3,7 @@ import TestTypes
|
|||
import Ambiguous 1.2
|
||||
|
||||
QtObject {
|
||||
id: self
|
||||
property string attachedForNonObject: objectName.Component.objectName
|
||||
property string attachedForNasty: Nasty.objectName
|
||||
|
||||
|
@ -27,4 +28,6 @@ QtObject {
|
|||
}
|
||||
|
||||
Component.onCompleted: doesNotExist()
|
||||
|
||||
property string aString: self + "a"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import QtQml
|
||||
|
||||
QtObject {
|
||||
id: self
|
||||
property QtObject other: QtObject {
|
||||
function toString() : string { throw "no" }
|
||||
}
|
||||
|
||||
function toString() : string { return "yes" }
|
||||
|
||||
property string yes: self + " yes"
|
||||
property string no: other + " no"
|
||||
}
|
|
@ -120,6 +120,7 @@ private slots:
|
|||
void boundComponents();
|
||||
void invisibleListElementType();
|
||||
void typePropertyClash();
|
||||
void objectToString();
|
||||
};
|
||||
|
||||
void tst_QmlCppCodegen::simpleBinding()
|
||||
|
@ -2194,6 +2195,20 @@ void tst_QmlCppCodegen::typePropertyClash()
|
|||
QCOMPARE(o->objectName(), u"Size: 5"_s);
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::objectToString()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, QUrl(u"qrc:/TestTypes/toString.qml"_s));
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "qrc:/TestTypes/toString.qml:6: no");
|
||||
QScopedPointer<QObject> o(c.create());
|
||||
QVERIFY(!o.isNull());
|
||||
|
||||
QCOMPARE(o->property("yes").toString(), u"yes yes"_s);
|
||||
QCOMPARE(o->property("no").toString(), u" no"_s); // throws, but that is ignored
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::runInterpreted()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
|
Loading…
Reference in New Issue