diff options
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r-- | src/tools/moc/moc.cpp | 219 |
1 files changed, 109 insertions, 110 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 7dd94cdca7..f2efcadad7 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -1,31 +1,26 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** @@ -141,7 +136,7 @@ bool Moc::parseClassHead(ClassDef *def) } while (test(COMMA)); if (!def->superclassList.isEmpty() - && knownGadgets.contains(def->superclassList.first().first)) { + && knownGadgets.contains(def->superclassList.constFirst().first)) { // Q_GADGET subclasses are treated as Q_GADGETs knownGadgets.insert(def->classname, def->qualified); knownGadgets.insert(def->qualified, def->qualified); @@ -317,7 +312,7 @@ void Moc::parseFunctionArguments(FunctionDef *def) } if (!def->arguments.isEmpty() - && def->arguments.last().normalizedType == "QPrivateSignal") { + && def->arguments.constLast().normalizedType == "QPrivateSignal") { def->arguments.removeLast(); def->isPrivateSignal = true; } @@ -458,9 +453,8 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) } if (scopedFunctionName) { - QByteArray msg("Function declaration "); - msg += def->name; - msg += " contains extra qualification. Ignoring as signal or slot."; + const QByteArray msg = "Function declaration " + def->name + + " contains extra qualification. Ignoring as signal or slot."; warning(msg.constData()); return false; } @@ -531,9 +525,8 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) def->isConst = test(CONST); if (scopedFunctionName && (def->isSignal || def->isSlot || def->isInvokable)) { - QByteArray msg("parsemaybe: Function declaration "); - msg += def->name; - msg += " contains extra qualification. Ignoring as signal or slot."; + const QByteArray msg = "parsemaybe: Function declaration " + def->name + + " contains extra qualification. Ignoring as signal or slot."; warning(msg.constData()); return false; } @@ -543,7 +536,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) void Moc::parse() { - QList<NamespaceDef> namespaceList; + QVector<NamespaceDef> namespaceList; bool templateClass = false; while (hasNext()) { Token t = next(); @@ -735,7 +728,7 @@ void Moc::parse() if (funcDef.isConstructor) { if ((access == FunctionDef::Public) && funcDef.isInvokable) { def.constructorList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.constructorList += funcDef; @@ -748,7 +741,7 @@ void Moc::parse() def.publicList += funcDef; if (funcDef.isSlot) { def.slotList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.slotList += funcDef; @@ -757,7 +750,7 @@ void Moc::parse() ++def.revisionedMethods; } else if (funcDef.isSignal) { def.signalList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.signalList += funcDef; @@ -766,7 +759,7 @@ void Moc::parse() ++def.revisionedMethods; } else if (funcDef.isInvokable) { def.methodList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.methodList += funcDef; @@ -806,9 +799,30 @@ void Moc::parse() } } -static void findRequiredContainers(ClassDef *cdef, QSet<QByteArray> *requiredQtContainers) +static bool any_type_contains(const QVector<PropertyDef> &properties, const QByteArray &pattern) +{ + for (const auto &p : properties) { + if (p.type.contains(pattern)) + return true; + } + return false; +} + +static bool any_arg_contains(const QVector<FunctionDef> &functions, const QByteArray &pattern) { - static const QVector<QByteArray> candidates = QVector<QByteArray>() + for (const auto &f : functions) { + for (const auto &arg : f.arguments) { + if (arg.normalizedType.contains(pattern)) + return true; + } + } + return false; +} + +static QByteArrayList make_candidates() +{ + QByteArrayList result; + result #define STREAM_SMART_POINTER(SMART_POINTER) << #SMART_POINTER QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(STREAM_SMART_POINTER) #undef STREAM_SMART_POINTER @@ -816,33 +830,38 @@ static void findRequiredContainers(ClassDef *cdef, QSet<QByteArray> *requiredQtC QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(STREAM_1ARG_TEMPLATE) #undef STREAM_1ARG_TEMPLATE ; + return result; +} - for (int i = 0; i < cdef->propertyList.count(); ++i) { - const PropertyDef &p = cdef->propertyList.at(i); - foreach (const QByteArray &candidate, candidates) { - if (p.type.contains(candidate + "<")) - requiredQtContainers->insert(candidate); - } - } +static QByteArrayList requiredQtContainers(const QVector<ClassDef> &classes) +{ + static const QByteArrayList candidates = make_candidates(); + + QByteArrayList required; + required.reserve(candidates.size()); - QList<FunctionDef> allFunctions = cdef->slotList + cdef->signalList + cdef->methodList; + for (const auto &candidate : candidates) { + const QByteArray pattern = candidate + '<'; - for (int i = 0; i < allFunctions.count(); ++i) { - const FunctionDef &f = allFunctions.at(i); - foreach (const ArgumentDef &arg, f.arguments) { - foreach (const QByteArray &candidate, candidates) { - if (arg.normalizedType.contains(candidate + "<")) - requiredQtContainers->insert(candidate); + for (const auto &c : classes) { + if (any_type_contains(c.propertyList, pattern) || + any_arg_contains(c.slotList, pattern) || + any_arg_contains(c.signalList, pattern) || + any_arg_contains(c.methodList, pattern)) { + required.push_back(candidate); + break; } } } + + return required; } void Moc::generate(FILE *out) { QByteArray fn = filename; int i = filename.length()-1; - while (i>0 && filename[i-1] != '/' && filename[i-1] != '\\') + while (i > 0 && filename.at(i - 1) != '/' && filename.at(i - 1) != '\\') --i; // skip path if (i >= 0) fn = filename.mid(i); @@ -858,7 +877,7 @@ void Moc::generate(FILE *out) includePath += '/'; for (int i = 0; i < includeFiles.size(); ++i) { QByteArray inc = includeFiles.at(i); - if (inc[0] != '<' && inc[0] != '"') { + if (inc.at(0) != '<' && inc.at(0) != '"') { if (includePath.size() && includePath != "./") inc.prepend(includePath); inc = '\"' + inc + '\"'; @@ -866,7 +885,7 @@ void Moc::generate(FILE *out) fprintf(out, "#include %s\n", inc.constData()); } } - if (classList.size() && classList.first().classname == "Qt") + if (classList.size() && classList.constFirst().classname == "Qt") fprintf(out, "#include <QtCore/qobject.h>\n"); fprintf(out, "#include <QtCore/qbytearray.h>\n"); // For QByteArrayData @@ -874,19 +893,9 @@ void Moc::generate(FILE *out) if (mustIncludeQPluginH) fprintf(out, "#include <QtCore/qplugin.h>\n"); - QSet<QByteArray> requiredQtContainers; - for (i = 0; i < classList.size(); ++i) { - findRequiredContainers(&classList[i], &requiredQtContainers); - } - - // after finding the containers, we sort them into a list to avoid - // non-deterministic behavior which may cause rebuilds unnecessarily. - QList<QByteArray> requiredContainerList = requiredQtContainers.toList(); - std::sort(requiredContainerList.begin(), requiredContainerList.end()); - - foreach (const QByteArray &qtContainer, requiredContainerList) { + const auto qtContainers = requiredQtContainers(classList); + for (const QByteArray &qtContainer : qtContainers) fprintf(out, "#include <QtCore/%s>\n", qtContainer.constData()); - } fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n" @@ -954,7 +963,7 @@ void Moc::parseSlots(ClassDef *def, FunctionDef::Access access) ++def->revisionedMethods; } def->slotList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->slotList += funcDef; @@ -1010,7 +1019,7 @@ void Moc::parseSignals(ClassDef *def) ++def->revisionedMethods; } def->signalList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->signalList += funcDef; @@ -1048,7 +1057,7 @@ void Moc::createPropertyDef(PropertyDef &propDef) next(); propDef.name = lexem(); while (test(IDENTIFIER)) { - QByteArray l = lexem(); + const QByteArray l = lexem(); if (l[0] == 'C' && l == "CONSTANT") { propDef.constant = true; continue; @@ -1121,25 +1130,19 @@ void Moc::createPropertyDef(PropertyDef &propDef) } } if (propDef.read.isNull() && propDef.member.isNull()) { - QByteArray msg; - msg += "Property declaration "; - msg += propDef.name; - msg += " has no READ accessor function or associated MEMBER variable. The property will be invalid."; + const QByteArray msg = "Property declaration " + propDef.name + + " has no READ accessor function or associated MEMBER variable. The property will be invalid."; warning(msg.constData()); } if (propDef.constant && !propDef.write.isNull()) { - QByteArray msg; - msg += "Property declaration "; - msg += propDef.name; - msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored."; + const QByteArray msg = "Property declaration " + propDef.name + + " is both WRITEable and CONSTANT. CONSTANT will be ignored."; propDef.constant = false; warning(msg.constData()); } if (propDef.constant && !propDef.notify.isNull()) { - QByteArray msg; - msg += "Property declaration "; - msg += propDef.name; - msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored."; + const QByteArray msg = "Property declaration " + propDef.name + + " is both NOTIFYable and CONSTANT. CONSTANT will be ignored."; propDef.constant = false; warning(msg.constData()); } @@ -1185,10 +1188,8 @@ void Moc::parsePluginData(ClassDef *def) } } if (!fi.exists()) { - QByteArray msg; - msg += "Plugin Metadata file "; - msg += lexem(); - msg += " does not exist. Declaration will be ignored"; + const QByteArray msg = "Plugin Metadata file " + lexem() + + " does not exist. Declaration will be ignored"; error(msg.constData()); return; } @@ -1201,10 +1202,8 @@ void Moc::parsePluginData(ClassDef *def) if (!metaData.isEmpty()) { def->pluginData.metaData = QJsonDocument::fromJson(metaData); if (!def->pluginData.metaData.isObject()) { - QByteArray msg; - msg += "Plugin Metadata file "; - msg += lexem(); - msg += " does not contain a valid JSON object. Declaration will be ignored"; + const QByteArray msg = "Plugin Metadata file " + lexem() + + " does not contain a valid JSON object. Declaration will be ignored"; warning(msg.constData()); def->pluginData.iid = QByteArray(); return; @@ -1308,7 +1307,7 @@ void Moc::parseInterfaces(ClassDef *def) { next(LPAREN); while (test(IDENTIFIER)) { - QList<ClassDef::Interface> iface; + QVector<ClassDef::Interface> iface; iface += ClassDef::Interface(lexem()); while (test(SCOPE)) { iface.last().className += lexem(); @@ -1384,7 +1383,7 @@ void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access) funcDef.access = access; parseFunction(&funcDef, true); def->slotList += funcDef; - while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { + while (funcDef.arguments.size() > 0 && funcDef.arguments.constLast().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def->slotList += funcDef; @@ -1444,7 +1443,7 @@ bool Moc::until(Token target) { case LPAREN: ++parenCount; break; case RPAREN: --parenCount; break; case LANGLE: - if (parenCount == 0 && braceCount == 0 && parenCount == 0) + if (parenCount == 0 && braceCount == 0) ++angleCount; break; case RANGLE: @@ -1501,12 +1500,12 @@ void Moc::checkSuperClasses(ClassDef *def) if (!knownQObjectClasses.contains(firstSuperclass)) { // enable once we /require/ include paths #if 0 - QByteArray msg; - msg += "Class "; - msg += def->className; - msg += " contains the Q_OBJECT macro and inherits from "; - msg += def->superclassList.value(0); - msg += " but that is not a known QObject subclass. You may get compilation errors."; + const QByteArray msg + = "Class " + + def->className + + " contains the Q_OBJECT macro and inherits from " + + def->superclassList.value(0) + + " but that is not a known QObject subclass. You may get compilation errors."; warning(msg.constData()); #endif return; @@ -1514,34 +1513,34 @@ void Moc::checkSuperClasses(ClassDef *def) for (int i = 1; i < def->superclassList.count(); ++i) { const QByteArray superClass = def->superclassList.at(i).first; if (knownQObjectClasses.contains(superClass)) { - QByteArray msg; - msg += "Class "; - msg += def->classname; - msg += " inherits from two QObject subclasses "; - msg += firstSuperclass; - msg += " and "; - msg += superClass; - msg += ". This is not supported!"; + const QByteArray msg + = "Class " + + def->classname + + " inherits from two QObject subclasses " + + firstSuperclass + + " and " + + superClass + + ". This is not supported!"; warning(msg.constData()); } if (interface2IdMap.contains(superClass)) { bool registeredInterface = false; for (int i = 0; i < def->interfaceList.count(); ++i) - if (def->interfaceList.at(i).first().className == superClass) { + if (def->interfaceList.at(i).constFirst().className == superClass) { registeredInterface = true; break; } if (!registeredInterface) { - QByteArray msg; - msg += "Class "; - msg += def->classname; - msg += " implements the interface "; - msg += superClass; - msg += " but does not list it in Q_INTERFACES. qobject_cast to "; - msg += superClass; - msg += " will not work!"; + const QByteArray msg + = "Class " + + def->classname + + " implements the interface " + + superClass + + " but does not list it in Q_INTERFACES. qobject_cast to " + + superClass + + " will not work!"; warning(msg.constData()); } } |