summaryrefslogtreecommitdiffstats
path: root/src/tools/moc/moc.cpp
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2012-03-08 12:01:25 +0100
committerJoão Abecasis <joao.abecasis@nokia.com>2012-03-08 12:02:41 +0100
commit79f2480c868523a7d8ffc9fb15055e8eab3237ba (patch)
tree8336143e8c09810dc97324970fed61af27e26a97 /src/tools/moc/moc.cpp
parent7e4f32993498db0e06346e32458a1ec7d0c7b3ec (diff)
parent12f221410fbe41d0b2efda4cd3289dfcf9044aa8 (diff)
Merge remote-tracking branch 'origin/api_changes' into containters
Conflicts: src/corelib/kernel/qmetaobject.cpp src/corelib/kernel/qvariant.cpp src/tools/moc/moc.h Change-Id: I2cd3d95b41d2636738c6b98064864941e3b0b4e6
Diffstat (limited to 'src/tools/moc/moc.cpp')
-rw-r--r--src/tools/moc/moc.cpp110
1 files changed, 108 insertions, 2 deletions
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 467f85c599..e85aadbba7 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -302,7 +302,9 @@ void Moc::parseFunctionArguments(FunctionDef *def)
arg.rightType += lexem();
}
arg.normalizedType = normalizeType(QByteArray(arg.type.name + ' ' + arg.rightType));
+ arg.normalizedType = getTypeSubstitution(arg.normalizedType);
arg.typeNameForCast = normalizeType(QByteArray(noRef(arg.type.name) + "(*)" + arg.rightType));
+ arg.typeNameForCast = getTypeSubstitution(arg.typeNameForCast);
if (test(EQ))
arg.isDefault = true;
def->arguments += arg;
@@ -412,6 +414,7 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
}
def->normalizedType = normalizeType(def->type.name);
+ def->normalizedType = getTypeSubstitution(def->normalizedType);
if (!test(RPAREN)) {
parseFunctionArguments(def);
@@ -510,6 +513,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
}
def->normalizedType = normalizeType(def->type.name);
+ def->normalizedType = getTypeSubstitution(def->normalizedType);
if (!test(RPAREN)) {
parseFunctionArguments(def);
@@ -966,6 +970,7 @@ void Moc::createPropertyDef(PropertyDef &propDef)
QVariant.
*/
type = normalizeType(type);
+ type = getTypeSubstitution(type);
if (type == "QMap")
type = "QMap<QString,QVariant>";
else if (type == "QValueList")
@@ -1077,7 +1082,6 @@ void Moc::parseProperty(ClassDef *def)
createPropertyDef(propDef);
next(RPAREN);
-
if(!propDef.notify.isEmpty())
def->notifyableProperties++;
if (propDef.revision > 0)
@@ -1240,7 +1244,8 @@ void Moc::parseInterfaces(ClassDef *def)
}
// resolve from classnames to interface ids
for (int i = 0; i < iface.count(); ++i) {
- const QByteArray iid = interface2IdMap.value(iface.at(i).className);
+ QByteArray className = getTypeSubstitution(iface.at(i).className);
+ QByteArray iid = interface2IdMap.value(className);
if (iid.isEmpty())
error("Undefined interface");
@@ -1498,6 +1503,107 @@ void Moc::checkProperties(ClassDef *cdef)
}
}
+QByteArray Moc::getSubstitution(const QByteArray &token) const
+{
+ Macros::ConstIterator it = preprocessor.macros.find(token);
+ if (it != preprocessor.macros.end() && it->symbols.count() == 1) {
+ // We can only handle substitutions that result in a single symbol
+ return it->symbols.at(0).lexem();
+ }
+
+ return QByteArray();
+}
+
+QByteArray Moc::getTokenSubstitution(const QByteArray &token) const
+{
+ QByteArray result = token;
+
+ QSet<QByteArray> used;
+
+ // Process substitution chain until no replacement exists
+ QByteArray substitution = getSubstitution(result);
+ while (!substitution.isEmpty()) {
+ used.insert(result);
+ result = substitution;
+
+ if (used.contains(result)) {
+ break;
+ }
+
+ substitution = getSubstitution(result);
+ }
+
+ return result;
+}
+
+QByteArray Moc::getWordSubstitution(const QByteArray &word) const
+{
+ QByteArray result;
+
+ // A word can contain multiple components separated by '*'
+ int startIndex = 0;
+ do {
+ int index = word.indexOf('*', startIndex);
+ if (index == -1) {
+ result.append(getTokenSubstitution(word.mid(startIndex)));
+ } else {
+ result.append(getTokenSubstitution(word.mid(startIndex, (index - startIndex))));
+ result.append('*');
+ }
+
+ startIndex = index + 1;
+ } while (startIndex != 0);
+
+ return result;
+}
+
+QByteArray Moc::getNameSubstitution(const QByteArray &name) const
+{
+ QByteArray result;
+
+ // Parse multiple tokens in this name independently
+ int startIndex = 0;
+ do {
+ int index = name.indexOf(' ', startIndex);
+ if (index == -1) {
+ result.append(getWordSubstitution(name.mid(startIndex)));
+ } else {
+ result.append(getWordSubstitution(name.mid(startIndex, (index - startIndex))));
+ result.append(' ');
+ }
+
+ startIndex = index + 1;
+ } while (startIndex != 0);
+
+ return result;
+}
+
+QByteArray Moc::getTypeSubstitution(const QByteArray &typeName) const
+{
+ int index = typeName.indexOf('<');
+ if (index != -1) {
+ QByteArray templateName = typeName.left(index);
+
+ int lastIndex = typeName.lastIndexOf('>');
+ if (lastIndex > index) {
+ QByteArray result = getNameSubstitution(templateName);
+
+ // Parse the interior type independently
+ QByteArray parameter = typeName.mid(index + 1, (lastIndex - index - 1));
+ QByteArray interior = getTypeSubstitution(parameter);
+ if (interior.endsWith('>')) {
+ interior.append(' ');
+ }
+ result.append('<').append(interior).append(typeName.mid(lastIndex));
+ return result;
+ } else {
+ // Something is broken; return the input unmodified
+ return typeName;
+ }
+ }
+
+ return getNameSubstitution(typeName);
+}
QT_END_NAMESPACE