aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp13
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h3
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp4
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst19
-rw-r--r--sources/shiboken6/generator/generator.cpp8
-rw-r--r--sources/shiboken6/generator/generator.h2
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp2
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp64
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.h4
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp12
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h4
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml4
12 files changed, 127 insertions, 12 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index 55e5d3e8a..a220996a1 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -93,6 +93,7 @@ public:
int m_sbkIndex = 0;
TypeEntry::Type m_type;
bool m_stream = false;
+ bool m_private = false;
};
TypeEntryPrivate::TypeEntryPrivate(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
@@ -344,6 +345,16 @@ void TypeEntry::setStream(bool b)
m_d->m_stream = b;
}
+bool TypeEntry::isPrivate() const
+{
+ return m_d->m_private;
+}
+
+void TypeEntry::setPrivate(bool b)
+{
+ m_d->m_private = b;
+}
+
QString TypeEntry::name() const
{
return m_d->m_name;
@@ -2061,6 +2072,8 @@ void TypeEntry::formatDebug(QDebug &debug) const
debug << ", sbkIndex=" << m_d->m_sbkIndex;
if (m_d->m_include.isValid())
debug << ", include=" << m_d->m_include;
+ if (m_d->m_private)
+ debug << ", [private]";
formatList(debug, "extraIncludes", m_d->m_extraIncludes, ", ");
}
diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h
index 7d96c1bfb..abbbcd049 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -147,6 +147,9 @@ public:
bool stream() const;
void setStream(bool b);
+ bool isPrivate() const;
+ void setPrivate(bool b);
+
// The type's name in C++, fully qualified
QString name() const;
// C++ excluding inline namespaces
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 42a4015fc..baf979a8f 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -100,6 +100,7 @@ static inline QString staticAttribute() { return QStringLiteral("static"); }
static inline QString threadAttribute() { return QStringLiteral("thread"); }
static inline QString sourceAttribute() { return QStringLiteral("source"); }
static inline QString streamAttribute() { return QStringLiteral("stream"); }
+static inline QString privateAttribute() { return QStringLiteral("private"); }
static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
static inline QString visibleAttribute() { return QStringLiteral("visible"); }
@@ -1551,6 +1552,9 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
const auto name = attributes->at(i).qualifiedName();
if (name == streamAttribute()) {
ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute(), false));
+ } else if (name == privateAttribute()) {
+ ctype->setPrivate(convertBoolean(attributes->takeAt(i).value(),
+ privateAttribute(), false));
} else if (name == generateAttribute()) {
generate = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
} else if (name ==packageAttribute()) {
diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst
index fadc78cd2..a8761d7f2 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -318,6 +318,7 @@ value-type
disable-wrapper="yes | no"
exception-handling="..."
hash-function="..."
+ private="yes | no"
stream="yes | no"
default-constructor="..."
revision="..."
@@ -344,6 +345,8 @@ value-type
For the *optional* **disable-wrapper** attribute, see :ref:`object-type`.
+ For the *optional* **private** attribute, see :ref:`private_types`.
+
The **revision** attribute can be used to specify a revision for each type, easing the
production of ABI compatible bindings.
@@ -378,6 +381,7 @@ object-type
exception-handling="..."
force-abstract="yes | no"
hash-function="..."
+ private="yes | no"
stream="yes | no"
revision="..."
snake-case="yes | no | both" />
@@ -402,6 +406,8 @@ object-type
references, or using a default value that cannot be generated for a
parameter, or similar).
+ For the *optional* **private** attribute, see :ref:`private_types`.
+
The *optional* attribute **stream** specifies whether this type will be able to
use externally defined operators, like QDataStream << and >>. If equals to **yes**,
these operators will be called as normal methods within the current class.
@@ -601,3 +607,16 @@ Conditional Processing
Other keywords can be specified using the
:ref:`--keywords <conditional_keywords>` command line option.
+
+.. _private_types:
+
+Private Types
+^^^^^^^^^^^^^
+
+Marking :ref:`object-type` or :ref:`value-type` entries as private causes a
+separate, private module header besides the public module header to be
+generated for them.
+
+This can be used for classes that are not referenced in dependent modules
+and helps to prevent the propagation of for example private C++ headers
+required for them.
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index 58998a380..1988c63f6 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -177,6 +177,7 @@ struct Generator::GeneratorPrivate
AbstractMetaTypeList instantiatedContainers;
AbstractMetaTypeList instantiatedSmartPointers;
AbstractMetaClassCList m_invisibleTopNamespaces;
+ bool m_hasPrivateClasses = false;
};
Generator::Generator() : m_d(new GeneratorPrivate)
@@ -464,6 +465,8 @@ bool Generator::generate()
for (auto cls : m_d->api.classes()) {
if (!generateFileForContext(contextForClass(cls)))
return false;
+ if (shouldGenerate(cls) && cls->typeEntry()->isPrivate())
+ m_d->m_hasPrivateClasses = true;
}
const auto smartPointers = m_d->api.smartPointers();
@@ -508,6 +511,11 @@ const ApiExtractorResult &Generator::api() const
return m_d->api;
}
+bool Generator::hasPrivateClasses() const
+{
+ return m_d->m_hasPrivateClasses;
+}
+
QString Generator::getFullTypeName(const TypeEntry *type)
{
QString result = type->qualifiedCppName();
diff --git a/sources/shiboken6/generator/generator.h b/sources/shiboken6/generator/generator.h
index 2930ff5ee..48ce9edca 100644
--- a/sources/shiboken6/generator/generator.h
+++ b/sources/shiboken6/generator/generator.h
@@ -237,6 +237,8 @@ public:
/// Returns the API as determined by ApiExtractor
const ApiExtractorResult &api() const;
+ bool hasPrivateClasses() const;
+
/**
* Retrieves the name of the currently processed module.
* While package name is a complete package idetification, e.g. 'PySide.QtCore',
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 2e9ea8d0b..c58842c95 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -413,6 +413,8 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
s << "#include <helper.h>\n#include <iostream>\n";
s << "\n// module include\n" << "#include \"" << getModuleHeaderFileName() << "\"\n";
+ if (hasPrivateClasses())
+ s << "#include \"" << getPrivateModuleHeaderFileName() << "\"\n";
QString headerfile = fileNameForContext(classContext);
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp
index 8bf22d52c..d4dc38090 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -404,6 +404,7 @@ bool HeaderGenerator::finishGeneration()
// This header should be included by binding modules
// extendind on top of this one.
QSet<Include> includes;
+ QSet<Include> privateIncludes;
StringStream macrosStream(TextStream::Language::Cpp);
const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
@@ -494,6 +495,7 @@ bool HeaderGenerator::finishGeneration()
macrosStream << "// Macros for type check\n";
StringStream typeFunctions(TextStream::Language::Cpp);
+ StringStream privateTypeFunctions(TextStream::Language::Cpp);
if (usePySideExtensions()) {
typeFunctions << "QT_WARNING_PUSH\n";
typeFunctions << "QT_WARNING_DISABLE_DEPRECATED\n";
@@ -512,19 +514,22 @@ bool HeaderGenerator::finishGeneration()
//Includes
const TypeEntry *classType = metaClass->typeEntry();
- includes << classType->include();
+ const bool isPrivate = classType->isPrivate();
+ auto &includeList = isPrivate ? privateIncludes : includes;
+ includeList << classType->include();
+ auto &typeFunctionsStr = isPrivate ? privateTypeFunctions : typeFunctions;
for (const AbstractMetaEnum &cppEnum : metaClass->enums()) {
if (cppEnum.isAnonymous() || cppEnum.isPrivate())
continue;
EnumTypeEntry *enumType = cppEnum.typeEntry();
- includes << enumType->include();
+ includeList << enumType->include();
writeProtectedEnumSurrogate(protEnumsSurrogates, cppEnum);
- writeSbkTypeFunction(typeFunctions, cppEnum);
+ writeSbkTypeFunction(typeFunctionsStr, cppEnum);
}
if (!metaClass->isNamespace())
- writeSbkTypeFunction(typeFunctions, metaClass);
+ writeSbkTypeFunction(typeFunctionsStr, metaClass);
}
for (const AbstractMetaType &metaType : instantiatedSmartPtrs) {
@@ -535,9 +540,9 @@ bool HeaderGenerator::finishGeneration()
if (usePySideExtensions())
typeFunctions << "QT_WARNING_POP\n";
- QString moduleHeaderFileName(outputDirectory()
- + QDir::separator() + subDirectoryForPackage(packageName())
- + QDir::separator() + getModuleHeaderFileName());
+ const QString moduleHeaderDir = outputDirectory() + QLatin1Char('/')
+ + subDirectoryForPackage(packageName()) + QLatin1Char('/');
+ const QString moduleHeaderFileName(moduleHeaderDir + getModuleHeaderFileName());
QString includeShield(QLatin1String("SBK_") + moduleName().toUpper() + QLatin1String("_PYTHON_H"));
@@ -599,7 +604,50 @@ bool HeaderGenerator::finishGeneration()
<< "} // namespace Shiboken\n\n"
<< "#endif // " << includeShield << "\n\n";
- return file.done() != FileOut::Failure;
+ if (file.done() == FileOut::Failure)
+ return false;
+
+ return !hasPrivateClasses()
+ || writePrivateHeader(moduleHeaderDir, includeShield,
+ privateIncludes, privateTypeFunctions.toString());
+}
+
+bool HeaderGenerator::writePrivateHeader(const QString &moduleHeaderDir,
+ const QString &publicIncludeShield,
+ const QSet<Include> &privateIncludes,
+ const QString &privateTypeFunctions)
+{
+ // Write includes and type functions of private classes
+
+ FileOut privateFile(moduleHeaderDir + getPrivateModuleHeaderFileName());
+ TextStream &ps = privateFile.stream;
+ ps.setLanguage(TextStream::Language::Cpp);
+ QString privateIncludeShield =
+ publicIncludeShield.left(publicIncludeShield.size() - 2)
+ + QStringLiteral("_P_H");
+
+ ps << licenseComment()<< "\n\n";
+
+ ps << "#ifndef " << privateIncludeShield << '\n';
+ ps << "#define " << privateIncludeShield << "\n\n";
+
+ for (const Include &include : qAsConst(privateIncludes))
+ ps << include;
+ ps << '\n';
+
+ if (usePySideExtensions())
+ ps << "QT_WARNING_PUSH\nQT_WARNING_DISABLE_DEPRECATED\n";
+
+ ps << "namespace Shiboken\n{\n\n"
+ << "// PyType functions, to get the PyObjectType for a type T\n"
+ << privateTypeFunctions << '\n'
+ << "} // namespace Shiboken\n\n";
+
+ if (usePySideExtensions())
+ ps << "QT_WARNING_POP\n";
+
+ ps << "#endif\n";
+ return privateFile.done() != FileOut::Failure;
}
void HeaderGenerator::writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum) const
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.h b/sources/shiboken6/generator/shiboken/headergenerator.h
index 1fe0dd444..91a10eef8 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.h
+++ b/sources/shiboken6/generator/shiboken/headergenerator.h
@@ -65,6 +65,10 @@ private:
void writeMemberFunctionWrapper(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const QString &postfix = {}) const;
+ bool writePrivateHeader(const QString &moduleHeaderDir,
+ const QString &publicIncludeShield,
+ const QSet<Include> &privateIncludes,
+ const QString &privateTypeFunctions);
QSet<AbstractMetaFunctionCPtr> m_inheritedOverloads;
};
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 05a9e7571..4ecc69b15 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -2125,9 +2125,19 @@ const AbstractMetaClass *ShibokenGenerator::getMultipleInheritingClass(const Abs
return getMultipleInheritingClass(metaClass->baseClass());
}
+QString ShibokenGenerator::getModuleHeaderFileBaseName(const QString &moduleName)
+{
+ return moduleCppPrefix(moduleName).toLower() + QStringLiteral("_python");
+}
+
QString ShibokenGenerator::getModuleHeaderFileName(const QString &moduleName)
{
- return moduleCppPrefix(moduleName).toLower() + QLatin1String("_python.h");
+ return getModuleHeaderFileBaseName(moduleName) + QStringLiteral(".h");
+}
+
+QString ShibokenGenerator::getPrivateModuleHeaderFileName(const QString &moduleName)
+{
+ return getModuleHeaderFileBaseName(moduleName) + QStringLiteral("_p.h");
}
std::optional<AbstractMetaType>
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index bcba349cf..29b32c23a 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -313,7 +313,8 @@ protected:
static QString getFormatUnitString(const AbstractMetaFunctionCPtr &func, bool incRef = false);
/// Returns the file name for the module global header. If no module name is provided the current will be used.
- static QString getModuleHeaderFileName(const QString &moduleName = QString()) ;
+ static QString getModuleHeaderFileName(const QString &moduleName = QString());
+ static QString getPrivateModuleHeaderFileName(const QString &moduleName = QString());
OptionDescriptions options() const override;
bool handleOption(const QString &key, const QString &value) override;
@@ -398,6 +399,7 @@ protected:
static const QHash<QString, QString> &formatUnits();
private:
+ static QString getModuleHeaderFileBaseName(const QString &moduleName = QString());
static QString cpythonGetterFunctionName(const QString &name,
const AbstractMetaClass *enclosingClass);
static QString cpythonSetterFunctionName(const QString &name,
diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
index fe5e4343c..d86a637ff 100644
--- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -2302,7 +2302,7 @@
<object-type name="MDerived5"/>
<object-type name="SonOfMDerived1"/>
- <object-type name="Bucket">
+ <object-type name="Bucket" private="true">
<modify-function signature="lock()" allow-thread="yes" />
<modify-function signature="virtualBlockerMethod()" allow-thread="yes"/>
<modify-function signature="callVirtualBlockerMethodButYouDontKnowThis()" allow-thread="yes"/>
@@ -2330,7 +2330,7 @@
<property type="RenderHints" name="renderHints" get="getRenderHints" set="setRenderHints"/>
</value-type>
- <value-type name="CtorConvRule">
+ <value-type name="CtorConvRule" private="true">
<modify-function signature="CtorConvRule(long)">
<modify-argument index="1">
<!--<replace-type modified-type="long"/>-->