📄 generator.cpp
字号:
fprintf(out, "\n // %ss: signature, parameters, type, tag, flags\n", functype); 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; fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n", strreg(sig), strreg(arguments), strreg(f.normalizedType), strreg(f.tag), flags); }}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 // if (cdef->propertyList.count()) fprintf(out, "\n // properties: name, type, flags\n"); 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; fprintf(out, " %4d, %4d, 0x%.8x,\n", strreg(p.name), strreg(p.type), flags); }}void Generator::generateEnums(int index){ if (cdef->enumDeclarations.isEmpty()) return; fprintf(out, "\n // enums: name, flags, count, data\n"); index += 4 * cdef->enumList.count(); int i; for (i = 0; i < cdef->enumList.count(); ++i) { const EnumDef &e = cdef->enumList.at(i); fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n", strreg(e.name), cdef->enumDeclarations.value(e.name) ? 1 : 0, e.values.count(), index); index += e.values.count() * 2; } fprintf(out, "\n // enum data: key, value\n"); 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); fprintf(out, " %4d, uint(%s::%s),\n", strreg(val), cdef->qualified.constData(), val.constData()); } }}void Generator::generateMetacall(){ bool isQObject = (cdef->classname == "QObject"); fprintf(out, "\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n", cdef->qualified.constData()); if (!purestSuperClass.isEmpty() && !isQObject) { QByteArray superClass = purestSuperClass; // workaround for VC6 if (superClass.contains("::")) { fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData()); superClass = "QMocSuperClass"; } fprintf(out, " _id = %s::qt_metacall(_c, _id, _a);\n", superClass.constData()); } fprintf(out, " if (_id < 0)\n return _id;\n"); fprintf(out, " "); bool needElse = false; QList<FunctionDef> methodList; methodList += cdef->signalList; methodList += cdef->slotList; methodList += cdef->methodList; if (methodList.size()) { needElse = true; fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n "); fprintf(out, "switch (_id) {\n"); for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) { const FunctionDef &f = methodList.at(methodindex); fprintf(out, " case %d: ", methodindex); if (f.normalizedType.size()) fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData()); if (f.inPrivateClass.size()) fprintf(out, "%s->", f.inPrivateClass.constData()); fprintf(out, "%s(", f.name.constData()); int offset = 1; for (int j = 0; j < f.arguments.count(); ++j) { const ArgumentDef &a = f.arguments.at(j); if (j) fprintf(out, ","); fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); } fprintf(out, ");"); if (f.normalizedType.size()) fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ", noRef(f.normalizedType).constData()); fprintf(out, " break;\n"); } fprintf(out, " }\n"); } if (methodList.size()) fprintf(out, " _id -= %d;\n }", methodList.size()); if (cdef->propertyList.size()) { bool needGet = false; bool needTempVarForGet = false; bool needSet = false; bool needReset = false; bool needDesignable = false; bool needScriptable = false; bool needStored = false; bool needEditable = false; bool needUser = false; for (int i = 0; i < cdef->propertyList.size(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); needGet |= !p.read.isEmpty(); if (!p.read.isEmpty()) needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec && p.gspec != PropertyDef::ReferenceSpec); needSet |= !p.write.isEmpty(); needReset |= !p.reset.isEmpty(); needDesignable |= p.designable.endsWith(')'); needScriptable |= p.scriptable.endsWith(')'); needStored |= p.stored.endsWith(')'); needEditable |= p.editable.endsWith(')'); needUser |= p.user.endsWith(')'); } bool needAnything = needGet | needSet | needReset | needDesignable | needScriptable | needStored | needEditable | needUser; if (!needAnything) goto skip_properties; fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n "); if (needElse) fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::ReadProperty) {\n"); if (needGet) { if (needTempVarForGet) fprintf(out, " void *_v = _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.read.isEmpty()) continue; if (p.gspec == PropertyDef::PointerSpec) fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s())); break;\n", propindex, p.read.constData()); else if (p.gspec == PropertyDef::ReferenceSpec) fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s())); break;\n", propindex, p.read.constData()); else if (cdef->enumDeclarations.value(p.type, false)) fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s()); break;\n", propindex, p.read.constData()); else fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s(); break;\n", propindex, p.type.constData(), p.read.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::WriteProperty) {\n"); if (needSet) { fprintf(out, " void *_v = _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.write.isEmpty()) continue; if (cdef->enumDeclarations.value(p.type, false)) { fprintf(out, " case %d: %s(QFlag(*reinterpret_cast<int*>(_v))); break;\n", propindex, p.write.constData()); } else { fprintf(out, " case %d: %s(*reinterpret_cast< %s*>(_v)); break;\n", propindex, p.write.constData(), p.type.constData()); } } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::ResetProperty) {\n"); if (needReset) { fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.reset.endsWith(')')) continue; fprintf(out, " case %d: %s; break;\n", propindex, p.reset.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyDesignable) {\n"); if (needDesignable) { 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.designable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.designable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyScriptable) {\n"); if (needScriptable) { 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.scriptable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.scriptable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyStored) {\n"); if (needStored) { 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.stored.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.stored.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyEditable) {\n"); if (needEditable) { 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.editable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -