Optimize QML enum resolution
authorMartin Jones <martin.jones@nokia.com>
Fri, 18 May 2012 01:52:17 +0000 (11:52 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 24 May 2012 05:17:34 +0000 (07:17 +0200)
Change-Id: Ibc9ffe882045adf1c1149601c3499e31b9393eeb
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
src/qml/qml/qqmlcompiler.cpp
src/qml/qml/qqmlcompiler_p.h
src/qml/qml/qqmlcustomparser.cpp

index d568cc4..b00f4b3 100644 (file)
@@ -2546,9 +2546,19 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
     if (!string.at(0).isUpper())
         return true;
 
+    int dot = string.indexOf(QLatin1Char('.'));
+    if (dot == -1 || dot == string.length()-1)
+        return true;
+
+    if (string.indexOf(QLatin1Char('.'), dot+1) != -1)
+        return true;
+
+    QHashedStringRef typeName(string.constData(), dot);
+    QString enumValue = string.mid(dot+1);
+
     if (isIntProp) {
         // Allow enum assignment to ints.
-        int enumval = evaluateEnum(string.toUtf8());
+        int enumval = evaluateEnum(typeName, enumValue.toUtf8());
         if (enumval != -1) {
             v->type = Value::Literal;
             v->value = QQmlScript::Variant((double)enumval);
@@ -2557,18 +2567,12 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
         return true;
     }
 
-    QStringList parts = string.split(QLatin1Char('.'));
-    if (parts.count() != 2)
-        return true;
-
-    QString typeName = parts.at(0);
     QQmlType *type = 0;
     unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
 
     if (!type)
         return true;
 
-    QString enumValue = parts.at(1);
     int value = 0;
     bool ok;
 
@@ -2608,24 +2612,22 @@ struct StaticQtMetaObject : public QObject
 };
 
 // Similar logic to above, but not knowing target property.
-int QQmlCompiler::evaluateEnum(const QByteArray& script) const
+int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue) const
 {
-    int dot = script.indexOf('.');
-    if (dot > 0) {
-        const QByteArray &scope = script.left(dot);
-        QQmlType *type = 0;
-        unit->imports().resolveType(QString::fromUtf8(script.left(dot)), &type, 0, 0, 0, 0);
-        if (!type && scope != "Qt")
+    QQmlType *type = 0;
+    if (scope != QLatin1String("Qt")) {
+        unit->imports().resolveType(scope, &type, 0, 0, 0, 0);
+        if (!type)
             return -1;
-        const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
-        const char *key = script.constData() + dot+1;
-        int i = mo->enumeratorCount();
-        while (i--) {
-            bool ok;
-            int v = mo->enumerator(i).keyToValue(key, &ok);
-            if (ok)
-                return v;
-        }
+
+    }
+    const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
+    int i = mo->enumeratorCount();
+    while (i--) {
+        bool ok;
+        int v = mo->enumerator(i).keyToValue(enumValue.constData(), &ok);
+        if (ok)
+            return v;
     }
     return -1;
 }
index f2e2376..a326344 100644 (file)
@@ -297,7 +297,7 @@ public:
     static bool isAttachedPropertyName(const QHashedStringRef &);
     static bool isSignalPropertyName(const QHashedStringRef &);
 
-    int evaluateEnum(const QByteArray& script) const; // for QQmlCustomParser::evaluateEnum
+    int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue) const; // for QQmlCustomParser::evaluateEnum
     const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType
     int rewriteBinding(const QQmlScript::Variant& value, const QString& name); // for QQmlCustomParser::rewriteBinding
     QString rewriteSignalHandler(const QQmlScript::Variant& value, const QString &name);  // for QQmlCustomParser::rewriteSignalHandler
index 67e580c..f020376 100644 (file)
@@ -286,7 +286,11 @@ void QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& de
 */
 int QQmlCustomParser::evaluateEnum(const QByteArray& script) const
 {
-    return compiler->evaluateEnum(script);
+    int dot = script.indexOf('.');
+    if (dot == -1)
+        return -1;
+
+    return compiler->evaluateEnum(QString::fromUtf8(script.left(dot)), script.mid(dot+1));
 }
 
 /*!