diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2011-04-14 19:47:06 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-09 19:10:16 -0300 |
commit | 427992fc248b60dc38e21a4a2e2a48f64c1cbe2c (patch) | |
tree | e35ace7dc101cf2a10883cf4c044135a769abf95 | |
parent | a4196f6b63d3050a7bc631e6276e17e0af4dc1eb (diff) |
Add support for adding reverse operators with add-function tag.
Reviewer: Renato Araújo <renato.filho@openbossa.org>
Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r-- | abstractmetabuilder.cpp | 62 | ||||
-rw-r--r-- | abstractmetabuilder.h | 3 |
2 files changed, 48 insertions, 17 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp index bfd272321..41c09a3ec 100644 --- a/abstractmetabuilder.cpp +++ b/abstractmetabuilder.cpp @@ -1439,22 +1439,8 @@ void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scopeItem, AbstractMe void AbstractMetaBuilder::fillAddedFunctions(AbstractMetaClass* metaClass) { // Add the functions added by the typesystem - foreach (AddedFunction addedFunc, metaClass->typeEntry()->addedFunctions()) { - AbstractMetaFunction* func = traverseFunction(addedFunc); - if (metaClass->isNamespace()) - *func += AbstractMetaFunction::Static; - if (func->name() == metaClass->name()) { - func->setFunctionType(AbstractMetaFunction::ConstructorFunction); - if (func->arguments().size() == 1 && func->arguments().first()->type()->typeEntry()->isCustom()) - func->setExplicit(true); - } else { - func->setFunctionType(AbstractMetaFunction::NormalFunction); - } - func->setDeclaringClass(metaClass); - func->setImplementingClass(metaClass); - metaClass->addFunction(func); - metaClass->setHasNonPrivateConstructor(true); - } + foreach (AddedFunction addedFunc, metaClass->typeEntry()->addedFunctions()) + traverseFunction(addedFunc, metaClass); } void AbstractMetaBuilder::applyFunctionModifications(AbstractMetaFunction* func) @@ -1612,6 +1598,11 @@ void AbstractMetaBuilder::traverseEnums(ScopeModelItem scopeItem, AbstractMetaCl AbstractMetaFunction* AbstractMetaBuilder::traverseFunction(const AddedFunction& addedFunc) { + return traverseFunction(addedFunc, 0); +} + +AbstractMetaFunction* AbstractMetaBuilder::traverseFunction(const AddedFunction& addedFunc, AbstractMetaClass* metaClass) +{ AbstractMetaFunction* metaFunction = createMetaFunction(); metaFunction->setConstant(addedFunc.isConstant()); metaFunction->setName(addedFunc.name()); @@ -1623,6 +1614,7 @@ AbstractMetaFunction* AbstractMetaBuilder::traverseFunction(const AddedFunction& metaFunction->setAttributes(metaFunction->attributes() | AbstractMetaAttributes::Final | isStatic); metaFunction->setType(translateType(addedFunc.version(), addedFunc.returnType())); + QList<AddedFunction::TypeInfo> args = addedFunc.arguments(); AbstractMetaArgumentList metaArguments; @@ -1639,6 +1631,25 @@ AbstractMetaFunction* AbstractMetaBuilder::traverseFunction(const AddedFunction& } metaFunction->setArguments(metaArguments); + if (metaFunction->isOperatorOverload() && !metaFunction->isCallOperator()) { + if (metaArguments.size() > 2) { + ReportHandler::warning("An operator overload need to have 0, 1 or 2 arguments if it's reverse."); + } else if (metaArguments.size() == 2) { + // Check if it's a reverse operator + if (metaArguments[1]->type()->typeEntry() == metaClass->typeEntry()) { + metaFunction->setReverseOperator(true); + // we need to call these two function to cache the old signature (with two args) + // we do this buggy behaviour to comply with the original apiextractor buggy behaviour. + metaFunction->signature(); + metaFunction->minimalSignature(); + metaArguments.removeLast(); + metaFunction->setArguments(metaArguments); + } else { + ReportHandler::warning("Operator overload can have two arguments only if it's a reverse operator!"); + } + } + } + // Find the correct default values for (int i = 0; i < metaArguments.size(); ++i) { @@ -1663,6 +1674,25 @@ AbstractMetaFunction* AbstractMetaBuilder::traverseFunction(const AddedFunction& metaFunction->setOriginalAttributes(metaFunction->attributes()); fixArgumentNames(metaFunction); + + if (metaClass) { + const AbstractMetaArgumentList fargs = metaFunction->arguments(); + if (metaClass->isNamespace()) + *metaFunction += AbstractMetaFunction::Static; + if (metaFunction->name() == metaClass->name()) { + metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); + if (fargs.size() == 1 && fargs.first()->type()->typeEntry()->isCustom()) + metaFunction->setExplicit(true); + } else { + metaFunction->setFunctionType(AbstractMetaFunction::NormalFunction); + } + + metaFunction->setDeclaringClass(metaClass); + metaFunction->setImplementingClass(metaClass); + metaClass->addFunction(metaFunction); + metaClass->setHasNonPrivateConstructor(true); + } + return metaFunction; } diff --git a/abstractmetabuilder.h b/abstractmetabuilder.h index 893ebece4..b4a2863ac 100644 --- a/abstractmetabuilder.h +++ b/abstractmetabuilder.h @@ -117,7 +117,8 @@ public: void traverseFields(ScopeModelItem item, AbstractMetaClass *parent); void traverseStreamOperator(FunctionModelItem functionItem); void traverseOperatorFunction(FunctionModelItem item); - AbstractMetaFunction *traverseFunction(const AddedFunction& addedFunc); + AbstractMetaFunction* traverseFunction(const AddedFunction& addedFunc); + AbstractMetaFunction* traverseFunction(const AddedFunction& addedFunc, AbstractMetaClass* metaClass); AbstractMetaFunction *traverseFunction(FunctionModelItem function); AbstractMetaField *traverseField(VariableModelItem field, const AbstractMetaClass *cls); void checkFunctionModifications(); |