Delay conversion of v8 exceptions to QQmlErrors.
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlexpression.cpp
index 60a0fe1..8c24c4a 100644 (file)
@@ -60,7 +60,7 @@ static QQmlJavaScriptExpression::VTable QQmlExpressionPrivate_jsvtable = {
 QQmlExpressionPrivate::QQmlExpressionPrivate()
 : QQmlJavaScriptExpression(&QQmlExpressionPrivate_jsvtable),
   expressionFunctionValid(true), expressionFunctionRewritten(false),
-  extractExpressionFromFunction(false), line(-1), dataRef(0)
+  line(-1)
 {
 }
 
@@ -68,8 +68,6 @@ QQmlExpressionPrivate::~QQmlExpressionPrivate()
 {
     qPersistentDispose(v8qmlscope);
     qPersistentDispose(v8function);
-    if (dataRef) dataRef->release();
-    dataRef = 0;
 }
 
 void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QObject *me)
@@ -137,7 +135,8 @@ QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object,
 
 /*!
     \class QQmlExpression
-    \since 4.7
+    \since 5.0
+    \inmodule QtQml
     \brief The QQmlExpression class evaluates JavaScript in a QML context.
 
     For example, given a file \c main.qml like this:
@@ -161,6 +160,8 @@ QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object,
     QQmlExpression *expr = new QQmlExpression(engine->rootContext(), myObject, "width * 2");
     int result = expr->evaluate().toInt();  // result = 400
     \endcode
+
+    Note that the QtQuick 1 version is called QDeclarativeExpression.
 */
 
 /*!
@@ -175,7 +176,7 @@ QQmlExpression::QQmlExpression()
 }
 
 /*!  \internal */
-QQmlExpression::QQmlExpression(QQmlContextData *ctxt, 
+QQmlExpression::QQmlExpression(QQmlContextData *ctxt,
                                                QObject *object, const QString &expr, bool isRewritten,
                                                const QString &url, int lineNumber, int columnNumber,
                                                QQmlExpressionPrivate &dd)
@@ -200,7 +201,7 @@ QQmlExpression::QQmlExpression(QQmlContextData *ctxt,
 /*!
     Create a QQmlExpression object that is a child of \a parent.
 
-    The \script provides the expression to be evaluated, the context to evaluate it in,
+    The \script provides the expression to be evaluated, the context to evaluate it in,
     and the scope object to evaluate it with.
 
     This constructor is functionally equivalent to the following, but in most cases
@@ -215,32 +216,28 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QObject *parent)
 : QObject(*new QQmlExpressionPrivate, parent)
 {
     Q_D(QQmlExpression);
-    bool defaultConstruction = false;
+
+    if (!script.context()->isValid())
+        return;
+
+    bool defaultConstruction = true;
 
     int id = script.d.data()->bindingId;
-    if (id < 0) {
-        defaultConstruction = true;
-    } else {
+    if (id >= 0) {
         QQmlContextData *ctxtdata = QQmlContextData::get(script.context());
-
         QQmlEnginePrivate *engine = QQmlEnginePrivate::get(script.context()->engine());
-        QQmlCompiledData *cdata = 0;
-        QQmlTypeData *typeData = 0;
         if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
-            typeData = engine->typeLoader.get(ctxtdata->url);
-            cdata = typeData->compiledData();
-        }
+            QQmlTypeData *typeData = engine->typeLoader.getType(ctxtdata->url);
+            Q_ASSERT(typeData);
 
-        if (cdata)
-            d->init(ctxtdata, cdata->primitives.at(id), true, script.scopeObject(),
-                    cdata->name, script.d.data()->lineNumber, script.d.data()->columnNumber);
-        else
-           defaultConstruction = true;
+            if (QQmlCompiledData *cdata = typeData->compiledData()) {
+                defaultConstruction = false;
+                d->init(ctxtdata, cdata->primitives.at(id), true, script.scopeObject(),
+                        cdata->name, script.d.data()->lineNumber, script.d.data()->columnNumber);
+            }
 
-        if (cdata)
-            cdata->release();
-        if (typeData)
             typeData->release();
+        }
     }
 
     if (defaultConstruction)
@@ -264,7 +261,7 @@ QQmlExpression::QQmlExpression(QQmlContext *ctxt,
     d->init(QQmlContextData::get(ctxt), expression, scope);
 }
 
-/*! 
+/*!
     \internal
 */
 QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope,
@@ -318,13 +315,7 @@ QQmlContext *QQmlExpression::context() const
 QString QQmlExpression::expression() const
 {
     Q_D(const QQmlExpression);
-    if (d->extractExpressionFromFunction && context()->engine()) {
-        QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(context()->engine());
-        v8::HandleScope handle_scope;
-        v8::Context::Scope scope(v8engine->context());
-
-        return v8engine->toString(v8::Handle<v8::Value>(d->v8function));
-    } else if (!d->expressionUtf8.isEmpty()) {
+    if (!d->expressionUtf8.isEmpty()) {
         return QString::fromUtf8(d->expressionUtf8);
     } else {
         return d->expression;
@@ -348,7 +339,7 @@ void QQmlExpression::setExpression(const QString &expression)
 }
 
 // Must be called with a valid handle scope
-v8::Local<v8::Value> QQmlExpressionPrivate::v8value(QObject *secondaryScope, bool *isUndefined)
+v8::Local<v8::Value> QQmlExpressionPrivate::v8value(bool *isUndefined)
 {
     if (!expressionFunctionValid) {
         bool ok = true;
@@ -366,21 +357,10 @@ v8::Local<v8::Value> QQmlExpressionPrivate::v8value(QObject *secondaryScope, boo
         expressionFunctionValid = true;
     }
 
-
-    if (secondaryScope) {
-        v8::Local<v8::Value> result;
-        QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
-        QObject *restoreSecondaryScope = 0;
-        restoreSecondaryScope = ep->v8engine()->contextWrapper()->setSecondaryScope(v8qmlscope, secondaryScope);
-        result = evaluate(context(), v8function, isUndefined);
-        ep->v8engine()->contextWrapper()->setSecondaryScope(v8qmlscope, restoreSecondaryScope);
-        return result;
-    } else {
-        return evaluate(context(), v8function, isUndefined);
-    }
+    return evaluate(context(), v8function, isUndefined);
 }
 
-QVariant QQmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
+QVariant QQmlExpressionPrivate::value(bool *isUndefined)
 {
     Q_Q(QQmlExpression);
 
@@ -397,7 +377,7 @@ QVariant QQmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined
     {
         v8::HandleScope handle_scope;
         v8::Context::Scope context_scope(ep->v8engine()->context());
-        v8::Local<v8::Value> result = v8value(secondaryScope, isUndefined);
+        v8::Local<v8::Value> result = v8value(isUndefined);
         rv = ep->v8engine()->toVariant(result, qMetaTypeId<QList<QObject*> >());
     }
 
@@ -418,7 +398,7 @@ QVariant QQmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined
 QVariant QQmlExpression::evaluate(bool *valueIsUndefined)
 {
     Q_D(QQmlExpression);
-    return d->value(0, valueIsUndefined);
+    return d->value(valueIsUndefined);
 }
 
 /*!
@@ -464,7 +444,7 @@ QString QQmlExpression::sourceFile() const
 }
 
 /*!
-    Returns the source file line number for this expression.  The source location 
+    Returns the source file line number for this expression.  The source location
     must have been previously set by calling setSourceLocation().
 */
 int QQmlExpression::lineNumber() const
@@ -510,7 +490,7 @@ QObject *QQmlExpression::scopeObject() const
 /*!
     Returns true if the last call to evaluate() resulted in an error,
     otherwise false.
-    
+
     \sa error(), clearError()
 */
 bool QQmlExpression::hasError() const
@@ -541,7 +521,7 @@ void QQmlExpression::clearError()
 QQmlError QQmlExpression::error() const
 {
     Q_D(const QQmlExpression);
-    return d->error();
+    return d->error(engine());
 }
 
 /*!
@@ -567,7 +547,7 @@ void QQmlExpressionPrivate::expressionChanged()
 QString QQmlExpressionPrivate::expressionIdentifier(QQmlJavaScriptExpression *e)
 {
     QQmlExpressionPrivate *This = static_cast<QQmlExpressionPrivate *>(e);
-    return QLatin1String("\"") + This->expression + QLatin1String("\"");
+    return QLatin1Char('"') + This->expression + QLatin1Char('"');
 }
 
 QT_END_NAMESPACE