aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Visser <mjmvisser@gmail.com>2013-04-30 14:12:37 -0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-08 10:46:13 +0200
commit13afb2b49daec9f5f65dc9a99151c91d685dce13 (patch)
tree79c00dec10a6d90152213c0a85fafe6a9a480a95 /src
parent22fc92cf9187460785a05e31620823fe8afe5eab (diff)
QQmlError.object now holds the scope object that caused exceptions.
Exception errors sent via QQmlEngine::warnings lacked a pointer to the containing scope. I added an object property to QQmlError, and the necessary code to fill it with the QObject* scope from binding exception callbacks. Task-number: QTBUG-30930 Change-Id: I2a987e8cefc3a2a474d338893e9ebcb77c167adf Reviewed-by: Kai Koehne <kai.koehne@digia.com> Reviewed-by: Alan Alpert <aalpert@blackberry.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlerror.cpp25
-rw-r--r--src/qml/qml/qqmlerror.h2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp9
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h1
-rw-r--r--src/qml/qml/qqmlproperty.cpp5
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp1
-rw-r--r--src/qml/qml/v8/qv8bindings.cpp1
7 files changed, 43 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 98d8259dda..0c8e46bd8d 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -84,10 +84,11 @@ public:
QString description;
quint16 line;
quint16 column;
+ QObject *object;
};
QQmlErrorPrivate::QQmlErrorPrivate()
-: line(0), column(0)
+: line(0), column(0), object()
{
}
@@ -122,6 +123,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
+ d->object = other.d->object;
}
return *this;
}
@@ -215,6 +217,27 @@ void QQmlError::setColumn(int column)
}
/*!
+ Returns the nearest object where this error occurred.
+ Exceptions in bound property expressions set this to the object
+ to which the property belongs. It will be 0 for all
+ other exceptions.
+ */
+QObject *QQmlError::object() const
+{
+ if (d) return d->object;
+ else return 0;
+}
+
+/*!
+ Sets the nearest \a object where this error occurred.
+ */
+void QQmlError::setObject(QObject *object)
+{
+ if (!d) d = new QQmlErrorPrivate;
+ d->object = object;
+}
+
+/*!
Returns the error as a human readable string.
*/
QString QQmlError::toString() const
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index cea9ee4cc0..cfa0dfcdbf 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -70,6 +70,8 @@ public:
void setLine(int);
int column() const;
void setColumn(int);
+ QObject *object() const;
+ void setObject(QObject *);
QString toString() const;
private:
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 4568307d5b..2a1ed1406a 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -79,6 +79,11 @@ void QQmlDelayedError::setErrorDescription(const QString &description)
m_error.setDescription(description);
}
+void QQmlDelayedError::setErrorObject(QObject *object)
+{
+ m_error.setObject(object);
+}
+
/*
Converting from a message to an error is relatively expensive.
@@ -348,6 +353,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -360,6 +366,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -390,6 +397,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -402,6 +410,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index c48972e6a1..b521ea3bee 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -84,6 +84,7 @@ public:
void setMessage(v8::Handle<v8::Message> message);
void setErrorLocation(const QUrl &url, quint16 line, quint16 column);
void setErrorDescription(const QString &description);
+ void setErrorObject(QObject *object);
private:
void convertMessageToError(QQmlEngine *engine) const;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 0baf450cbf..0936df59c4 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1555,6 +1555,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
// we explicitly disallow this case to avoid confusion. Users can still store one
// in an array in a var property if they need to, but the common case is user error.
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
@@ -1570,6 +1571,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
if (!result.IsEmpty() && result->IsFunction()
&& !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) {
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
writeValueProperty(object, core, QVariant::fromValue(v8engine->scriptValueFromInternal(result)), context, flags);
@@ -1580,12 +1582,14 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
else
errorStr += QLatin1String(QMetaType::typeName(type));
expression->delayedError()->setErrorDescription(errorStr);
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (result->IsFunction()) {
if (!result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty())
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
else
expression->delayedError()->setErrorDescription(QLatin1String("Unable to assign a function to a property of any type other than var."));
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (!writeValueProperty(object, core, value, context, flags)) {
@@ -1618,6 +1622,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QLatin1String(valueType) +
QLatin1String(" to ") +
QLatin1String(propertyType));
+ expression->delayedError()->setErrorObject(object);
return false;
}
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index b680bf798b..668f7b4d05 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -793,6 +793,7 @@ static void throwException(int id, QQmlDelayedError *error,
error->setErrorDescription(QLatin1String("TypeError: Result of expression is not an object"));
else
error->setErrorDescription(description);
+ error->setErrorObject(context->contextObject);
if (id != 0xFF) {
quint32 e = *((quint32 *)(program->data() + program->exceptionDataOffset) + id);
error->setErrorLocation(context->url, (e >> 16), (e & 0xFFFF));
diff --git a/src/qml/qml/v8/qv8bindings.cpp b/src/qml/qml/v8/qv8bindings.cpp
index 8d133e728a..757d9d9cf6 100644
--- a/src/qml/qml/v8/qv8bindings.cpp
+++ b/src/qml/qml/v8/qv8bindings.cpp
@@ -191,6 +191,7 @@ void QV8Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags)
delayedError()->setErrorLocation(parent->url(), instruction->line, 0);
if (hasError()) {
+ delayedError()->setErrorObject(object());
if (!delayedError()->addError(ep)) ep->warning(this->error(context->engine));
} else {
clearError();