Commit ceef6d65bda41eb3f90ccf694ecb11a759ebc26a
- Diff rendering mode:
- inline
- side by side
src/tools/moc/generator.cpp
(0 / 295)
|   | |||
| 1013 | 1013 | fprintf(out, "}\n"); | |
| 1014 | 1014 | } | |
| 1015 | 1015 | ||
| 1016 | // | ||
| 1017 | // Functions used when generating QMetaObject directly | ||
| 1018 | // | ||
| 1019 | // Much of this code is copied from the corresponding | ||
| 1020 | // C++ code-generating functions; we can change the | ||
| 1021 | // two generators so that more of the code is shared. | ||
| 1022 | // The key difference from the C++ code generator is | ||
| 1023 | // that instead of calling fprintf(), we append bytes | ||
| 1024 | // to a buffer. | ||
| 1025 | // | ||
| 1026 | |||
| 1027 | QMetaObject *Generator::generateMetaObject(bool ignoreProperties) | ||
| 1028 | { | ||
| 1029 | // | ||
| 1030 | // build the data array | ||
| 1031 | // | ||
| 1032 | |||
| 1033 | // filter out undeclared enumerators and sets | ||
| 1034 | { | ||
| 1035 | QList<EnumDef> enumList; | ||
| 1036 | for (int i = 0; i < cdef->enumList.count(); ++i) { | ||
| 1037 | EnumDef def = cdef->enumList.at(i); | ||
| 1038 | if (cdef->enumDeclarations.contains(def.name)) { | ||
| 1039 | enumList += def; | ||
| 1040 | } | ||
| 1041 | QByteArray alias = cdef->flagAliases.value(def.name); | ||
| 1042 | if (cdef->enumDeclarations.contains(alias)) { | ||
| 1043 | def.name = alias; | ||
| 1044 | enumList += def; | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | cdef->enumList = enumList; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | int index = 10; | ||
| 1051 | meta_data | ||
| 1052 | << 1 // revision | ||
| 1053 | << strreg(cdef->qualified) // classname | ||
| 1054 | << cdef->classInfoList.count() << (cdef->classInfoList.count() ? index : 0) // classinfo | ||
| 1055 | ; | ||
| 1056 | index += cdef->classInfoList.count() * 2; | ||
| 1057 | |||
| 1058 | int methodCount = cdef->functionList.count(); | ||
| 1059 | meta_data << methodCount << (methodCount ? index : 0); // methods | ||
| 1060 | index += methodCount * 5; | ||
| 1061 | if (!ignoreProperties) { | ||
| 1062 | meta_data << cdef->propertyList.count() << (cdef->propertyList.count() ? index : 0); // properties | ||
| 1063 | index += cdef->propertyList.count() * 3; | ||
| 1064 | } else { | ||
| 1065 | meta_data << 0 << 0; // properties | ||
| 1066 | } | ||
| 1067 | meta_data << cdef->enumList.count() << (cdef->enumList.count() ? index : 0); // enums/sets | ||
| 1068 | |||
| 1069 | // | ||
| 1070 | // Build classinfo array | ||
| 1071 | // | ||
| 1072 | _generateClassInfos(); | ||
| 1073 | |||
| 1074 | _generateFunctions(cdef->functionList); | ||
| 1075 | // | ||
| 1076 | // Build property array | ||
| 1077 | // | ||
| 1078 | if (!ignoreProperties) | ||
| 1079 | _generateProperties(); | ||
| 1080 | |||
| 1081 | // | ||
| 1082 | // Build enums array | ||
| 1083 | // | ||
| 1084 | _generateEnums(index); | ||
| 1085 | |||
| 1086 | // | ||
| 1087 | // Terminate data array | ||
| 1088 | // | ||
| 1089 | meta_data << 0; | ||
| 1090 | |||
| 1091 | // | ||
| 1092 | // Build stringdata array | ||
| 1093 | // | ||
| 1094 | QVector<char> string_data; | ||
| 1095 | for (int i = 0; i < strings.size(); ++i) { | ||
| 1096 | const char *s = strings.at(i).constData(); | ||
| 1097 | char c; | ||
| 1098 | do { | ||
| 1099 | c = *(s++); | ||
| 1100 | string_data << c; | ||
| 1101 | } while (c != '\0'); | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | // | ||
| 1105 | // Finally create and initialize the static meta object | ||
| 1106 | // | ||
| 1107 | const int meta_object_offset = 0; | ||
| 1108 | const int meta_object_size = sizeof(QMetaObject); | ||
| 1109 | const int meta_data_offset = meta_object_offset + meta_object_size; | ||
| 1110 | const int meta_data_size = meta_data.count() * sizeof(uint); | ||
| 1111 | const int string_data_offset = meta_data_offset + meta_data_size; | ||
| 1112 | const int string_data_size = string_data.count(); | ||
| 1113 | const int total_size = string_data_offset + string_data_size; | ||
| 1114 | |||
| 1115 | char *blob = new char[total_size]; | ||
| 1116 | |||
| 1117 | char *string_data_output = blob + string_data_offset; | ||
| 1118 | const char *string_data_src = string_data.constData(); | ||
| 1119 | for (int i = 0; i < string_data.count(); ++i) | ||
| 1120 | string_data_output[i] = string_data_src[i]; | ||
| 1121 | |||
| 1122 | uint *meta_data_output = reinterpret_cast<uint *>(blob + meta_data_offset); | ||
| 1123 | const uint *meta_data_src = meta_data.constData(); | ||
| 1124 | for (int i = 0; i < meta_data.count(); ++i) | ||
| 1125 | meta_data_output[i] = meta_data_src[i]; | ||
| 1126 | |||
| 1127 | QMetaObject *meta_object = new (blob + meta_object_offset)QMetaObject; | ||
| 1128 | meta_object->d.superdata = 0; | ||
| 1129 | meta_object->d.stringdata = string_data_output; | ||
| 1130 | meta_object->d.data = meta_data_output; | ||
| 1131 | meta_object->d.extradata = 0; | ||
| 1132 | return meta_object; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | void Generator::_generateClassInfos() | ||
| 1136 | { | ||
| 1137 | for (int i = 0; i < cdef->classInfoList.size(); ++i) { | ||
| 1138 | const ClassInfoDef &c = cdef->classInfoList.at(i); | ||
| 1139 | meta_data << strreg(c.name) << strreg(c.value); | ||
| 1140 | } | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | void Generator::_generateFunctions(QList<FunctionDef> &list) | ||
| 1144 | { | ||
| 1145 | for (int i = 0; i < list.count(); ++i) { | ||
| 1146 | const FunctionDef &f = list.at(i); | ||
| 1147 | |||
| 1148 | QByteArray sig = f.name + '('; | ||
| 1149 | QByteArray arguments; | ||
| 1150 | |||
| 1151 | for (int j = 0; j < f.arguments.count(); ++j) { | ||
| 1152 | const ArgumentDef &a = f.arguments.at(j); | ||
| 1153 | if (j) { | ||
| 1154 | sig += ','; | ||
| 1155 | arguments += ','; | ||
| 1156 | } | ||
| 1157 | sig += a.normalizedType; | ||
| 1158 | arguments += a.name; | ||
| 1159 | } | ||
| 1160 | sig += ')'; | ||
| 1161 | |||
| 1162 | char flags = 0; | ||
| 1163 | if (f.isSlot) | ||
| 1164 | flags = MethodSlot; | ||
| 1165 | else if (f.isSignal) | ||
| 1166 | flags = MethodSignal; | ||
| 1167 | else if (f.isConstructor) | ||
| 1168 | flags = MethodConstructor; | ||
| 1169 | else | ||
| 1170 | flags = MethodMethod; | ||
| 1171 | |||
| 1172 | if (f.access == FunctionDef::Private) | ||
| 1173 | flags |= AccessPrivate; | ||
| 1174 | else if (f.access == FunctionDef::Public) | ||
| 1175 | flags |= AccessPublic; | ||
| 1176 | else if (f.access == FunctionDef::Protected) | ||
| 1177 | flags |= AccessProtected; | ||
| 1178 | if (f.access == FunctionDef::Private) | ||
| 1179 | flags |= AccessPrivate; | ||
| 1180 | else if (f.access == FunctionDef::Public) | ||
| 1181 | flags |= AccessPublic; | ||
| 1182 | else if (f.access == FunctionDef::Protected) | ||
| 1183 | flags |= AccessProtected; | ||
| 1184 | if (f.isCompat) | ||
| 1185 | flags |= MethodCompatibility; | ||
| 1186 | if (f.wasCloned) | ||
| 1187 | flags |= MethodCloned; | ||
| 1188 | if (f.isScriptable) | ||
| 1189 | flags |= MethodScriptable; | ||
| 1190 | |||
| 1191 | meta_data << strreg(sig) | ||
| 1192 | << strreg(arguments) | ||
| 1193 | << strreg(f.normalizedType) | ||
| 1194 | << strreg(f.tag) | ||
| 1195 | << flags; | ||
| 1196 | } | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | void Generator::_generateEnums(int index) | ||
| 1200 | { | ||
| 1201 | index += 4 * cdef->enumList.count(); | ||
| 1202 | int i; | ||
| 1203 | for (i = 0; i < cdef->enumList.count(); ++i) { | ||
| 1204 | const EnumDef &e = cdef->enumList.at(i); | ||
| 1205 | meta_data << strreg(e.name) << (cdef->enumDeclarations.value(e.name) ? 1 : 0) | ||
| 1206 | << e.values.count() << index; | ||
| 1207 | index += e.values.count() * 2; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | for (i = 0; i < cdef->enumList.count(); ++i) { | ||
| 1211 | const EnumDef &e = cdef->enumList.at(i); | ||
| 1212 | for (int j = 0; j < e.values.count(); ++j) { | ||
| 1213 | const QByteArray &val = e.values.at(j); | ||
| 1214 | meta_data << strreg(val) << 0; // we don't know the value itself | ||
| 1215 | } | ||
| 1216 | } | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | void Generator::_generateProperties() | ||
| 1220 | { | ||
| 1221 | // | ||
| 1222 | // specify get function, for compatibiliy we accept functions | ||
| 1223 | // returning pointers, or const char * for QByteArray. | ||
| 1224 | // | ||
| 1225 | for (int i = 0; i < cdef->propertyList.count(); ++i) { | ||
| 1226 | PropertyDef &p = cdef->propertyList[i]; | ||
| 1227 | if (p.read.isEmpty()) | ||
| 1228 | continue; | ||
| 1229 | for (int j = 0; j < cdef->publicList.count(); ++j) { | ||
| 1230 | const FunctionDef &f = cdef->publicList.at(j); | ||
| 1231 | if (f.name != p.read) | ||
| 1232 | continue; | ||
| 1233 | if (!f.isConst) // get functions must be const | ||
| 1234 | continue; | ||
| 1235 | if (f.arguments.size()) // and must not take any arguments | ||
| 1236 | continue; | ||
| 1237 | PropertyDef::Specification spec = PropertyDef::ValueSpec; | ||
| 1238 | QByteArray tmp = f.normalizedType; | ||
| 1239 | if (p.type == "QByteArray" && tmp == "const char *") | ||
| 1240 | tmp = "QByteArray"; | ||
| 1241 | if (tmp.left(6) == "const ") | ||
| 1242 | tmp = tmp.mid(6); | ||
| 1243 | if (p.type != tmp && tmp.endsWith('*')) { | ||
| 1244 | tmp.chop(1); | ||
| 1245 | spec = PropertyDef::PointerSpec; | ||
| 1246 | } else if (f.type.name.endsWith('&')) { // raw type, not normalized type | ||
| 1247 | spec = PropertyDef::ReferenceSpec; | ||
| 1248 | } | ||
| 1249 | if (p.type != tmp) | ||
| 1250 | continue; | ||
| 1251 | p.gspec = spec; | ||
| 1252 | break; | ||
| 1253 | } | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | |||
| 1257 | // | ||
| 1258 | // Create meta data | ||
| 1259 | // | ||
| 1260 | |||
| 1261 | for (int i = 0; i < cdef->propertyList.count(); ++i) { | ||
| 1262 | const PropertyDef &p = cdef->propertyList.at(i); | ||
| 1263 | uint flags = Invalid; | ||
| 1264 | if (!isVariantType(p.type)) { | ||
| 1265 | flags |= EnumOrFlag; | ||
| 1266 | } else { | ||
| 1267 | flags |= qvariant_nameToType(p.type) << 24; | ||
| 1268 | } | ||
| 1269 | if (!p.read.isEmpty()) | ||
| 1270 | flags |= Readable; | ||
| 1271 | if (!p.write.isEmpty()) { | ||
| 1272 | flags |= Writable; | ||
| 1273 | if (p.stdCppSet()) | ||
| 1274 | flags |= StdCppSet; | ||
| 1275 | } | ||
| 1276 | if (!p.reset.isEmpty()) | ||
| 1277 | flags |= Resettable; | ||
| 1278 | |||
| 1279 | // if (p.override) | ||
| 1280 | // flags |= Override; | ||
| 1281 | |||
| 1282 | if (p.designable.isEmpty()) | ||
| 1283 | flags |= ResolveDesignable; | ||
| 1284 | else if (p.designable != "false") | ||
| 1285 | flags |= Designable; | ||
| 1286 | |||
| 1287 | if (p.scriptable.isEmpty()) | ||
| 1288 | flags |= ResolveScriptable; | ||
| 1289 | else if (p.scriptable != "false") | ||
| 1290 | flags |= Scriptable; | ||
| 1291 | |||
| 1292 | if (p.stored.isEmpty()) | ||
| 1293 | flags |= ResolveStored; | ||
| 1294 | else if (p.stored != "false") | ||
| 1295 | flags |= Stored; | ||
| 1296 | |||
| 1297 | if (p.editable.isEmpty()) | ||
| 1298 | flags |= ResolveEditable; | ||
| 1299 | else if (p.editable != "false") | ||
| 1300 | flags |= Editable; | ||
| 1301 | |||
| 1302 | if (p.user.isEmpty()) | ||
| 1303 | flags |= ResolveUser; | ||
| 1304 | else if (p.user != "false") | ||
| 1305 | flags |= User; | ||
| 1306 | |||
| 1307 | meta_data << strreg(p.name) << strreg(p.type) << flags; | ||
| 1308 | } | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | 1016 | QT_END_NAMESPACE |
src/tools/moc/generator.h
(0 / 7)
|   | |||
| 54 | 54 | public: | |
| 55 | 55 | Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0); | |
| 56 | 56 | void generateCode(); | |
| 57 | QMetaObject *generateMetaObject(bool ignoreProperties); | ||
| 58 | 57 | private: | |
| 59 | 58 | void generateClassInfos(); | |
| 60 | 59 | void generateFunctions(QList<FunctionDef> &list, const char *type); | |
| … | … | ||
| 62 | 62 | void generateMetacall(); | |
| 63 | 63 | void generateStaticMetacall(const QByteArray &prefix); | |
| 64 | 64 | void generateSignal(FunctionDef *def, int index); | |
| 65 | |||
| 66 | // used by binary QMetaObject generator | ||
| 67 | void _generateClassInfos(); | ||
| 68 | void _generateFunctions(QList<FunctionDef> &list); | ||
| 69 | void _generateEnums(int index); | ||
| 70 | void _generateProperties(); | ||
| 71 | 65 | ||
| 72 | 66 | int strreg(const char *); // registers a string and returns its id | |
| 73 | 67 | QList<QByteArray> strings; |
src/tools/moc/moc.cpp
(0 / 10)
|   | |||
| 771 | 771 | } | |
| 772 | 772 | ||
| 773 | 773 | ||
| 774 | QList<QMetaObject*> Moc::generate(bool ignoreProperties) | ||
| 775 | { | ||
| 776 | QList<QMetaObject*> result; | ||
| 777 | for (int i = 0; i < classList.size(); ++i) { | ||
| 778 | Generator generator(&classList[i], metaTypes); | ||
| 779 | result << generator.generateMetaObject(ignoreProperties); | ||
| 780 | } | ||
| 781 | return result; | ||
| 782 | } | ||
| 783 | |||
| 784 | 774 | void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) | |
| 785 | 775 | { | |
| 786 | 776 | next(COLON); |
src/tools/moc/moc.h
(0 / 1)
|   | |||
| 204 | 204 | ||
| 205 | 205 | void parse(); | |
| 206 | 206 | void generate(FILE *out); | |
| 207 | QList<QMetaObject*> generate(bool ignoreProperties); | ||
| 208 | 207 | ||
| 209 | 208 | bool parseClassHead(ClassDef *def); | |
| 210 | 209 | inline bool inClass(const ClassDef *def) const { |
Comments
Add a new comment:
Login or create an account to post a comment
Add your comment
Please log in to comment

