summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Lima <hugo.lima@openbossa.org>2009-09-18 11:17:08 -0300
committerHugo Lima <hugo.lima@openbossa.org>2009-09-18 11:53:12 -0300
commit31bf15c779fc5c66c0ed37b557d288dd7911dfa3 (patch)
tree8668d328cc389d50486bac5d9485598a7d0fdb0a
parent2ed8b4dcc030ce0274ea056dd541f48d57629ee8 (diff)
Revert "Fix a bug related to function default values."
This fix bring to much regressions. This reverts commit 752c22056f4ba61961a01819992f9af71a3b0416.
-rw-r--r--abstractmetabuilder.cpp93
-rw-r--r--abstractmetabuilder.h3
-rw-r--r--tests/testabstractmetaclass.cpp53
-rw-r--r--tests/testabstractmetaclass.h2
4 files changed, 95 insertions, 56 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 243bbae..0ba989d 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -1517,7 +1517,10 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu
if (!expr.isEmpty())
metaArg->setOriginalDefaultValueExpression(expr);
- metaArg->setDefaultValueExpression(metaArg->originalDefaultValueExpression());
+ if (m_currentClass) {
+ expr = translateDefaultValue(arg, metaArg->type(), metaFunction, m_currentClass, i);
+ metaArg->setDefaultValueExpression(expr);
+ }
if (expr.isEmpty())
firstDefaultArgument = i;
@@ -1850,6 +1853,94 @@ void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *metaType)
}
}
+QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
+ AbstractMetaFunction *fnc, AbstractMetaClass *implementingClass,
+ int argumentIndex)
+{
+ QString functionName = fnc->name();
+ QString className = implementingClass->qualifiedCppName();
+
+ QString replacedExpression = fnc->replacedDefaultExpression(implementingClass, argumentIndex + 1);
+ if (fnc->removedDefaultExpression(implementingClass, argumentIndex + 1))
+ return "";
+ else if (!replacedExpression.isEmpty())
+ return replacedExpression;
+
+ QString expr = item->defaultValueExpression();
+ if (type) {
+ if (type->isPrimitive()) {
+ if (type->name() == "boolean") {
+ if (expr != "false" && expr != "true") {
+ bool ok = false;
+ int number = expr.toInt(&ok);
+ if (ok && number)
+ expr = "true";
+ else
+ expr = "false";
+ }
+ } else if (expr == "QVariant::Invalid") {
+ expr = QString::number(QVariant::Invalid);
+ } else {
+ // This can be an enum or flag so I need to delay the
+ // translation untill all namespaces are completly
+ // processed. This is done in figureOutEnumValues()
+ }
+ } else if (type->isFlags() || type->isEnum()) {
+ bool isNumber;
+ expr.toInt(&isNumber);
+ if (!isNumber && expr.indexOf("::") < 0) {
+ // Add the enum/flag scope to default value, making it usable
+ // from other contexts beside its owner class hierarchy
+ QRegExp typeRegEx("[^<]*[<]([^:]*::).*");
+ typeRegEx.indexIn(type->minimalSignature());
+ expr = typeRegEx.cap(1) + expr;
+ }
+ } else if (type->isContainer() && expr.contains('<')) {
+ QRegExp typeRegEx("[^<]*<(.*)>");
+ typeRegEx.indexIn(type->minimalSignature());
+ QRegExp defaultRegEx("([^<]*<).*(>[^>]*)");
+ defaultRegEx.indexIn(expr);
+ expr = defaultRegEx.cap(1) + typeRegEx.cap(1) + defaultRegEx.cap(2);
+ } else {
+ // Here the default value is supposed to be a constructor,
+ // a class field, or a constructor receiving a class field
+ QRegExp defaultRegEx("([^\\(]*\\(|)([^\\)]*)(\\)|)");
+ defaultRegEx.indexIn(expr);
+
+ QString defaultValueCtorName = defaultRegEx.cap(1);
+ if (defaultValueCtorName.endsWith('('))
+ defaultValueCtorName.chop(1);
+
+ // Fix the scope for constructor using the already
+ // resolved argument type as a reference.
+ // The following regular expression extracts any
+ // use of namespaces/scopes from the type string.
+ QRegExp typeRegEx("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$");
+ typeRegEx.indexIn(type->minimalSignature());
+
+ QString typeNamespace = typeRegEx.cap(1);
+ QString typeCtorName = typeRegEx.cap(2);
+ if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName)
+ expr.prepend(typeNamespace);
+
+ // Fix scope if the parameter is a field of the current class
+ foreach (const AbstractMetaField* field, implementingClass->fields()) {
+ if (defaultRegEx.cap(2) == field->name()) {
+ expr = defaultRegEx.cap(1) + implementingClass->name() + "::" + defaultRegEx.cap(2) + defaultRegEx.cap(3);
+ break;
+ }
+ }
+ }
+ } else {
+ QString warn = QString("undefined type for default value '%3' of argument in function '%1', class '%2'")
+ .arg(functionName).arg(className).arg(item->defaultValueExpression());
+ ReportHandler::warning(warn);
+ expr = QString();
+ }
+
+ return expr;
+}
+
bool AbstractMetaBuilder::isQObject(const QString &qualifiedName)
{
if (qualifiedName == "QObject")
diff --git a/abstractmetabuilder.h b/abstractmetabuilder.h
index fb40193..4f09791 100644
--- a/abstractmetabuilder.h
+++ b/abstractmetabuilder.h
@@ -117,6 +117,9 @@ public:
void setupClonable(AbstractMetaClass *cls);
void setupFunctionDefaults(AbstractMetaFunction *metaFunction, AbstractMetaClass *metaClass);
+ QString translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
+ AbstractMetaFunction *fnc, AbstractMetaClass *,
+ int argumentIndex);
AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true);
void decideUsagePattern(AbstractMetaType *type);
diff --git a/tests/testabstractmetaclass.cpp b/tests/testabstractmetaclass.cpp
index 63df545..2050fca 100644
--- a/tests/testabstractmetaclass.cpp
+++ b/tests/testabstractmetaclass.cpp
@@ -137,59 +137,6 @@ void TestAbstractMetaClass::testVirtualMethods()
QCOMPARE(funcC->implementingClass(), c);
}
-void TestAbstractMetaClass::testDefaultValues()
-{
- const char* cppCode ="\
- struct A {\
- class B {};\
- void method(B b = B());\
- };\
- ";
- const char* xmlCode = "\
- <typesystem package=\"Foo\"> \
- <value-type name='A'/> \
- <value-type name='A::B'/> \
- </typesystem>";
- TestUtil t(cppCode, xmlCode, false);
- AbstractMetaClassList classes = t.builder()->classes();
- QCOMPARE(classes.count(), 2);
- AbstractMetaClass* classA = classes.findClass("A");
- QCOMPARE(classA->queryFunctionsByName("method").count(), 1);
- AbstractMetaFunction* method = classA->queryFunctionsByName("method").first();
- AbstractMetaArgument* arg = method->arguments().first();
- QCOMPARE(arg->defaultValueExpression(), arg->originalDefaultValueExpression());
-}
-
-void TestAbstractMetaClass::testModifiedDefaultValues()
-{
- const char* cppCode ="\
- struct A {\
- class B {};\
- void method(B b = B());\
- };\
- ";
- const char* xmlCode = "\
- <typesystem package=\"Foo\"> \
- <value-type name='A'> \
- <modify-function signature='method'>\
- <modify-argument index='1'>\
- <replace-default-expression with='Hello'/>\
- </modify-argument>\
- </modify-function>\
- </value-type>\
- <value-type name='A::B'/> \
- </typesystem>";
- TestUtil t(cppCode, xmlCode, false);
- AbstractMetaClassList classes = t.builder()->classes();
- QCOMPARE(classes.count(), 2);
- AbstractMetaClass* classA = classes.findClass("A");
- QCOMPARE(classA->queryFunctionsByName("method").count(), 1);
- AbstractMetaFunction* method = classA->queryFunctionsByName("method").first();
- AbstractMetaArgument* arg = method->arguments().first();
- QCOMPARE(arg->defaultValueExpression(), QString("B()"));
- QCOMPARE(arg->originalDefaultValueExpression(), QString("Hello"));
-}
-
QTEST_APPLESS_MAIN(TestAbstractMetaClass)
diff --git a/tests/testabstractmetaclass.h b/tests/testabstractmetaclass.h
index c89cbc5..54336e7 100644
--- a/tests/testabstractmetaclass.h
+++ b/tests/testabstractmetaclass.h
@@ -35,8 +35,6 @@ private slots:
void testClassName();
void testClassNameUnderNamespace();
void testVirtualMethods();
- void testDefaultValues();
- void testModifiedDefaultValues();
};
#endif // TESTABSTRACTMETACLASS_H