diff options
author | Hugo Lima <hugo.lima@openbossa.org> | 2009-09-18 11:17:08 -0300 |
---|---|---|
committer | Hugo Lima <hugo.lima@openbossa.org> | 2009-09-18 11:53:12 -0300 |
commit | 31bf15c779fc5c66c0ed37b557d288dd7911dfa3 (patch) | |
tree | 8668d328cc389d50486bac5d9485598a7d0fdb0a | |
parent | 2ed8b4dcc030ce0274ea056dd541f48d57629ee8 (diff) |
Revert "Fix a bug related to function default values."
This fix bring to much regressions.
This reverts commit 752c22056f4ba61961a01819992f9af71a3b0416.
-rw-r--r-- | abstractmetabuilder.cpp | 93 | ||||
-rw-r--r-- | abstractmetabuilder.h | 3 | ||||
-rw-r--r-- | tests/testabstractmetaclass.cpp | 53 | ||||
-rw-r--r-- | tests/testabstractmetaclass.h | 2 |
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 |