summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlcompiler.cpp83
-rw-r--r--src/declarative/qml/qmlcompiler_p.h1
-rw-r--r--src/declarative/qml/qmlinstruction.cpp3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h7
-rw-r--r--src/declarative/qml/qmlvme.cpp33
-rw-r--r--tests/auto/declarative/qmlparser/missingSignal.errors.txt2
6 files changed, 59 insertions, 70 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index ed520c1..b205efb 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -725,51 +725,82 @@ bool QmlCompiler::compileFetchedObject(Object *obj, int ctxt)
return true;
}
+int QmlCompiler::signalByName(const QMetaObject *mo, const QByteArray &name)
+{
+ int methods = mo->methodCount();
+ for (int ii = methods - 1; ii >= 0; --ii) {
+ QMetaMethod method = mo->method(ii);
+ QByteArray methodName = method.signature();
+ int idx = methodName.indexOf('(');
+ methodName = methodName.left(idx);
+
+ if (methodName == name)
+ return ii;
+ }
+ return -1;
+}
+
bool QmlCompiler::compileSignal(Property *prop, Object *obj)
{
+ Q_ASSERT(obj->metaObject());
+
if (prop->values.isEmpty() && !prop->value)
return true;
if (prop->value || prop->values.count() > 1)
COMPILE_EXCEPTION("Incorrectly specified signal");
- if (prop->values.at(0)->object) {
- int pr = output->indexForByteArray(prop->name);
+ QByteArray name = prop->name;
+ Q_ASSERT(name.startsWith("on"));
+ name = name.mid(2);
+ if(name[0] >= 'A' && name[0] <= 'Z')
+ name[0] = name[0] - 'A' + 'a';
- bool rv = compileObject(prop->values.at(0)->object, 0);
+ int sigIdx = signalByName(obj->metaObject(), name);
- if (rv) {
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignSignalObject;
- assign.line = prop->values.at(0)->location.start.line;
- assign.assignSignalObject.signal = pr;
+ if (sigIdx == -1) {
- output->bytecode << assign;
+ COMPILE_CHECK(compileProperty(prop, obj, 0));
- prop->values.at(0)->type = Value::SignalObject;
- }
+ } else {
- return rv;
+ if (prop->values.at(0)->object) {
+ int pr = output->indexForByteArray(prop->name);
- } else {
- QString script = prop->values.at(0)->value.asScript().trimmed();
- if (script.isEmpty())
- return true;
+ bool rv = compileObject(prop->values.at(0)->object, 0);
+
+ if (rv) {
+ QmlInstruction assign;
+ assign.type = QmlInstruction::AssignSignalObject;
+ assign.line = prop->values.at(0)->location.start.line;
+ assign.assignSignalObject.signal = pr;
- int idx = output->indexForString(script);
- int pr = output->indexForByteArray(prop->name);
+ output->bytecode << assign;
- QmlInstruction assign;
- assign.type = QmlInstruction::AssignSignal;
- assign.line = prop->values.at(0)->location.start.line;
- assign.assignSignal.signal = pr;
- assign.assignSignal.value = idx;
+ prop->values.at(0)->type = Value::SignalObject;
+ }
- output->bytecode << assign;
+ return rv;
- prop->values.at(0)->type = Value::SignalExpression;
- }
+ } else {
+ QString script = prop->values.at(0)->value.asScript().trimmed();
+ if (script.isEmpty())
+ return true;
+ int idx = output->indexForString(script);
+
+ QmlInstruction store;
+ store.line = prop->values.at(0)->location.start.line;
+ store.type = QmlInstruction::StoreSignal;
+ store.storeSignal.signalIndex = sigIdx;
+ store.storeSignal.value = idx;
+
+ output->bytecode << store;
+
+ prop->values.at(0)->type = Value::SignalExpression;
+ }
+ }
+
return true;
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 246dd70..64400c5 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -139,6 +139,7 @@ private:
bool compileFetchedObject(QmlParser::Object *obj, int);
bool compileSignal(QmlParser::Property *prop, QmlParser::Object *obj);
bool testProperty(QmlParser::Property *prop, QmlParser::Object *obj);
+ int signalByName(const QMetaObject *, const QByteArray &name);
bool compileProperty(QmlParser::Property *prop, QmlParser::Object *obj, int);
bool compileIdProperty(QmlParser::Property *prop,
QmlParser::Object *obj);
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 0617913..6b49359 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -127,9 +127,6 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
case QmlInstruction::AssignConstant:
qWarning() << idx << "\t" << line << "\t" << "ASSIGN_CONSTANT\t" << instr->assignConstant.property << "\t" << instr->assignConstant.constant << "\t\t" << datas.at(instr->assignConstant.property) << primitives.at(instr->assignConstant.constant);
break;
- case QmlInstruction::AssignSignal:
- qWarning() << idx << "\t" << line << "\t" << "ASSIGN_SIGNAL\t\t" << instr->assignSignal.signal << "\t" << instr->assignSignal.value << "\t\t" << datas.at(instr->assignSignal.signal) << primitives.at(instr->assignSignal.value);
- break;
case QmlInstruction::AssignSignalObject:
qWarning() << idx << "\t" << line << "\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal);
break;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index f465e9f..f06f0e6 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -112,10 +112,7 @@ public:
//
// AssignConstant - Store a value in a property. Will resolve into
// a Store* instruction.
- // AssignSignal - Set a signal handler on the property. Will resolve
- // into a Store*Signal instruction.
AssignConstant, /* assignConstant */
- AssignSignal, /* assignSignal */
AssignSignalObject, /* assignSignalObject */
AssignCustomType, /* assignCustomType */
@@ -273,10 +270,6 @@ public:
} storeSignal;
struct {
int signal;
- int value;
- } assignSignal;
- struct {
- int signal;
} assignSignalObject;
struct {
int count;
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index dc9ef06..51534e7 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -88,7 +88,6 @@ Q_DECLARE_PERFORMANCE_LOG(QFxCompiler) {
Q_DECLARE_PERFORMANCE_METRIC(InstrStoreSignal);
Q_DECLARE_PERFORMANCE_METRIC(InstrStoreObjectQmlList);
Q_DECLARE_PERFORMANCE_METRIC(InstrAssignConstant);
- Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignal);
Q_DECLARE_PERFORMANCE_METRIC(InstrAssignSignalObject);
Q_DECLARE_PERFORMANCE_METRIC(InstrAssignBinding);
Q_DECLARE_PERFORMANCE_METRIC(InstrAssignCompiledBinding);
@@ -138,7 +137,6 @@ Q_DEFINE_PERFORMANCE_LOG(QFxCompiler, "QFxCompiler") {
Q_DEFINE_PERFORMANCE_METRIC(InstrStoreSignal, "StoreSignal");
Q_DEFINE_PERFORMANCE_METRIC(InstrStoreObjectQmlList, "StoreObjectQmlList");
Q_DEFINE_PERFORMANCE_METRIC(InstrAssignConstant, "AssignConstant");
- Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignal, "AssignSignal");
Q_DEFINE_PERFORMANCE_METRIC(InstrAssignSignalObject, "AssignSignalObject");
Q_DEFINE_PERFORMANCE_METRIC(InstrAssignBinding, "AssignBinding");
Q_DEFINE_PERFORMANCE_METRIC(InstrAssignCompiledBinding, "AssignCompiledBinding");
@@ -356,37 +354,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
- case QmlInstruction::AssignSignal:
- {
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrAssignSignal> cc;
-#endif
- // Fixup instruction
- QObject *target = stack.top();
- int sigIdx = instr.assignSignal.signal;
- const QByteArray &pr = datas.at(sigIdx);
-
- QmlMetaProperty prop(target, QLatin1String(pr));
- if (prop.type() & QmlMetaProperty::SignalProperty) {
- int coreIdx = prop.coreIndex();
- int primRef = instr.assignSignal.value;
- instr.type = QmlInstruction::StoreSignal;
- instr.storeSignal.signalIndex = coreIdx;
- instr.storeSignal.value = primRef;
- --ii;
- } else if (prop.type() & QmlMetaProperty::Property) {
- int prop = sigIdx;
- int primRef = instr.assignSignal.value;
- instr.type = QmlInstruction::AssignConstant;
- instr.assignConstant.property = prop;
- instr.assignConstant.constant = primRef;
- --ii;
- } else {
- VME_EXCEPTION("Cannot assign a signal to property" << pr);
- }
- }
- break;
-
case QmlInstruction::AssignSignalObject:
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
diff --git a/tests/auto/declarative/qmlparser/missingSignal.errors.txt b/tests/auto/declarative/qmlparser/missingSignal.errors.txt
index 8ae1bbe4..9815b99 100644
--- a/tests/auto/declarative/qmlparser/missingSignal.errors.txt
+++ b/tests/auto/declarative/qmlparser/missingSignal.errors.txt
@@ -1 +1 @@
-2:-1:Cannot assign a signal to property "onClicked"
+2:-1:Unknown property "onClicked"