summaryrefslogtreecommitdiffstats
path: root/generator/shibokengenerator.h
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-09-20 17:26:09 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2010-09-20 17:33:18 -0300
commit231253beff97ce9d81d63ee437b833cc73ed1142 (patch)
treef3a1bd609b7e4c97aa17133a52666379ac8eb32d /generator/shibokengenerator.h
parenta02e6fff64cdfcf2022c73d03d779a2584544842 (diff)
downloadshiboken-231253beff97ce9d81d63ee437b833cc73ed1142.tar.gz
shiboken-231253beff97ce9d81d63ee437b833cc73ed1142.tar.xz
shiboken-231253beff97ce9d81d63ee437b833cc73ed1142.zip
Shiboken generator code moved to the directory generator.
Reviewer: Renato Ara├║jo <renato.filho@openbossa.org> Luciano Wolf <luciano.wolf@openbossa.org>
Diffstat (limited to 'generator/shibokengenerator.h')
-rw-r--r--generator/shibokengenerator.h364
1 files changed, 364 insertions, 0 deletions
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
new file mode 100644
index 00000000..1a7c5a63
--- /dev/null
+++ b/generator/shibokengenerator.h
@@ -0,0 +1,364 @@
+/*
+ * This file is part of the Shiboken Python Bindings Generator project.
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef SHIBOKENGENERATOR_H
+#define SHIBOKENGENERATOR_H
+
+#define PYTHON_RETURN_VAR "pyResult"
+#define CPP_RETURN_VAR "cppResult"
+#define THREAD_STATE_SAVER_VAR "threadStateSaver"
+#define CPP_SELF_VAR "cppSelf"
+
+#include <generator.h>
+#include <QtCore/QTextStream>
+
+#include "overloaddata.h"
+
+class DocParser;
+
+/**
+ * Abstract generator that contains common methods used in CppGenerator and HeaderGenerator.
+ */
+class ShibokenGenerator : public Generator
+{
+public:
+ ShibokenGenerator();
+
+ QString translateTypeForWrapperMethod(const AbstractMetaType* cType,
+ const AbstractMetaClass* context, Options opt = NoOption) const;
+
+ /**
+ * Returns a map with all functions grouped, the function name is used as key.
+ * Example ofg return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"}
+ * \param scope Where to search for functions, null means all global functions.
+ */
+ QMap<QString, AbstractMetaFunctionList> getFunctionGroups(const AbstractMetaClass* scope = 0);
+ /**
+ * Returns all overloads for a function named \p functionName.
+ * \param scope scope used to search for overloads.
+ * \param functionName the function name.
+ */
+ AbstractMetaFunctionList getFunctionOverloads(const AbstractMetaClass* scope, const QString& functionName);
+ /**
+ * Returns the minimun and maximun number of arguments which this function and all overloads
+ * can accept. Arguments removed by typesystem are considered as well.
+ */
+ QPair<int, int> getMinMaxArguments(const AbstractMetaFunction* metaFunction);
+ /**
+ * Write a function argument in the C++ in the text stream \p s.
+ * This function just call \code s << argumentString(); \endcode
+ * \param s text stream used to write the output.
+ * \param func the current metafunction.
+ * \param argument metaargument information to be parsed.
+ * \param options some extra options.
+ */
+ void writeArgument(QTextStream &s,
+ const AbstractMetaFunction* func,
+ const AbstractMetaArgument* argument,
+ Options options = NoOption) const;
+ /**
+ * Create a QString in the C++ format to an function argument.
+ * \param func the current metafunction.
+ * \param argument metaargument information to be parsed.
+ * \param options some extra options.
+ */
+ QString argumentString(const AbstractMetaFunction* func,
+ const AbstractMetaArgument* argument,
+ Options options = NoOption) const;
+
+ void writeArgumentNames(QTextStream &s,
+ const AbstractMetaFunction* func,
+ Options options = NoOption) const;
+
+ /**
+ * Function used to write the fucntion arguments on the class buffer.
+ * \param s the class output buffer
+ * \param func the pointer to metafunction information
+ * \param count the number of function arguments
+ * \param options some extra options used during the parser
+ */
+ void writeFunctionArguments(QTextStream &s,
+ const AbstractMetaFunction* func,
+ Options options = NoOption) const;
+ QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const;
+ /**
+ * Write a code snip into the buffer \p s.
+ * CodeSnip are codes inside inject-code tags.
+ * \param s the buffer
+ * \param code_snips a list of code snips
+ * \param position the position to insert the code snip
+ * \param language the kind of code snip
+ * \param func the cpp function
+ * \param lastArg last argument whose value is available, usually the last;
+ * a NULL pointer indicates that no argument will be available,
+ * i.e. a call without arguments.
+ * \param context the class context for the place where the code snip will be written
+ */
+ void writeCodeSnips(QTextStream &s,
+ const CodeSnipList &code_snips,
+ CodeSnip::Position position,
+ TypeSystem::Language language,
+ const AbstractMetaFunction* func = 0,
+ const AbstractMetaArgument* lastArg = 0,
+ const AbstractMetaClass* context = 0);
+
+ /**
+ * Verifies if any of the function's code injections of the "target"
+ * type needs the type system variable "%CPPSELF".
+ * \param func the function to check
+ * \return true if the function's target code snippets use "%CPPSELF"
+ */
+ bool injectedCodeUsesCppSelf(const AbstractMetaFunction* func);
+
+ /**
+ * Verifies if any of the function's code injections of the "native"
+ * type needs the type system variable "%PYSELF".
+ * \param func the function to check
+ * \return true if the function's native code snippets use "%PYSELF"
+ */
+ bool injectedCodeUsesPySelf(const AbstractMetaFunction* func);
+
+ /**
+ * Verifies if any of the function's code injections makes a call
+ * to the C++ method. This is used by the generator to avoid writing calls
+ * to C++ when the user custom code already does this.
+ * \param func the function to check
+ * \return true if the function's code snippets call the wrapped C++ function
+ */
+ bool injectedCodeCallsCppFunction(const AbstractMetaFunction* func);
+
+ /**
+ * Verifies if any of the function's code injections of the "native" class makes a
+ * call to the C++ method. This is used by the generator to avoid writing calls to
+ * Python overrides of C++ virtual methods when the user custom code already does this.
+ * \param func the function to check
+ * \return true if the function's code snippets call the Python override for a C++ virtual method
+ */
+ bool injectedCodeCallsPythonOverride(const AbstractMetaFunction* func);
+
+ /**
+ * Verifies if any of the function's code injections attributes values to
+ * the return variable (%0 or %PYARG_0).
+ * \param func the function to check
+ * \param language the kind of code snip
+ * \return true if the function's code attributes values to "%0" or "%PYARG_0"
+ */
+ bool injectedCodeHasReturnValueAttribution(const AbstractMetaFunction* func, TypeSystem::Language language = TypeSystem::TargetLangCode);
+
+ /**
+ * Function which parse the metafunction information
+ * \param func the function witch will be parserd
+ * \param option some extra options
+ * \param arg_count the number of function arguments
+ */
+ QString functionSignature(const AbstractMetaFunction* func,
+ QString prepend = "",
+ QString append = "",
+ Options options = NoOption,
+ int arg_count = -1) const;
+
+ /// Returns true if there are cases of multiple inheritance in any of its ancestors.
+ bool hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass);
+
+ /// Returns true if the class needs to have a getattro function.
+ bool classNeedsGetattroFunction(const AbstractMetaClass* metaClass);
+
+ /// Returns a list of methods of the given class where each one is part of a different overload with both static and non-static method.
+ AbstractMetaFunctionList getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass* metaClass);
+
+ /// Returns a list of parent classes for a given class.
+ AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass);
+
+ /// Returns a list of all ancestor classes for the given class.
+ AbstractMetaClassList getAllAncestors(const AbstractMetaClass* metaClass);
+
+ const AbstractMetaClass* getMultipleInheritingClass(const AbstractMetaClass* metaClass);
+
+ void writeBaseConversion(QTextStream& s, const AbstractMetaType* type,
+ const AbstractMetaClass* context, Options options = NoOption);
+ /// Simpler version of writeBaseConversion, uses only the base name of the type.
+ void writeBaseConversion(QTextStream& s, const TypeEntry* type);
+ void writeToPythonConversion(QTextStream& s, const AbstractMetaType* type,
+ const AbstractMetaClass* context, const QString& argumentName = QString());
+ void writeToCppConversion(QTextStream& s, const AbstractMetaType* type,
+ const AbstractMetaClass* context, const QString& argumentName, Options options = NoOption);
+ void writeToCppConversion(QTextStream& s, const AbstractMetaClass* metaClass, const QString& argumentName);
+
+ /// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
+ static bool shouldGenerateCppWrapper(const AbstractMetaClass* metaClass);
+
+ static QString wrapperName(const AbstractMetaClass* metaClass);
+
+ static QString fullPythonFunctionName(const AbstractMetaFunction* func);
+ static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
+ static QString protectedFieldGetterName(const AbstractMetaField* field);
+ static QString protectedFieldSetterName(const AbstractMetaField* field);
+
+ static QString pythonPrimitiveTypeName(const QString& cppTypeName);
+ static QString pythonPrimitiveTypeName(const PrimitiveTypeEntry* type);
+
+ static QString pythonOperatorFunctionName(QString cppOpFuncName);
+ static QString pythonOperatorFunctionName(const AbstractMetaFunction* func);
+ static QString pythonRichCompareOperatorId(QString cppOpFuncName);
+ static QString pythonRichCompareOperatorId(const AbstractMetaFunction* func);
+
+ static QString cpythonOperatorFunctionName(const AbstractMetaFunction* func);
+
+ static bool isNumber(QString cpythonApiName);
+ static bool isNumber(const TypeEntry* type);
+ static bool isNumber(const AbstractMetaType* type);
+ static bool isPyInt(const TypeEntry* type);
+ static bool isPyInt(const AbstractMetaType* type);
+ static bool isCString(const AbstractMetaType* type);
+ static bool isPairContainer(const AbstractMetaType* type);
+
+ /// Checks if an argument type should be dereferenced by the Python method wrapper before calling the C++ method.
+ static bool shouldDereferenceArgumentPointer(const AbstractMetaArgument* arg);
+ /// Checks if a meta type should be dereferenced by the Python method wrapper passing it to C++.
+ static bool shouldDereferenceAbstractMetaTypePointer(const AbstractMetaType* metaType);
+
+ static bool visibilityModifiedToPrivate(const AbstractMetaFunction* func);
+
+ QString cpythonBaseName(const AbstractMetaClass* metaClass);
+ QString cpythonBaseName(const TypeEntry* type);
+ QString cpythonBaseName(const AbstractMetaType* type);
+ QString cpythonTypeName(const AbstractMetaClass* metaClass);
+ QString cpythonTypeName(const TypeEntry* type);
+ QString cpythonTypeNameExt(const TypeEntry* type);
+ QString cpythonCheckFunction(const TypeEntry* type, bool genericNumberType = false);
+ QString cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
+ QString guessCPythonCheckFunction(const QString& type);
+ QString cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType = false, bool checkExact = false);
+ QString cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
+ QString cpythonIsConvertibleFunction(const AbstractMetaArgument* metaArg, bool genericNumberType = false)
+ {
+ return cpythonIsConvertibleFunction(metaArg->type(), genericNumberType);
+ }
+ QString guessCPythonIsConvertible(const QString& type);
+ QString cpythonFunctionName(const AbstractMetaFunction* func);
+ QString cpythonMethodDefinitionName(const AbstractMetaFunction* func);
+ QString cpythonGettersSettersDefinitionName(const AbstractMetaClass* metaClass);
+ QString cpythonGetattroFunctionName(const AbstractMetaClass* metaClass);
+ QString cpythonSetattroFunctionName(const AbstractMetaClass* metaClass);
+ QString cpythonGetterFunctionName(const AbstractMetaField* metaField);
+ QString cpythonSetterFunctionName(const AbstractMetaField* metaField);
+ QString cpythonWrapperCPtr(const AbstractMetaClass* metaClass, QString argName = "self");
+ 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)
+ {
+ return cpythonEnumName(metaEnum->typeEntry());
+ }
+
+ QString cpythonFlagsName(const FlagsTypeEntry* flagsEntry);
+ QString cpythonFlagsName(const AbstractMetaEnum* metaEnum)
+ {
+ FlagsTypeEntry* flags = metaEnum->typeEntry()->flags();
+ if (!flags)
+ return QString();
+ return cpythonFlagsName(flags);
+ }
+ /// Returns the special cast function name, the function used to proper cast class with multiple inheritance.
+ QString cpythonSpecialCastFunctionName(const AbstractMetaClass* metaClass);
+
+ QString getFunctionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const;
+ QString getFormatUnitString(const AbstractMetaFunction* func, bool incRef = false) const;
+
+ /// Returns the file name for the module global header. If no module name is provided the current will be used.
+ QString getModuleHeaderFileName(const QString& moduleName = QString()) const;
+
+ QString extendedIsConvertibleFunctionName(const TypeEntry* targetType) const;
+ QString extendedToCppFunctionName(const TypeEntry* targetType) const;
+
+ QMap< QString, QString > options() const;
+
+ /// Returns true if the user enabled the so called "parent constructor heuristic".
+ bool useCtorHeuristic() const;
+ /// Returns true if the user enabled the so called "return value heuristic".
+ bool useReturnValueHeuristic() const;
+ /// Returns true if the user enabled PySide extensions.
+ bool usePySideExtensions() const;
+ QString cppApiVariableName(const QString& moduleName = QString()) const;
+ QString getTypeIndexVariableName(const TypeEntry* metaType);
+ /// Returns true if the user don't want verbose error messages on the generated bindings.
+ bool verboseErrorMessagesDisabled() const;
+
+ /**
+ * Builds an AbstractMetaType object from a QString.
+ * Returns NULL if no type could be built from the string.
+ * \param typeString The string describing the type to be built.
+ * \return A new AbstractMetaType object that must be deleted by the caller, or a NULL pointer in case of failure.
+ */
+ AbstractMetaType* buildAbstractMetaTypeFromString(QString typeString);
+
+protected:
+ bool doSetup(const QMap<QString, QString>& args);
+ // verify whether the class is copyable
+ bool isCopyable(const AbstractMetaClass* metaClass);
+
+ bool m_native_jump_table;
+ static QHash<QString, QString> m_pythonPrimitiveTypeName;
+ static QHash<QString, QString> m_pythonOperators;
+ static QHash<QString, QString> m_formatUnits;
+ static QHash<QString, QString> m_tpFuncs;
+
+ void clearTpFuncs();
+
+ const char* name() const { return "Shiboken"; }
+
+ /**
+ * Initialize correspondences between primitive and Python types
+ */
+ static void initPrimitiveTypesCorrespondences();
+
+ void writeFunctionCall(QTextStream& s,
+ const AbstractMetaFunction* metaFunc,
+ Options options = NoOption) const;
+
+ static AbstractMetaFunctionList filterFunctions(const AbstractMetaClass* metaClass);
+
+ // All data about extended converters: the type entries of the target type, and a
+ // list of AbstractMetaClasses accepted as argument for the conversion.
+ typedef QHash<const TypeEntry*, QList<const AbstractMetaClass*> > ExtendedConverterData;
+ /// Returns all extended conversions for the current module.
+ ExtendedConverterData getExtendedConverters() const;
+
+ /// Returns true if the Python wrapper for the received OverloadData must accept a list of arguments.
+ static bool pythonFunctionWrapperUsesListOfArguments(const OverloadData& overloadData);
+
+ Indentor INDENT;
+private:
+ bool m_useCtorHeuristic;
+ bool m_userReturnValueHeuristic;
+ bool m_usePySideExtensions;
+ bool m_verboseErrorMessagesDisabled;
+};
+
+
+#endif // SHIBOKENGENERATOR_H
+