aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-06-15 14:57:58 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2010-06-15 15:13:56 -0300
commit7e6b26aeeb9d97cbae6ac9fca290b109fdd2e828 (patch)
tree4d412a7aa69e2eb98083e6465a5f20ea5bbada8c
parent93262f84164a48800024b61479ff16561ed811fa (diff)
Added method to guess scope of function argument default values.
The default values for arguments are simple strings, sometimes during binding code generation scope information is needed. The method ShibokenGenerator::guessScopeForDefaultValue tries to guess scope information for default values.
-rw-r--r--shibokengenerator.cpp106
-rw-r--r--shibokengenerator.h3
2 files changed, 109 insertions, 0 deletions
diff --git a/shibokengenerator.cpp b/shibokengenerator.cpp
index f2fd835c4..4a2cc7b98 100644
--- a/shibokengenerator.cpp
+++ b/shibokengenerator.cpp
@@ -283,6 +283,112 @@ static QString cpythonEnumFlagsName(QString moduleName, QString qualifiedCppName
return result;
}
+static QString searchForEnumScope(const AbstractMetaClass* metaClass, const QString& value)
+{
+ QString enumValueName = value.trimmed();
+
+ if (!metaClass)
+ return QString();
+
+ foreach (const AbstractMetaEnum* metaEnum, metaClass->enums()) {
+ foreach (const AbstractMetaEnumValue* enumValue, metaEnum->values()) {
+ if (enumValueName == enumValue->name())
+ return metaClass->qualifiedCppName();
+ }
+ }
+
+ return searchForEnumScope(metaClass->enclosingClass(), enumValueName);
+}
+
+/*
+ * This function uses some heuristics to find out the scope for a given
+ * argument default value. New situations may arise in the future and
+ * this method should be updated, do it with care.
+ */
+QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg)
+{
+ if (arg->defaultValueExpression().isEmpty())
+ return QString();
+
+ static QRegExp enumValueRegEx("^([A-Za-z_]\\w*)?$");
+ QString value = arg->defaultValueExpression();
+ QString prefix;
+ QString suffix;
+
+ if (arg->type()->isEnum()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(arg->type());
+ if (metaEnum->enclosingClass()) {
+ prefix = metaEnum->enclosingClass()->qualifiedCppName() + "::";
+ if (value.startsWith(prefix))
+ prefix = QString();
+ }
+ } else if (arg->type()->isFlags()) {
+ static QRegExp numberRegEx("^\\d+$"); // Numbers to flags
+ if (numberRegEx.exactMatch(value)) {
+ QString typeName = translateTypeForWrapperMethod(arg->type(), func->implementingClass());
+ if (arg->type()->isConstant())
+ typeName.remove(0, sizeof("const ") / sizeof(char) - 1);
+ if (arg->type()->isReference())
+ typeName.chop(1);
+ prefix = typeName + '(';
+ suffix = ')';
+ }
+
+ static QRegExp enumCombinationRegEx("^([A-Za-z_][\\w:]*)\\(([^,\\(\\)]*)\\)$"); // FlagName(EnumItem|EnumItem|...)
+ if (prefix.isEmpty() && enumCombinationRegEx.indexIn(value) != -1) {
+ QString flagName = enumCombinationRegEx.cap(1);
+ QStringList enumItems = enumCombinationRegEx.cap(2).split("|");
+ QString scope = searchForEnumScope(func->implementingClass(), enumItems.first());
+ if (!scope.isEmpty())
+ scope.append("::");
+
+ QStringList fixedEnumItems;
+ foreach (const QString& enumItem, enumItems)
+ fixedEnumItems << QString(scope + enumItem);
+
+ if (!fixedEnumItems.isEmpty()) {
+ prefix = flagName + '(';
+ value = fixedEnumItems.join("|");
+ suffix = ')';
+ }
+ }
+ } else if (arg->type()->typeEntry()->isValue()) {
+ const AbstractMetaClass* metaClass = classes().findClass(arg->type()->typeEntry());
+ if (enumValueRegEx.exactMatch(value))
+ prefix = metaClass->qualifiedCppName() + "::";
+ if (value.startsWith(prefix))
+ prefix = QString();
+ } else if (arg->type()->isPrimitive() && arg->type()->name() == "int") {
+ if (enumValueRegEx.exactMatch(value) && func->implementingClass()) {
+ prefix = func->implementingClass()->qualifiedCppName() + "::";
+ if (value.startsWith(prefix))
+ prefix = QString();
+ }
+ } else if(arg->type()->isPrimitive()) {
+ static QRegExp unknowArgumentRegEx("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$"); // [PrimitiveType(] DESIREDNAME [)]
+ if (unknowArgumentRegEx.indexIn(value) != -1 && func->implementingClass()) {
+ foreach (const AbstractMetaField* field, func->implementingClass()->fields()) {
+ if (unknowArgumentRegEx.cap(1).trimmed() == field->name()) {
+ QString fieldName = field->name();
+ if (field->isStatic())
+ fieldName.prepend(func->implementingClass()->qualifiedCppName() + "::");
+ else
+ fieldName.prepend(CPP_SELF_VAR "->");
+ value.replace(unknowArgumentRegEx.cap(1), fieldName);
+ break;
+ }
+ }
+ }
+ }
+
+ if (!prefix.isEmpty())
+ value.prepend(prefix);
+ if (!suffix.isEmpty())
+ value.append(suffix);
+
+ return value;
+}
+
QString ShibokenGenerator::cpythonEnumName(const EnumTypeEntry* enumEntry)
{
return cpythonEnumFlagsName(enumEntry->targetLangPackage().replace(".", "_"), enumEntry->qualifiedCppName());
diff --git a/shibokengenerator.h b/shibokengenerator.h
index 3985c95be..62c72b81d 100644
--- a/shibokengenerator.h
+++ b/shibokengenerator.h
@@ -266,6 +266,9 @@ public:
QString cpythonWrapperCPtr(const AbstractMetaType* metaType, QString argName);
QString cpythonWrapperCPtr(const TypeEntry* type, QString argName);
+ /// Guesses the scope to where belongs an argument's default value.
+ QString guessScopeForDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg);
+
QString cpythonEnumName(const EnumTypeEntry* enumEntry);
QString cpythonEnumName(const AbstractMetaEnum* metaEnum)
{