aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-17 12:54:10 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-24 13:52:35 +0200
commit97b4305474fd25a68b95b815cca6e413fcc80884 (patch)
tree7cf8259bac7367a3c4fed2b98ffc331680d37757
parent56c24b5d1aa507c62bdf3af917519e6c7cf7718c (diff)
shiboken6: TypeEntry: Use a pointer to the target lang API type entry
Replace the string m_targetLangApiName by a pointer to the type entry; allowing to retrieve the check function. Similarly, in TargetToNativeConversion::sourceTypeCheck(), use the existing type entry to retrieve the check function, allowing for removing some heuristics. Task-number: PYSIDE-1660 Change-Id: Ieeda43f804b4e129d3cc0984e36bd0c0d546fd86 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h1
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp33
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h5
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp13
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp15
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp52
7 files changed, 88 insertions, 37 deletions
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index d851a02e0..00d9dd816 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -826,3 +826,9 @@ QString msgDuplicateTypeEntry(const QString &name)
{
return u"Duplicate type entry: '"_qs + name + u"'."_qs;
}
+
+QString msgInvalidTargetLanguageApiName(const QString &name)
+{
+ return u"Invalid target language API name \""_qs
+ + name + u"\"."_qs;
+}
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 8c924aa86..7e6fd87a5 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -237,5 +237,6 @@ QString msgUnknownTypeInArgumentTypeReplacement(const QString &typeReplaced,
QString msgDuplicateBuiltInTypeEntry(const QString &name);
QString msgDuplicateTypeEntry(const QString &name);
+QString msgInvalidTargetLanguageApiName(const QString &name);
#endif // MESSAGES_H
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index 298baa7d7..6ad87a736 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -71,7 +71,6 @@ public:
const TypeEntry *m_parent;
QString m_name; // C++ fully qualified
- QString m_targetLangApiName;
mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
@@ -89,6 +88,7 @@ public:
SourceLocation m_sourceLocation; // XML file
TypeEntry::CodeGeneration m_codeGeneration = TypeEntry::GenerateCode;
TypeEntry *m_viewOn = nullptr;
+ CustomTypeEntry *m_targetLangApiType = nullptr;
int m_revision = 0;
int m_sbkIndex = 0;
TypeEntry::Type m_type;
@@ -440,15 +440,25 @@ QString TypeEntry::qualifiedCppName() const
return m_d->m_name;
}
-QString TypeEntry::targetLangApiName() const
+const CustomTypeEntry *TypeEntry::targetLangApiType() const
+{
+ return m_d->m_targetLangApiType;
+}
+
+bool TypeEntry::hasTargetLangApiType() const
{
- return m_d->m_targetLangApiName.isEmpty()
- ? m_d->m_name : m_d->m_targetLangApiName;
+ return m_d->m_targetLangApiType != nullptr;
}
-void TypeEntry::setTargetLangApiName(const QString &t)
+void TypeEntry::setTargetLangApiType(CustomTypeEntry *cte)
{
- m_d->m_targetLangApiName = t;
+ m_d->m_targetLangApiType = cte;
+}
+
+QString TypeEntry::targetLangApiName() const
+{
+ return m_d->m_targetLangApiType != nullptr
+ ? m_d->m_targetLangApiType->name() : m_d->m_name;
}
QString TypeEntry::targetLangName() const
@@ -2067,7 +2077,16 @@ QString CustomConversion::TargetToNativeConversion::sourceTypeName() const
QString CustomConversion::TargetToNativeConversion::sourceTypeCheck() const
{
- return m_d->sourceTypeCheck;
+ if (!m_d->sourceTypeCheck.isEmpty())
+ return m_d->sourceTypeCheck;
+
+ if (m_d->sourceType != nullptr && m_d->sourceType->isCustom()) {
+ const auto *cte = static_cast<const CustomTypeEntry *>(m_d->sourceType);
+ if (cte->hasCheckFunction())
+ return cte->checkFunction() + u"(%in)"_qs;
+ }
+
+ return {};
}
QString CustomConversion::TargetToNativeConversion::conversion() const
diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h
index fcd0abe99..fc77fc6ca 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -43,6 +43,7 @@ class FlagsTypeEntry;
class SourceLocation;
class PrimitiveTypeEntry;
class TypeSystemTypeEntry;
+class CustomTypeEntry;
class TypeEntryPrivate;
class TemplateArgumentEntryPrivate;
@@ -185,8 +186,10 @@ public:
/// be a JNI name, for Python it should represent the CPython type name.
/// \return string representing the target language API name
/// Currently used only for PrimitiveTypeEntry (attribute "target").
+ const CustomTypeEntry *targetLangApiType() const;
+ bool hasTargetLangApiType() const;
+ void setTargetLangApiType(CustomTypeEntry *cte);
QString targetLangApiName() const;
- void setTargetLangApiName(const QString &t);
// The type's name in TargetLang
QString targetLangName() const; // "Foo.Bar"
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index fe1761dd8..a3730ef29 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -1334,6 +1334,7 @@ PrimitiveTypeEntry *
if (!checkRootElement())
return nullptr;
auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry());
+ QString targetLangApiName;
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
for (int i = attributes->size() - 1; i >= 0; --i) {
@@ -1341,7 +1342,7 @@ PrimitiveTypeEntry *
if (name == targetLangNameAttribute()) {
type->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == QLatin1String("target-lang-api-name")) {
- type->setTargetLangApiName(attributes->takeAt(i).value().toString());
+ targetLangApiName = attributes->takeAt(i).value().toString();
} else if (name == preferredConversionAttribute()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
@@ -1354,8 +1355,14 @@ PrimitiveTypeEntry *
}
}
- if (type->targetLangApiName().isEmpty())
- type->setTargetLangApiName(type->name());
+ if (!targetLangApiName.isEmpty()) {
+ auto *e = m_database->findType(targetLangApiName);
+ if (e == nullptr || !e->isCustom()) {
+ m_error = msgInvalidTargetLanguageApiName(targetLangApiName);
+ return nullptr;
+ }
+ type->setTargetLangApiType(static_cast<CustomTypeEntry *>(e));
+ }
type->setTargetLangPackage(m_defaultPackage);
return type;
}
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 8e1a2c934..0b9ad6636 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -1576,7 +1576,7 @@ return result;)";
const AbstractMetaType sourceType = conv->arguments().constFirst().type();
typeCheck = cpythonCheckFunction(sourceType);
bool isUserPrimitiveWithoutTargetLangName = sourceType.isUserPrimitive()
- && sourceType.typeEntry()->targetLangApiName() == sourceType.typeEntry()->name();
+ && !sourceType.typeEntry()->hasTargetLangApiType();
if (!sourceType.isWrapperType()
&& !isUserPrimitiveWithoutTargetLangName
&& !sourceType.typeEntry()->isEnum()
@@ -3266,15 +3266,6 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
typeCheck = QLatin1String("Shiboken::isShibokenEnum(%in)");
else if (pyTypeName == QLatin1String("SbkObject"))
typeCheck = QLatin1String("Shiboken::Object::checkType(%in)");
- else if (pyTypeName == cPyTypeObjectT())
- typeCheck = QLatin1String("PyType_Check(%in)");
- else if (pyTypeName == cPyObjectT())
- typeCheck = QLatin1String("PyObject_TypeCheck(%in, &PyBaseObject_Type)");
- // PYSIDE-795: We abuse PySequence for iterables
- else if (pyTypeName == cPySequenceT())
- typeCheck = QLatin1String("Shiboken::String::checkIterable(%in)");
- else if (pyTypeName.startsWith(QLatin1String("Py")))
- typeCheck = pyTypeName + QLatin1String("_Check(%in)");
}
if (typeCheck.isEmpty()) {
if (!toNative->sourceType() || toNative->sourceType()->isPrimitive()) {
@@ -4040,8 +4031,8 @@ void CppGenerator::writePrimitiveConverterInitialization(TextStream &s,
QString converter = converterObject(type);
s << "// Register converter for type '" << type->qualifiedTargetLangName() << "'.\n"
<< converter << " = Shiboken::Conversions::createConverter(";
- if (type->targetLangApiName() == type->name())
- s << '0';
+ if (!type->hasTargetLangApiType())
+ s << "nullptr";
else if (type->targetLangApiName() == cPyObjectT())
s << "&PyBaseObject_Type";
else
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 282d8dc34..99e90c1ef 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -695,10 +695,8 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntry *type)
baseName = QLatin1String("Sbk_") + type->name();
} else if (type->isPrimitive()) {
const auto *ptype = type->asPrimitive()->basicReferencedTypeEntry();
- if (ptype->targetLangApiName() == ptype->name())
- baseName = pythonPrimitiveTypeName(ptype->name());
- else
- baseName = ptype->targetLangApiName();
+ baseName = ptype->hasTargetLangApiType()
+ ? ptype->targetLangApiName() : pythonPrimitiveTypeName(ptype->name());
} else if (type->isEnum()) {
baseName = cpythonEnumName(static_cast<const EnumTypeEntry *>(type));
} else if (type->isFlags()) {
@@ -949,12 +947,30 @@ bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
|| cpythonApiName == pyBoolT();
}
+static std::optional<TypeSystem::CPythonType>
+ targetLangApiCPythonType(const PrimitiveTypeEntry *t)
+{
+ if (!t->hasTargetLangApiType())
+ return {};
+ const auto *cte = t->targetLangApiType();
+ if (cte->type() != TypeEntry::PythonType)
+ return {};
+ return static_cast<const PythonTypeEntry *>(cte)->cPythonType();
+}
+
bool ShibokenGenerator::isNumber(const TypeEntry *type)
{
if (!type->isPrimitive())
return false;
const auto *pte = type->asPrimitive()->basicReferencedTypeEntry();
- return isNumber(pythonPrimitiveTypeName(pte->name()));
+ const auto cPythonTypeOpt = targetLangApiCPythonType(pte);
+ // FIXME PYSIDE-1660: Return false here after making primitive types built-in?
+ if (!cPythonTypeOpt.has_value())
+ return isNumber(pythonPrimitiveTypeName(pte->name()));
+ const auto cPythonType = cPythonTypeOpt.value();
+ return cPythonType == TypeSystem::CPythonType::Bool
+ || cPythonType == TypeSystem::CPythonType::Float
+ || cPythonType == TypeSystem::CPythonType::Integer;
}
bool ShibokenGenerator::isNumber(const AbstractMetaType &type)
@@ -968,6 +984,11 @@ bool ShibokenGenerator::isPyInt(const TypeEntry *type)
return false;
const auto *pte = type->asPrimitive()->basicReferencedTypeEntry();
return pythonPrimitiveTypeName(pte->name()) == u"PyLong";
+ const auto cPythonTypeOpt = targetLangApiCPythonType(pte);
+ // FIXME PYSIDE-1660: Return false here after making primitive types built-in?
+ if (!cPythonTypeOpt.has_value())
+ return pythonPrimitiveTypeName(pte->name()) == pyLongT();
+ return cPythonTypeOpt.value() == TypeSystem::CPythonType::Integer;
}
bool ShibokenGenerator::isPyInt(const AbstractMetaType &type)
@@ -1064,19 +1085,22 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type) const
if (type->isEnum() || type->isFlags() || type->isWrapperType())
return u"SbkObject_TypeCheck("_qs + cpythonTypeNameExt(type) + u", "_qs;
+
+ if (type->isPrimitive())
+ type = type->asPrimitive()->basicReferencedTypeEntry();
+
+ if (auto *tla = type->targetLangApiType()) {
+ if (tla->hasCheckFunction())
+ return tla->checkFunction();
+ }
+
if (type->isExtendedCppPrimitive()) {
- const auto *pte = type->asPrimitive()->basicReferencedTypeEntry();
+ const auto *pte = type->asPrimitive();
return pythonPrimitiveTypeName(pte->name())
+ QLatin1String("_Check");
}
- QString typeCheck;
- if (type->targetLangApiName() == type->name())
- typeCheck = cpythonIsConvertibleFunction(type);
- else if (type->targetLangApiName() == QLatin1String("PyUnicode"))
- typeCheck = QLatin1String("Shiboken::String::check");
- else
- typeCheck = type->targetLangApiName() + QLatin1String("_Check");
- return typeCheck;
+
+ return cpythonIsConvertibleFunction(type);
}
ShibokenGenerator::CPythonCheckFunctionResult