📄 generator.cpp
字号:
propindex, p.editable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyUser) {\n"); if (needUser) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.user.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.user.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, "\n#endif // QT_NO_PROPERTIES"); } skip_properties: if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size()) fprintf(out, "\n "); fprintf(out,"return _id;\n}\n");}void Generator::generateSignal(FunctionDef *def,int index){ if (def->wasCloned) return; fprintf(out, "\n// SIGNAL %d\n%s %s::%s(", index, def->type.name.constData(), cdef->qualified.constData(), def->name.constData()); QByteArray thisPtr = "this"; const char *constQualifier = ""; if (def->isConst) { thisPtr = "const_cast< "; thisPtr += cdef->qualified; thisPtr += " *>(this)"; constQualifier = "const"; } if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) { fprintf(out, ")%s\n{\n" " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n" "}\n", constQualifier, thisPtr.constData(), index); return; } int offset = 1; for (int j = 0; j < def->arguments.count(); ++j) { const ArgumentDef &a = def->arguments.at(j); if (j) fprintf(out, ", "); fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData()); } fprintf(out, ")%s\n{\n", constQualifier); if (def->type.name.size() && def->normalizedType.size()) fprintf(out, " %s _t0;\n", noRef(def->normalizedType).constData()); fprintf(out, " void *_a[] = { "); if (def->normalizedType.isEmpty()) { fprintf(out, "0"); } else { if (def->returnTypeIsVolatile) fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))"); else fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))"); } int i; for (i = 1; i < offset; ++i) if (def->arguments.at(i - 1).type.isVolatile) fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i); else fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i); fprintf(out, " };\n"); int n = 0; for (i = 0; i < def->arguments.count(); ++i) if (def->arguments.at(i).isDefault) ++n; if (n) fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, %d, _a);\n", thisPtr.constData(), index, index + n); else fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index); if (def->normalizedType.size()) fprintf(out, " return _t0;\n"); fprintf(out, "}\n");}//// Functions used when generating QMetaObject directly//// Much of this code is copied from the corresponding// C++ code-generating functions; we can change the// two generators so that more of the code is shared.// The key difference from the C++ code generator is// that instead of calling fprintf(), we append bytes// to a buffer.//QMetaObject *Generator::generateMetaObject(bool ignoreProperties){//// build the data array// // filter out undeclared enumerators and sets { QList<EnumDef> enumList; for (int i = 0; i < cdef->enumList.count(); ++i) { EnumDef def = cdef->enumList.at(i); if (cdef->enumDeclarations.contains(def.name)) { enumList += def; } QByteArray alias = cdef->flagAliases.value(def.name); if (cdef->enumDeclarations.contains(alias)) { def.name = alias; enumList += def; } } cdef->enumList = enumList; } int index = 10; meta_data << 1 // revision << strreg(cdef->qualified) // classname << cdef->classInfoList.count() << (cdef->classInfoList.count() ? index : 0) // classinfo ; index += cdef->classInfoList.count() * 2; int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count(); meta_data << methodCount << (methodCount ? index : 0); // methods index += methodCount * 5; if (!ignoreProperties) { meta_data << cdef->propertyList.count() << (cdef->propertyList.count() ? index : 0); // properties index += cdef->propertyList.count() * 3; } else { meta_data << 0 << 0; // properties } meta_data << cdef->enumList.count() << (cdef->enumList.count() ? index : 0); // enums/sets//// Build classinfo array// _generateClassInfos();//// Build signals array first, otherwise the signal indices would be wrong// _generateFunctions(cdef->signalList, MethodSignal);//// Build slots array// _generateFunctions(cdef->slotList, MethodSlot);//// Build method array// _generateFunctions(cdef->methodList, MethodMethod);//// Build property array// if (!ignoreProperties) _generateProperties();//// Build enums array// _generateEnums(index);//// Terminate data array// meta_data << 0;//// Build stringdata array// QVector<char> string_data; for (int i = 0; i < strings.size(); ++i) { const char *s = strings.at(i).constData(); char c; do { c = *(s++); string_data << c; } while (c != '\0'); }//// Finally create and initialize the static meta object// const int meta_object_offset = 0; const int meta_object_size = sizeof(QMetaObject); const int meta_data_offset = meta_object_offset + meta_object_size; const int meta_data_size = meta_data.count() * sizeof(uint); const int string_data_offset = meta_data_offset + meta_data_size; const int string_data_size = string_data.count(); const int total_size = string_data_offset + string_data_size; char *blob = new char[total_size]; char *string_data_output = blob + string_data_offset; const char *string_data_src = string_data.constData(); for (int i = 0; i < string_data.count(); ++i) string_data_output[i] = string_data_src[i]; uint *meta_data_output = reinterpret_cast<uint *>(blob + meta_data_offset); const uint *meta_data_src = meta_data.constData(); for (int i = 0; i < meta_data.count(); ++i) meta_data_output[i] = meta_data_src[i]; QMetaObject *meta_object = new (blob + meta_object_offset)QMetaObject; meta_object->d.superdata = 0; meta_object->d.stringdata = string_data_output; meta_object->d.data = meta_data_output; meta_object->d.extradata = 0; return meta_object;}void Generator::_generateClassInfos(){ for (int i = 0; i < cdef->classInfoList.size(); ++i) { const ClassInfoDef &c = cdef->classInfoList.at(i); meta_data << strreg(c.name) << strreg(c.value); }}void Generator::_generateFunctions(QList<FunctionDef> &list, int type){ for (int i = 0; i < list.count(); ++i) { const FunctionDef &f = list.at(i); QByteArray sig = f.name + '('; QByteArray arguments; for (int j = 0; j < f.arguments.count(); ++j) { const ArgumentDef &a = f.arguments.at(j); if (j) { sig += ","; arguments += ","; } sig += a.normalizedType; arguments += a.name; } sig += ')'; char flags = type; if (f.access == FunctionDef::Private) flags |= AccessPrivate; else if (f.access == FunctionDef::Public) flags |= AccessPublic; else if (f.access == FunctionDef::Protected) flags |= AccessProtected; if (f.access == FunctionDef::Private) flags |= AccessPrivate; else if (f.access == FunctionDef::Public) flags |= AccessPublic; else if (f.access == FunctionDef::Protected) flags |= AccessProtected; if (f.isCompat) flags |= MethodCompatibility; if (f.wasCloned) flags |= MethodCloned; if (f.isScriptable) flags |= MethodScriptable; meta_data << strreg(sig) << strreg(arguments) << strreg(f.normalizedType) << strreg(f.tag) << flags; }}void Generator::_generateEnums(int index){ index += 4 * cdef->enumList.count(); int i; for (i = 0; i < cdef->enumList.count(); ++i) { const EnumDef &e = cdef->enumList.at(i); meta_data << strreg(e.name) << (cdef->enumDeclarations.value(e.name) ? 1 : 0) << e.values.count() << index; index += e.values.count() * 2; } for (i = 0; i < cdef->enumList.count(); ++i) { const EnumDef &e = cdef->enumList.at(i); for (int j = 0; j < e.values.count(); ++j) { const QByteArray &val = e.values.at(j); meta_data << strreg(val) << 0; // we don't know the value itself } }}void Generator::_generateProperties(){ // // 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; } } // // Create meta data // for (int i = 0; i < cdef->propertyList.count(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); uint flags = Invalid; if (!isVariantType(p.type)) { flags |= EnumOrFlag; } else { flags |= qvariant_nameToType(p.type) << 24; } if (!p.read.isEmpty()) flags |= Readable; if (!p.write.isEmpty()) { flags |= Writable; if (p.stdCppSet()) flags |= StdCppSet; } if (!p.reset.isEmpty()) flags |= Resettable;// if (p.override)// flags |= Override; if (p.designable.isEmpty()) flags |= ResolveDesignable; else if (p.designable != "false") flags |= Designable; if (p.scriptable.isEmpty()) flags |= ResolveScriptable; else if (p.scriptable != "false") flags |= Scriptable; if (p.stored.isEmpty()) flags |= ResolveStored; else if (p.stored != "false") flags |= Stored; if (p.editable.isEmpty()) flags |= ResolveEditable; else if (p.editable != "false") flags |= Editable; if (p.user.isEmpty()) flags |= ResolveUser; else if (p.user != "false") flags |= User; meta_data << strreg(p.name) << strreg(p.type) << flags; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -