725 |
725 |
726 if (!def.hasQObject && !def.hasQGadget) |
726 if (!def.hasQObject && !def.hasQGadget) |
727 error("Class declarations lacks Q_OBJECT macro."); |
727 error("Class declarations lacks Q_OBJECT macro."); |
728 |
728 |
729 checkSuperClasses(&def); |
729 checkSuperClasses(&def); |
|
730 checkProperties(&def); |
730 |
731 |
731 classList += def; |
732 classList += def; |
732 knownQObjectClasses.insert(def.classname); |
733 knownQObjectClasses.insert(def.classname); |
733 knownQObjectClasses.insert(def.qualified); |
734 knownQObjectClasses.insert(def.qualified); |
734 } |
735 } |
1209 } |
1210 } |
1210 } |
1211 } |
1211 |
1212 |
1212 //when searching commas within the default argument, we should take care of template depth (anglecount) |
1213 //when searching commas within the default argument, we should take care of template depth (anglecount) |
1213 // unfortunatelly, we do not have enough semantic information to know if '<' is the operator< or |
1214 // unfortunatelly, we do not have enough semantic information to know if '<' is the operator< or |
1214 // the begining of a template type. so we just use heuristics. |
1215 // the beginning of a template type. so we just use heuristics. |
1215 int possible = -1; |
1216 int possible = -1; |
1216 |
1217 |
1217 while (index < symbols.size()) { |
1218 while (index < symbols.size()) { |
1218 Token t = symbols.at(index++).token; |
1219 Token t = symbols.at(index++).token; |
1219 switch (t) { |
1220 switch (t) { |
1310 } |
1311 } |
1311 } |
1312 } |
1312 } |
1313 } |
1313 } |
1314 } |
1314 |
1315 |
|
1316 void Moc::checkProperties(ClassDef *cdef) |
|
1317 { |
|
1318 // |
|
1319 // specify get function, for compatibiliy we accept functions |
|
1320 // returning pointers, or const char * for QByteArray. |
|
1321 // |
|
1322 for (int i = 0; i < cdef->propertyList.count(); ++i) { |
|
1323 PropertyDef &p = cdef->propertyList[i]; |
|
1324 if (p.read.isEmpty()) |
|
1325 continue; |
|
1326 for (int j = 0; j < cdef->publicList.count(); ++j) { |
|
1327 const FunctionDef &f = cdef->publicList.at(j); |
|
1328 if (f.name != p.read) |
|
1329 continue; |
|
1330 if (!f.isConst) // get functions must be const |
|
1331 continue; |
|
1332 if (f.arguments.size()) // and must not take any arguments |
|
1333 continue; |
|
1334 PropertyDef::Specification spec = PropertyDef::ValueSpec; |
|
1335 QByteArray tmp = f.normalizedType; |
|
1336 if (p.type == "QByteArray" && tmp == "const char *") |
|
1337 tmp = "QByteArray"; |
|
1338 if (tmp.left(6) == "const ") |
|
1339 tmp = tmp.mid(6); |
|
1340 if (p.type != tmp && tmp.endsWith('*')) { |
|
1341 tmp.chop(1); |
|
1342 spec = PropertyDef::PointerSpec; |
|
1343 } else if (f.type.name.endsWith('&')) { // raw type, not normalized type |
|
1344 spec = PropertyDef::ReferenceSpec; |
|
1345 } |
|
1346 if (p.type != tmp) |
|
1347 continue; |
|
1348 p.gspec = spec; |
|
1349 break; |
|
1350 } |
|
1351 if(!p.notify.isEmpty()) { |
|
1352 int notifyId = -1; |
|
1353 for (int j = 0; j < cdef->signalList.count(); ++j) { |
|
1354 const FunctionDef &f = cdef->signalList.at(j); |
|
1355 if(f.name != p.notify) { |
|
1356 continue; |
|
1357 } else { |
|
1358 notifyId = j /* Signal indexes start from 0 */; |
|
1359 break; |
|
1360 } |
|
1361 } |
|
1362 p.notifyId = notifyId; |
|
1363 if (notifyId == -1) { |
|
1364 QByteArray msg = "NOTIFY signal '" + p.notify + "' of property '" + p.name |
|
1365 + "' does not exist in class " + cdef->classname + "."; |
|
1366 error(msg.constData()); |
|
1367 } |
|
1368 } |
|
1369 } |
|
1370 } |
|
1371 |
|
1372 |
1315 |
1373 |
1316 QT_END_NAMESPACE |
1374 QT_END_NAMESPACE |