📄 moc.cpp
字号:
while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.methodList += funcDef; } } } else { index = rewind; } } } next(RBRACE); if (!def.hasQObject && def.signalList.isEmpty() && def.slotList.isEmpty() && def.propertyList.isEmpty() && def.enumDeclarations.isEmpty()) continue; // no meta object code required if (!def.hasQObject && !def.hasQGadget) error("Class declarations lacks Q_OBJECT macro."); classList += def; } }}void Moc::generate(FILE *out){ QDateTime dt = QDateTime::currentDateTime(); QByteArray dstr = dt.toString().toLatin1(); QByteArray fn = filename; int i = filename.length()-1; while (i>0 && filename[i-1] != '/' && filename[i-1] != '\\') --i; // skip path if (i >= 0) fn = filename.mid(i); fprintf(out, "/****************************************************************************\n" "** Meta object code from reading C++ file '%s'\n**\n" , (const char*)fn); fprintf(out, "** Created: %s\n" "** by: The Qt Meta Object Compiler version %d (Qt %s)\n**\n" , dstr.data(), mocOutputRevision, QT_VERSION_STR); fprintf(out, "** WARNING! All changes made in this file will be lost!\n" "*****************************************************************************/\n\n"); if (!noInclude) { if (includePath.size() && includePath.right(1) != "/") includePath += "/"; for (int i = 0; i < includeFiles.size(); ++i) { QByteArray inc = includeFiles.at(i); if (inc[0] != '<' && inc[0] != '"') { if (includePath.size() && includePath != "./") inc.prepend(includePath); inc = "\"" + inc + "\""; } fprintf(out, "#include %s\n", inc.constData()); } } if (classList.size() && classList.first().classname == "Qt") fprintf(out, "#include <QtCore/qobject.h>\n"); fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n" "#error \"The header file '%s' doesn't include <QObject>.\"\n", (const char *)fn); fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision); fprintf(out, "#error \"This file was generated using the moc from %s." " It\"\n#error \"cannot be used with the include files from" " this version of Qt.\"\n#error \"(The moc has changed too" " much.)\"\n", QT_VERSION_STR); fprintf(out, "#endif\n\n"); for (i = 0; i < classList.size(); ++i) { Generator generator(out, &classList[i]); generator.generateCode(); }}void Moc::parseSlots(ClassDef *def, FunctionDef::Access access){ next(COLON); while (inClass(def) && hasNext()) { switch (next()) { case PUBLIC: case PROTECTED: case PRIVATE: case SIGNALS: case SLOTS: prev(); return; case SEMIC: continue; case FRIEND: until(SEMIC); continue; case USING: error("'using' directive not supported in 'slots' section"); default: prev(); } FunctionDef funcDef; funcDef.access = access; if (!parseFunction(&funcDef)) continue; def->slotList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->slotList += funcDef; } }}void Moc::parseSignals(ClassDef *def){ next(COLON); while (inClass(def) && hasNext()) { switch (next()) { case PUBLIC: case PROTECTED: case PRIVATE: case SIGNALS: case SLOTS: prev(); return; case SEMIC: continue; case FRIEND: until(SEMIC); continue; case USING: error("'using' directive not supported in 'signals' section"); default: prev(); } FunctionDef funcDef; funcDef.access = FunctionDef::Protected; parseFunction(&funcDef); if (funcDef.isVirtual) error("Signals cannot be declared virtual"); if (funcDef.inlineCode) error("Not a signal declaration"); def->signalList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->signalList += funcDef; } }}void Moc::parseProperty(ClassDef *def){ next(LPAREN); PropertyDef propDef; QByteArray type = parseType().name; if (type.isEmpty()) error(); propDef.designable = propDef.scriptable = propDef.stored = "true"; propDef.user = "false"; /* The Q_PROPERTY construct cannot contain any commas, since commas separate macro arguments. We therefore expect users to type "QMap" instead of "QMap<QString, QVariant>". For coherence, we also expect the same for QValueList<QVariant>, the other template class supported by QVariant. */ type = normalizeType(type); if (type == "QMap") type = "QMap<QString,QVariant>"; else if (type == "QValueList") type = "QValueList<QVariant>"; else if (type == "LongLong") type = "qlonglong"; else if (type == "ULongLong") type = "qulonglong"; propDef.type = type; next(); propDef.name = lexem(); while (test(IDENTIFIER)) { QByteArray l = lexem(); QByteArray v, v2; if (test(LPAREN)) { v = lexemUntil(RPAREN); } else { next(IDENTIFIER); v = lexem(); if (test(LPAREN)) v2 = lexemUntil(RPAREN); else if (v != "true" && v != "false") v2 = "()"; } switch (l[0]) { case 'R': if (l == "READ") propDef.read = v; else if (l == "RESET") propDef.reset = v + v2; else error(2); break; case 'S': if (l == "SCRIPTABLE") propDef.scriptable = v + v2; else if (l == "STORED") propDef.stored = v + v2; else error(2); break; case 'W': if (l != "WRITE") error(2); propDef.write = v; break; case 'D': if (l != "DESIGNABLE") error(2); propDef.designable = v + v2; break; case 'E': if (l != "EDITABLE") error(2); propDef.editable = v + v2; break; case 'N': if (l != "NOTIFY") error(2); break; case 'U': if (l != "USER") error(2); propDef.user = v + v2; break; default: error(2); } } next(RPAREN); def->propertyList += propDef;}void Moc::parseEnumOrFlag(ClassDef *def, bool isFlag){ next(LPAREN); QByteArray identifier; while (test(IDENTIFIER)) { identifier = lexem(); while (test(SCOPE) && test(IDENTIFIER)) { identifier += "::"; identifier += lexem(); } def->enumDeclarations[identifier] = isFlag; } next(RPAREN);}void Moc::parseFlag(ClassDef *def){ next(LPAREN); QByteArray flagName, enumName; while (test(IDENTIFIER)) { flagName = lexem(); while (test(SCOPE) && test(IDENTIFIER)) { flagName += "::"; flagName += lexem(); } } next(COMMA); while (test(IDENTIFIER)) { enumName = lexem(); while (test(SCOPE) && test(IDENTIFIER)) { enumName += "::"; enumName += lexem(); } } def->flagAliases.insert(enumName, flagName); next(RPAREN);}void Moc::parseClassInfo(ClassDef *def){ next(LPAREN); ClassInfoDef infoDef; next(STRING_LITERAL); infoDef.name = symbol().unquotedLexem(); next(COMMA); if (test(STRING_LITERAL)) { infoDef.value = symbol().unquotedLexem(); } else { // support Q_CLASSINFO("help", QT_TR_NOOP("blah")) next(IDENTIFIER); next(LPAREN); next(STRING_LITERAL); infoDef.value = symbol().unquotedLexem(); next(RPAREN); } next(RPAREN); def->classInfoList += infoDef;}void Moc::parseInterfaces(ClassDef *def){ next(LPAREN); while (test(IDENTIFIER)) { QList<ClassDef::Interface> iface; iface += ClassDef::Interface(lexem()); while (test(SCOPE)) { iface.last().className += lexem(); next(IDENTIFIER); iface.last().className += lexem(); } while (test(COLON)) { next(IDENTIFIER); iface += ClassDef::Interface(lexem()); while (test(SCOPE)) { iface.last().className += lexem(); next(IDENTIFIER); iface.last().className += lexem(); } } // resolve from classnames to interface ids for (int i = 0; i < iface.count(); ++i) { const QByteArray iid = interface2IdMap.value(iface.at(i).className); if (iid.isEmpty()) error("Undefined interface"); iface[i].interfaceId = iid; } def->interfaceList += iface; } next(RPAREN);}void Moc::parseDeclareInterface(){ next(LPAREN); QByteArray interface; next(IDENTIFIER); interface += lexem(); while (test(SCOPE)) { interface += lexem(); next(IDENTIFIER); interface += lexem(); } next(COMMA); QByteArray iid; if (test(STRING_LITERAL)) { iid = symbol().lexem(); } else { next(IDENTIFIER); iid = lexem(); } interface2IdMap.insert(interface, iid); next(RPAREN);}void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access){ next(LPAREN); FunctionDef funcDef; next(IDENTIFIER); funcDef.inPrivateClass = lexem(); // also allow void functions if (test(LPAREN)) { next(RPAREN); funcDef.inPrivateClass += "()"; } next(COMMA); funcDef.access = access; parseFunction(&funcDef, true); def->slotList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->slotList += funcDef; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -