aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-03-29 14:11:38 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-29 21:20:32 +0100
commit61e519e230217aa32869ed70fc38ee947fb9b313 (patch)
treee39ee106dbeb8b493d1d836d394e4ed7d6d709b1
parentabbb5c2bd9e1701c07d59d47e3f401a84537cc75 (diff)
Eliminate noop translation bindings
We can store them as regular strings. This has the advantage that the entire special handling from the custom parser of the list model goes away, we don't need astForBinding in QQmlCustomParser anymore neither and types with a custom parser can now generally benefit from the expression simplification pass. Change-Id: I39d1b76edd1273d8c73b847aed71f7bcce37d877 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp54
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp5
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h4
-rw-r--r--src/qml/types/qqmllistmodel.cpp42
-rw-r--r--src/qml/types/qqmllistmodel_p.h2
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp6
7 files changed, 48 insertions, 67 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 224bd23898..57cadfd1e4 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1641,17 +1641,6 @@ const QQmlImports &QQmlPropertyValidator::imports() const
return *compiler->imports();
}
-QQmlJS::AST::Node *QQmlPropertyValidator::astForBinding(int objectIndex, int scriptIndex) const
-{
- const QmlIR::Object *obj = compiler->qmlObjects()->at(objectIndex);
- // ####
- int reverseIndex = obj->runtimeFunctionIndices->indexOf(scriptIndex);
- if (reverseIndex == -1)
- return 0;
- QmlIR::CompiledFunctionOrExpression *foe = obj->functionsAndExpressions->slowAt(reverseIndex);
- return foe ? foe->node : 0;
-}
-
QQmlBinding::Identifier QQmlPropertyValidator::bindingIdentifier(const QV4::CompiledData::Binding *binding, QQmlCustomParser *)
{
const int id = customParserBindings.count();
@@ -2465,7 +2454,6 @@ void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex)
QQmlJavaScriptBindingExpressionSimplificationPass::QQmlJavaScriptBindingExpressionSimplificationPass(QQmlTypeCompiler *typeCompiler)
: QQmlCompilePass(typeCompiler)
, qmlObjects(*typeCompiler->qmlObjects())
- , customParsers(typeCompiler->customParserCache())
, jsModule(typeCompiler->jsIRModule())
{
@@ -2484,10 +2472,6 @@ void QQmlJavaScriptBindingExpressionSimplificationPass::reduceTranslationBinding
void QQmlJavaScriptBindingExpressionSimplificationPass::reduceTranslationBindings(int objectIndex)
{
const QmlIR::Object *obj = qmlObjects.at(objectIndex);
- // Don't feed QV4::CompiledData::Binding::Type_Translation into custom parsers.
- const bool allowTranslations = !customParsers.contains(obj->inheritedTypeNameIndex);
- if (!allowTranslations)
- return;
for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
if (binding->type != QV4::CompiledData::Binding::Type_Script)
@@ -2705,6 +2689,44 @@ bool QQmlJavaScriptBindingExpressionSimplificationPass::detectTranslationCallAnd
binding->stringIndex = compiler->registerString(id);
binding->value.translationData = translationData;
return true;
+ } else if (*_nameOfFunctionCalled == QStringLiteral("QT_TR_NOOP") || *_nameOfFunctionCalled == QStringLiteral("QT_TRID_NOOP")) {
+ QVector<int>::ConstIterator param = _functionParameters.constBegin();
+ QVector<int>::ConstIterator end = _functionParameters.constEnd();
+ if (param == end)
+ return false;
+
+ QV4::IR::String *stringParam = _temps[*param]->asString();
+ if (!stringParam)
+ return false;
+
+ ++param;
+ if (param != end)
+ return false;
+
+ binding->type = QV4::CompiledData::Binding::Type_String;
+ binding->stringIndex = compiler->registerString(*stringParam->value);
+ return true;
+ } else if (*_nameOfFunctionCalled == QStringLiteral("QT_TRANSLATE_NOOP")) {
+ QVector<int>::ConstIterator param = _functionParameters.constBegin();
+ QVector<int>::ConstIterator end = _functionParameters.constEnd();
+ if (param == end)
+ return false;
+
+ ++param;
+ if (param == end)
+ return false;
+
+ QV4::IR::String *stringParam = _temps[*param]->asString();
+ if (!stringParam)
+ return false;
+
+ ++param;
+ if (param != end)
+ return false;
+
+ binding->type = QV4::CompiledData::Binding::Type_String;
+ binding->stringIndex = compiler->registerString(*stringParam->value);
+ return true;
}
return false;
}
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index ca84cee1f8..d54bc1b37b 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -254,7 +254,6 @@ public:
// Re-implemented for QQmlCustomParser
virtual const QQmlImports &imports() const;
- virtual QQmlJS::AST::Node *astForBinding(int objectIndex, int scriptIndex) const;
virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding, QQmlCustomParser *parser);
private:
@@ -340,7 +339,6 @@ private:
bool detectTranslationCallAndConvertBinding(QmlIR::Binding *binding);
const QList<QmlIR::Object*> &qmlObjects;
- const QHash<int, QQmlCustomParser*> &customParsers;
QV4::IR::Module *jsModule;
bool _canSimplify;
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index fc08f33141..75acbdb778 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -142,11 +142,6 @@ QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QV4::CompiledD
return compiler->bindingIdentifier(binding, this);
}
-QQmlJS::AST::Node *QQmlCustomParser::astForBinding(int objectIndex, int scriptIndex) const
-{
- return compiler->astForBinding(objectIndex, scriptIndex);
-}
-
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index fb9c405b59..49a397d3bb 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -71,8 +71,6 @@ struct QQmlCustomParserCompilerBackend
const QMetaObject *resolveType(const QString& name) const;
virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *, QQmlCustomParser *) { return QQmlBinding::Invalid; }
-
- virtual QQmlJS::AST::Node *astForBinding(int, int) const { return 0; }
};
class Q_QML_PRIVATE_EXPORT QQmlCustomParser
@@ -110,8 +108,6 @@ protected:
QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding);
- QQmlJS::AST::Node *astForBinding(int objectIndex, int scriptIndex) const;
-
private:
QList<QQmlError> exceptions;
QQmlCustomParserCompilerBackend *compiler;
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index f9badcd381..12b42d6de1 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -2254,7 +2254,7 @@ void QQmlListModel::sync()
qmlInfo(this) << "List sync() can only be called from a WorkerScript";
}
-bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList<QQmlListModelParser::ListInstruction> &instr, QByteArray &data)
+bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<QQmlListModelParser::ListInstruction> &instr, QByteArray &data)
{
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
const quint32 targetObjectIndex = binding->value.objectIndex;
@@ -2296,7 +2296,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU
li.dataIdx = ref;
instr << li;
- if (!compileProperty(qmlUnit, targetObjectIndex, binding, instr, data))
+ if (!compileProperty(qmlUnit, binding, instr, data))
return false;
li.type = ListInstruction::Pop;
@@ -2334,38 +2334,8 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU
bool ok;
int v = evaluateEnum(script, &ok);
if (!ok) {
- using namespace QQmlJS;
- AST::Node *node = astForBinding(objectIndex, binding->value.compiledScriptIndex);
- if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement*>(node))
- node = stmt->expression;
- AST::StringLiteral *literal = 0;
- if (AST::CallExpression *callExpr = AST::cast<AST::CallExpression *>(node)) {
- if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(callExpr->base)) {
- if (idExpr->name == QLatin1String("QT_TR_NOOP") || idExpr->name == QLatin1String("QT_TRID_NOOP")) {
- if (callExpr->arguments && !callExpr->arguments->next)
- literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression);
- if (!literal) {
- error(binding, QQmlListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString()));
- return false;
- }
- } else if (idExpr->name == QLatin1String("QT_TRANSLATE_NOOP")) {
- if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next)
- literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression);
- if (!literal) {
- error(binding, QQmlListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP"));
- return false;
- }
- }
- }
- }
-
- if (literal) {
- d[0] = char(String);
- d += literal->value.toUtf8();
- } else {
- error(binding, QQmlListModel::tr("ListElement: cannot use script for property value"));
- return false;
- }
+ error(binding, QQmlListModel::tr("ListElement: cannot use script for property value"));
+ return false;
} else {
d[0] = char(Number);
d += QByteArray::number(v);
@@ -2387,7 +2357,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU
return true;
}
-QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList<const QV4::CompiledData::Binding *> &bindings)
+QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int /*objectIndex*/, const QList<const QV4::CompiledData::Binding *> &bindings)
{
QList<ListInstruction> instr;
QByteArray data;
@@ -2399,7 +2369,7 @@ QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUni
error(binding, QQmlListModel::tr("ListModel: undefined property '%1'").arg(propName));
return QByteArray();
}
- if (!compileProperty(qmlUnit, objectIndex, binding, instr, data))
+ if (!compileProperty(qmlUnit, binding, instr, data))
return QByteArray();
}
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 17fbb8a819..c41983eaed 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -183,7 +183,7 @@ private:
int instrCount;
ListInstruction *instructions() const;
};
- bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList<ListInstruction> &instr, QByteArray &data);
+ bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<ListInstruction> &instr, QByteArray &data);
bool definesEmptyList(const QString &);
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 787aa0f7da..678849c371 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -296,17 +296,17 @@ void tst_qqmllistmodel::static_i18n_data()
QTest::newRow("QT_TR_NOOP extra param")
<< QString::fromUtf8("ListElement { foo: QT_TR_NOOP(\"hello\",\"world\") }")
<< QVariant(QString())
- << QString("ListElement: improperly specified QT_TR_NOOP");
+ << QString("ListElement: cannot use script for property value");
QTest::newRow("QT_TRANSLATE_NOOP missing params")
<< "ListElement { foo: QT_TRANSLATE_NOOP() }"
<< QVariant(QString())
- << QString("ListElement: improperly specified QT_TRANSLATE_NOOP");
+ << QString("ListElement: cannot use script for property value");
QTest::newRow("QT_TRID_NOOP missing param")
<< QString::fromUtf8("ListElement { foo: QT_TRID_NOOP() }")
<< QVariant(QString())
- << QString("ListElement: improperly specified QT_TRID_NOOP");
+ << QString("ListElement: cannot use script for property value");
}
void tst_qqmllistmodel::static_i18n()