diff options
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r-- | src/tools/moc/moc.cpp | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index c175d1d86d..03976771e5 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -43,30 +43,9 @@ QT_BEGIN_NAMESPACE // only moc needs this function -static QByteArray normalizeType(const QByteArray &ba, bool fixScope = false) +static QByteArray normalizeType(const QByteArray &ba) { - const char *s = ba.constData(); - int len = ba.size(); - char stackbuf[64]; - char *buf = (len >= 64 ? new char[len + 1] : stackbuf); - char *d = buf; - char last = 0; - while(*s && is_space(*s)) - s++; - while (*s) { - while (*s && !is_space(*s)) - last = *d++ = *s++; - while (*s && is_space(*s)) - s++; - if (*s && ((is_ident_char(*s) && is_ident_char(last)) - || ((*s == ':') && (last == '<')))) { - last = *d++ = ' '; - } - } - *d = '\0'; - QByteArray result = normalizeTypeInternal(buf, d, fixScope); - if (buf != stackbuf) - delete [] buf; + QByteArray result = normalizeTypeInternal(ba.constBegin(), ba.constEnd()); return result; } @@ -328,6 +307,11 @@ void Moc::parseFunctionArguments(FunctionDef *def) def->arguments.removeLast(); def->isPrivateSignal = true; } + if (def->arguments.size() == 1 + && def->arguments.constLast().normalizedType == "QMethodRawArguments") { + def->arguments.removeLast(); + def->isRawSlot = true; + } } bool Moc::testFunctionAttribute(FunctionDef *def) @@ -371,17 +355,42 @@ bool Moc::skipCxxAttributes() return false; } -bool Moc::testFunctionRevision(FunctionDef *def) +QTypeRevision Moc::parseRevision() { - if (test(Q_REVISION_TOKEN)) { - next(LPAREN); - QByteArray revision = lexemUntil(RPAREN); - revision.remove(0, 1); - revision.chop(1); + next(LPAREN); + QByteArray revisionString = lexemUntil(RPAREN); + revisionString.remove(0, 1); + revisionString.chop(1); + const QList<QByteArray> majorMinor = revisionString.split(','); + switch (majorMinor.length()) { + case 1: { bool ok = false; - def->revision = revision.toInt(&ok); - if (!ok || def->revision < 0) + const int revision = revisionString.toInt(&ok); + if (!ok || !QTypeRevision::isValidSegment(revision)) error("Invalid revision"); + return QTypeRevision::fromMinorVersion(revision); + } + case 2: { // major.minor + bool ok = false; + const int major = majorMinor[0].toInt(&ok); + if (!ok || !QTypeRevision::isValidSegment(major)) + error("Invalid major version"); + const int minor = majorMinor[1].toInt(&ok); + if (!ok || !QTypeRevision::isValidSegment(minor)) + error("Invalid minor version"); + return QTypeRevision::fromVersion(major, minor); + } + default: + error("Invalid revision"); + return QTypeRevision(); + } +} + +bool Moc::testFunctionRevision(FunctionDef *def) +{ + + if (test(Q_REVISION_TOKEN)) { + def->revision = parseRevision().toEncodedVersion<int>(); return true; } @@ -648,6 +657,11 @@ void Moc::parse() case Q_CLASSINFO_TOKEN: parseClassInfo(&def); break; + case Q_MOC_INCLUDE_TOKEN: + // skip it, the namespace is parsed twice + next(LPAREN); + lexemUntil(RPAREN); + break; case ENUM: { EnumDef enumDef; if (parseEnum(&enumDef)) @@ -691,6 +705,9 @@ void Moc::parse() case Q_DECLARE_METATYPE_TOKEN: parseDeclareMetatype(); break; + case Q_MOC_INCLUDE_TOKEN: + parseMocInclude(); + break; case USING: if (test(NAMESPACE)) { while (test(SCOPE) || test(IDENTIFIER)) @@ -823,6 +840,9 @@ void Moc::parse() case Q_CLASSINFO_TOKEN: parseClassInfo(&def); break; + case Q_MOC_INCLUDE_TOKEN: + parseMocInclude(); + break; case Q_INTERFACES_TOKEN: parseInterfaces(&def); break; @@ -1084,17 +1104,9 @@ void Moc::generate(FILE *out, FILE *jsonOutput) void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) { - int defaultRevision = -1; - if (test(Q_REVISION_TOKEN)) { - next(LPAREN); - QByteArray revision = lexemUntil(RPAREN); - revision.remove(0, 1); - revision.chop(1); - bool ok = false; - defaultRevision = revision.toInt(&ok); - if (!ok || defaultRevision < 0) - error("Invalid revision"); - } + QTypeRevision defaultRevision; + if (test(Q_REVISION_TOKEN)) + defaultRevision = parseRevision(); next(COLON); while (inClass(def) && hasNext()) { @@ -1123,8 +1135,8 @@ void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) continue; if (funcDef.revision > 0) { ++def->revisionedMethods; - } else if (defaultRevision != -1) { - funcDef.revision = defaultRevision; + } else if (defaultRevision.isValid()) { + funcDef.revision = defaultRevision.toEncodedVersion<int>(); ++def->revisionedMethods; } def->slotList += funcDef; @@ -1138,17 +1150,9 @@ void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) void Moc::parseSignals(ClassDef *def) { - int defaultRevision = -1; - if (test(Q_REVISION_TOKEN)) { - next(LPAREN); - QByteArray revision = lexemUntil(RPAREN); - revision.remove(0, 1); - revision.chop(1); - bool ok = false; - defaultRevision = revision.toInt(&ok); - if (!ok || defaultRevision < 0) - error("Invalid revision"); - } + QTypeRevision defaultRevision; + if (test(Q_REVISION_TOKEN)) + defaultRevision = parseRevision(); next(COLON); while (inClass(def) && hasNext()) { @@ -1179,8 +1183,8 @@ void Moc::parseSignals(ClassDef *def) error("Not a signal declaration"); if (funcDef.revision > 0) { ++def->revisionedMethods; - } else if (defaultRevision != -1) { - funcDef.revision = defaultRevision; + } else if (defaultRevision.isValid()) { + funcDef.revision = defaultRevision.toEncodedVersion<int>(); ++def->revisionedMethods; } def->signalList += funcDef; @@ -1241,6 +1245,10 @@ void Moc::createPropertyDef(PropertyDef &propDef) } else if (l[0] == 'R' && l == "REQUIRED") { propDef.required = true; continue; + } else if (l[0] == 'R' && l == "REVISION" && test(LPAREN)) { + prev(); + propDef.revision = parseRevision().toEncodedVersion<int>(); + continue; } QByteArray v, v2; @@ -1273,9 +1281,10 @@ void Moc::createPropertyDef(PropertyDef &propDef) propDef.reset = v + v2; else if (l == "REVISION") { bool ok = false; - propDef.revision = v.toInt(&ok); - if (!ok || propDef.revision < 0) + const int minor = v.toInt(&ok); + if (!ok || !QTypeRevision::isValidSegment(minor)) error(1); + propDef.revision = QTypeRevision::fromMinorVersion(minor).toEncodedVersion<int>(); } else error(2); break; @@ -1483,6 +1492,8 @@ void Moc::parseClassInfo(BaseDef *def) next(COMMA); if (test(STRING_LITERAL)) { infoDef.value = symbol().unquotedLexem(); + } else if (test(Q_REVISION_TOKEN)) { + infoDef.value = QByteArray::number(parseRevision().toEncodedVersion<quint16>()); } else { // support Q_CLASSINFO("help", QT_TR_NOOP("blah")) next(IDENTIFIER); @@ -1560,6 +1571,16 @@ void Moc::parseDeclareMetatype() metaTypes.append(typeName); } +void Moc::parseMocInclude() +{ + next(LPAREN); + QByteArray include = lexemUntil(RPAREN); + // remove parentheses + include.remove(0, 1); + include.chop(1); + includeFiles.append(include); +} + void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access) { next(LPAREN); |