src/tools/moc/moc.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
--- a/src/tools/moc/moc.cpp	Fri Sep 17 08:34:18 2010 +0300
+++ b/src/tools/moc/moc.cpp	Mon Oct 04 01:19:32 2010 +0300
@@ -727,6 +727,7 @@
                 error("Class declarations lacks Q_OBJECT macro.");
 
             checkSuperClasses(&def);
+            checkProperties(&def);
 
             classList += def;
             knownQObjectClasses.insert(def.classname);
@@ -1211,7 +1212,7 @@
 
     //when searching commas within the default argument, we should take care of template depth (anglecount)
     // unfortunatelly, we do not have enough semantic information to know if '<' is the operator< or
-    // the begining of a template type. so we just use heuristics.
+    // the beginning of a template type. so we just use heuristics.
     int possible = -1;
 
     while (index < symbols.size()) {
@@ -1312,5 +1313,62 @@
     }
 }
 
+void Moc::checkProperties(ClassDef *cdef)
+{
+    //
+    // specify get function, for compatibiliy we accept functions
+    // returning pointers, or const char * for QByteArray.
+    //
+    for (int i = 0; i < cdef->propertyList.count(); ++i) {
+        PropertyDef &p = cdef->propertyList[i];
+        if (p.read.isEmpty())
+            continue;
+        for (int j = 0; j < cdef->publicList.count(); ++j) {
+            const FunctionDef &f = cdef->publicList.at(j);
+            if (f.name != p.read)
+                continue;
+            if (!f.isConst) // get  functions must be const
+                continue;
+            if (f.arguments.size()) // and must not take any arguments
+                continue;
+            PropertyDef::Specification spec = PropertyDef::ValueSpec;
+            QByteArray tmp = f.normalizedType;
+            if (p.type == "QByteArray" && tmp == "const char *")
+                tmp = "QByteArray";
+            if (tmp.left(6) == "const ")
+                tmp = tmp.mid(6);
+            if (p.type != tmp && tmp.endsWith('*')) {
+                tmp.chop(1);
+                spec = PropertyDef::PointerSpec;
+            } else if (f.type.name.endsWith('&')) { // raw type, not normalized type
+                spec = PropertyDef::ReferenceSpec;
+            }
+            if (p.type != tmp)
+                continue;
+            p.gspec = spec;
+            break;
+        }
+        if(!p.notify.isEmpty()) {
+            int notifyId = -1;
+            for (int j = 0; j < cdef->signalList.count(); ++j) {
+                const FunctionDef &f = cdef->signalList.at(j);
+                if(f.name != p.notify) {
+                    continue;
+                } else {
+                    notifyId = j /* Signal indexes start from 0 */;
+                    break;
+                }
+            }
+            p.notifyId = notifyId;
+            if (notifyId == -1) {
+                QByteArray msg = "NOTIFY signal '" + p.notify + "' of property '" + p.name
+                        + "' does not exist in class " + cdef->classname + ".";
+                error(msg.constData());
+            }
+        }
+    }
+}
+
+
 
 QT_END_NAMESPACE