aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-01-11 17:50:36 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-01-18 16:33:25 +0100
commitc1e64f5e5583ba6e9e36bf54327747018a2541bc (patch)
treeffa8b7cd64b671cdcc2432fab6ed2bc9fc7cf493
parent26a1b40e4fa878a11995528dcf04158b44477477 (diff)
shiboken6/Type system parser: Handle native-to-target and vv in argument conversion rules
Introduce new parser states and handle it accordingly in </native-to-target> and </target-to-native>. Use it in the sample tests. Pick-to: 6.2 Fixes: PYSIDE-1766 Change-Id: Id00dd3ad65799c497b008499c02fbf7ee2e5f856 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp86
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml28
2 files changed, 80 insertions, 34 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 77dbeedae..6302b9ba4 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -548,6 +548,8 @@ enum class ParserState
PrimitiveTypeNativeToTargetConversion,
PrimitiveTypeTargetToNativeConversion,
ArgumentConversion, // Argument conversion rule with class attribute
+ ArgumentNativeToTargetConversion,
+ ArgumentTargetToNativeConversion,
FunctionCodeInjection,
TypeEntryCodeInjection,
TypeSystemCodeInjection,
@@ -884,27 +886,47 @@ bool TypeSystemParser::endElement(StackElement element)
while (modIndex < top->functionMods.size())
top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex));
}
- break;
+ break;
case StackElement::NativeToTarget:
- case StackElement::AddConversion: {
- auto *customConversion = top->entry->customConversion();
- if (!customConversion) {
- m_error = QLatin1String("CustomConversion object is missing.");
- return false;
- }
-
- QString code = top->conversionCodeSnips.takeLast().code();
- if (element == StackElement::AddConversion) {
- if (customConversion->targetToNativeConversions().isEmpty()) {
- m_error = QLatin1String("CustomConversion's target to native conversions missing.");
+ case StackElement::AddConversion:
+ switch (parserState()) {
+ case ParserState::PrimitiveTypeNativeToTargetConversion:
+ case ParserState::PrimitiveTypeTargetToNativeConversion:
+ if (auto *customConversion = top->entry->customConversion()) {
+ QString code = top->conversionCodeSnips.constLast().code();
+ if (element == StackElement::AddConversion) {
+ if (customConversion->targetToNativeConversions().isEmpty()) {
+ m_error = u"CustomConversion's target to native conversions missing."_qs;
+ return false;
+ }
+ customConversion->targetToNativeConversions().last()->setConversion(code);
+ } else {
+ customConversion->setNativeToTargetConversion(code);
+ }
+ } else {
+ m_error = QLatin1String("CustomConversion object is missing.");
return false;
}
- customConversion->targetToNativeConversions().last()->setConversion(code);
- } else {
- customConversion->setNativeToTargetConversion(code);
+ break;
+
+ case ParserState::ArgumentNativeToTargetConversion: {
+ top->conversionCodeSnips.last().language = TypeSystem::TargetLangCode;
+ auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
+ lastArgMod.conversionRules().append(top->conversionCodeSnips.constLast());
}
- }
- break;
+ break;
+ case ParserState::ArgumentTargetToNativeConversion: {
+ top->conversionCodeSnips.last().language = TypeSystem::NativeCode;
+ auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
+ lastArgMod.conversionRules().append(top->conversionCodeSnips.constLast());
+ }
+ break;
+ default:
+ break;
+ }
+ top->conversionCodeSnips.clear();
+ break;
+
case StackElement::EnumTypeEntry:
top->entry->setDocModification(top->docModifications);
top->docModifications = DocModificationList();
@@ -947,9 +969,13 @@ ParserState TypeSystemParser::parserState(qsizetype offset) const
switch (m_stack.at(last)) {
// Primitive entry with conversion rule
case StackElement::NativeToTarget: // <conversion-rule><native-to-target>
+ if (stackSize > 2 && m_stack.at(last - 2) == StackElement::ModifyArgument)
+ return ParserState::ArgumentNativeToTargetConversion;
return ParserState::PrimitiveTypeNativeToTargetConversion;
case StackElement::AddConversion: // <conversion-rule><target-to-native><add-conversion>
+ if (stackSize > 3 && m_stack.at(last - 3) == StackElement::ModifyArgument)
+ return ParserState::ArgumentTargetToNativeConversion;
return ParserState::PrimitiveTypeTargetToNativeConversion;
case StackElement::ConversionRule:
@@ -995,6 +1021,8 @@ CodeSnipAbstract *TypeSystemParser::injectCodeTarget(qsizetype offset) const
switch (state) {
case ParserState::PrimitiveTypeNativeToTargetConversion:
case ParserState::PrimitiveTypeTargetToNativeConversion:
+ case ParserState::ArgumentNativeToTargetConversion:
+ case ParserState::ArgumentTargetToNativeConversion:
return &top->conversionCodeSnips.last();
case ParserState::ArgumentConversion:
return &top->functionMods.last().argument_mods().last().conversionRules().last();
@@ -2108,6 +2136,13 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
CodeSnip snip;
if (!readFileSnippet(attributes, &snip))
return false;
+
+ const auto &top = m_contextStack.top();
+ top->conversionCodeSnips.append(snip);
+
+ if (parserState() == ParserState::ArgumentTargetToNativeConversion)
+ return true;
+
for (int i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == QLatin1String("type"))
@@ -2115,13 +2150,12 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
else if (name == QLatin1String("check"))
typeCheck = attributes->takeAt(i).value().toString();
}
+
if (sourceTypeName.isEmpty()) {
m_error = QLatin1String("Target to Native conversions must specify the input type with the 'type' attribute.");
return false;
}
- const auto &top = m_contextStack.top();
top->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
- top->conversionCodeSnips.append(snip);
return true;
}
@@ -3165,11 +3199,15 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
m_error = QLatin1String("Target to Native conversions can only be specified for custom conversion rules.");
return false;
}
- const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
- const bool replace = replaceIndex == -1
- || convertBoolean(attributes.takeAt(replaceIndex).value(),
- replaceAttribute(), true);
- top->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
+
+ const auto topParent = m_stack.value(m_stack.size() - 3, StackElement::None);
+ if ((topParent & StackElement::TypeEntryMask) != 0) {
+ const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
+ const bool replace = replaceIndex == -1
+ || convertBoolean(attributes.takeAt(replaceIndex).value(),
+ replaceAttribute(), true);
+ top->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
+ }
}
break;
case StackElement::AddConversion:
diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
index 5ec2c6302..7d463b3a5 100644
--- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -486,8 +486,12 @@
<modify-function signature="doSomethingWithArray(const unsigned char*, unsigned int, const char*)">
<modify-argument index="1">
<replace-type modified-type="const char*"/>
- <conversion-rule class="native">
- const unsigned char* %out = reinterpret_cast&lt;const unsigned char*>(Shiboken::String::toCString(%PYARG_1));
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ const unsigned char* %out = reinterpret_cast&lt;const unsigned char*>(Shiboken::String::toCString(%PYARG_1));
+ </add-conversion>
+ </target-to-native>
</conversion-rule>
</modify-argument>
<modify-argument index="2">
@@ -1161,14 +1165,18 @@
</modify-argument>
<modify-argument index="return">
<replace-type modified-type="PySequence"/>
- <conversion-rule class="native">
- Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
- Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
- *%2 = %CONVERTTOCPP[bool](_py_ok_);
- %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
- </conversion-rule>
- <conversion-rule class="target">
- <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
+ *%2 = %CONVERTTOCPP[bool](_py_ok_);
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
+ </add-conversion>
+ </target-to-native>
+ <native-to-target>
+ <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ </native-to-target>
</conversion-rule>
</modify-argument>
</modify-function>