Adapt to Qt5 meta-object changes
[profile/ivi/qtdeclarative.git] / src / qml / qml / v8 / qv8qobjectwrapper.cpp
index b84ae33..d61ca8b 100644 (file)
@@ -513,13 +513,13 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject
     if (!result)
         return v8::Handle<v8::Value>();
 
-    if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) {
+    if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
         QQmlData *ddata = QQmlData::get(object);
         if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
             return v8::Handle<v8::Value>();
     }
 
-    if (result->isFunction()) {
+    if (result->isFunction() && !result->isVMEProperty()) {
         if (result->isVMEFunction()) {
             return ((QQmlVMEMetaObject *)(object->metaObject()))->vmeMethod(result->coreIndex);
         } else if (result->isV8Function()) {
@@ -579,24 +579,55 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert
                                  v8::Handle<v8::Value> value)
 {
     QQmlBinding *newBinding = 0;
-
     if (value->IsFunction()) {
-        QQmlContextData *context = engine->callingContext();
-        v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
-
-        v8::Local<v8::StackTrace> trace = 
-            v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | 
-                                                                                     v8::StackTrace::kScriptName));
-        v8::Local<v8::StackFrame> frame = trace->GetFrame(0);
-        int lineNumber = frame->GetLineNumber();
-        int columNumber = frame->GetColumn();
-        QString url = engine->toString(frame->GetScriptName());
-
-        newBinding = new QQmlBinding(&function, object, context);
-        newBinding->setSourceLocation(url, lineNumber, columNumber);
-        newBinding->setTarget(object, *property, context);
-        newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
-                                     QQmlBinding::RequiresThisObject);
+        if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) {
+            if (!property->isVMEProperty()) {
+                // XXX TODO: uncomment the following lines
+                // assigning a JS function to a non-var-property is not allowed.
+                //QString error = QLatin1String("Cannot assign JavaScript function to ") +
+                //                QLatin1String(QMetaType::typeName(property->propType));
+                //v8::ThrowException(v8::Exception::Error(engine->toString(error)));
+                //return;
+                // XXX TODO: remove the following transition behaviour
+                // Temporarily allow assignment of functions to non-var properties
+                // to mean binding assignment (as per old behaviour).
+                QQmlContextData *context = engine->callingContext();
+                v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
+
+                v8::Local<v8::StackTrace> trace =
+                    v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
+                                                                                             v8::StackTrace::kScriptName));
+                v8::Local<v8::StackFrame> frame = trace->GetFrame(0);
+                int lineNumber = frame->GetLineNumber();
+                int columNumber = frame->GetColumn();
+                QString url = engine->toString(frame->GetScriptName());
+
+                newBinding = new QQmlBinding(&function, object, context);
+                newBinding->setSourceLocation(url, lineNumber, columNumber);
+                newBinding->setTarget(object, *property, context);
+                newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
+                                             QQmlBinding::RequiresThisObject);
+                qWarning("WARNING: function assignment is DEPRECATED and will be removed!  Wrap RHS in Qt.binding(): %s:%d", qPrintable(engine->toString(frame->GetScriptName())), frame->GetLineNumber());
+            }
+        } else {
+            // binding assignment.
+            QQmlContextData *context = engine->callingContext();
+            v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
+
+            v8::Local<v8::StackTrace> trace =
+                v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
+                                                                                         v8::StackTrace::kScriptName));
+            v8::Local<v8::StackFrame> frame = trace->GetFrame(0);
+            int lineNumber = frame->GetLineNumber();
+            int columNumber = frame->GetColumn();
+            QString url = engine->toString(frame->GetScriptName());
+
+            newBinding = new QQmlBinding(&function, object, context);
+            newBinding->setSourceLocation(url, lineNumber, columNumber);
+            newBinding->setTarget(object, *property, context);
+            newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
+                                         QQmlBinding::RequiresThisObject);
+        }
     }
 
     QQmlAbstractBinding *oldBinding = 
@@ -604,6 +635,12 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert
     if (oldBinding)
         oldBinding->destroy();
 
+    if (!newBinding && property->isVMEProperty()) {
+        // allow assignment of "special" values (null, undefined, function) to var properties
+        static_cast<QQmlVMEMetaObject *>(const_cast<QMetaObject *>(object->metaObject()))->setVMEProperty(property->coreIndex, value);
+        return;
+    }
+
 #define PROPERTY_STORE(cpptype, value) \
     cpptype o = value; \
     int status = -1; \
@@ -673,7 +710,7 @@ bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, const QH
     if (!result)
         return false;
 
-    if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) {
+    if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
         QQmlData *ddata = QQmlData::get(object);
         if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
             return false;
@@ -1636,16 +1673,6 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject)
     return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
 }
 
-static QByteArray QMetaMethod_name(const QMetaMethod &m)
-{
-    QByteArray sig = m.signature();
-    int paren = sig.indexOf('(');
-    if (paren == -1)
-        return sig;
-    else
-        return sig.left(paren);
-}
-
 /*!
 Returns the next related method, if one, or 0.
 */
@@ -1674,9 +1701,9 @@ static const QQmlPropertyData * RelatedMethod(QObject *object,
         dummy.load(method);
         
         // Look for overloaded methods
-        QByteArray methodName = QMetaMethod_name(method);
+        QByteArray methodName = method.name();
         for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) {
-            if (methodName == QMetaMethod_name(mo->method(ii))) {
+            if (methodName == mo->method(ii).name()) {
                 dummy.setFlags(dummy.getFlags() | QQmlPropertyData::IsOverload);
                 dummy.overrideIndexIsProperty = 0;
                 dummy.overrideIndex = ii;
@@ -1790,7 +1817,7 @@ static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QQmlPropertyD
         const QQmlPropertyData *candidate = &data;
         while (candidate) {
             error += QLatin1String("\n    ") + 
-                     QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).signature());
+                     QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).methodSignature().constData());
             candidate = RelatedMethod(object, candidate, dummy);
         }