diff options
-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, 56 insertions, 95 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp index 0ba989dc7..243bbae32 100644 --- a/abstractmetabuilder.cpp +++ b/abstractmetabuilder.cpp @@ -1517,10 +1517,7 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu if (!expr.isEmpty()) metaArg->setOriginalDefaultValueExpression(expr); - if (m_currentClass) { - expr = translateDefaultValue(arg, metaArg->type(), metaFunction, m_currentClass, i); - metaArg->setDefaultValueExpression(expr); - } + metaArg->setDefaultValueExpression(metaArg->originalDefaultValueExpression()); if (expr.isEmpty()) firstDefaultArgument = i; @@ -1853,94 +1850,6 @@ 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 4f0979129..fb4019317 100644 --- a/abstractmetabuilder.h +++ b/abstractmetabuilder.h @@ -117,9 +117,6 @@ 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 2050fca20..63df54598 100644 --- a/tests/testabstractmetaclass.cpp +++ b/tests/testabstractmetaclass.cpp @@ -137,6 +137,59 @@ 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 54336e7bf..c89cbc5d1 100644 --- a/tests/testabstractmetaclass.h +++ b/tests/testabstractmetaclass.h @@ -35,6 +35,8 @@ private slots: void testClassName(); void testClassNameUnderNamespace(); void testVirtualMethods(); + void testDefaultValues(); + void testModifiedDefaultValues(); }; #endif // TESTABSTRACTMETACLASS_H |